Unverified Commit 2fd47427 authored by Jonah Brüchert's avatar Jonah Brüchert 🌳

Initial Kirigami port

parent 0a68cd2b
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.0
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.core 2.0 as PlasmaCore
PlasmaComponents.Button {
width : units.gridUnit * 5
height: units.gridUnit * 3
}
import QtQuick 2.7
import QtMultimedia 5.8
import org.kde.kirigami 2.0 as Kirigami
import QtQuick.Controls 2.0 as Controls
import QtQuick.Layouts 1.2
Kirigami.Page {
id: cameraPage
leftPadding: 0
rightPadding: 0
bottomPadding: 0
topPadding: 0
mainAction: Kirigami.Action {
id: captureAction
text: qsTr("Capture")
iconName: {
if (camera.captureMode == Camera.CaptureStillImage)
return "camera-photo"
else if (camera.captureMode == Camera.CaptureVideo)
return "video-mp4"
}
onTriggered: camera.imageCapture.capture()
}
leftAction: Kirigami.Action {
id: switchAction
text: qsTr("Switch mode")
iconName: "document-swap"
onTriggered: {
if (camera.captureMode == Camera.CaptureStillImage)
camera.captureMode = Camera.CaptureVideo
else
camera.captureMode = Camera.CaptureStillImage
console.log("Capture Mode switched")
}
}
Rectangle {
id: cameraUI
state: "PhotoCapture"
anchors {
fill: parent
centerIn: parent
}
color: "darkgrey"
states: [
State {
name: "PhotoCapture"
StateChangeScript {
script: {
camera.captureMode = Camera.CaptureStillImage
camera.start()
}
}
},
State {
name: "VideoCapture"
StateChangeScript {
script: {
camera.captureMode = Camera.CaptureVideo
camera.start()
}
}
}
]
Camera {
id: camera
captureMode: Camera.CaptureStillImage
imageProcessing.whiteBalanceMode: CameraImageProcessing.WhiteBalanceFlash
imageCapture {
id: imageCapture
}
videoRecorder {
id: videoRecorder
resolution: settings.videoResolution
frameRate: 15
}
}
VideoPreview {
id : videoPreview
anchors.fill : parent
onClosed: cameraUI.state = "VideoCapture"
visible: cameraUI.state == "VideoPreview"
focus: visible
//don't load recorded video if preview is invisible
source: visible ? camera.videoRecorder.actualLocation : ""
}
VideoOutput {
id: viewfinder
visible: cameraUI.state == "PhotoCapture" || cameraUI.state == "VideoCapture"
// Workaround
orientation: Kirigami.Settings.isMobile ? -90 : 0
anchors.fill: parent
source: camera
}
PinchArea {
anchors.fill: parent
property real initialZoom
onPinchStarted: {
initialZoom = camera.digitalZoom;
}
onPinchUpdated: {
var scale = camera.maximumDigitalZoom / 8 * pinch.scale - camera.maximumDigitalZoom / 8;
camera.setDigitalZoom(Math.min(camera.maximumDigitalZoom, camera.digitalZoom + scale))
}
}
}
Controls.Slider {
orientation: Qt.Vertical
from: 1
value: camera.digitalZoom
to: Math.min(4.0, camera.maximumDigitalZoom)
height: Kirigami.Units.gridUnit * 30
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
}
onValueChanged: camera.setDigitalZoom(value)
}
}
import org.kde.kirigami 2.0 as Kirigami
import QtQuick 2.7
Kirigami.GlobalDrawer {
actions: [
Kirigami.Action {
text: qsTr("Video resolution")
Kirigami.Action {
text: "640x480"
onTriggered: settings.videoResolution = text;
}
Kirigami.Action {
text: "1280x720"
onTriggered: settings.videoResolution = text;
}
Kirigami.Action {
text: "1920x1080"
onTriggered: settings.resolution = text
}
}
]
Component.onCompleted: console.log(imageCapture.supportedResolutions)
}
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.4
import QtMultimedia 5.4
import org.kde.plasma.core 2.0 as PlasmaCore
FocusScope {
property Camera camera
property bool previewAvailable : false
property int buttonsPanelWidth: buttonPaneShadow.width
signal previewSelected
signal videoModeSelected
id : captureControls
PlasmaCore.FrameSvgItem {
id: buttonPaneShadow
imagePath: "widgets/background"
enabledBorders: PlasmaCore.FrameSvgItem.RightBorder
width: bottomColumn.width + 16 + margins.right
height: parent.height
anchors.top: parent.top
x: menuShown ? 0 : -width
Behavior on x {
XAnimator {
duration: units.shortDuration
easing.type: Easing.InOutQuad
}
}
Column {
anchors {
left: parent.left
top: parent.top
margins: 8
}
id: buttonsColumn
spacing: 8
FocusButton {
camera: captureControls.camera
visible: camera.cameraStatus == Camera.ActiveStatus && camera.focus.isFocusModeSupported(Camera.FocusAuto)
}
CameraPropertyButton {
id : wbModesButton
value: CameraImageProcessing.WhiteBalanceAuto
model: ListModel {
ListElement {
icon: "images/camera_auto_mode.png"
value: CameraImageProcessing.WhiteBalanceAuto
text: "Auto"
}
ListElement {
icon: "images/camera_white_balance_sunny.png"
value: CameraImageProcessing.WhiteBalanceSunlight
text: "Sunlight"
}
ListElement {
icon: "images/camera_white_balance_cloudy.png"
value: CameraImageProcessing.WhiteBalanceCloudy
text: "Cloudy"
}
ListElement {
icon: "images/camera_white_balance_incandescent.png"
value: CameraImageProcessing.WhiteBalanceTungsten
text: "Tungsten"
}
ListElement {
icon: "images/camera_white_balance_flourescent.png"
value: CameraImageProcessing.WhiteBalanceFluorescent
text: "Fluorescent"
}
}
onValueChanged: captureControls.camera.imageProcessing.whiteBalanceMode = wbModesButton.value
}
CameraButton {
text: "View"
onClicked: captureControls.previewSelected()
visible: captureControls.previewAvailable
}
}
Column {
anchors {
bottom: parent.bottom
left: parent.left
margins: 8
}
id: bottomColumn
spacing: 8
CameraListButton {
model: QtMultimedia.availableCameras
onValueChanged: captureControls.camera.deviceId = value
}
CameraButton {
id: switchButton
text: "Switch to Video"
onClicked: captureControls.videoModeSelected()
}
Item {
width: 1
height: switchButton.height
}
}
}
CameraButton {
anchors {
margins: 8
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
}
text: "Capture"
visible: camera.imageCapture.ready
onClicked: camera.imageCapture.capture()
}
CameraButton {
z: 99
anchors {
margins: 8
left: parent.left
bottom: parent.bottom
}
text: "Menu"
onClicked: menuShown = !menuShown
}
ZoomControl {
anchors {
top: parent.top
right: parent.right
margins: units.gridUnit
}
width : units.gridUnit
height: units.gridUnit * 20
currentZoom: camera.digitalZoom
maximumZoom: camera.maximumDigitalZoom
onZoomTo: camera.setDigitalZoom(value)
}
}
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.4
import QtMultimedia 5.4
import org.kde.plasma.core 2.0 as PlasmaCore
FocusScope {
property Camera camera
property bool previewAvailable : false
property int buttonsPanelWidth: buttonPaneShadow.width
signal previewSelected
signal photoModeSelected
id : captureControls
PlasmaCore.FrameSvgItem {
id: buttonPaneShadow
imagePath: "widgets/background"
enabledBorders: PlasmaCore.FrameSvgItem.RightBorder
width: bottomColumn.width + 16 + margins.right
height: parent.height
anchors.top: parent.top
x: menuShown ? 0 : -width
Behavior on x {
XAnimator {
duration: units.shortDuration
easing.type: Easing.InOutQuad
}
}
Column {
anchors {
left: parent.left
top: parent.top
margins: 8
}
id: buttonsColumn
spacing: 8
FocusButton {
camera: captureControls.camera
visible: camera.cameraStatus == Camera.ActiveStatus && camera.focus.isFocusModeSupported(Camera.FocusAuto)
}
CameraButton {
text: "View"
onClicked: captureControls.previewSelected()
//don't show View button during recording
visible: camera.videoRecorder.actualLocation && !stopButton.visible
}
}
Column {
anchors {
bottom: parent.bottom
left: parent.left
margins: 8
}
id: bottomColumn
spacing: 8
CameraListButton {
model: QtMultimedia.availableCameras
onValueChanged: captureControls.camera.deviceId = value
}
CameraButton {
id: switchButton
text: "Switch to Photo"
onClicked: captureControls.photoModeSelected()
}
Item {
width: 1
height: switchButton.height
}
}
}
CameraButton {
anchors {
margins: 8
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
}
text: camera.videoRecorder.recorderStatus == CameraRecorder.RecordingStatus ? "Stop" : "Record"
onClicked: {
if (camera.videoRecorder.recorderStatus == CameraRecorder.RecordingStatus) {
camera.videoRecorder.stop();
} else {
camera.videoRecorder.record();
}
}
}
CameraButton {
z: 99
anchors {
margins: 8
left: parent.left
bottom: parent.bottom
}
text: "Menu"
onClicked: menuShown = !menuShown
}
ZoomControl {
x : 0
y : 0
width : 100
height: parent.height
currentZoom: camera.digitalZoom
maximumZoom: Math.min(4.0, camera.maximumDigitalZoom)
onZoomTo: camera.setDigitalZoom(value)
}
}
......@@ -38,163 +38,24 @@
**
****************************************************************************/
import QtQuick 2.0
import QtMultimedia 5.4
import QtQuick 2.7
import org.kde.kirigami 2.2 as Kirigami
import Qt.labs.settings 1.0
Rectangle {
id : cameraUI
width: 1080
height: 1920
color: "black"
state: "PhotoCapture"
property bool menuShown: false
states: [
State {
name: "PhotoCapture"
StateChangeScript {
script: {
camera.captureMode = Camera.CaptureStillImage
camera.start()
}
}
PropertyChanges {
target: photoPreview
width: cameraUI.width / 5
height: cameraUI.height / 5
}
},
State {
name: "PhotoPreview"
PropertyChanges {
target: photoPreview
width: cameraUI.width
height: cameraUI.height
}
PropertyChanges {
target: photoPreviewTimer
running: true
}
},
State {
name: "VideoCapture"
StateChangeScript {
script: {
camera.captureMode = Camera.CaptureVideo
camera.start()
}
}
},
State {
name: "VideoPreview"
StateChangeScript {
script: {
camera.stop()
}
}
}
]
transitions: [
Transition {
id: previewTransition
NumberAnimation {
properties: "width, height"
duration: units.longDuration
}
}
]
Timer {
id: photoPreviewTimer
interval: 2000
onTriggered: cameraUI.state = "PhotoCapture"
Kirigami.ApplicationWindow {
Settings {
id: settings
// Default settings
property string videoResolution: "640x480"
}
Camera {
id: camera
captureMode: Camera.CaptureStillImage
imageCapture {
onImageCaptured: {
stillControls.previewAvailable = true
previewTransition.enabled = false;
cameraUI.state = "PhotoPreview"
previewTransition.enabled = true;
}
}
videoRecorder {
resolution: "640x480"
frameRate: 15
}
}
PhotoPreview {
id : photoPreview
z: 999
anchors {
right : parent.right
bottom: parent.bottom
}
onClicked: {
cameraUI.state == "PhotoCapture" ? cameraUI.state = "PhotoPreview" : cameraUI.state = "PhotoCapture";
photoPreviewTimer.running = false;
}
//visible: cameraUI.state == "PhotoPreview"