summaryrefslogtreecommitdiffstats
path: root/experimental
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@digia.com>2013-06-24 15:47:31 +0200
committerEirik Aavitsland <eirik.aavitsland@digia.com>2013-09-23 12:54:29 +0300
commit35edc19994995491aaf44e9bac851e1f8cda17ce (patch)
tree986e0114b63f846619601b89e550bf28b431bdcc /experimental
parentd571f4769863bfb8035ff9ab61a7fbd797ae0452 (diff)
Added Mediaplayer and Camera demos.
It's currently in the experimental directory since it has been tested only on the Nexus 7. Change-Id: I9503ded9504841b80a88c6e2541bed0234d73cfc Reviewed-by: Eirik Aavitsland <eirik.aavitsland@digia.com>
Diffstat (limited to 'experimental')
-rw-r--r--experimental/Camera/CameraControlButton.qml54
-rw-r--r--experimental/Camera/CameraSetting.qml28
-rw-r--r--experimental/Camera/CaptureControl.qml40
-rw-r--r--experimental/Camera/CapturePreview.qml45
-rw-r--r--experimental/Camera/Controls.qml159
-rw-r--r--experimental/Camera/FocusControl.qml111
-rw-r--r--experimental/Camera/Picker.qml89
-rw-r--r--experimental/Camera/README2
-rw-r--r--experimental/Camera/RecordingTime.qml70
-rw-r--r--experimental/Camera/Slider.qml93
-rw-r--r--experimental/Camera/ZoomControl.qml40
-rw-r--r--experimental/Camera/description.txt5
-rw-r--r--experimental/Camera/main.qml223
-rw-r--r--experimental/Camera/qmlplugin/camerautils.cpp189
-rw-r--r--experimental/Camera/qmlplugin/camerautils.h87
-rw-r--r--experimental/Camera/qmlplugin/camerautils.pro19
-rw-r--r--experimental/Camera/qmlplugin/plugin.cpp60
-rw-r--r--experimental/Camera/qmlplugin/qmldir2
-rwxr-xr-xexperimental/Media Player/Content.qml124
-rwxr-xr-xexperimental/Media Player/ContentVideo.qml93
-rwxr-xr-xexperimental/Media Player/ControlBar.qml285
-rwxr-xr-xexperimental/Media Player/EffectSelectionPanel.qml162
-rwxr-xr-xexperimental/Media Player/Effects/Effect.qml75
-rwxr-xr-xexperimental/Media Player/Effects/EffectBillboard.qml89
-rwxr-xr-xexperimental/Media Player/Effects/EffectBlackAndWhite.qml74
-rwxr-xr-xexperimental/Media Player/Effects/EffectEmboss.qml73
-rwxr-xr-xexperimental/Media Player/Effects/EffectGaussianBlur.qml136
-rwxr-xr-xexperimental/Media Player/Effects/EffectGlow.qml74
-rwxr-xr-xexperimental/Media Player/Effects/EffectIsolate.qml105
-rwxr-xr-xexperimental/Media Player/Effects/EffectMagnify.qml117
-rwxr-xr-xexperimental/Media Player/Effects/EffectPageCurl.qml196
-rwxr-xr-xexperimental/Media Player/Effects/EffectPassThrough.qml46
-rwxr-xr-xexperimental/Media Player/Effects/EffectPixelate.qml76
-rwxr-xr-xexperimental/Media Player/Effects/EffectPosterize.qml82
-rwxr-xr-xexperimental/Media Player/Effects/EffectRipple.qml98
-rwxr-xr-xexperimental/Media Player/Effects/EffectSepia.qml61
-rwxr-xr-xexperimental/Media Player/Effects/EffectSharpen.qml87
-rwxr-xr-xexperimental/Media Player/Effects/EffectShockwave.qml109
-rwxr-xr-xexperimental/Media Player/Effects/EffectSobelEdgeDetection1.qml98
-rwxr-xr-xexperimental/Media Player/Effects/EffectSobelEdgeDetection2.qml89
-rwxr-xr-xexperimental/Media Player/Effects/EffectTiltShift.qml77
-rwxr-xr-xexperimental/Media Player/Effects/EffectToon.qml111
-rwxr-xr-xexperimental/Media Player/Effects/EffectVignette.qml66
-rwxr-xr-xexperimental/Media Player/Effects/EffectWarhol.qml68
-rwxr-xr-xexperimental/Media Player/Effects/EffectWobble.qml79
-rw-r--r--experimental/Media Player/FileBrowser.qml415
-rwxr-xr-xexperimental/Media Player/ImageButton.qml44
-rw-r--r--experimental/Media Player/Intro.qml48
-rw-r--r--experimental/Media Player/MetadataView.qml173
-rw-r--r--experimental/Media Player/ParameterPanel.qml110
-rwxr-xr-xexperimental/Media Player/PlaybackControl.qml60
-rwxr-xr-xexperimental/Media Player/SeekControl.qml83
-rw-r--r--experimental/Media Player/Slider.qml98
-rw-r--r--experimental/Media Player/UrlBar.qml80
-rwxr-xr-xexperimental/Media Player/VolumeControl.qml45
-rw-r--r--experimental/Media Player/description.txt3
-rw-r--r--experimental/Media Player/images/CameraButton.pngbin0 -> 237 bytes
-rw-r--r--experimental/Media Player/images/ControlBar.pngbin0 -> 5081 bytes
-rw-r--r--experimental/Media Player/images/FXButton.pngbin0 -> 1208 bytes
-rw-r--r--experimental/Media Player/images/FileButton.pngbin0 -> 564 bytes
-rwxr-xr-xexperimental/Media Player/images/FullscreenButton.pngbin0 -> 4304 bytes
-rw-r--r--experimental/Media Player/images/PauseButton.pngbin0 -> 762 bytes
-rw-r--r--experimental/Media Player/images/PlayButton.pngbin0 -> 1679 bytes
-rwxr-xr-xexperimental/Media Player/images/PlaybackSlider.pngbin0 -> 435 bytes
-rw-r--r--experimental/Media Player/images/RateButtonForward.pngbin0 -> 1387 bytes
-rw-r--r--experimental/Media Player/images/RateButtonReverse.pngbin0 -> 1433 bytes
-rw-r--r--experimental/Media Player/images/SliderBackground.pngbin0 -> 793 bytes
-rwxr-xr-xexperimental/Media Player/images/SliderHandle.pngbin0 -> 4459 bytes
-rwxr-xr-xexperimental/Media Player/images/SliderProgress.pngbin0 -> 4461 bytes
-rw-r--r--experimental/Media Player/images/UrlButton.pngbin0 -> 1613 bytes
-rwxr-xr-xexperimental/Media Player/images/VolumeDown.pngbin0 -> 4130 bytes
-rwxr-xr-xexperimental/Media Player/images/VolumeUp.pngbin0 -> 4258 bytes
-rw-r--r--experimental/Media Player/images/folder.pngbin0 -> 1841 bytes
-rw-r--r--experimental/Media Player/images/gradient.pngbin0 -> 34302 bytes
-rw-r--r--experimental/Media Player/images/pattern.pngbin0 -> 2627 bytes
-rwxr-xr-xexperimental/Media Player/images/qt-logo.pngbin0 -> 11465 bytes
-rw-r--r--experimental/Media Player/images/titlebar.pngbin0 -> 1436 bytes
-rwxr-xr-xexperimental/Media Player/images/titlebar.sci5
-rw-r--r--experimental/Media Player/images/up.pngbin0 -> 662 bytes
-rwxr-xr-xexperimental/Media Player/main.qml289
80 files changed, 5519 insertions, 0 deletions
diff --git a/experimental/Camera/CameraControlButton.qml b/experimental/Camera/CameraControlButton.qml
new file mode 100644
index 0000000..dc82435
--- /dev/null
+++ b/experimental/Camera/CameraControlButton.qml
@@ -0,0 +1,54 @@
+import QtQuick 2.0
+
+MouseArea {
+ id: buttonRoot
+ property alias title: titleTxt.text
+ property alias subtitle: valueTxt.text
+ property bool toggled: false
+
+ width: 78 * root.contentScale
+ height: 78 * root.contentScale
+ opacity: pressed ? 0.3 : 1.0
+ rotation: root.contentRotation
+ Behavior on rotation { NumberAnimation { } }
+
+ Rectangle {
+ anchors.fill: parent
+ color: toggled ? "#8898c66c" : "#77333333"
+ radius: 5 * root.contentScale
+ }
+
+ Column {
+ id: expModeControls
+ spacing: 2 * root.contentScale
+ anchors.centerIn: parent
+
+ Text {
+ id: titleTxt
+ anchors.horizontalCenter: expModeControls.horizontalCenter
+ font.pixelSize: 22 * root.contentScale
+ font.letterSpacing: -1
+ color: "white"
+ font.bold: true
+ }
+
+ Text {
+ id: valueTxt
+ anchors.horizontalCenter: expModeControls.horizontalCenter
+ height: 22 * root.contentScale
+ verticalAlignment: Text.AlignVCenter
+ color: "white"
+
+ Connections {
+ target: root
+ onContentScaleChanged: valueTxt.font.pixelSize = Math.round(18 * root.contentScale)
+ }
+
+ onTextChanged: font.pixelSize = Math.round(18 * root.contentScale)
+ onPaintedWidthChanged: {
+ if (paintedWidth > buttonRoot.width - (8 * root.contentScale))
+ font.pixelSize -= Math.round(2 * root.contentScale);
+ }
+ }
+ }
+}
diff --git a/experimental/Camera/CameraSetting.qml b/experimental/Camera/CameraSetting.qml
new file mode 100644
index 0000000..224c70c
--- /dev/null
+++ b/experimental/Camera/CameraSetting.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.0
+
+Item {
+ width: button.width
+ height: button.height
+ visible: enabled && picker.count > 1
+
+ property alias title: button.title
+ property alias selectedValue: picker.value
+ property alias currentIndex: picker.currentIndex
+ property alias model: picker.model
+ property alias count: picker.count
+
+ CameraControlButton {
+ id: button
+ anchors.centerIn: parent
+
+ subtitle: picker.name
+ toggled: picker.visible
+
+ onClicked: picker.visible = true
+ }
+
+ Picker {
+ id: picker
+ }
+
+}
diff --git a/experimental/Camera/CaptureControl.qml b/experimental/Camera/CaptureControl.qml
new file mode 100644
index 0000000..b8180f9
--- /dev/null
+++ b/experimental/Camera/CaptureControl.qml
@@ -0,0 +1,40 @@
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Rectangle {
+ id: controlRoot
+
+ signal clicked
+
+ property bool videoMode: camera.captureMode === Camera.CaptureVideo
+
+ width: 180 * root.contentScale
+ height: width
+ radius: width / 2
+ color: mouser.pressed ? (controlRoot.videoMode ? "#77fa334f" : "#7798c66c") : "#77333333"
+ visible: enabled
+
+ Rectangle {
+ id: center
+ anchors.centerIn: parent
+ width: parent.width * 0.45
+ height: width
+ radius: width / 2
+ opacity: mouser.pressed ? 0.7 : 1
+ color: controlRoot.videoMode ? "#fa334f" : "#98c66c"
+ }
+
+ Rectangle {
+ anchors.centerIn: parent
+ color: "white"
+ visible: camera.videoRecorder.recorderStatus === CameraRecorder.RecordingStatus
+ width: center.width * 0.3
+ height: width
+ }
+
+ MouseArea {
+ id: mouser
+ anchors.fill: parent
+ onClicked: controlRoot.clicked()
+ }
+}
diff --git a/experimental/Camera/CapturePreview.qml b/experimental/Camera/CapturePreview.qml
new file mode 100644
index 0000000..611fa53
--- /dev/null
+++ b/experimental/Camera/CapturePreview.qml
@@ -0,0 +1,45 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ anchors.fill: parent
+ color: "black"
+ opacity: 0
+ enabled: opacity !== 0
+
+ property string previewSrc: ""
+
+ onOpacityChanged: {
+ if (opacity === 1 && previewSrc !== "") {
+ previewImage.source = previewSrc;
+ previewSrc = "";
+ }
+ }
+
+ Behavior on opacity { NumberAnimation { duration: 100 } }
+
+ function show() {
+ previewImage.source = "";
+ opacity = 1;
+ }
+
+ function setPreview(preview) {
+ if (root.opacity === 1)
+ previewImage.source = preview;
+ else
+ root.previewSrc = preview;
+ }
+
+ Image {
+ id: previewImage
+ anchors.fill: parent
+ fillMode: Image.PreserveAspectFit
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ root.opacity = 0;
+ }
+ }
+}
diff --git a/experimental/Camera/Controls.qml b/experimental/Camera/Controls.qml
new file mode 100644
index 0000000..63f750b
--- /dev/null
+++ b/experimental/Camera/Controls.qml
@@ -0,0 +1,159 @@
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Item {
+ id: controlsRoot
+ anchors.fill: parent
+
+ property alias cameraMode: cameraModeControl.selectedValue
+
+ property alias requestedZoom: zoomControl.requestedZoom
+ property alias actualZoom: zoomControl.actualZoom
+ property alias maximumZoom: zoomControl.maximumZoom
+
+ property alias flashMode: flashControl.selectedValue
+ property alias focusMode: focusModeControl.selectedValue
+ property alias exposureMode: expModeControl.selectedValue
+ property alias exposureCompensation: expCompControl.selectedValue
+ property alias whiteBalanceMode: wbControl.selectedValue
+ property alias resolution: resControl.selectedValue
+
+ property bool captureReady: false
+
+ signal capture
+ signal searchAndLock
+
+ FocusControl {
+ id: focusControl
+ anchors.fill: parent
+ onSearchAndLock: controlsRoot.searchAndLock()
+ enabled: camera.captureMode === Camera.CaptureStillImage
+ }
+
+ ZoomControl {
+ id: zoomControl
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 50
+ }
+
+ CameraSetting {
+ id: cameraModeControl
+ anchors.right: parent.right
+ anchors.rightMargin: 20
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 20
+ title: "MODE"
+ model: ListModel {
+ ListElement {
+ name: "Picture"
+ value: Camera.CaptureStillImage
+ }
+ ListElement {
+ name: "Video"
+ value: Camera.CaptureVideo
+ }
+ }
+ onCountChanged: currentIndex = 0
+ enabled: controlsRoot.captureReady
+ }
+
+ RecordingTime {
+ anchors.right: parent.right
+ anchors.rightMargin: 40
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 60 * root.contentScale
+ visible: camera.videoRecorder.recorderStatus === CameraRecorder.RecordingStatus
+ }
+
+ Row {
+ anchors.left: parent.left
+ anchors.leftMargin: 20
+ anchors.top: parent.top
+ anchors.topMargin: 20
+ height: 84
+ spacing: 20
+
+ CameraSetting {
+ id: flashControl
+ title: "FLASH"
+ model: cameraUtils.supportedFlashModes
+ }
+
+ CameraSetting {
+ id: focusModeControl
+ title: "FOCUS"
+ model: cameraUtils.supportedFocusModes
+ enabled: camera.captureMode === Camera.CaptureStillImage
+ }
+
+ CameraSetting {
+ id: expModeControl
+ title: "SCENE"
+ model: cameraUtils.supportedSceneModes
+ }
+
+ CameraSetting {
+ id: expCompControl
+ title: "EV"
+ model: ListModel {
+ ListElement {
+ name: "+2"
+ value: 2
+ }
+ ListElement {
+ name: "+1"
+ value: 1
+ }
+ ListElement {
+ name: "0"
+ value: 0
+ }
+ ListElement {
+ name: "-1"
+ value: -1
+ }
+ ListElement {
+ name: "-2"
+ value: -2
+ }
+ }
+ }
+
+ CameraSetting {
+ id: wbControl
+ title: "WB"
+ model: cameraUtils.supportedWhiteBalanceModes
+ }
+
+ CameraSetting {
+ id: resControl
+ title: "SIZE"
+ model: cameraUtils.supportedCaptureResolutions
+// onCountChanged: currentIndex = 1
+
+ Component.onCompleted: currentIndex = 1
+
+ Connections {
+ target: camera
+ onCaptureModeChanged: {
+ if (camera.captureMode === Camera.CaptureStillImage) {
+ resControl.model = cameraUtils.supportedCaptureResolutions;
+ } else {
+ resControl.model = cameraUtils.supportedVideoResolutions;
+ }
+ }
+ }
+ }
+ }
+
+ CaptureControl {
+ id: captureControl
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ anchors.rightMargin: -30
+ enabled: controlsRoot.captureReady || camera.videoRecorder.recorderStatus === CameraRecorder.RecordingStatus
+
+ onClicked: controlsRoot.capture()
+ }
+}
diff --git a/experimental/Camera/FocusControl.qml b/experimental/Camera/FocusControl.qml
new file mode 100644
index 0000000..f9b2f29
--- /dev/null
+++ b/experimental/Camera/FocusControl.qml
@@ -0,0 +1,111 @@
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+MouseArea {
+ id: focusRoot
+
+ signal searchAndLock
+
+ onClicked: {
+ camera.focus.focusPointMode = Camera.FocusPointCustom
+ camera.focus.customFocusPoint = viewfinder.mapPointToSourceNormalized(Qt.point(mouse.x, mouse.y))
+ focusRoot.searchAndLock()
+ }
+
+ Item {
+ id: zones
+ anchors.fill: parent
+
+ property color focusAreaColor
+ property real focusAreaScale: 1
+
+ Repeater {
+ model: camera.focus.focusZones
+
+ Rectangle {
+ border {
+ width: Math.round(2 * root.contentScale)
+ color: zones.focusAreaColor
+ }
+ radius: 8 * root.contentScale
+ color: "transparent"
+ scale: zones.focusAreaScale
+
+ // Map from the relative, normalized frame coordinates
+ property rect mappedRect: viewfinder.mapNormalizedRectToItem(area);
+
+ Connections {
+ target: viewfinder
+ onContentRectChanged: {
+ mappedRect = viewfinder.mapNormalizedRectToItem(area);
+ }
+ }
+
+ x: mappedRect.x - (width - mappedRect.width) / 2
+ y: mappedRect.y - (height - mappedRect.height) / 2
+ width: Math.round(120 * root.contentScale)
+ height: width
+
+ Rectangle {
+ anchors.fill: parent
+ anchors.margins: -1.5
+ color: "transparent"
+ border.width: 1
+ border.color: "black"
+ radius: parent.radius + 2
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ anchors.margins: 1 + parent.border.width / 2 + 0.5
+ color: "transparent"
+ border.width: 1
+ border.color: "black"
+ radius: parent.radius - 3
+ }
+ }
+ }
+
+ states: [
+ State {
+ name: "unlocked"; when: camera.lockStatus === Camera.Unlocked
+ PropertyChanges { target: zones; opacity: 0; focusAreaColor: "red" }
+ },
+ State {
+ name: "searching"; when: camera.lockStatus === Camera.Searching
+ PropertyChanges { target: zones; opacity: 1; focusAreaColor: "white" }
+ },
+ State {
+ name: "locked"; when: camera.lockStatus === Camera.Locked
+ PropertyChanges { target: zones; opacity: 0; focusAreaColor: "green" }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ to: "searching"
+ NumberAnimation { properties: "opacity"; duration: 60 }
+ SequentialAnimation {
+ NumberAnimation {
+ target: zones; property: "focusAreaScale"; from: 1; to: 1.3; duration: 150
+ }
+ PauseAnimation { duration: 20 }
+ NumberAnimation {
+ target: zones; property: "focusAreaScale"; easing.period: 1; easing.amplitude: 1.4
+ easing.type: Easing.OutElastic; from: 1.3; to: 1
+ duration: 450
+ }
+ }
+ },
+ Transition {
+ from: "searching"
+ SequentialAnimation {
+ PauseAnimation { duration: 1500 }
+ NumberAnimation { properties: "opacity"; duration: 60 }
+ }
+ }
+
+ ]
+ }
+
+}
diff --git a/experimental/Camera/Picker.qml b/experimental/Camera/Picker.qml
new file mode 100644
index 0000000..364fed7
--- /dev/null
+++ b/experimental/Camera/Picker.qml
@@ -0,0 +1,89 @@
+import QtQuick 2.0
+
+MouseArea {
+ id: pickerRoot
+
+ parent: root
+ anchors.fill: parent
+
+ onClicked: visible = false
+ visible: false
+
+ property alias contentWidth: back.width
+ property real contentHeight: 350 * root.contentScale
+ property alias model: list.model
+ property variant value: null
+ property string name: ""
+ property alias currentIndex: list.currentIndex
+ property alias count: list.count
+
+ onValueChanged: {
+ for (var i = 0; i < list.count; ++i) {
+ var data = list.model[i];
+ if (data === undefined)
+ data = list.model.get(i);
+ if (data.value === pickerRoot.value) {
+ list.currentIndex = i;
+ return;
+ }
+ }
+ list.currentIndex = -1;
+ }
+
+ Rectangle {
+ id: back
+ color: "#77333333"
+ width: 200 * root.contentScale
+ height: Math.min(pickerRoot.contentHeight, list.contentHeight + list.anchors.margins * 2)
+ anchors.centerIn: parent
+ property int itemHeight: 25 * root.contentScale
+ rotation: root.contentRotation
+ Behavior on rotation { NumberAnimation { } }
+
+ ListView {
+ id: list
+ anchors.fill: parent
+ clip: true
+ anchors.margins: 14 * root.contentScale
+
+ currentIndex: -1
+
+ onCurrentIndexChanged: {
+ if (list.currentIndex >= 0) {
+ var data = list.model[list.currentIndex];
+ if (data === undefined)
+ data = list.model.get(list.currentIndex);
+ pickerRoot.value = data.value;
+ pickerRoot.name = data.name;
+ } else {
+ pickerRoot.value = null
+ pickerRoot.name = ""
+ }
+ }
+
+ delegate: Item {
+ height: 40 * root.contentScale
+ width: parent.width
+ Rectangle {
+ anchors.fill: parent
+ border.color: index == list.currentIndex ? "#44ffffff" : "transparent"
+ color: index == list.currentIndex ? "#22ffffff" : "transparent"
+ radius: 3 * root.contentScale
+ Text {
+ color: "white"
+ text: (typeof modelData === 'undefined' ? name : modelData.name)
+ anchors.centerIn: parent
+ font.pixelSize: Math.round(20 * root.contentScale)
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ list.currentIndex = index;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/experimental/Camera/README b/experimental/Camera/README
new file mode 100644
index 0000000..e249fae
--- /dev/null
+++ b/experimental/Camera/README
@@ -0,0 +1,2 @@
+You need to compile and intall the included qml plugin for this demo to work.
+
diff --git a/experimental/Camera/RecordingTime.qml b/experimental/Camera/RecordingTime.qml
new file mode 100644
index 0000000..504d232
--- /dev/null
+++ b/experimental/Camera/RecordingTime.qml
@@ -0,0 +1,70 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: recRoot
+ width: row.width + 14 * root.contentScale
+ height: circle.height + 14 * root.contentScale
+ color: "#77333333"
+ radius: 5 * root.contentScale
+ rotation: root.contentRotation
+ Behavior on rotation { NumberAnimation { } }
+
+ Row {
+ id: row
+ anchors.centerIn: parent
+ spacing: 10 * root.contentScale
+
+ Item {
+ anchors.verticalCenter: timeText.verticalCenter
+ width: 18 * root.contentScale
+ height: width
+
+ Rectangle {
+ id: circle
+ width: parent.width
+ height: parent.height
+ radius: width / 2
+ color: "#fa334f"
+
+ SequentialAnimation {
+ loops: Animation.Infinite
+ running: recRoot.visible
+ PropertyAction { target: circle; property: "visible"; value: true }
+ PauseAnimation { duration: 1000 }
+ PropertyAction { target: circle; property: "visible"; value: false }
+ PauseAnimation { duration: 1000 }
+ }
+ }
+ }
+
+ Text {
+ id: timeText
+ color: "white"
+ font.pixelSize: 24 * root.contentScale
+ text: formatTime(camera.videoRecorder.duration)
+ }
+ }
+
+ function formatTime(time) {
+ time = time / 1000
+ var hours = Math.floor(time / 3600);
+ time = time - hours * 3600;
+ var minutes = Math.floor(time / 60);
+ var seconds = Math.floor(time - minutes * 60);
+
+ if (hours > 0)
+ return formatTimeBlock(hours) + ":" + formatTimeBlock(minutes) + ":" + formatTimeBlock(seconds);
+ else
+ return formatTimeBlock(minutes) + ":" + formatTimeBlock(seconds);
+
+ }
+
+ function formatTimeBlock(time) {
+ if (time === 0)
+ return "00"
+ if (time < 10)
+ return "0" + time;
+ else
+ return time.toString();
+ }
+}
diff --git a/experimental/Camera/Slider.qml b/experimental/Camera/Slider.qml
new file mode 100644
index 0000000..025d521
--- /dev/null
+++ b/experimental/Camera/Slider.qml
@@ -0,0 +1,93 @@
+import QtQuick 2.0
+
+Item {
+ id: slider
+
+ height: handleBack.height
+ // value is read/write.
+ property real value: 0
+ property real maximum: 1
+ property real minimum: 0
+ property int xMax: width - handle.width
+ onXMaxChanged: updatePos()
+ onMinimumChanged: updatePos()
+ onValueChanged: if (!pressed) updatePos()
+ property bool mutable: true
+ property alias pressed : backgroundMouse.pressed
+
+ signal valueChangedByHandle(int newValue)
+
+ function updatePos() {
+ if (maximum > minimum) {
+ var pos = 0 + (value - minimum) * slider.xMax / (maximum - minimum);
+ pos = Math.min(pos, width - handle.width - 0);
+ pos = Math.max(pos, 0);
+ handle.x = pos;
+ } else {
+ handle.x = 0;
+ }
+ }
+
+ Rectangle {
+ id: background
+ width: slider.width
+ anchors.verticalCenter: slider.verticalCenter
+ height: 4 * root.contentScale
+ color: "#666666"
+
+ MouseArea {
+ id: backgroundMouse
+ anchors.fill: parent
+ anchors.topMargin: -24 * root.contentScale
+ anchors.bottomMargin: -24 * root.contentScale
+ enabled: slider.mutable
+ drag.target: handle
+ drag.axis: Drag.XAxis
+ drag.minimumX: 0
+ drag.maximumX: slider.xMax
+ onPressedChanged: {
+ value = Math.max(minimum, Math.min(maximum, (maximum - minimum) * (mouseX - handle.width/2) / slider.xMax + minimum));
+ valueChangedByHandle(value);
+ updatePos();
+ }
+ onPositionChanged: {
+ value = Math.max(minimum, Math.min(maximum, (maximum - minimum) * (mouseX - handle.width/2) / slider.xMax + minimum));
+ valueChangedByHandle(value);
+ }
+ }
+ }
+
+ Rectangle {
+ id: progress
+ height: 8 * root.contentScale
+ anchors.verticalCenter: background.verticalCenter
+ anchors.left: background.left
+ anchors.right: handle.right
+ anchors.rightMargin: handle.width / 2
+ visible: slider.enabled
+ color: "#98c66c"
+ }
+
+ Rectangle {
+ id: handleBack
+ width: 40 * root.contentScale
+ height: width
+ radius: width / 2
+ color: "#8898c66c"
+ antialiasing: true
+ anchors.centerIn: handle
+ visible: handle.visible
+ }
+
+ Rectangle {
+ id: handle
+ width: 14 * root.contentScale
+ height: width
+ radius: width / 2
+ antialiasing: true
+ color: "#98c66c"
+ anchors.verticalCenter: background.verticalCenter
+ visible: slider.enabled
+ }
+}
+
diff --git a/experimental/Camera/ZoomControl.qml b/experimental/Camera/ZoomControl.qml
new file mode 100644
index 0000000..493defe
--- /dev/null
+++ b/experimental/Camera/ZoomControl.qml
@@ -0,0 +1,40 @@
+import QtQuick 2.0
+
+Column {
+ width: 400 * root.contentScale
+ spacing: 20 * root.contentScale
+ visible: maximumZoom > 1
+
+ property alias maximumZoom: zoomSlider.maximum
+ property alias requestedZoom: zoomSlider.value
+ property real actualZoom: 1
+
+ Rectangle {
+ anchors.horizontalCenter: zoomSlider.horizontalCenter
+ width: zoomText.width + 10 * root.contentScale
+ height: zoomText.height + 10 * root.contentScale
+ color: "#77333333"
+ radius: 5 * root.contentScale
+ rotation: root.contentRotation
+ Behavior on rotation { NumberAnimation { } }
+
+ Text {
+ id: zoomText
+ anchors.centerIn: parent
+ font.pixelSize: Math.round(24 * root.contentScale)
+ color: "white"
+ font.bold: true
+ text: (Math.round(actualZoom * 100) / 100) + "x"
+ }
+ }
+
+ Slider {
+ id: zoomSlider
+ width: parent.width
+ rotation: root.contentRotation === -90 ? 180 : (root.contentRotation === 90 ? 0 : root.contentRotation)
+
+ minimum: 1
+ maximum: 1
+ value: 1
+ }
+}
diff --git a/experimental/Camera/description.txt b/experimental/Camera/description.txt
new file mode 100644
index 0000000..7e94e89
--- /dev/null
+++ b/experimental/Camera/description.txt
@@ -0,0 +1,5 @@
+This example demonstrates the use of the camera features of Qt Multimedia with Qt Quick.
+
+It can take pictures and record videos. Files are saved inside the 'DCIM' folder on the external storage.
+
+Camera parameters such as flash mode, scene mode or white balance can be changed. The availability of parameters depends on what the camera driver provides.
diff --git a/experimental/Camera/main.qml b/experimental/Camera/main.qml
new file mode 100644
index 0000000..a1cc89c
--- /dev/null
+++ b/experimental/Camera/main.qml
@@ -0,0 +1,223 @@
+import QtQuick 2.0
+import QtMultimedia 5.0
+//import QtSensors 5.0
+import CameraUtils 1.0
+
+Rectangle {
+ id: root
+ color: "black"
+
+ property real contentScale: root.width / 1280
+ property int contentRotation: 0
+
+ Text {
+ anchors.centerIn: parent
+ color: "white"
+ font.pixelSize: 30
+ text: "Camera service is not available..."
+ visible: camera.cameraStatus === Camera.UnavailableStatus
+ }
+
+ CameraUtils {
+ id: cameraUtils
+ }
+
+ Camera {
+ id: camera
+ property bool updateFocusPointMode: true
+ property bool captureWhenLocked: false
+
+ Component.onCompleted: cameraUtils.setCamera(camera)
+
+ digitalZoom: controls.requestedZoom
+ captureMode: Camera.CaptureStillImage
+
+ onCaptureModeChanged: {
+ if (camera.captureMode === Camera.CaptureVideo) {
+ controls.focusMode = Camera.FocusContinuous;
+ camera.unlock();
+ } else {
+ controls.focusMode = Camera.FocusAuto;
+ }
+ }
+
+ onLockStatusChanged: {
+ if (camera.lockStatus === Camera.Locked && captureWhenLocked) {
+ camera.imageCapture.capture();
+ captureWhenLocked = false;
+ }
+ }
+
+ focus {
+ onFocusModeChanged: {
+ camera.unlock();
+ if (camera.updateFocusPointMode)
+ camera.focus.focusPointMode = Camera.FocusPointAuto
+ }
+ onCustomFocusPointChanged: {
+ if (camera.focus.focusPointMode === Camera.FocusPointCustom
+ && camera.focus.focusMode !== Camera.FocusAuto
+ && camera.focus.focusMode !== Camera.FocusMacro) {
+ camera.updateFocusPointMode = false;
+ camera.focus.focusMode = Camera.FocusAuto
+ controls.focusMode = Camera.FocusAuto
+ camera.updateFocusPointMode = true;
+ }
+ }
+ }
+
+ onCameraStatusChanged: {
+ if (cameraStatus === Camera.ActiveStatus) {
+ controls.exposureMode = camera.exposure.exposureMode
+ controls.exposureCompensation = camera.exposure.exposureCompensation
+ controls.whiteBalanceMode = camera.imageProcessing.whiteBalanceMode
+ controls.flashMode = Camera.FlashAuto
+ if (camera.captureMode === Camera.CaptureStillImage)
+ controls.focusMode = camera.focus.focusMode
+ else
+ camera.focus.focusMode = Camera.FocusContinuous
+ }
+ }
+
+ imageCapture {
+ onImageExposed: capturePreview.show()
+ onImageCaptured: {
+ camera.unlock();
+ capturePreview.setPreview(preview);
+ }
+ onCaptureFailed: print(requestId + " " + message)
+ }
+
+ videoRecorder {
+ // mediaContainer: "mp4"
+ // audioCodec: "aac"
+ // audioSampleRate: 48000
+ // audioBitRate: 192000
+ // audioChannels: 2
+ // videoCodec: "h264"
+ // resolution: Qt.size(960, 720)
+ onResolutionChanged: {
+ if (camera.videoRecorder.resolution == Qt.size(1920, 1080))
+ camera.videoRecorder.videoBitRate = 20000000;
+ else if (camera.videoRecorderresolution == Qt.size(1280, 720))
+ camera.videoRecorder.videoBitRate = 10000000;
+ else
+ camera.videoRecorder.videoBitRate = 5000000;
+ }
+ }
+
+ }
+
+ VideoOutput {
+ id: viewfinder
+ source: camera
+ anchors.fill: parent
+ fillMode: VideoOutput.PreserveAspectFit
+ }
+
+ // OrientationSensor {
+ // active: true
+ // onReadingChanged: {
+ // if (reading.orientation === OrientationReading.TopUp)
+ // root.contentRotation = -90;
+ // else if (reading.orientation === OrientationReading.RightUp)
+ // root.contentRotation = 0;
+ // else if (reading.orientation === OrientationReading.LeftUp)
+ // root.contentRotation = 180;
+ // else if (reading.orientation === OrientationReading.TopDown)
+ // root.contentRotation = 90;
+ // }
+ // }
+
+ // RotationSensor {
+ // active: (camera.cameraStatus === Camera.ActiveStatus)
+ // dataRate: 20
+ // property real lastxvalue: 0
+ // property real lastyvalue: 0
+ // property real lastzvalue: 0
+
+ // onActiveChanged: {
+ // lastxvalue = 0
+ // lastyvalue = 0
+ // lastzvalue = 0
+ // }
+
+ // onReadingChanged: {
+ // if (lastxvalue != 0 && camera.focus.focusMode === Camera.FocusContinuous && camera.lockStatus === Camera.Locked && camera.imageCapture.ready) {
+ // if (Math.abs(reading.x - lastxvalue) > 3 || Math.abs(reading.y - lastyvalue) > 3 || Math.abs(reading.z - lastzvalue) > 3)
+ // camera.unlock();
+ // }
+ // lastxvalue = reading.x;
+ // lastyvalue = reading.y;
+ // lastzvalue = reading.z;
+ // }
+ // }
+
+ Controls {
+ id: controls
+ visible: camera.cameraStatus === Camera.ActiveStatus
+
+ actualZoom: camera.digitalZoom
+ maximumZoom: camera.maximumDigitalZoom
+
+ onCameraModeChanged: camera.captureMode = controls.cameraMode
+
+ onFlashModeChanged: if (visible) camera.flash.mode = controls.flashMode
+ onFocusModeChanged: if (visible) camera.focus.focusMode = controls.focusMode
+ onExposureModeChanged: if (visible) camera.exposure.exposureMode = controls.exposureMode
+ onExposureCompensationChanged: if (visible) camera.exposure.exposureCompensation = controls.exposureCompensation
+ onWhiteBalanceModeChanged: if (visible) camera.imageProcessing.whiteBalanceMode = controls.whiteBalanceMode
+ onResolutionChanged: {
+ if (controls.resolution != null) {
+ if (camera.captureMode === Camera.CaptureStillImage)
+ camera.imageCapture.resolution = controls.resolution;
+ else
+ camera.videoRecorder.resolution = controls.resolution;
+ }
+ }
+
+ onSearchAndLock: {
+ camera.searchAndLock();
+ }
+
+ captureReady: camera.imageCapture.ready
+ onCapture: {
+ if (camera.captureMode === Camera.CaptureVideo) {
+ if (camera.videoRecorder.recorderState === CameraRecorder.RecordingState) {
+ camera.videoRecorder.stop();
+ } else {
+ camera.videoRecorder.record();
+ }
+ } else {
+ if ((camera.focus.focusMode === Camera.FocusAuto || camera.focus.focusMode === Camera.FocusMacro)
+ && camera.focus.focusPointMode === Camera.FocusPointAuto
+ && camera.lockStatus === Camera.Unlocked) {
+ camera.captureWhenLocked = true;
+ camera.searchAndLock();
+ } else {
+ camera.imageCapture.capture();
+ }
+ }
+ }
+ }
+
+ // CameraControlButton {
+ // anchors.left: parent.left
+ // anchors.leftMargin: 30
+ // anchors.bottom: parent.bottom
+ // anchors.bottomMargin: 20
+ // title: camera.cameraStatus === Camera.ActiveStatus ? "Stop" : "Start"
+
+ // onClicked: {
+ // if (camera.cameraStatus === Camera.ActiveStatus)
+ // camera.cameraState = Camera.UnloadedState
+ // else
+ // camera.start();
+ // }
+ // }
+
+ CapturePreview {
+ id: capturePreview
+ }
+
+}
diff --git a/experimental/Camera/qmlplugin/camerautils.cpp b/experimental/Camera/qmlplugin/camerautils.cpp
new file mode 100644
index 0000000..608bfaa
--- /dev/null
+++ b/experimental/Camera/qmlplugin/camerautils.cpp
@@ -0,0 +1,189 @@
+#include "camerautils.h"
+
+#include <QCamera>
+#include <QCameraImageCapture>
+#include <QCameraImageProcessing>
+#include <QCameraExposure>
+#include <QCameraFocus>
+#include <QMediaRecorder>
+
+static QList<CameraSettingsValue*> g_commonResolutions;
+static QList<CameraSettingsValue*> g_commonVideoResolutions;
+static QList<CameraSettingsValue*> g_whiteBalanceModes;
+static QList<CameraSettingsValue*> g_sceneModes;
+static QList<CameraSettingsValue*> g_flashModes;
+static QList<CameraSettingsValue*> g_focusModes;
+
+QDebug operator<<(QDebug dbg, const CameraSettingsValue &r) {
+ dbg.nospace() << "CameraSettingsValue(" << r.name() << ", " << r.value() << ')';
+ return dbg.space();
+}
+
+CameraUtils::CameraUtils(QObject *parent)
+ : QObject(parent)
+ , m_camera(0)
+{
+ if (g_commonResolutions.isEmpty()) {
+ g_commonResolutions << new CameraSettingsValue(QStringLiteral("QVGA"), QSize(320, 240))
+ << new CameraSettingsValue(QStringLiteral("0.3M"), QSize(640, 480))
+ << new CameraSettingsValue(QStringLiteral("0.8M"), QSize(1024, 768))
+ << new CameraSettingsValue(QStringLiteral("1.2M"), QSize(1280, 960))
+ << new CameraSettingsValue(QStringLiteral("2M"), QSize(1600, 1200))
+ << new CameraSettingsValue(QStringLiteral("5M"), QSize(2560, 1920))
+ << new CameraSettingsValue(QStringLiteral("8M"), QSize(3264, 2448));
+
+ g_commonVideoResolutions << new CameraSettingsValue(QStringLiteral("1080p (16:9)"), QSize(1920, 1080))
+ << new CameraSettingsValue(QStringLiteral("1080p (16:9)"), QSize(1920, 1088))
+ << new CameraSettingsValue(QStringLiteral("1080p (4:3)"), QSize(1440, 1080))
+ << new CameraSettingsValue(QStringLiteral("1080p (4:3)"), QSize(1440, 1088))
+ << new CameraSettingsValue(QStringLiteral("720p (16:9)"), QSize(1280, 720))
+ << new CameraSettingsValue(QStringLiteral("720p (4:3)"), QSize(960, 720))
+ << new CameraSettingsValue(QStringLiteral("480p (16:9)"), QSize(720, 480))
+ << new CameraSettingsValue(QStringLiteral("480p (4:3)"), QSize(640, 480))
+ << new CameraSettingsValue(QStringLiteral("QVGA"), QSize(320, 240));
+
+ g_whiteBalanceModes << new CameraSettingsValue(QStringLiteral("Auto"), QCameraImageProcessing::WhiteBalanceAuto)
+ << new CameraSettingsValue(QStringLiteral("Manual"), QCameraImageProcessing::WhiteBalanceManual)
+ << new CameraSettingsValue(QStringLiteral("Sunlight"), QCameraImageProcessing::WhiteBalanceSunlight)
+ << new CameraSettingsValue(QStringLiteral("Cloudy"), QCameraImageProcessing::WhiteBalanceCloudy)
+ << new CameraSettingsValue(QStringLiteral("Shade"), QCameraImageProcessing::WhiteBalanceShade)
+ << new CameraSettingsValue(QStringLiteral("Tungsten"), QCameraImageProcessing::WhiteBalanceTungsten)
+ << new CameraSettingsValue(QStringLiteral("Fluorescent"), QCameraImageProcessing::WhiteBalanceFluorescent)
+ << new CameraSettingsValue(QStringLiteral("Flash"), QCameraImageProcessing::WhiteBalanceFlash)
+ << new CameraSettingsValue(QStringLiteral("Sunset"), QCameraImageProcessing::WhiteBalanceSunset);
+
+ g_sceneModes << new CameraSettingsValue(QStringLiteral("Auto"), QCameraExposure::ExposureAuto)
+ << new CameraSettingsValue(QStringLiteral("Manual"), QCameraExposure::ExposureManual)
+ << new CameraSettingsValue(QStringLiteral("Portrait"), QCameraExposure::ExposurePortrait)
+ << new CameraSettingsValue(QStringLiteral("Night"), QCameraExposure::ExposureNight)
+ << new CameraSettingsValue(QStringLiteral("Backlight"), QCameraExposure::ExposureBacklight)
+ << new CameraSettingsValue(QStringLiteral("Spotlight"), QCameraExposure::ExposureSpotlight)
+ << new CameraSettingsValue(QStringLiteral("Sports"), QCameraExposure::ExposureSports)
+ << new CameraSettingsValue(QStringLiteral("Snow"), QCameraExposure::ExposureSnow)
+ << new CameraSettingsValue(QStringLiteral("Beach"), QCameraExposure::ExposureBeach)
+ << new CameraSettingsValue(QStringLiteral("Large Aperture"), QCameraExposure::ExposureLargeAperture)
+ << new CameraSettingsValue(QStringLiteral("Small Aperture"), QCameraExposure::ExposureSmallAperture);
+
+ g_flashModes << new CameraSettingsValue(QStringLiteral("Auto"), QCameraExposure::FlashAuto)
+ << new CameraSettingsValue(QStringLiteral("Off"), QCameraExposure::FlashOff)
+ << new CameraSettingsValue(QStringLiteral("On"), QCameraExposure::FlashOn)
+ << new CameraSettingsValue(QStringLiteral("Red-Eye"), QCameraExposure::FlashRedEyeReduction)
+ << new CameraSettingsValue(QStringLiteral("Torch"), QCameraExposure::FlashVideoLight);
+
+ g_focusModes << new CameraSettingsValue(QStringLiteral("Auto"), QCameraFocus::AutoFocus)
+ << new CameraSettingsValue(QStringLiteral("Continuous"), QCameraFocus::ContinuousFocus)
+ << new CameraSettingsValue(QStringLiteral("Hyperfocal"), QCameraFocus::HyperfocalFocus)
+ << new CameraSettingsValue(QStringLiteral("Infinity"), QCameraFocus::InfinityFocus)
+ << new CameraSettingsValue(QStringLiteral("Macro"), QCameraFocus::MacroFocus)
+ << new CameraSettingsValue(QStringLiteral("Off"), QCameraFocus::ManualFocus);
+ }
+
+}
+
+CameraUtils::~CameraUtils()
+{
+}
+
+void CameraUtils::init()
+{
+ m_camera = new QCamera;
+ connect(m_camera, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(onCameraStatusChanged()));
+ connect(m_camera, SIGNAL(error(QCamera::Error)), this, SLOT(onError()));
+ m_camera->load();
+}
+
+void CameraUtils::setCamera(QObject *obj)
+{
+ QObject *mediaObject = qvariant_cast<QObject*>(obj->property("mediaObject"));
+ if (!mediaObject)
+ return;
+
+ m_camera = qobject_cast<QCamera*>(mediaObject);
+ if (!m_camera)
+ return;
+
+ if (m_camera->status() >= QCamera::LoadedStatus)
+ onCameraStatusChanged();
+ else
+ connect(m_camera, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(onCameraStatusChanged()));
+}
+
+void CameraUtils::onError()
+{
+ if (m_camera && m_camera->status() == QCamera::UnavailableStatus) {
+ delete m_camera;
+ m_camera = 0;
+
+ emit done();
+ }
+}
+
+void CameraUtils::onCameraStatusChanged()
+{
+ if (!m_camera || m_camera->status() < QCamera::LoadedStatus)
+ return;
+
+ disconnect(m_camera, SIGNAL(statusChanged(QCamera::Status)), this, SLOT(onCameraStatusChanged()));
+
+ QCameraImageCapture *imageCapture = new QCameraImageCapture(m_camera);
+ QCameraImageProcessing *imageProc = m_camera->imageProcessing();
+ QCameraExposure *exposure = m_camera->exposure();
+ QCameraFocus *focus = m_camera->focus();
+ QMediaRecorder rec(m_camera);
+
+ // Supported image resolutions
+ QList<QSize> resolutions = imageCapture->supportedResolutions();
+ for (int i = resolutions.size() - 1; i >= 0; --i) {
+ QSize reso = resolutions.at(i);
+ int mp = reso.width() * reso.height();
+ CameraSettingsValue *r = new CameraSettingsValue(QString::number(mp / double(1000000), 'f', 1) + QLatin1String("M"), reso);
+ m_supportedResolutions.append(r);
+ }
+
+ // Supported video resolutions
+ QList<QSize> suppRes = rec.supportedResolutions();
+ for (int i = 0; i < g_commonVideoResolutions.size(); ++i) {
+ CameraSettingsValue *r = g_commonVideoResolutions.at(i);
+ if (suppRes.contains(r->value().toSize()))
+ m_supportedVideoResolutions.append(r);
+ }
+
+
+ // Supported white balance modes
+ for (int i = 0; i < g_whiteBalanceModes.size(); ++i) {
+ CameraSettingsValue *m = g_whiteBalanceModes.at(i);
+ if (imageProc->isWhiteBalanceModeSupported(QCameraImageProcessing::WhiteBalanceMode(m->value().toInt())))
+ m_supportedWhiteBalanceModes.append(m);
+ }
+
+ // Supported scene modes
+ for (int i = 0; i < g_sceneModes.size(); ++i) {
+ CameraSettingsValue *sm = g_sceneModes.at(i);
+ if (exposure->isExposureModeSupported(QCameraExposure::ExposureMode(sm->value().toInt())))
+ m_supportedSceneModes.append(sm);
+ }
+
+ // Supported flash modes
+ for (int i = 0; i < g_flashModes.size(); ++i) {
+ CameraSettingsValue *sm = g_flashModes.at(i);
+ if (exposure->isFlashModeSupported(QCameraExposure::FlashModes(sm->value().toInt())))
+ m_supportedFlashModes.append(sm);
+ }
+
+ // Supported focus modes
+ for (int i = 0; i < g_focusModes.size(); ++i) {
+ CameraSettingsValue *sm = g_focusModes.at(i);
+ if (focus->isFocusModeSupported(QCameraFocus::FocusModes(sm->value().toInt())))
+ m_supportedFocusModes.append(sm);
+ }
+
+ delete imageCapture;
+
+ emit supportedCaptureResolutionsChanged();
+ emit supportedVideoResolutionsChanged();
+ emit supportedWhiteBalanceModesChanged();
+ emit supportedSceneModesChanged();
+ emit supportedFlashModesChanged();
+}
+
+
diff --git a/experimental/Camera/qmlplugin/camerautils.h b/experimental/Camera/qmlplugin/camerautils.h
new file mode 100644
index 0000000..562b675
--- /dev/null
+++ b/experimental/Camera/qmlplugin/camerautils.h
@@ -0,0 +1,87 @@
+#ifndef CAMERAUTILS_H
+#define CAMERAUTILS_H
+
+#include <QObject>
+#include <QVariant>
+
+class QCamera;
+
+class CameraSettingsValue : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
+
+public:
+ CameraSettingsValue(const QString &n, const QVariant &v)
+ : QObject()
+ , m_name(n)
+ , m_value(v)
+ { }
+
+ QString name() const { return m_name; }
+ void setName(const QString &n) { m_name = n; emit nameChanged(); }
+
+ QVariant value() const { return m_value; }
+ void setValue(const QVariant &v) { m_value = v; emit valueChanged(); }
+
+Q_SIGNALS:
+ void nameChanged();
+ void valueChanged();
+
+private:
+ QString m_name;
+ QVariant m_value;
+};
+
+QDebug operator<<(QDebug, const CameraSettingsValue &);
+
+class CameraUtils : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QList<QObject*> supportedCaptureResolutions READ supportedCaptureResolutions NOTIFY supportedCaptureResolutionsChanged)
+ Q_PROPERTY(QList<QObject*> supportedWhiteBalanceModes READ supportedWhiteBalanceModes NOTIFY supportedWhiteBalanceModesChanged)
+ Q_PROPERTY(QList<QObject*> supportedSceneModes READ supportedSceneModes NOTIFY supportedSceneModesChanged)
+ Q_PROPERTY(QList<QObject*> supportedFlashModes READ supportedFlashModes NOTIFY supportedFlashModesChanged)
+ Q_PROPERTY(QList<QObject*> supportedFocusModes READ supportedFocusModes NOTIFY supportedFocusModesChanged)
+ Q_PROPERTY(QList<QObject*> supportedVideoResolutions READ supportedVideoResolutions NOTIFY supportedVideoResolutionsChanged)
+public:
+ explicit CameraUtils(QObject *parent = 0);
+ ~CameraUtils();
+
+ Q_INVOKABLE void init();
+ Q_INVOKABLE void setCamera(QObject *cam);
+
+ QList<QObject*> supportedCaptureResolutions() const { return m_supportedResolutions; }
+ QList<QObject*> supportedVideoResolutions() const { return m_supportedVideoResolutions; }
+ QList<QObject*> supportedWhiteBalanceModes() const { return m_supportedWhiteBalanceModes; }
+ QList<QObject*> supportedSceneModes() const { return m_supportedSceneModes; }
+ QList<QObject*> supportedFlashModes() const { return m_supportedFlashModes; }
+ QList<QObject*> supportedFocusModes() const { return m_supportedFocusModes; }
+
+Q_SIGNALS:
+ void supportedCaptureResolutionsChanged();
+ void supportedWhiteBalanceModesChanged();
+ void supportedSceneModesChanged();
+ void supportedFlashModesChanged();
+ void supportedFocusModesChanged();
+ void supportedVideoResolutionsChanged();
+
+ void done();
+
+private Q_SLOTS:
+ void onCameraStatusChanged();
+ void onError();
+
+private:
+ QCamera *m_camera;
+
+ QList<QObject*> m_supportedResolutions;
+ QList<QObject*> m_supportedVideoResolutions;
+ QList<QObject*> m_supportedWhiteBalanceModes;
+ QList<QObject*> m_supportedSceneModes;
+ QList<QObject*> m_supportedFlashModes;
+ QList<QObject*> m_supportedFocusModes;
+};
+
+#endif // CAMERAUTILS_H
diff --git a/experimental/Camera/qmlplugin/camerautils.pro b/experimental/Camera/qmlplugin/camerautils.pro
new file mode 100644
index 0000000..938a0a9
--- /dev/null
+++ b/experimental/Camera/qmlplugin/camerautils.pro
@@ -0,0 +1,19 @@
+TEMPLATE = lib
+CONFIG += plugin
+QT += qml multimedia
+
+TARGET = camerautilsplugin
+
+SOURCES += plugin.cpp \
+ camerautils.cpp
+
+HEADERS += camerautils.h
+
+pluginfiles.files += \
+ qmldir \
+
+target.path += $$[QT_INSTALL_QML]/CameraUtils
+pluginfiles.path += $$[QT_INSTALL_QML]/CameraUtils
+
+INSTALLS += target pluginfiles
+
diff --git a/experimental/Camera/qmlplugin/plugin.cpp b/experimental/Camera/qmlplugin/plugin.cpp
new file mode 100644
index 0000000..2a8c3ea
--- /dev/null
+++ b/experimental/Camera/qmlplugin/plugin.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 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$
+**
+****************************************************************************/
+
+#include <QtQml/QQmlExtensionPlugin>
+#include <QtQml/qqml.h>
+#include <qdebug.h>
+
+#include "camerautils.h"
+
+class QExampleQmlPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ void registerTypes(const char *uri)
+ {
+ qmlRegisterType<CameraUtils>(uri, 1, 0, "CameraUtils");
+ }
+};
+
+
+#include "plugin.moc"
diff --git a/experimental/Camera/qmlplugin/qmldir b/experimental/Camera/qmlplugin/qmldir
new file mode 100644
index 0000000..a5ab412
--- /dev/null
+++ b/experimental/Camera/qmlplugin/qmldir
@@ -0,0 +1,2 @@
+module CameraUtils
+plugin camerautilsplugin
diff --git a/experimental/Media Player/Content.qml b/experimental/Media Player/Content.qml
new file mode 100755
index 0000000..d519fcb
--- /dev/null
+++ b/experimental/Media Player/Content.qml
@@ -0,0 +1,124 @@
+ /****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Rectangle {
+ id: root
+ property alias effect: effectLoader.item
+ property string effectSource
+ property alias videoPlayer: videoContent
+ signal contentSizeChanged(size contentSize)
+
+ color: "black"
+
+ ShaderEffectSource {
+ id: theSource
+ smooth: true
+ hideSource: true
+ }
+
+ Intro {
+ id: introBackground
+ anchors.fill: root
+ visible: videoContent.mediaSource == "" ? true : false
+ }
+
+ ContentVideo {
+ id: videoContent
+ anchors.fill: root
+ visible: mediaSource == "" ? false : true
+
+ onSourceRectChanged: {
+ contentSizeChanged(Qt.size(sourceRect.width, sourceRect.height));
+ }
+ }
+
+ Loader {
+ id: effectLoader
+ source: effectSource
+ }
+
+ onWidthChanged: {
+ if (effectLoader.item)
+ effectLoader.item.targetWidth = root.width
+ }
+
+ onHeightChanged: {
+ if (effectLoader.item)
+ effectLoader.item.targetHeight = root.height
+ }
+
+ onEffectSourceChanged: {
+ effectLoader.source = effectSource
+ effectLoader.item.parent = root
+ effectLoader.item.targetWidth = root.width
+ effectLoader.item.targetHeight = root.height
+ updateSource()
+ effectLoader.item.source = theSource
+ }
+
+ function init() {
+ theSource.sourceItem = introBackground
+ root.effectSource = "Effects/EffectPassThrough.qml"
+ }
+
+ function updateSource() {
+
+ theSource.sourceItem = videoContent.mediaSource == "" ? introBackground : videoContent
+ if (effectLoader.item)
+ effectLoader.item.anchors.fill = videoContent
+ }
+
+ function openVideo(path) {
+ stop();
+ videoContent.mediaSource = path;
+ updateSource();
+ }
+
+ function stop() {
+ theSource.sourceItem = introBackground
+ if (videoContent.mediaSource !== undefined) {
+ videoContent.stop();
+ }
+ }
+}
diff --git a/experimental/Media Player/ContentVideo.qml b/experimental/Media Player/ContentVideo.qml
new file mode 100755
index 0000000..fb5c86d
--- /dev/null
+++ b/experimental/Media Player/ContentVideo.qml
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+VideoOutput {
+ id: videoOutput
+ source: mediaPlayer
+ fillMode: VideoOutput.PreserveAspectFit
+ property alias mediaSource: mediaPlayer.source
+ property alias mediaPlayer: mediaPlayer
+ property bool isPlaying: false
+
+ MediaPlayer {
+ id: mediaPlayer
+ autoLoad: true
+ autoPlay: true
+
+ onPlaybackRateChanged: {
+ //console.debug("playbackRate: " + playbackRate);
+ }
+
+ onPlaybackStateChanged: {
+ //console.debug("playbackState = " + mediaPlayer.playbackState);
+ if (playbackState === MediaPlayer.PlayingState)
+ videoOutput.isPlaying = true;
+ else
+ videoOutput.isPlaying = false;
+ }
+
+ onAvailabilityChanged: {
+ //console.debug("availability = " + mediaPlayer.availability);
+ }
+
+ onErrorChanged: {
+ //console.debug("error = " + mediaPlayer.error);
+ }
+
+ onStatusChanged: {
+ console.debug("status = " + mediaPlayer.status);
+ if ((mediaPlayer.status == MediaPlayer.Loaded) || (mediaPlayer.status == MediaPlayer.Buffered)) {
+ //now that media is loaded, we should know its size, and should request a resize
+ //if we are not fullscreen, then the window should resize to the native size of the video
+ //TODO: automatically resize video window to native move size
+ }
+ }
+
+ onBufferProgressChanged: {
+ //console.debug("buffer progress = " + mediaPlayer.bufferProgress);
+ }
+ }
+ function play() { mediaPlayer.play() }
+ function stop() { mediaPlayer.stop() }
+}
diff --git a/experimental/Media Player/ControlBar.qml b/experimental/Media Player/ControlBar.qml
new file mode 100755
index 0000000..1778728
--- /dev/null
+++ b/experimental/Media Player/ControlBar.qml
@@ -0,0 +1,285 @@
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+Rectangle {
+ id: controlBar
+ height: 150
+ color: "#88333333"
+
+ property MediaPlayer mediaPlayer: null
+ property bool isMouseAbove: false
+
+ signal openFile()
+ signal openCamera()
+ signal openURL()
+ signal openFX()
+ signal toggleFullScreen()
+
+ state: "VISIBLE"
+
+ onMediaPlayerChanged: {
+ if (mediaPlayer === null)
+ return;
+ volumeControl.volume = mediaPlayer.volume;
+ }
+
+// MouseArea {
+// anchors.fill: controlBar
+// hoverEnabled: true
+
+// onEntered: controlBar.isMouseAbove = true;
+// onExited: controlBar.isMouseAbove = false;
+// }
+
+ function statusString(stat)
+ {
+ if (stat === MediaPlayer.NoMedia)
+ return "No Media";
+ else if (stat === MediaPlayer.Loading)
+ return "Loading";
+ else if (stat === MediaPlayer.Loaded)
+ return "Loaded";
+ else if (stat === MediaPlayer.Buffering)
+ return "Buffering";
+ else if (stat === MediaPlayer.Stalled)
+ return "Stalled";
+ else if (stat === MediaPlayer.Buffered)
+ return "Buffered";
+ else if (stat === MediaPlayer.EndOfMedia)
+ return "EndOfMedia";
+ else if (stat === MediaPlayer.InvalidMedia)
+ return "InvalidMedia";
+ else if (stat === MediaPlayer.UnknownStatus)
+ return "UnknownStatus";
+ }
+
+// Text {
+// id: statusText
+// anchors.left: parent.left
+// anchors.bottom: parent.top
+// anchors.bottomMargin: 12
+// font.pixelSize: 18
+// color: "white"
+// text: "Status: " + statusString(mediaPlayer.status)
+// }
+
+// Text {
+// anchors.verticalCenter: statusText.verticalCenter
+// anchors.left: statusText.right
+// anchors.leftMargin: 16
+// font.pixelSize: 18
+// color: "white"
+// text: Math.round(mediaPlayer.bufferProgress * 100.0) + "%"
+// }
+
+ VolumeControl {
+ id: volumeControl
+ anchors.verticalCenter: playbackControl.verticalCenter
+ anchors.left: controlBar.left
+ anchors.leftMargin: 15
+ onVolumeChanged: mediaPlayer.volume = volume
+
+ Component.onCompleted: {
+ volumeControl.volume = 0.5;
+ }
+
+ Connections {
+ target: mediaPlayer
+ onVolumeChanged: volumeControl.volume = mediaPlayer.volume
+ }
+ }
+
+ //Playback Controls
+ PlaybackControl {
+ id: playbackControl
+ anchors.horizontalCenter: controlBar.horizontalCenter
+ anchors.bottom: seekControl.top
+ anchors.bottomMargin: 20
+
+ onPlayButtonPressed: {
+ if (isPlaying) {
+ mediaPlayer.pause();
+ } else {
+ mediaPlayer.play();
+ }
+ }
+
+ onReverseButtonPressed: {
+ if (mediaPlayer.seekable) {
+ //Subtract 10 seconds
+ mediaPlayer.seek(normalizeSeek(Math.round(-mediaPlayer.duration * 0.1)));
+ }
+ }
+
+ onForwardButtonPressed: {
+ if (mediaPlayer.seekable) {
+ //Add 10 seconds
+ mediaPlayer.seek(normalizeSeek(Math.round(mediaPlayer.duration * 0.1)));
+ }
+ }
+
+ onStopButtonPressed: mediaPlayer.stop();
+ }
+
+ //Toolbar Controls
+ Row {
+ id: toolbarMenuButtons
+ anchors.right: controlBar.right
+ anchors.rightMargin: 15
+ anchors.verticalCenter: playbackControl.verticalCenter
+ spacing: 22
+
+ ImageButton {
+ id: fxButton
+ imageSource: "images/FXButton.png"
+ checkable: true
+ checked: effectSelectionPanel.visible
+ onClicked: {
+ openFX();
+ }
+ }
+ ImageButton {
+ id: fileButton
+ imageSource: "images/FileButton.png"
+ onClicked: {
+ openFile();
+ }
+ }
+ ImageButton {
+ id: urlButton
+ imageSource: "images/UrlButton.png"
+ onClicked: {
+ openURL();
+ }
+ }
+ }
+
+// ImageButton {
+// id: fullscreenButton
+// imageSource: "images/FullscreenButton.png"
+// onClicked: {
+// //Toggle fullscreen
+// toggleFullScreen();
+// }
+// checkable: true
+// checked: applicationWindow.isFullScreen
+// anchors.right: controlBar.right
+// anchors.top: controlBar.top
+// anchors.rightMargin: 15
+// anchors.topMargin: 15
+// }
+
+ //Seek controls
+ SeekControl {
+ id: seekControl
+ anchors.bottom: controlBar.bottom
+ anchors.bottomMargin: 10
+ anchors.right: controlBar.right
+ anchors.left: controlBar.left
+ anchors.rightMargin: 15
+ anchors.leftMargin: 15
+ enabled: playbackControl.isPlaybackEnabled
+
+ duration: mediaPlayer.duration
+
+ onSeekValueChanged: {
+ mediaPlayer.seek(newPosition);
+ position = mediaPlayer.position;
+ }
+
+ Component.onCompleted: {
+ seekable = mediaPlayer.seekable;
+ }
+ }
+
+ Connections {
+ target: mediaPlayer
+ onPositionChanged: {
+ if (!seekControl.pressed) seekControl.position = mediaPlayer.position;
+ }
+ onStatusChanged: {
+ if ((mediaPlayer.status == MediaPlayer.Loaded) || (mediaPlayer.status == MediaPlayer.Buffered) || mediaPlayer.status === MediaPlayer.Buffering || mediaPlayer.status === MediaPlayer.EndOfMedia)
+ playbackControl.isPlaybackEnabled = true;
+ else
+ playbackControl.isPlaybackEnabled = false;
+ }
+ onPlaybackStateChanged: {
+ if (mediaPlayer.playbackState === MediaPlayer.PlayingState) {
+ playbackControl.isPlaying = true;
+ applicationWindow.resetTimer();
+ } else {
+ show();
+ playbackControl.isPlaying = false;
+ }
+ }
+
+ onSeekableChanged: {
+ // console.log("seekableChanged: " + mediaPlayer.seekable);
+ seekControl.seekable = mediaPlayer.seekable;
+ }
+ }
+
+ function hide() {
+ controlBar.state = "HIDDEN";
+ }
+
+ function show() {
+ controlBar.state = "VISIBLE";
+ }
+
+ //Usage: give the value you wish to modify position,
+ //returns a value between 0 and duration
+ function normalizeSeek(value) {
+ var newPosition = mediaPlayer.position + value;
+ if (newPosition < 0)
+ newPosition = 0;
+ else if (newPosition > mediaPlayer.duration)
+ newPosition = mediaPlayer.duration;
+ return newPosition;
+ }
+
+ states: [
+ State {
+ name: "HIDDEN"
+ PropertyChanges {
+ target: controlBar
+ opacity: 0.0
+ }
+ },
+ State {
+ name: "VISIBLE"
+ PropertyChanges {
+ target: controlBar
+ opacity: 0.95
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "HIDDEN"
+ to: "VISIBLE"
+ NumberAnimation {
+ id: showAnimation
+ target: controlBar
+ properties: "opacity"
+ from: 0.0
+ to: 1.0
+ duration: 200
+ }
+ },
+ Transition {
+ from: "VISIBLE"
+ to: "HIDDEN"
+ NumberAnimation {
+ id: hideAnimation
+ target: controlBar
+ properties: "opacity"
+ from: 0.95
+ to: 0.0
+ duration: 200
+ }
+ }
+ ]
+}
diff --git a/experimental/Media Player/EffectSelectionPanel.qml b/experimental/Media Player/EffectSelectionPanel.qml
new file mode 100755
index 0000000..4f7e161
--- /dev/null
+++ b/experimental/Media Player/EffectSelectionPanel.qml
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ color: "#BB333333"
+ height: 78
+ property int itemHeight: 25
+ property string effectSource: ""
+ property bool isMouseAbove: mouseAboveMonitor.containsMouse
+
+ Keys.onEscapePressed: visible = false
+
+ signal clicked
+ QtObject {
+ id: d
+ property Item selectedItem
+ }
+
+ ListModel {
+ id: sources
+ ListElement { name: "No effect"; source: "Effects/EffectPassThrough.qml" }
+ ListElement { name: "Billboard"; source: "Effects/EffectBillboard.qml" }
+ ListElement { name: "Black & white"; source: "Effects/EffectBlackAndWhite.qml" }
+ ListElement { name: "Blur"; source: "Effects/EffectGaussianBlur.qml" }
+ ListElement { name: "Edge detection"; source: "Effects/EffectSobelEdgeDetection1.qml" }
+ ListElement { name: "Emboss"; source: "Effects/EffectEmboss.qml" }
+ ListElement { name: "Glow"; source: "Effects/EffectGlow.qml" }
+ ListElement { name: "Isolate"; source: "Effects/EffectIsolate.qml" }
+ //ListElement { name: "Magnify"; source: "Effects/EffectMagnify.qml" }
+// ListElement { name: "Page curl"; source: "Effects/EffectPageCurl.qml" }
+ ListElement { name: "Pixelate"; source: "Effects/EffectPixelate.qml" }
+ ListElement { name: "Posterize"; source: "Effects/EffectPosterize.qml" }
+// ListElement { name: "Ripple"; source: "Effects/EffectRipple.qml" }
+ ListElement { name: "Sepia"; source: "Effects/EffectSepia.qml" }
+ ListElement { name: "Sharpen"; source: "Effects/EffectSharpen.qml" }
+ ListElement { name: "Shockwave"; source: "Effects/EffectShockwave.qml" }
+// ListElement { name: "Tilt shift"; source: "Effects/EffectTiltShift.qml" }
+ ListElement { name: "Toon"; source: "Effects/EffectToon.qml" }
+ ListElement { name: "Warhol"; source: "Effects/EffectWarhol.qml" }
+ ListElement { name: "Wobble"; source: "Effects/EffectWobble.qml" }
+ ListElement { name: "Vignette"; source: "Effects/EffectVignette.qml" }
+ }
+
+ Component {
+ id: sourceDelegate
+ Item {
+ id: sourceDelegateItem
+ width: root.width
+ height: itemHeight
+
+ Text {
+ id: sourceSelectorItem
+ anchors.centerIn: parent
+ width: 0.9 * parent.width
+ height: 0.8 * itemHeight
+ text: name
+ color: "white"
+ }
+
+ states: [
+ State {
+ name: "selected"
+ PropertyChanges {
+ target: sourceSelectorItem
+ bgColor: "#ff8888"
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ from: "*"
+ to: "*"
+ ColorAnimation {
+ properties: "color"
+ easing.type: Easing.OutQuart
+ duration: 500
+ }
+ }
+ ]
+ }
+ }
+
+ MouseArea {
+ id: mouseAboveMonitor
+ anchors.fill: parent
+ hoverEnabled: true
+ }
+
+ ListView {
+ id: list
+ anchors.fill: parent
+ clip: true
+ anchors.margins: 14
+ model: sources
+ focus: root.visible && root.opacity && urlBar.opacity === 0
+
+ currentIndex: 0
+
+ onCurrentIndexChanged : {
+ effectSource = model.get(currentIndex).source
+ root.clicked()
+ applicationWindow.resetTimer()
+ }
+
+ delegate: Item {
+ height: 40
+ width: parent.width
+ Rectangle {
+ anchors.fill: parent
+ border.color: index == list.currentIndex ? "#44ffffff" : "transparent"
+ color: index == list.currentIndex ? "#22ffffff" : "transparent"
+ radius: 3
+ Text { color: "white" ; text: name ; anchors.centerIn: parent; font.pixelSize: 20 }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: list.currentIndex = index
+ }
+ }
+ }
+ }
+}
diff --git a/experimental/Media Player/Effects/Effect.qml b/experimental/Media Player/Effects/Effect.qml
new file mode 100755
index 0000000..99308fd
--- /dev/null
+++ b/experimental/Media Player/Effects/Effect.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+ShaderEffect {
+ property variant source
+ property ListModel parameters: ListModel { }
+ property bool divider: false
+ property real dividerValue: 1.0
+ property real targetWidth: 0
+ property real targetHeight: 0
+ property string fragmentShaderSrc
+ property string vertexShaderSrc
+
+ QtObject {
+ id: d
+ property string fragmentShaderCommon: "
+ #ifdef GL_ES
+ precision mediump float;
+ #else
+ # define lowp
+ # define mediump
+ # define highp
+ #endif // GL_ES
+ "
+ }
+
+ // The following is a workaround for the fact that ShaderEffect
+ // doesn't provide a way for shader programs to be read from a file,
+ // rather than being inline in the QML file
+
+ onFragmentShaderSrcChanged:
+ fragmentShader = d.fragmentShaderCommon + fragmentShaderSrc
+ onVertexShaderSrcChanged:
+ vertexShader = vertexShaderSrc
+}
diff --git a/experimental/Media Player/Effects/EffectBillboard.qml b/experimental/Media Player/Effects/EffectBillboard.qml
new file mode 100755
index 0000000..947209e
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectBillboard.qml
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "grid spacing"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real grid: parameters.get(0).value * 10
+
+ property real step_x: 0.0015625
+ property real step_y: targetHeight ? (step_x * targetWidth / targetHeight) : 0.0
+
+ fragmentShaderSrc: "uniform float grid;
+ uniform float dividerValue;
+ uniform float step_x;
+ uniform float step_y;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ float offx = floor(uv.x / (grid * step_x));
+ float offy = floor(uv.y / (grid * step_y));
+ vec3 res = texture2D(source, vec2(offx * grid * step_x , offy * grid * step_y)).rgb;
+ vec2 prc = fract(uv / vec2(grid * step_x, grid * step_y));
+ vec2 pw = pow(abs(prc - 0.5), vec2(2.0));
+ float rs = pow(0.45, 2.0);
+ float gr = smoothstep(rs - 0.1, rs + 0.1, pw.x + pw.y);
+ float y = (res.r + res.g + res.b) / 3.0;
+ vec3 ra = res / y;
+ float ls = 0.3;
+ float lb = ceil(y / ls);
+ float lf = ls * lb + 0.3;
+ res = lf * res;
+ vec3 col = mix(res, vec3(0.1, 0.1, 0.1), gr);
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * texture2D(source, uv);
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectBlackAndWhite.qml b/experimental/Media Player/Effects/EffectBlackAndWhite.qml
new file mode 100755
index 0000000..8cbba60
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectBlackAndWhite.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "threshold"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real threshold: parameters.get(0).value
+
+ fragmentShaderSrc: "uniform float threshold;
+ uniform float dividerValue;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 orig = texture2D(source, uv);
+ vec3 col = orig.rgb;
+ float y = 0.3 *col.r + 0.59 * col.g + 0.11 * col.b;
+ y = y < threshold ? 0.0 : 1.0;
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(y, y, y, 1.0);
+ else
+ gl_FragColor = qt_Opacity * orig;
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectEmboss.qml b/experimental/Media Player/Effects/EffectEmboss.qml
new file mode 100755
index 0000000..23ef1cb
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectEmboss.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderSrc: "uniform float dividerValue;
+ const float step_w = 0.0015625;
+ const float step_h = 0.0027778;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec3 t1 = texture2D(source, vec2(uv.x - step_w, uv.y - step_h)).rgb;
+ vec3 t2 = texture2D(source, vec2(uv.x, uv.y - step_h)).rgb;
+ vec3 t3 = texture2D(source, vec2(uv.x + step_w, uv.y - step_h)).rgb;
+ vec3 t4 = texture2D(source, vec2(uv.x - step_w, uv.y)).rgb;
+ vec3 t5 = texture2D(source, uv).rgb;
+ vec3 t6 = texture2D(source, vec2(uv.x + step_w, uv.y)).rgb;
+ vec3 t7 = texture2D(source, vec2(uv.x - step_w, uv.y + step_h)).rgb;
+ vec3 t8 = texture2D(source, vec2(uv.x, uv.y + step_h)).rgb;
+ vec3 t9 = texture2D(source, vec2(uv.x + step_w, uv.y + step_h)).rgb;
+ vec3 rr = -4.0 * t1 - 4.0 * t2 - 4.0 * t4 + 12.0 * t5;
+ float y = (rr.r + rr.g + rr.b) / 3.0;
+ vec3 col = vec3(y, y, y) + 0.3;
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * texture2D(source, uv);
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectGaussianBlur.qml b/experimental/Media Player/Effects/EffectGaussianBlur.qml
new file mode 100755
index 0000000..f866524
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectGaussianBlur.qml
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Based on http://www.geeks3d.com/20100909/shader-library-gaussian-blur-post-processing-filter-in-glsl/
+
+import QtQuick 2.0
+
+Item {
+ id: root
+ property bool divider: true
+ property real dividerValue: 1
+ property ListModel parameters: ListModel {
+ ListElement {
+ name: "radius"
+ value: 0.5
+ }
+ }
+
+ property alias targetWidth: verticalShader.targetWidth
+ property alias targetHeight: verticalShader.targetHeight
+ property alias source: verticalShader.source
+
+ Effect {
+ id: verticalShader
+ anchors.fill: parent
+ dividerValue: parent.dividerValue
+ property real blurSize: 4.0 * parent.parameters.get(0).value / targetHeight
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform float blurSize;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 c = vec4(0.0);
+ if (uv.x < dividerValue) {
+ c += texture2D(source, uv - vec2(0.0, 4.0*blurSize)) * 0.05;
+ c += texture2D(source, uv - vec2(0.0, 3.0*blurSize)) * 0.09;
+ c += texture2D(source, uv - vec2(0.0, 2.0*blurSize)) * 0.12;
+ c += texture2D(source, uv - vec2(0.0, 1.0*blurSize)) * 0.15;
+ c += texture2D(source, uv) * 0.18;
+ c += texture2D(source, uv + vec2(0.0, 1.0*blurSize)) * 0.15;
+ c += texture2D(source, uv + vec2(0.0, 2.0*blurSize)) * 0.12;
+ c += texture2D(source, uv + vec2(0.0, 3.0*blurSize)) * 0.09;
+ c += texture2D(source, uv + vec2(0.0, 4.0*blurSize)) * 0.05;
+ } else {
+ c = texture2D(source, qt_TexCoord0);
+ }
+ // First pass we don't apply opacity
+ gl_FragColor = c;
+ }"
+ }
+
+ Effect {
+ id: horizontalShader
+ anchors.fill: parent
+ dividerValue: parent.dividerValue
+ property real blurSize: 4.0 * parent.parameters.get(0).value / parent.targetWidth
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform float blurSize;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 c = vec4(0.0);
+ if (uv.x < dividerValue) {
+ c += texture2D(source, uv - vec2(4.0*blurSize, 0.0)) * 0.05;
+ c += texture2D(source, uv - vec2(3.0*blurSize, 0.0)) * 0.09;
+ c += texture2D(source, uv - vec2(2.0*blurSize, 0.0)) * 0.12;
+ c += texture2D(source, uv - vec2(1.0*blurSize, 0.0)) * 0.15;
+ c += texture2D(source, uv) * 0.18;
+ c += texture2D(source, uv + vec2(1.0*blurSize, 0.0)) * 0.15;
+ c += texture2D(source, uv + vec2(2.0*blurSize, 0.0)) * 0.12;
+ c += texture2D(source, uv + vec2(3.0*blurSize, 0.0)) * 0.09;
+ c += texture2D(source, uv + vec2(4.0*blurSize, 0.0)) * 0.05;
+ } else {
+ c = texture2D(source, qt_TexCoord0);
+ }
+ gl_FragColor = qt_Opacity * c;
+ }"
+ source: horizontalShaderSource
+
+ ShaderEffectSource {
+ id: horizontalShaderSource
+ sourceItem: verticalShader
+ smooth: true
+ hideSource: true
+ }
+ }
+}
+
diff --git a/experimental/Media Player/Effects/EffectGlow.qml b/experimental/Media Player/Effects/EffectGlow.qml
new file mode 100755
index 0000000..2cfee3b
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectGlow.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderSrc: "uniform float dividerValue;
+ const float step_w = 0.0015625;
+ const float step_h = 0.0027778;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec3 t1 = texture2D(source, vec2(uv.x - step_w, uv.y - step_h)).rgb;
+ vec3 t2 = texture2D(source, vec2(uv.x, uv.y - step_h)).rgb;
+ vec3 t3 = texture2D(source, vec2(uv.x + step_w, uv.y - step_h)).rgb;
+ vec3 t4 = texture2D(source, vec2(uv.x - step_w, uv.y)).rgb;
+ vec3 t5 = texture2D(source, uv).rgb;
+ vec3 t6 = texture2D(source, vec2(uv.x + step_w, uv.y)).rgb;
+ vec3 t7 = texture2D(source, vec2(uv.x - step_w, uv.y + step_h)).rgb;
+ vec3 t8 = texture2D(source, vec2(uv.x, uv.y + step_h)).rgb;
+ vec3 t9 = texture2D(source, vec2(uv.x + step_w, uv.y + step_h)).rgb;
+ vec3 xx = t1 + 2.0*t2 + t3 - t7 - 2.0*t8 - t9;
+ vec3 yy = t1 - t3 + 2.0*t4 - 2.0*t6 + t7 - t9;
+ vec3 rr = sqrt(xx * xx + yy * yy);
+ vec3 col = rr * 2.0 * t5;
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * texture2D(source, uv);
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectIsolate.qml b/experimental/Media Player/Effects/EffectIsolate.qml
new file mode 100755
index 0000000..4c569a5
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectIsolate.qml
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "hue"
+ value: 0.5
+ }
+ ListElement {
+ name: "width"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real targetHue: parameters.get(0).value * 360
+ property real windowWidth: parameters.get(1).value * 60
+
+ fragmentShaderSrc: "uniform float targetHue;
+ uniform float windowWidth;
+ uniform float dividerValue;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void rgb2hsl(vec3 rgb, out float h, out float s, float l)
+ {
+ float maxval = max(rgb.r, max(rgb.g, rgb.b));
+ float minval = min(rgb.r, min(rgb.g, rgb.b));
+ float delta = maxval - minval;
+ l = (minval + maxval) / 2.0;
+ s = 0.0;
+ if (l > 0.0 && l < 1.0)
+ s = delta / (l < 0.5 ? 2.0 * l : 2.0 - 2.0 * l);
+ h = 0.0;
+ if (delta > 0.0)
+ {
+ if (rgb.r == maxval && rgb.g != maxval)
+ h += (rgb.g - rgb.b ) / delta;
+ if (rgb.g == maxval && rgb.b != maxval)
+ h += 2.0 + (rgb.b - rgb.r) / delta;
+ if (rgb.b == maxval && rgb.r != maxval)
+ h += 4.0 + (rgb.r - rgb.g) / delta;
+ h *= 60.0;
+ }
+ }
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec3 col = texture2D(source, uv).rgb;
+ float h, s, l;
+ rgb2hsl(col, h, s, l);
+ float h2 = (h > targetHue) ? h - 360.0 : h + 360.0;
+ float y = 0.3 * col.r + 0.59 * col.g + 0.11 * col.b;
+ vec3 result;
+ if (uv.x > dividerValue || (abs(h - targetHue) < windowWidth) || (abs(h2 - targetHue) < windowWidth))
+ result = col;
+ else
+ result = vec3(y, y, y);
+ gl_FragColor = qt_Opacity * vec4(result, 1.0);
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectMagnify.qml b/experimental/Media Player/Effects/EffectMagnify.qml
new file mode 100755
index 0000000..01f33a5
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectMagnify.qml
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ id: root
+ divider: false
+ parameters: ListModel {
+ ListElement {
+ name: "radius"
+ value: 0.5
+ }
+ ListElement {
+ name: "diffraction"
+ value: 0.5
+ }
+ }
+
+ property real posX: -1
+ property real posY: -1
+
+ QtObject {
+ id: d
+ property real oldTargetWidth: root.targetWidth
+ property real oldTargetHeight: root.targetHeight
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real radius: parameters.get(0).value * 100
+ property real diffractionIndex: parameters.get(1).value
+
+ onTargetWidthChanged: {
+ if (posX == -1)
+ posX = targetWidth / 2
+ else if (d.oldTargetWidth != 0)
+ posX *= (targetWidth / d.oldTargetWidth)
+ d.oldTargetWidth = targetWidth
+ }
+
+ onTargetHeightChanged: {
+ if (posY == -1)
+ posY = targetHeight / 2
+ else if (d.oldTargetHeight != 0)
+ posY *= (targetHeight / d.oldTargetHeight)
+ d.oldTargetHeight = targetHeight
+ }
+
+ fragmentShaderSrc: "uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+ uniform float radius;
+ uniform float diffractionIndex;
+ uniform float targetWidth;
+ uniform float targetHeight;
+ uniform float posX;
+ uniform float posY;
+
+ void main()
+ {
+ vec2 tc = qt_TexCoord0;
+ vec2 center = vec2(posX, posY);
+ vec2 xy = gl_FragCoord.xy - center.xy;
+ float r = sqrt(xy.x * xy.x + xy.y * xy.y);
+ if (r < radius) {
+ float h = diffractionIndex * 0.5 * radius;
+ vec2 new_xy = r < radius ? xy * (radius - h) / sqrt(radius * radius - r * r) : xy;
+ vec2 targetSize = vec2(targetWidth, targetHeight);
+ tc = (new_xy + center) / targetSize;
+ tc.y = 1.0 - tc.y;
+ }
+ gl_FragColor = qt_Opacity * texture2D(source, tc);
+ }"
+
+ MouseArea {
+ anchors.fill: parent
+ onPositionChanged: { root.posX = mouse.x; root.posY = root.targetHeight - mouse.y }
+ }
+}
diff --git a/experimental/Media Player/Effects/EffectPageCurl.qml b/experimental/Media Player/Effects/EffectPageCurl.qml
new file mode 100755
index 0000000..39947d9
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectPageCurl.qml
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ divider: false
+ parameters: ListModel {
+ ListElement {
+ name: "extent"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real curlExtent: 1.0 - parameters.get(0).value
+
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform float curlExtent;
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ const float minAmount = -0.16;
+ const float maxAmount = 1.3;
+ const float PI = 3.141592653589793;
+ const float scale = 512.0;
+ const float sharpness = 3.0;
+ const vec4 bgColor = vec4(1.0, 1.0, 0.8, 1.0);
+
+ float amount = curlExtent * (maxAmount - minAmount) + minAmount;
+ float cylinderCenter = amount;
+ // 360 degrees * amount
+ float cylinderAngle = 2.0 * PI * amount;
+ const float cylinderRadius = 1.0 / PI / 2.0;
+
+ vec3 hitPoint(float hitAngle, float yc, vec3 point, mat3 rrotation)
+ {
+ float hitPoint = hitAngle / (2.0 * PI);
+ point.y = hitPoint;
+ return rrotation * point;
+ }
+
+ vec4 antiAlias(vec4 color1, vec4 color2, float distance)
+ {
+ distance *= scale;
+ if (distance < 0.0) return color2;
+ if (distance > 2.0) return color1;
+ float dd = pow(1.0 - distance / 2.0, sharpness);
+ return ((color2 - color1) * dd) + color1;
+ }
+
+ float distanceToEdge(vec3 point)
+ {
+ float dx = abs(point.x > 0.5 ? 1.0 - point.x : point.x);
+ float dy = abs(point.y > 0.5 ? 1.0 - point.y : point.y);
+ if (point.x < 0.0) dx = -point.x;
+ if (point.x > 1.0) dx = point.x - 1.0;
+ if (point.y < 0.0) dy = -point.y;
+ if (point.y > 1.0) dy = point.y - 1.0;
+ if ((point.x < 0.0 || point.x > 1.0) && (point.y < 0.0 || point.y > 1.0)) return sqrt(dx * dx + dy * dy);
+ return min(dx, dy);
+ }
+
+ vec4 seeThrough(float yc, vec2 p, mat3 rotation, mat3 rrotation)
+ {
+ float hitAngle = PI - (acos(yc / cylinderRadius) - cylinderAngle);
+ vec3 point = hitPoint(hitAngle, yc, rotation * vec3(p, 1.0), rrotation);
+ if (yc <= 0.0 && (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0))
+ return bgColor;
+ if (yc > 0.0)
+ return texture2D(source, p);
+ vec4 color = texture2D(source, point.xy);
+ vec4 tcolor = vec4(0.0);
+ return antiAlias(color, tcolor, distanceToEdge(point));
+ }
+
+ vec4 seeThroughWithShadow(float yc, vec2 p, vec3 point, mat3 rotation, mat3 rrotation)
+ {
+ float shadow = distanceToEdge(point) * 30.0;
+ shadow = (1.0 - shadow) / 3.0;
+ if (shadow < 0.0)
+ shadow = 0.0;
+ else
+ shadow *= amount;
+ vec4 shadowColor = seeThrough(yc, p, rotation, rrotation);
+ shadowColor.r -= shadow;
+ shadowColor.g -= shadow;
+ shadowColor.b -= shadow;
+ return shadowColor;
+ }
+
+ vec4 backside(float yc, vec3 point)
+ {
+ vec4 color = texture2D(source, point.xy);
+ float gray = (color.r + color.b + color.g) / 15.0;
+ gray += (8.0 / 10.0) * (pow(1.0 - abs(yc / cylinderRadius), 2.0 / 10.0) / 2.0 + (5.0 / 10.0));
+ color.rgb = vec3(gray);
+ return color;
+ }
+
+ void main(void)
+ {
+ const float angle = 30.0 * PI / 180.0;
+ float c = cos(-angle);
+ float s = sin(-angle);
+ mat3 rotation = mat3(
+ c, s, 0,
+ -s, c, 0,
+ 0.12, 0.258, 1
+ );
+ c = cos(angle);
+ s = sin(angle);
+ mat3 rrotation = mat3(
+ c, s, 0,
+ -s, c, 0,
+ 0.15, -0.5, 1
+ );
+ vec3 point = rotation * vec3(qt_TexCoord0, 1.0);
+ float yc = point.y - cylinderCenter;
+ vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
+ if (yc < -cylinderRadius) {
+ // See through to background
+ color = bgColor;
+ } else if (yc > cylinderRadius) {
+ // Flat surface
+ color = texture2D(source, qt_TexCoord0);
+ } else {
+ float hitAngle = (acos(yc / cylinderRadius) + cylinderAngle) - PI;
+ float hitAngleMod = mod(hitAngle, 2.0 * PI);
+ if ((hitAngleMod > PI && amount < 0.5) || (hitAngleMod > PI/2.0 && amount < 0.0)) {
+ color = seeThrough(yc, qt_TexCoord0, rotation, rrotation);
+ } else {
+ point = hitPoint(hitAngle, yc, point, rrotation);
+ if (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0) {
+ color = seeThroughWithShadow(yc, qt_TexCoord0, point, rotation, rrotation);
+ } else {
+ color = backside(yc, point);
+ vec4 otherColor;
+ if (yc < 0.0) {
+ float shado = 1.0 - (sqrt(pow(point.x - 0.5, 2.0) + pow(point.y - 0.5, 2.0)) / 0.71);
+ shado *= pow(-yc / cylinderRadius, 3.0);
+ shado *= 0.5;
+ otherColor = vec4(0.0, 0.0, 0.0, shado);
+ } else {
+ otherColor = texture2D(source, qt_TexCoord0);
+ }
+ color = antiAlias(color, otherColor, cylinderRadius - abs(yc));
+
+ // This second antialiasing step causes the shader to fail to render, on
+ // Symbian devices (tested so far using IVE3.5). Running out of scratch
+ // memory?
+ }
+ }
+ }
+ gl_FragColor = qt_Opacity * color;
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectPassThrough.qml b/experimental/Media Player/Effects/EffectPassThrough.qml
new file mode 100755
index 0000000..1f259be
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectPassThrough.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ divider: false
+}
diff --git a/experimental/Media Player/Effects/EffectPixelate.qml b/experimental/Media Player/Effects/EffectPixelate.qml
new file mode 100755
index 0000000..4bc73d3
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectPixelate.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "granularity"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real granularity: parameters.get(0).value * 20
+
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform float granularity;
+ uniform float targetWidth;
+ uniform float targetHeight;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec2 tc = qt_TexCoord0;
+ if (uv.x < dividerValue && granularity > 0.0) {
+ float dx = granularity / targetWidth;
+ float dy = granularity / targetHeight;
+ tc = vec2(dx*(floor(uv.x/dx) + 0.5),
+ dy*(floor(uv.y/dy) + 0.5));
+ }
+ gl_FragColor = qt_Opacity * texture2D(source, tc);
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectPosterize.qml b/experimental/Media Player/Effects/EffectPosterize.qml
new file mode 100755
index 0000000..4b661a5
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectPosterize.qml
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "gamma"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real gamma: parameters.get(0).value
+
+ property real numColors: 8.0
+
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform float gamma;
+ uniform float numColors;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 c = vec4(0.0);
+ if (uv.x < dividerValue) {
+ vec3 x = texture2D(source, uv).rgb;
+ x = pow(x, vec3(gamma, gamma, gamma));
+ x = x * numColors;
+ x = floor(x);
+ x = x / numColors;
+ x = pow(x, vec3(1.0/gamma));
+ c = vec4(x, 1.0);
+ } else {
+ c = texture2D(source, uv);
+ }
+ gl_FragColor = qt_Opacity * c;
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectRipple.qml b/experimental/Media Player/Effects/EffectRipple.qml
new file mode 100755
index 0000000..7a82f50
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectRipple.qml
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "amplitude"
+ value: 0.5
+ }
+ ListElement {
+ name: "frequency"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real amplitude: parameters.get(0).value * 0.03
+ property real n: parameters.get(1).value * 7
+
+ property real time: 0
+ NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 600 }
+
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform float targetWidth;
+ uniform float targetHeight;
+ uniform float time;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ const float PI = 3.1415926535;
+ const int ITER = 7;
+ const float RATE = 0.1;
+ uniform float amplitude;
+ uniform float n;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec2 tc = uv;
+ vec2 p = vec2(-1.0 + 2.0 * gl_FragCoord.x / targetWidth, -(-1.0 + 2.0 * gl_FragCoord.y / targetHeight));
+ float diffx = 0.0;
+ float diffy = 0.0;
+ vec4 col;
+ if (uv.x < dividerValue) {
+ for (int i=0; i<ITER; ++i) {
+ float theta = float(i) * PI / float(ITER);
+ vec2 r = vec2(cos(theta) * p.x + sin(theta) * p.y, -1.0 * sin(theta) * p.x + cos(theta) * p.y);
+ float diff = (sin(2.0 * PI * n * (r.y + time * RATE)) + 1.0) / 2.0;
+ diffx += diff * sin(theta);
+ diffy += diff * cos(theta);
+ }
+ tc = 0.5*(vec2(1.0,1.0) + p) + amplitude * vec2(diffx, diffy);
+ }
+ gl_FragColor = qt_Opacity * texture2D(source, tc);
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectSepia.qml b/experimental/Media Player/Effects/EffectSepia.qml
new file mode 100755
index 0000000..2539680
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectSepia.qml
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 orig = texture2D(source, uv);
+ vec3 col = orig.rgb;
+ float y = 0.3 * col.r + 0.59 * col.g + 0.11 * col.b;
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(y + 0.15, y + 0.07, y - 0.12, 1.0);
+ else
+ gl_FragColor = qt_Opacity * orig;
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectSharpen.qml b/experimental/Media Player/Effects/EffectSharpen.qml
new file mode 100755
index 0000000..c30f298
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectSharpen.qml
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "sharpness"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real amount: parameters.get(0).value * 18
+
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform float amount;
+ const float step_w = 0.0015625;
+ const float step_h = 0.0027778;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ vec3 sharpen(vec3 t1, vec3 t2, vec3 t3, vec3 t4, vec3 t5, vec3 t6, vec3 t7, vec3 t8, vec3 t9)
+ {
+ return -t1 - t2 - t3 - t4 + amount * t5 - t6 - t7 - t8 - t9;
+ }
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec3 t1 = texture2D(source, vec2(uv.x - step_w, uv.y - step_h)).rgb;
+ vec3 t2 = texture2D(source, vec2(uv.x, uv.y - step_h)).rgb;
+ vec3 t3 = texture2D(source, vec2(uv.x + step_w, uv.y - step_h)).rgb;
+ vec3 t4 = texture2D(source, vec2(uv.x - step_w, uv.y)).rgb;
+ vec3 t5 = texture2D(source, uv).rgb;
+ vec3 t6 = texture2D(source, vec2(uv.x + step_w, uv.y)).rgb;
+ vec3 t7 = texture2D(source, vec2(uv.x - step_w, uv.y + step_h)).rgb;
+ vec3 t8 = texture2D(source, vec2(uv.x, uv.y + step_h)).rgb;
+ vec3 t9 = texture2D(source, vec2(uv.x + step_w, uv.y + step_h)).rgb;
+ vec3 col = sharpen(t1, t2, t3, t4, t5, t6, t7, t8, t9);
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * texture2D(source, uv);
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectShockwave.qml b/experimental/Media Player/Effects/EffectShockwave.qml
new file mode 100755
index 0000000..1078b73
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectShockwave.qml
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ id: root
+ parameters: ListModel {
+ ListElement {
+ name: "amplitude"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real granularity: parameters.get(0).value * 20
+ property real weight: parameters.get(0).value
+
+ property real centerX
+ property real centerY
+ property real time
+
+ SequentialAnimation {
+ running: true
+ loops: Animation.Infinite
+ ScriptAction {
+ script: {
+ centerX = Math.random()
+ centerY = Math.random()
+ }
+ }
+ NumberAnimation {
+ target: root
+ property: "time"
+ from: 0
+ to: 1
+ duration: 1000
+ }
+ }
+
+ fragmentShaderSrc: "uniform float centerX;
+ uniform float centerY;
+ uniform float dividerValue;
+ uniform float granularity;
+ uniform float time;
+ uniform float weight;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec2 tc = qt_TexCoord0;
+ vec2 center = vec2(centerX, centerY);
+ const vec3 shock = vec3(10.0, 1.5, 0.1);
+ if (uv.x < dividerValue) {
+ float distance = distance(uv, center);
+ if ((distance <= (time + shock.z)) &&
+ (distance >= (time - shock.z))) {
+ float diff = (distance - time);
+ float powDiff = 1.0 - pow(abs(diff*shock.x), shock.y*weight);
+ float diffTime = diff * powDiff;
+ vec2 diffUV = normalize(uv - center);
+ tc += (diffUV * diffTime);
+ }
+ }
+ gl_FragColor = qt_Opacity * texture2D(source, tc);
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectSobelEdgeDetection1.qml b/experimental/Media Player/Effects/EffectSobelEdgeDetection1.qml
new file mode 100755
index 0000000..56f4869
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectSobelEdgeDetection1.qml
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "threshold"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real mixLevel: parameters.get(0).value
+ property real targetSize: 250 - (200 * mixLevel) // TODO: fix ...
+ property real resS: targetSize
+ property real resT: targetSize
+
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform float mixLevel;
+ uniform float resS;
+ uniform float resT;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 c = vec4(0.0);
+ if (uv.x < dividerValue) {
+ vec2 st = qt_TexCoord0.st;
+ vec3 irgb = texture2D(source, st).rgb;
+ vec2 stp0 = vec2(1.0 / resS, 0.0);
+ vec2 st0p = vec2(0.0 , 1.0 / resT);
+ vec2 stpp = vec2(1.0 / resS, 1.0 / resT);
+ vec2 stpm = vec2(1.0 / resS, -1.0 / resT);
+ const vec3 W = vec3(0.2125, 0.7154, 0.0721);
+ float i00 = dot(texture2D(source, st).rgb, W);
+ float im1m1 = dot(texture2D(source, st-stpp).rgb, W);
+ float ip1p1 = dot(texture2D(source, st+stpp).rgb, W);
+ float im1p1 = dot(texture2D(source, st-stpm).rgb, W);
+ float ip1m1 = dot(texture2D(source, st+stpm).rgb, W);
+ float im10 = dot(texture2D(source, st-stp0).rgb, W);
+ float ip10 = dot(texture2D(source, st+stp0).rgb, W);
+ float i0m1 = dot(texture2D(source, st-st0p).rgb, W);
+ float i0p1 = dot(texture2D(source, st+st0p).rgb, W);
+ float h = -1.0*im1p1 - 2.0*i0p1 - 1.0*ip1p1 + 1.0*im1m1 + 2.0*i0m1 + 1.0*ip1m1;
+ float v = -1.0*im1m1 - 2.0*im10 - 1.0*im1p1 + 1.0*ip1m1 + 2.0*ip10 + 1.0*ip1p1;
+ float mag = 1.0 - length(vec2(h, v));
+ vec3 target = vec3(mag, mag, mag);
+ c = vec4(target, 1.0);
+ } else {
+ c = texture2D(source, qt_TexCoord0);
+ }
+ gl_FragColor = qt_Opacity * c;
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectSobelEdgeDetection2.qml b/experimental/Media Player/Effects/EffectSobelEdgeDetection2.qml
new file mode 100755
index 0000000..938912d
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectSobelEdgeDetection2.qml
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "threshold"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real weight: parameters.get(0).value
+
+ fragmentShaderSrc: "#version 130
+ uniform sampler2D source;
+ uniform float dividerValue;
+ uniform float weight;
+ mat3 G[2] = mat3[](
+ mat3( 1.0, 2.0, 1.0, 0.0, 0.0, 0.0, -1.0, -2.0, -1.0 ),
+ mat3( 1.0, 0.0, -1.0, 2.0, 0.0, -2.0, 1.0, 0.0, -1.0 )
+ );
+ uniform lowp float qt_Opacity;
+ in vec2 qt_TexCoord0;
+ out vec4 FragmentColor;
+ void main() {
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 c = vec4(0.0);
+ if (uv.x < dividerValue) {
+ mat3 intensity;
+ float conv[2];
+ vec3 sample;
+ for (int i=0; i<3; ++i) {
+ for (int j=0; j<3; ++j) {
+ sample = texelFetch(source, ivec2(gl_FragCoord) + ivec2(i-1, j-1), 0).rgb;
+ intensity[i][j] = length(sample) * weight;
+ }
+ }
+ for (int i=0; i<2; ++i) {
+ float dp3 = dot(G[i][0], intensity[0]) + dot(G[i][1], intensity[1]) + dot(G[i][2], intensity[2]);
+ conv[i] = dp3 * dp3;
+ }
+ c = vec4(0.5 * sqrt(conv[0]*conv[0] + conv[1]*conv[1]));
+ } else {
+ c = texture2D(source, qt_TexCoord0);
+ }
+ FragmentColor = qt_Opacity * c;
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectTiltShift.qml b/experimental/Media Player/Effects/EffectTiltShift.qml
new file mode 100755
index 0000000..d0cf9c4
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectTiltShift.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderSrc: "uniform float dividerValue;
+ const float step_w = 0.0015625;
+ const float step_h = 0.0027778;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ vec3 blur()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ float y = uv.y < 0.4 ? uv.y : 1.0 - uv.y;
+ float dist = 8.0 - 20.0 * y;
+ vec3 acc = vec3(0.0, 0.0, 0.0);
+ for (float y=-2.0; y<=2.0; ++y) {
+ for (float x=-2.0; x<=2.0; ++x) {
+ acc += texture2D(source, vec2(uv.x + dist * x * step_w, uv.y + 0.5 * dist * y * step_h)).rgb;
+ }
+ }
+ return acc / 25.0;
+ }
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec3 col;
+ if (uv.x > dividerValue || (uv.y >= 0.4 && uv.y <= 0.6))
+ col = texture2D(source, uv).rgb;
+ else
+ col = blur();
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectToon.qml b/experimental/Media Player/Effects/EffectToon.qml
new file mode 100755
index 0000000..a17ad1c
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectToon.qml
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "threshold"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real threshold: parameters.get(0).value
+ property real targetSize: 250 - (200 * threshold) // TODO: fix ...
+ property real resS: targetSize
+ property real resT: targetSize
+
+ // TODO
+ property real magTol: 0.3
+ property real quantize: 8.0
+
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform float threshold;
+ uniform float resS;
+ uniform float resT;
+ uniform float magTol;
+ uniform float quantize;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec4 color = vec4(1.0, 0.0, 0.0, 1.1);
+ vec2 uv = qt_TexCoord0.xy;
+ if (uv.x < dividerValue) {
+ vec2 st = qt_TexCoord0.st;
+ vec3 rgb = texture2D(source, st).rgb;
+ vec2 stp0 = vec2(1.0/resS, 0.0);
+ vec2 st0p = vec2(0.0 , 1.0/resT);
+ vec2 stpp = vec2(1.0/resS, 1.0/resT);
+ vec2 stpm = vec2(1.0/resS, -1.0/resT);
+ float i00 = dot( texture2D(source, st).rgb, vec3(0.2125,0.7154,0.0721));
+ float im1m1 = dot( texture2D(source, st-stpp).rgb, vec3(0.2125,0.7154,0.0721));
+ float ip1p1 = dot( texture2D(source, st+stpp).rgb, vec3(0.2125,0.7154,0.0721));
+ float im1p1 = dot( texture2D(source, st-stpm).rgb, vec3(0.2125,0.7154,0.0721));
+ float ip1m1 = dot( texture2D(source, st+stpm).rgb, vec3(0.2125,0.7154,0.0721));
+ float im10 = dot( texture2D(source, st-stp0).rgb, vec3(0.2125,0.7154,0.0721));
+ float ip10 = dot( texture2D(source, st+stp0).rgb, vec3(0.2125,0.7154,0.0721));
+ float i0m1 = dot( texture2D(source, st-st0p).rgb, vec3(0.2125,0.7154,0.0721));
+ float i0p1 = dot( texture2D(source, st+st0p).rgb, vec3(0.2125,0.7154,0.0721));
+ float h = -1.*im1p1 - 2.*i0p1 - 1.*ip1p1 + 1.*im1m1 + 2.*i0m1 + 1.*ip1m1;
+ float v = -1.*im1m1 - 2.*im10 - 1.*im1p1 + 1.*ip1m1 + 2.*ip10 + 1.*ip1p1;
+ float mag = sqrt(h*h + v*v);
+ if (mag > magTol) {
+ color = vec4(0.0, 0.0, 0.0, 1.0);
+ }
+ else {
+ rgb.rgb *= quantize;
+ rgb.rgb += vec3(0.5, 0.5, 0.5);
+ ivec3 irgb = ivec3(rgb.rgb);
+ rgb.rgb = vec3(irgb) / quantize;
+ color = vec4(rgb, 1.0);
+ }
+ } else {
+ color = texture2D(source, uv);
+ }
+ gl_FragColor = qt_Opacity * color;
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectVignette.qml b/experimental/Media Player/Effects/EffectVignette.qml
new file mode 100755
index 0000000..5ec5090
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectVignette.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 orig = texture2D(source, uv);
+ float cr = pow(0.1, 2.0);
+ float pt = pow(uv.x - 0.5, 2.0) + pow(uv.y - 0.5, 2.0);
+ float d = pt - cr;
+ float cf = 1.0;
+ if (d > 0.0)
+ cf = 1.0 - 2.0 * d;
+ vec3 col = cf * orig.rgb;
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * orig;
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectWarhol.qml b/experimental/Media Player/Effects/EffectWarhol.qml
new file mode 100755
index 0000000..1e40b30
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectWarhol.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ fragmentShaderSrc: "uniform float dividerValue;
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec4 orig = texture2D(source, uv);
+ vec3 col = orig.rgb;
+ float y = 0.3 *col.r + 0.59 * col.g + 0.11 * col.b;
+ y = y < 0.3 ? 0.0 : (y < 0.6 ? 0.5 : 1.0);
+ if (y == 0.5)
+ col = vec3(0.8, 0.0, 0.0);
+ else if (y == 1.0)
+ col = vec3(0.9, 0.9, 0.0);
+ else
+ col = vec3(0.0, 0.0, 0.0);
+ if (uv.x < dividerValue)
+ gl_FragColor = qt_Opacity * vec4(col, 1.0);
+ else
+ gl_FragColor = qt_Opacity * orig;
+ }"
+}
diff --git a/experimental/Media Player/Effects/EffectWobble.qml b/experimental/Media Player/Effects/EffectWobble.qml
new file mode 100755
index 0000000..4b07639
--- /dev/null
+++ b/experimental/Media Player/Effects/EffectWobble.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Effect {
+ parameters: ListModel {
+ ListElement {
+ name: "amplitude"
+ value: 0.5
+ }
+ }
+
+ // Transform slider values, and bind result to shader uniforms
+ property real amplitude: parameters.get(0).value * 0.05
+
+ property real frequency: 20
+ property real time: 0
+
+ NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 600 }
+
+ fragmentShaderSrc: "uniform float amplitude;
+ uniform float dividerValue;
+ uniform float frequency;
+ uniform float time;
+
+ uniform sampler2D source;
+ uniform lowp float qt_Opacity;
+ varying vec2 qt_TexCoord0;
+
+ void main()
+ {
+ vec2 uv = qt_TexCoord0.xy;
+ vec2 tc = qt_TexCoord0;
+ if (uv.x < dividerValue) {
+ vec2 p = sin(time + frequency * qt_TexCoord0);
+ tc += amplitude * vec2(p.y, -p.x);
+ }
+ gl_FragColor = qt_Opacity * texture2D(source, tc);
+ }"
+}
diff --git a/experimental/Media Player/FileBrowser.qml b/experimental/Media Player/FileBrowser.qml
new file mode 100644
index 0000000..33d14cf
--- /dev/null
+++ b/experimental/Media Player/FileBrowser.qml
@@ -0,0 +1,415 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import Qt.labs.folderlistmodel 2.0
+
+Rectangle {
+ id: fileBrowser
+ color: "transparent"
+
+ property string folder: "file:///cache"
+
+ signal fileSelected(string file)
+
+ function selectFile(file) {
+ if (file != "")
+ folder = loader.item.folders.folder
+ loader.sourceComponent = undefined
+ if (file != "")
+ fileBrowser.fileSelected("file://" + file)
+ }
+
+ Loader {
+ id: loader
+ }
+
+ function show() {
+ loader.sourceComponent = fileBrowserComponent
+ loader.item.parent = fileBrowser
+ loader.item.anchors.fill = fileBrowser
+ loader.item.folder = fileBrowser.folder
+ }
+
+ Component {
+ id: fileBrowserComponent
+
+ Rectangle {
+ id: root
+ gradient: Gradient {
+ GradientStop { position: 0; color: "#111111" }
+ GradientStop { position: 1; color: "#222222"}
+ }
+ property bool showFocusHighlight: false
+ property variant folders: folders1
+ property variant view: view1
+ property alias folder: folders1.folder
+ property color textColor: "white"
+
+ FolderListModel {
+ id: folders1
+ folder: folder
+ }
+
+ FolderListModel {
+ id: folders2
+ folder: folder
+ }
+
+ SystemPalette {
+ id: palette
+ }
+
+ Component {
+ id: folderDelegate
+
+ Rectangle {
+ id: wrapper
+ function launch() {
+ if (folders.isFolder(index))
+ down(filePath);
+ else
+ fileBrowser.selectFile(filePath)
+ }
+ width: root.width
+ height: 50
+ color: "transparent"
+
+ Rectangle {
+ id: highlight; visible: false
+ anchors.fill: parent
+ color: palette.highlight
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ }
+
+ Item {
+ width: 40; height: 40
+ y: 3
+ x: 5
+ Image {
+ source: "images/FileButton.png"
+ width: 34; height: 34
+ anchors.centerIn: parent
+ visible: folders.isFolder(index)
+ }
+ }
+
+ Text {
+ id: nameText
+ anchors.fill: parent; verticalAlignment: Text.AlignVCenter
+ text: fileName
+ anchors.leftMargin: 54
+ font.pixelSize: 24
+ color: (wrapper.ListView.isCurrentItem && root.showFocusHighlight) ? palette.highlightedText : textColor
+ elide: Text.ElideRight
+ }
+
+ MouseArea {
+ id: mouseRegion
+ anchors.fill: parent
+ onPressed: {
+ root.showFocusHighlight = false;
+ wrapper.ListView.view.currentIndex = index;
+ }
+ onClicked: { if (folders == wrapper.ListView.view.model) launch() }
+ }
+
+ states: [
+ State {
+ name: "pressed"
+ when: mouseRegion.pressed
+ PropertyChanges { target: highlight; visible: true }
+ PropertyChanges { target: nameText; color: palette.highlightedText }
+ }
+ ]
+ }
+ }
+
+ ListView {
+ id: view1
+ anchors.top: titleBar.bottom
+ anchors.topMargin: 15
+ anchors.bottom: parent.bottom
+ x: 0
+ width: parent.width
+ model: folders1
+ delegate: folderDelegate
+ highlight: Rectangle {
+ color: palette.highlight
+ visible: root.showFocusHighlight && view1.count != 0
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ width: view1.currentItem == null ? 0 : view1.currentItem.width
+ }
+ highlightMoveVelocity: 1000
+ pressDelay: 100
+ focus: true
+ state: "current"
+ states: [
+ State {
+ name: "current"
+ PropertyChanges { target: view1; x: 0 }
+ },
+ State {
+ name: "exitLeft"
+ PropertyChanges { target: view1; x: -root.width }
+ },
+ State {
+ name: "exitRight"
+ PropertyChanges { target: view1; x: root.width }
+ }
+ ]
+ transitions: [
+ Transition {
+ to: "current"
+ SequentialAnimation {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ },
+ Transition {
+ NumberAnimation { properties: "x"; duration: 250 }
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ ]
+ Keys.onPressed: root.keyPressed(event.key)
+ }
+
+ ListView {
+ id: view2
+ anchors.top: titleBar.bottom
+ anchors.topMargin: 15
+ anchors.bottom: parent.bottom
+ x: parent.width
+ width: parent.width
+ model: folders2
+ delegate: folderDelegate
+ highlight: Rectangle {
+ color: palette.highlight
+ visible: root.showFocusHighlight && view2.count != 0
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ width: view1.currentItem == null ? 0 : view1.currentItem.width
+ }
+ highlightMoveVelocity: 1000
+ pressDelay: 100
+ states: [
+ State {
+ name: "current"
+ PropertyChanges { target: view2; x: 0 }
+ },
+ State {
+ name: "exitLeft"
+ PropertyChanges { target: view2; x: -root.width }
+ },
+ State {
+ name: "exitRight"
+ PropertyChanges { target: view2; x: root.width }
+ }
+ ]
+ transitions: [
+ Transition {
+ to: "current"
+ SequentialAnimation {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ },
+ Transition {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ ]
+ Keys.onPressed: root.keyPressed(event.key)
+ }
+
+ Keys.onPressed: {
+ root.keyPressed(event.key);
+ if (event.key == Qt.Key_Return || event.key == Qt.Key_Select || event.key == Qt.Key_Right) {
+ view.currentItem.launch();
+ event.accepted = true;
+ } else if (event.key == Qt.Key_Left) {
+ up();
+ }
+ }
+
+ Rectangle {
+ width: parent.width;
+ height: 70
+ color: "#111111"
+ y: -7
+ id: titleBar
+
+ Rectangle {
+ id: upButton
+ width: 90
+ height: titleBar.height - 7
+ color: "transparent"
+ Image { anchors.centerIn: parent; source: "images/up.png"; width: 32; height: 32 }
+ MouseArea { id: upRegion; anchors.centerIn: parent
+ anchors.fill: parent
+ onClicked: if (folders.parentFolder != "") up()
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: upRegion.pressed
+ PropertyChanges { target: upButton; color: palette.highlight }
+ }
+ ]
+ }
+
+// Rectangle {
+// color: "gray"
+// x: 70
+// width: 1
+// height: 63
+// }
+
+ Rectangle {
+ id: cancelButton
+ width: 100
+ height: titleBar.height - 7
+ color: "transparent"
+ anchors { left: upButton.right; leftMargin: 1; }
+
+ Text {
+ anchors { fill: parent; topMargin: 3 }
+ text: "Cancel"
+ color: "white"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.pixelSize: 22
+ }
+
+ MouseArea {
+ id: cancelRegion
+ anchors.fill: parent
+ onClicked: fileBrowser.selectFile("")
+ }
+
+ states: [
+ State {
+ name: "pressed"
+ when: cancelRegion.pressed
+ PropertyChanges { target: cancelButton; color: palette.highlight }
+ }
+ ]
+ }
+
+// Rectangle {
+// color: "gray"
+// x: 171
+// width: 1
+// height: 63
+// }
+
+ Text {
+ anchors.left: cancelButton.right; anchors.right: parent.right; height: parent.height
+ anchors.leftMargin: 4; anchors.rightMargin: 4
+ text: String(folders.folder).replace("file://", "")
+ color: "white"
+ elide: Text.ElideLeft; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
+ font.pixelSize: 28
+ }
+
+ Rectangle {
+ width: parent.width
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 3
+ height: 2
+ color: palette.highlight
+ }
+ }
+
+ function down(path) {
+ if (folders == folders1) {
+ view = view2
+ folders = folders2;
+ view1.state = "exitLeft";
+ } else {
+ view = view1
+ folders = folders1;
+ view2.state = "exitLeft";
+ }
+ view.x = root.width;
+ view.state = "current";
+ view.focus = true;
+ folders.folder = "file://" + path;
+ }
+
+ function up() {
+ var path = folders.parentFolder;
+ if (folders == folders1) {
+ view = view2
+ folders = folders2;
+ view1.state = "exitRight";
+ } else {
+ view = view1
+ folders = folders1;
+ view2.state = "exitRight";
+ }
+ view.x = -root.width;
+ view.state = "current";
+ view.focus = true;
+ folders.folder = path;
+ }
+
+ function keyPressed(key) {
+ switch (key) {
+ case Qt.Key_Up:
+ case Qt.Key_Down:
+ case Qt.Key_Left:
+ case Qt.Key_Right:
+ root.showFocusHighlight = true;
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/experimental/Media Player/ImageButton.qml b/experimental/Media Player/ImageButton.qml
new file mode 100755
index 0000000..274efd5
--- /dev/null
+++ b/experimental/Media Player/ImageButton.qml
@@ -0,0 +1,44 @@
+
+import QtQuick 2.0
+
+Item {
+ id: root
+
+ property alias enabled: mouseArea.enabled
+ property alias imageSource: image.source
+
+ property bool checkable: false
+ property bool checked: false
+ property alias hover: mouseArea.containsMouse
+ property alias pressed: mouseArea.pressed
+
+ opacity: enabled ? 1.0 : 0.3
+ signal clicked
+
+ width: image.width
+ height: image.height
+
+ Image {
+ id: image
+ anchors.centerIn: parent
+ visible: true
+ opacity: pressed ? 0.6 : 1
+ smooth: true
+ }
+
+// ColorOverlay {
+// id: glowEffect
+// anchors.fill: image
+// source: image
+// color: pressed ? "#22000000" : checked ? "orange" : "white"
+// visible: checked || hover || pressed
+// }
+
+ MouseArea {
+ id: mouseArea
+ hoverEnabled: true
+ anchors.fill: root
+ onPositionChanged: applicationWindow.resetTimer()
+ onClicked: root.clicked();
+ }
+}
diff --git a/experimental/Media Player/Intro.qml b/experimental/Media Player/Intro.qml
new file mode 100644
index 0000000..a5dbb2a
--- /dev/null
+++ b/experimental/Media Player/Intro.qml
@@ -0,0 +1,48 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ color: "#111111"
+
+// Image {
+// anchors.fill: parent
+// source: "images/gradient.png"
+// }
+
+ Image {
+ id: logo
+ anchors.centerIn: root
+ anchors.verticalCenterOffset: -60
+ source: "images/qt-logo.png"
+ opacity: 0.5
+
+ }
+// Rectangle {
+// id: button
+// opacity: mouse.containsMouse ? 1 : 0
+// Behavior on opacity {NumberAnimation{duration: 100}}
+// color: mouse.pressed ? "#11000000" : "#11ffffff"
+// anchors.top: logo.bottom
+// anchors.horizontalCenter: parent.horizontalCenter
+// border.color: "#33ffffff"
+// width: text.width + 40
+// height: text.height + 4
+// antialiasing: true
+// radius: 4
+// MouseArea {
+// id: mouse
+// anchors.fill: parent
+// hoverEnabled: true
+// onClicked: applicationWindow.openVideo()
+// }
+// }
+
+// Text {
+// id: text
+// color: "#44ffffff"
+// text: "Open File"
+// font.bold: true
+// font.pixelSize: 18
+// anchors.centerIn: button
+// }
+}
diff --git a/experimental/Media Player/MetadataView.qml b/experimental/Media Player/MetadataView.qml
new file mode 100644
index 0000000..b0b907b
--- /dev/null
+++ b/experimental/Media Player/MetadataView.qml
@@ -0,0 +1,173 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+
+ property variant mediaPlayer: null
+
+ anchors.fill: parent
+ color: "#AA000000"
+ Behavior on opacity { NumberAnimation { } }
+ opacity: 0
+
+ Rectangle {
+ height: column.height + 30
+ width: 500
+ color: "#BB222222"
+ anchors.centerIn: parent
+ anchors.verticalCenterOffset: -50
+
+
+ Column {
+ id: column
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.margins: 15
+ spacing: 12
+
+ Text {
+ text: "Media Type: " + (mediaPlayer ? mediaPlayer.metaData.mediaType : "")
+ visible: mediaPlayer && mediaPlayer.metaData.mediaType !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Title: " + (mediaPlayer ? mediaPlayer.metaData.title : "")
+ visible: mediaPlayer && mediaPlayer.metaData.title !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Artist: " + (mediaPlayer ? mediaPlayer.metaData.leadPerformer : "")
+ visible: mediaPlayer && mediaPlayer.metaData.leadPerformer !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Artist: " + (mediaPlayer ? mediaPlayer.metaData.contributingArtist : "")
+ visible: mediaPlayer && mediaPlayer.metaData.contributingArtist !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Album: " + (mediaPlayer ? mediaPlayer.metaData.albumTitle : "")
+ visible: mediaPlayer && mediaPlayer.metaData.albumTitle !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Album Artist: " + (mediaPlayer ? mediaPlayer.metaData.albumArtist : "")
+ visible: mediaPlayer && mediaPlayer.metaData.albumArtist !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Author: " + (mediaPlayer ? mediaPlayer.metaData.author : "")
+ visible: mediaPlayer && mediaPlayer.metaData.author !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Composer: " + (mediaPlayer ? mediaPlayer.metaData.composer : "")
+ visible: mediaPlayer && mediaPlayer.metaData.composer !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Writer: " + (mediaPlayer ? mediaPlayer.metaData.writer : "")
+ visible: mediaPlayer && mediaPlayer.metaData.writer !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Genre: " + (mediaPlayer ? mediaPlayer.metaData.genre : "")
+ visible: mediaPlayer && mediaPlayer.metaData.genre !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Track Number: " + (mediaPlayer ? mediaPlayer.metaData.trackNumber : "")
+ visible: mediaPlayer && mediaPlayer.metaData.trackNumber !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Year: " + (mediaPlayer ? mediaPlayer.metaData.year : "")
+ visible: mediaPlayer && mediaPlayer.metaData.year !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Duration: " + (mediaPlayer ? Qt.formatTime(new Date(mediaPlayer.metaData.duration), mediaPlayer.metaData.duration >= 3600000 ? "H:mm:ss" : "m:ss") : "")
+ visible: mediaPlayer && mediaPlayer.metaData.duration !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Resolution: " + (mediaPlayer && mediaPlayer.metaData.resolution !== undefined ? (mediaPlayer.metaData.resolution.width + "x" + mediaPlayer.metaData.resolution.height) : "")
+ visible: mediaPlayer && mediaPlayer.metaData.resolution !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Audio Bitrate: " + (mediaPlayer ? Math.round(mediaPlayer.metaData.audioBitRate / 1000) + " kbps" : "")
+ visible: mediaPlayer && mediaPlayer.metaData.audioBitRate !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Video Bitrate: " + (mediaPlayer ? Math.round(mediaPlayer.metaData.videoBitRate / 1000) + " kbps" : "")
+ visible: mediaPlayer && mediaPlayer.metaData.videoBitRate !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ Text {
+ text: "Date: " + (mediaPlayer ? Qt.formatDate(mediaPlayer.metaData.date) : "")
+ visible: mediaPlayer && mediaPlayer.metaData.date !== undefined
+ color: "white"
+ font.pixelSize: 24
+ width: parent.width
+ wrapMode: Text.WordWrap
+ }
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.opacity = 0
+ enabled: root.opacity !== 0
+ }
+}
diff --git a/experimental/Media Player/ParameterPanel.qml b/experimental/Media Player/ParameterPanel.qml
new file mode 100644
index 0000000..51b9938
--- /dev/null
+++ b/experimental/Media Player/ParameterPanel.qml
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ height: view.model.count * sliderHeight
+ color: "#BB333333"
+ property color lineColor: "black"
+ property real spacing: 10
+ property real sliderHeight: 50
+ property bool isMouseAbove: mouseAboveMonitor.containsMouse
+
+ property ListModel model: ListModel { }
+
+ MouseArea {
+ id: mouseAboveMonitor
+ anchors.fill: parent
+ hoverEnabled: true;
+ }
+
+ Component {
+ id: editDelegate
+
+ Rectangle {
+ id: delegate
+ width: parent.width
+ height: root.sliderHeight
+ color: "transparent"
+
+ Text {
+ id: text
+ text: name
+ color: "white"
+ anchors {
+ top: parent.top
+ bottom: parent.bottom
+ leftMargin: 15
+ left: parent.left
+ }
+ horizontalAlignment: Text.AlignRight
+ verticalAlignment: Text.AlignVCenter
+ font.pixelSize: 20
+ font.capitalization: Font.Capitalize
+ width: 90
+ }
+
+ Slider {
+ anchors {
+ verticalCenter: text.verticalCenter
+ verticalCenterOffset: 3
+ left: text.right
+ leftMargin: 20
+ right: parent.right
+ rightMargin: 20
+ }
+ value: model.value
+ onValueChanged: view.model.setProperty(index, "value", value)
+ }
+ }
+ }
+
+ ListView {
+ id: view
+ anchors.fill: parent
+ anchors.margins: 8
+ model: root.model
+ delegate: editDelegate
+ interactive: false
+ }
+}
diff --git a/experimental/Media Player/PlaybackControl.qml b/experimental/Media Player/PlaybackControl.qml
new file mode 100755
index 0000000..2dc609f
--- /dev/null
+++ b/experimental/Media Player/PlaybackControl.qml
@@ -0,0 +1,60 @@
+
+import QtQuick 2.0
+
+Row {
+ id: root
+ spacing: 26
+ height: playButton.height
+
+ property bool isPlaybackEnabled: false
+ property bool isPlaying: false
+
+ signal forwardButtonPressed()
+ signal reverseButtonPressed()
+ signal playButtonPressed()
+ signal stopButtonPressed()
+
+ //Playback Controls
+ ImageButton {
+ id: rateReverseButton
+ enabled: isPlaybackEnabled
+ imageSource: "images/RateButtonReverse.png"
+ anchors.verticalCenter: root.verticalCenter
+ onClicked: {
+ reverseButtonPressed();
+ }
+ }
+ ImageButton {
+ id: playButton
+ enabled: isPlaybackEnabled
+ imageSource: !isPlaying ? "images/PlayButton.png" : "images/PauseButton.png"
+ anchors.verticalCenter: root.verticalCenter
+// anchors.right: rateForwardButton.left
+// anchors.rightMargin: 10
+ onClicked: {
+ playButtonPressed();
+ }
+ }
+// Rectangle{
+// enabled: isPlaybackEnabled
+// color: "white"
+// opacity: enabled ? 1 : 0.3
+// width: playButton.width
+// height: width
+// anchors.verticalCenter: root.verticalCenter
+// MouseArea {
+// anchors.fill: parent
+// onClicked: stopButtonPressed();
+// }
+// }
+
+ ImageButton {
+ id: rateForwardButton
+ enabled: isPlaybackEnabled
+ imageSource: "images/RateButtonForward.png"
+ anchors.verticalCenter: root.verticalCenter
+ onClicked: {
+ forwardButtonPressed();
+ }
+ }
+}
diff --git a/experimental/Media Player/SeekControl.qml b/experimental/Media Player/SeekControl.qml
new file mode 100755
index 0000000..fa0842d
--- /dev/null
+++ b/experimental/Media Player/SeekControl.qml
@@ -0,0 +1,83 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ height: seekSlider.height
+
+ property int position: 0
+ property int duration: 0
+ property bool seekable: false
+ property alias pressed : seekSlider.pressed
+ property bool enabled
+
+ signal seekValueChanged(int newPosition)
+
+ onPositionChanged: {
+ elapsedText.text = formatTime(position);
+ seekSlider.value = position;
+ }
+
+ onDurationChanged: {
+ remainingText.text = formatTime(duration);
+ }
+
+ Text {
+ id: elapsedText
+ anchors.verticalCenter: seekSlider.verticalCenter
+ anchors.left: root.left
+ text: "00:00"
+ font.pixelSize: 20
+ color: "#cccccc"
+ }
+
+ Slider {
+ id: seekSlider
+ anchors.leftMargin: 30
+ anchors.rightMargin: 30
+ anchors.left: elapsedText.right
+ anchors.right: remainingText.left
+ anchors.verticalCenter: root.verticalCenter
+ mutable: root.seekable
+ enabled: root.enabled
+
+ minimum: 0.0
+ maximum: root.duration !== 0 ? root.duration : 1
+
+ onValueChangedByHandle: {
+ seekValueChanged(newValue);
+ applicationWindow.resetTimer()
+ }
+ }
+
+ Text {
+ id: remainingText
+ anchors.verticalCenter: seekSlider.verticalCenter
+ anchors.right: root.right
+ text: "00:00"
+ font.pixelSize: 20
+ color: "#cccccc"
+ }
+
+ function formatTime(time) {
+ time = time / 1000
+ var hours = Math.floor(time / 3600);
+ time = time - hours * 3600;
+ var minutes = Math.floor(time / 60);
+ var seconds = Math.floor(time - minutes * 60);
+
+ if (hours > 0)
+ return formatTimeBlock(hours) + ":" + formatTimeBlock(minutes) + ":" + formatTimeBlock(seconds);
+ else
+ return formatTimeBlock(minutes) + ":" + formatTimeBlock(seconds);
+
+ }
+
+ function formatTimeBlock(time) {
+ if (time === 0)
+ return "00"
+ if (time < 10)
+ return "0" + time;
+ else
+ return time.toString();
+ }
+}
diff --git a/experimental/Media Player/Slider.qml b/experimental/Media Player/Slider.qml
new file mode 100644
index 0000000..17fd8cd
--- /dev/null
+++ b/experimental/Media Player/Slider.qml
@@ -0,0 +1,98 @@
+import QtQuick 2.0
+
+Item {
+ id: slider
+
+ height: handleBack.height
+ // value is read/write.
+ property real value: 0
+ property real maximum: 1
+ property real minimum: 0
+ property int xMax: width - handle.width
+ onXMaxChanged: updatePos()
+ onMinimumChanged: updatePos()
+ onValueChanged: if (!pressed) updatePos()
+ property bool mutable: true
+ property alias pressed : backgroundMouse.pressed
+
+ signal valueChangedByHandle(int newValue)
+
+ function updatePos() {
+ if (maximum > minimum) {
+ var pos = 0 + (value - minimum) * slider.xMax / (maximum - minimum);
+ pos = Math.min(pos, width - handle.width - 0);
+ pos = Math.max(pos, 0);
+ handle.x = pos;
+ } else {
+ handle.x = 0;
+ }
+ }
+
+ Rectangle {
+ id: background
+ width: slider.width
+ anchors.verticalCenter: slider.verticalCenter
+ height: 2
+ color: "#666666"
+
+ MouseArea {
+ id: backgroundMouse
+ anchors.fill: parent
+ anchors.topMargin: -24
+ anchors.bottomMargin: -24
+ enabled: slider.mutable
+ drag.target: handle
+ drag.axis: Drag.XAxis
+ drag.minimumX: 0
+ drag.maximumX: slider.xMax
+ onPressedChanged: {
+ value = Math.max(minimum, Math.min(maximum, (maximum - minimum) * (mouseX - handle.width/2) / slider.xMax + minimum));
+ valueChangedByHandle(value);
+ updatePos();
+ }
+ onPositionChanged: {
+ value = Math.max(minimum, Math.min(maximum, (maximum - minimum) * (mouseX - handle.width/2) / slider.xMax + minimum));
+ valueChangedByHandle(value);
+ }
+ onWheel: {
+ value = Math.max(minimum, Math.min(maximum, value + (wheel.angleDelta.y > 0 ? 1 : -1) * (10 / slider.xMax) * (slider.maximum - slider.minimum)));
+ valueChangedByHandle(value);
+ updatePos();
+ }
+ }
+ }
+
+ Rectangle {
+ id: progress
+ height: 5
+ anchors.verticalCenter: background.verticalCenter
+ anchors.left: background.left
+ anchors.right: handle.right
+ anchors.rightMargin: handle.width / 2
+ visible: slider.enabled
+ color: "#98c66c"
+ }
+
+ Rectangle {
+ id: handleBack
+ width: 40
+ height: width
+ radius: width / 2
+ color: "#8898c66c"
+ antialiasing: true
+ anchors.centerIn: handle
+ visible: handle.visible
+ }
+
+ Rectangle {
+ id: handle
+ width: 14
+ height: width
+ radius: width / 2
+ antialiasing: true
+ color: "#98c66c"
+ anchors.verticalCenter: background.verticalCenter
+ visible: slider.enabled
+ }
+}
+
diff --git a/experimental/Media Player/UrlBar.qml b/experimental/Media Player/UrlBar.qml
new file mode 100644
index 0000000..cfada41
--- /dev/null
+++ b/experimental/Media Player/UrlBar.qml
@@ -0,0 +1,80 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ height: 50
+ signal urlAccepted(string text)
+ color: "#cc222222"
+ Behavior on opacity { NumberAnimation{} }
+ onOpacityChanged: {
+ if (opacity == 1)
+ urlInput.focus = true
+ else if (opacity == 0)
+ urlInput.focus = false
+ }
+
+ Keys.onEscapePressed: root.opacity = 0
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.opacity = 0
+ }
+
+ Text {
+ anchors.bottom: urlBar.top
+ anchors.left: urlBar.left
+ anchors.bottomMargin: 8
+ text: "Enter URL"
+ color: "white"
+ font.pixelSize: 20
+ }
+
+ BorderImage {
+ id: urlBar
+ source: "images/ControlBar.png"
+ border.top: 12
+ border.bottom: 12
+ border.left: 12
+ border.right: 12
+ height: 70
+ anchors.centerIn: parent
+ anchors.verticalCenterOffset: -170
+ width: 600
+
+ Rectangle {
+ anchors.fill: parent
+ anchors.margins: 16
+ color: "#66ffffff"
+ border.color: "#bbffffff"
+ radius: 2
+ antialiasing: true
+
+ TextInput {
+ id: urlInput
+ selectionColor: "#aaffffff"
+ selectedTextColor: "black"
+ selectByMouse: true
+ anchors.fill: parent
+ anchors.margins: 5
+ font.pixelSize: 24
+ color: "black"
+ text: "http://"
+ onAccepted: root.urlAccepted(urlInput.text);
+
+ }
+ }
+ }
+
+// Rectangle {
+// anchors.right: urlBar.left
+// anchors.rightMargin: 32
+// anchors.verticalCenter: urlBar.verticalCenter
+// height: 70
+// width: 70
+// color: "gray"
+// MouseArea {
+// anchors.fill: parent
+// onClicked: { urlInput.text = ""; urlInput.paste(); }
+// }
+// }
+}
diff --git a/experimental/Media Player/VolumeControl.qml b/experimental/Media Player/VolumeControl.qml
new file mode 100755
index 0000000..e814b99
--- /dev/null
+++ b/experimental/Media Player/VolumeControl.qml
@@ -0,0 +1,45 @@
+
+import QtQuick 2.0
+
+Item {
+ id: root
+ width: 210
+ height: volumeUp.height
+
+ property alias volume: volumeSlider.value
+
+ //Volume Controls
+ ImageButton {
+ id: volumeDown
+ imageSource: "images/VolumeDown.png"
+ anchors.verticalCenter: root.verticalCenter
+ anchors.left: root.left
+ scale: 1.4
+ onClicked: {
+ root.volume = 0.0;
+ }
+ }
+ Slider {
+ id: volumeSlider
+ anchors.left: volumeDown.right
+ anchors.leftMargin: 22
+ anchors.rightMargin: 22
+ anchors.right: volumeUp.left
+ maximum: 1.0
+ minimum: 0.0
+ anchors.verticalCenter: root.verticalCenter
+ anchors.verticalCenterOffset: 1
+ }
+
+ ImageButton {
+ id: volumeUp
+ imageSource: "images/VolumeUp.png"
+ anchors.verticalCenter: root.verticalCenter
+ anchors.verticalCenterOffset: 1
+ anchors.right: root.right
+ scale: 1.4
+ onClicked: {
+ root.volume = 1.0
+ }
+ }
+}
diff --git a/experimental/Media Player/description.txt b/experimental/Media Player/description.txt
new file mode 100644
index 0000000..bf034e5
--- /dev/null
+++ b/experimental/Media Player/description.txt
@@ -0,0 +1,3 @@
+The Media Player example demonstrates the use of the media playback features of Qt Multimedia with Qt Quick.
+
+It can play from a file or from Internet, both videos and music.
diff --git a/experimental/Media Player/images/CameraButton.png b/experimental/Media Player/images/CameraButton.png
new file mode 100644
index 0000000..d950f78
--- /dev/null
+++ b/experimental/Media Player/images/CameraButton.png
Binary files differ
diff --git a/experimental/Media Player/images/ControlBar.png b/experimental/Media Player/images/ControlBar.png
new file mode 100644
index 0000000..8b5f545
--- /dev/null
+++ b/experimental/Media Player/images/ControlBar.png
Binary files differ
diff --git a/experimental/Media Player/images/FXButton.png b/experimental/Media Player/images/FXButton.png
new file mode 100644
index 0000000..04530f4
--- /dev/null
+++ b/experimental/Media Player/images/FXButton.png
Binary files differ
diff --git a/experimental/Media Player/images/FileButton.png b/experimental/Media Player/images/FileButton.png
new file mode 100644
index 0000000..d65e681
--- /dev/null
+++ b/experimental/Media Player/images/FileButton.png
Binary files differ
diff --git a/experimental/Media Player/images/FullscreenButton.png b/experimental/Media Player/images/FullscreenButton.png
new file mode 100755
index 0000000..413872a
--- /dev/null
+++ b/experimental/Media Player/images/FullscreenButton.png
Binary files differ
diff --git a/experimental/Media Player/images/PauseButton.png b/experimental/Media Player/images/PauseButton.png
new file mode 100644
index 0000000..0d3e2d1
--- /dev/null
+++ b/experimental/Media Player/images/PauseButton.png
Binary files differ
diff --git a/experimental/Media Player/images/PlayButton.png b/experimental/Media Player/images/PlayButton.png
new file mode 100644
index 0000000..9a85633
--- /dev/null
+++ b/experimental/Media Player/images/PlayButton.png
Binary files differ
diff --git a/experimental/Media Player/images/PlaybackSlider.png b/experimental/Media Player/images/PlaybackSlider.png
new file mode 100755
index 0000000..3716315
--- /dev/null
+++ b/experimental/Media Player/images/PlaybackSlider.png
Binary files differ
diff --git a/experimental/Media Player/images/RateButtonForward.png b/experimental/Media Player/images/RateButtonForward.png
new file mode 100644
index 0000000..4b52603
--- /dev/null
+++ b/experimental/Media Player/images/RateButtonForward.png
Binary files differ
diff --git a/experimental/Media Player/images/RateButtonReverse.png b/experimental/Media Player/images/RateButtonReverse.png
new file mode 100644
index 0000000..64e94ed
--- /dev/null
+++ b/experimental/Media Player/images/RateButtonReverse.png
Binary files differ
diff --git a/experimental/Media Player/images/SliderBackground.png b/experimental/Media Player/images/SliderBackground.png
new file mode 100644
index 0000000..b83f729
--- /dev/null
+++ b/experimental/Media Player/images/SliderBackground.png
Binary files differ
diff --git a/experimental/Media Player/images/SliderHandle.png b/experimental/Media Player/images/SliderHandle.png
new file mode 100755
index 0000000..5206100
--- /dev/null
+++ b/experimental/Media Player/images/SliderHandle.png
Binary files differ
diff --git a/experimental/Media Player/images/SliderProgress.png b/experimental/Media Player/images/SliderProgress.png
new file mode 100755
index 0000000..e0efc87
--- /dev/null
+++ b/experimental/Media Player/images/SliderProgress.png
Binary files differ
diff --git a/experimental/Media Player/images/UrlButton.png b/experimental/Media Player/images/UrlButton.png
new file mode 100644
index 0000000..876951f
--- /dev/null
+++ b/experimental/Media Player/images/UrlButton.png
Binary files differ
diff --git a/experimental/Media Player/images/VolumeDown.png b/experimental/Media Player/images/VolumeDown.png
new file mode 100755
index 0000000..60c626d
--- /dev/null
+++ b/experimental/Media Player/images/VolumeDown.png
Binary files differ
diff --git a/experimental/Media Player/images/VolumeUp.png b/experimental/Media Player/images/VolumeUp.png
new file mode 100755
index 0000000..886fde7
--- /dev/null
+++ b/experimental/Media Player/images/VolumeUp.png
Binary files differ
diff --git a/experimental/Media Player/images/folder.png b/experimental/Media Player/images/folder.png
new file mode 100644
index 0000000..e53e2ad
--- /dev/null
+++ b/experimental/Media Player/images/folder.png
Binary files differ
diff --git a/experimental/Media Player/images/gradient.png b/experimental/Media Player/images/gradient.png
new file mode 100644
index 0000000..1cd7281
--- /dev/null
+++ b/experimental/Media Player/images/gradient.png
Binary files differ
diff --git a/experimental/Media Player/images/pattern.png b/experimental/Media Player/images/pattern.png
new file mode 100644
index 0000000..028181e
--- /dev/null
+++ b/experimental/Media Player/images/pattern.png
Binary files differ
diff --git a/experimental/Media Player/images/qt-logo.png b/experimental/Media Player/images/qt-logo.png
new file mode 100755
index 0000000..242bb28
--- /dev/null
+++ b/experimental/Media Player/images/qt-logo.png
Binary files differ
diff --git a/experimental/Media Player/images/titlebar.png b/experimental/Media Player/images/titlebar.png
new file mode 100644
index 0000000..51c9008
--- /dev/null
+++ b/experimental/Media Player/images/titlebar.png
Binary files differ
diff --git a/experimental/Media Player/images/titlebar.sci b/experimental/Media Player/images/titlebar.sci
new file mode 100755
index 0000000..0418d94
--- /dev/null
+++ b/experimental/Media Player/images/titlebar.sci
@@ -0,0 +1,5 @@
+border.left: 10
+border.top: 12
+border.bottom: 12
+border.right: 10
+source: titlebar.png
diff --git a/experimental/Media Player/images/up.png b/experimental/Media Player/images/up.png
new file mode 100644
index 0000000..b05f802
--- /dev/null
+++ b/experimental/Media Player/images/up.png
Binary files differ
diff --git a/experimental/Media Player/main.qml b/experimental/Media Player/main.qml
new file mode 100755
index 0000000..d8075c8
--- /dev/null
+++ b/experimental/Media Player/main.qml
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtMultimedia 5.0
+
+FocusScope {
+ id: applicationWindow
+ focus: true
+
+ MouseArea {
+ id: mouseActivityMonitor
+ anchors.fill: parent
+
+ hoverEnabled: true
+ onClicked: {
+ if (controlBar.state === "VISIBLE" && content.videoPlayer.mediaPlayer.status === MediaPlayer.Loaded) {
+ controlBar.hide();
+ } else {
+ controlBar.show();
+ controlBarTimer.restart();
+ }
+ }
+ }
+
+ signal resetTimer
+ onResetTimer: {
+ controlBar.show();
+ controlBarTimer.restart();
+ }
+
+ Component.onCompleted: {
+ init();
+ }
+
+ Content {
+ id: content
+ anchors.fill: parent
+ }
+
+ Timer {
+ id: controlBarTimer
+ interval: 4000
+ running: false
+
+ onTriggered: {
+ hideToolBars();
+ }
+ }
+
+ ControlBar {
+ id: controlBar
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: applicationWindow.bottom
+ mediaPlayer: content.videoPlayer.mediaPlayer
+
+ onOpenFile: {
+ applicationWindow.openVideo();
+ }
+
+ onOpenURL: {
+ applicationWindow.openURL();
+ }
+
+ onOpenFX: {
+ applicationWindow.openFX();
+ }
+
+ onToggleFullScreen: {
+// viewer.toggleFullscreen();
+ }
+ }
+
+ ParameterPanel {
+ id: parameterPanel
+ opacity: controlBar.opacity
+ visible: effectSelectionPanel.visible && model.count !== 0
+ height: 116
+ width: 500
+ anchors {
+ bottomMargin: 15
+ bottom: controlBar.top
+ right: effectSelectionPanel.left
+ rightMargin: 15
+ }
+ }
+
+ EffectSelectionPanel {
+ id: effectSelectionPanel
+ visible: false
+ opacity: controlBar.opacity
+ anchors {
+ bottom: controlBar.top
+ right: controlBar.right
+ // rightMargin: 15
+ bottomMargin: 15
+ }
+ width: 250
+ height: 350
+ itemHeight: 80
+ onEffectSourceChanged: {
+ content.effectSource = effectSource
+ parameterPanel.model = content.effect.parameters
+ }
+ }
+
+ UrlBar {
+ id: urlBar
+ opacity: 0
+ visible: opacity != 0
+ anchors.fill: parent
+ onUrlAccepted: {
+ urlBar.opacity = 0;
+ if (text != "")
+ content.openVideo(text)
+ }
+ }
+
+ Rectangle {
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.rightMargin: 32
+ anchors.topMargin: 32
+ width: 40
+ height: 40
+ radius: width / 2
+ color: infoMouser.pressed ? "#BB999999" : "#88444444"
+ antialiasing: true
+ visible: content.videoPlayer.mediaPlayer.status !== MediaPlayer.NoMedia && controlBar.state === "VISIBLE"
+
+ Text {
+ anchors.centerIn: parent
+ text: "i"
+ font.italic: true
+ font.bold: true
+ color: "white"
+ font.pixelSize: 28
+ }
+
+ MouseArea {
+ id: infoMouser
+ anchors.fill: parent
+ anchors.margins: -10
+ onClicked: metadataView.opacity = 1
+ }
+ }
+
+ MetadataView {
+ id: metadataView
+ mediaPlayer: content.videoPlayer.mediaPlayer
+ }
+
+ property real volumeBeforeMuted: 1.0
+ property bool isFullScreen: false
+
+ FileBrowser {
+ id: fileBrowser
+ anchors.fill: parent
+ onFileSelected: {
+ if (file != "")
+ content.openVideo(file);
+ }
+ }
+
+ Keys.onPressed: {
+ applicationWindow.resetTimer();
+ if (event.key === Qt.Key_O && event.modifiers & Qt.ControlModifier) {
+ openVideo();
+ return;
+ } else if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
+ openURL();
+ return;
+ } else if (event.key === Qt.Key_E && event.modifiers & Qt.ControlModifier) {
+ openFX();
+ return;
+ } else if (event.key === Qt.Key_F && event.modifiers & Qt.ControlModifier) {
+// viewer.toggleFullscreen();
+ return;
+ } else if (event.key === Qt.Key_Up || event.key === Qt.Key_VolumeUp) {
+ content.videoPlayer.mediaPlayer.volume = Math.min(1, content.videoPlayer.mediaPlayer.volume + 0.1);
+ return;
+ } else if (event.key === Qt.Key_Down || event.key === Qt.Key_VolumeDown) {
+ if (event.modifiers & Qt.ControlModifier) {
+ if (content.videoPlayer.mediaPlayer.volume) {
+ volumeBeforeMuted = content.videoPlayer.mediaPlayer.volume;
+ content.videoPlayer.mediaPlayer.volume = 0
+ } else {
+ content.videoPlayer.mediaPlayer.volume = volumeBeforeMuted;
+ }
+ } else {
+ content.videoPlayer.mediaPlayer.volume = Math.max(0, content.videoPlayer.mediaPlayer.volume - 0.1);
+ }
+ return;
+ } else if (applicationWindow.isFullScreen && event.key === Qt.Key_Escape) {
+// viewer.toggleFullscreen();
+ return;
+ }
+
+ // What's next should be handled only if there's a loaded media
+ if (content.videoPlayer.mediaPlayer.status !== MediaPlayer.Loaded
+ && content.videoPlayer.mediaPlayer.status !== MediaPlayer.Buffered)
+ return;
+
+ if (event.key === Qt.Key_Space) {
+ if (content.videoPlayer.mediaPlayer.playbackState === MediaPlayer.PlayingState)
+ content.videoPlayer.mediaPlayer.pause()
+ else if (content.videoPlayer.mediaPlayer.playbackState === MediaPlayer.PausedState
+ || content.videoPlayer.mediaPlayer.playbackState === MediaPlayer.StoppedState)
+ content.videoPlayer.mediaPlayer.play()
+ } else if (event.key === Qt.Key_Left) {
+ content.videoPlayer.mediaPlayer.seek(Math.max(0, content.videoPlayer.mediaPlayer.position - 30000));
+ return;
+ } else if (event.key === Qt.Key_Right) {
+ content.videoPlayer.mediaPlayer.seek(Math.min(content.videoPlayer.mediaPlayer.duration, content.videoPlayer.mediaPlayer.position + 30000));
+ return;
+ }
+ }
+
+ function init() {
+ content.init()
+ }
+
+ function openVideo() {
+ //videoFileBrowser.show()
+ // var videoFile = viewer.openFileDialog();
+ // if (videoFile != "")
+ // content.openVideo(videoFile);
+ fileBrowser.show()
+ }
+
+ function openCamera() {
+ content.openCamera()
+ }
+
+ function openURL() {
+ urlBar.opacity = urlBar.opacity === 0 ? 1 : 0
+ }
+
+ function openFX() {
+ effectSelectionPanel.visible = !effectSelectionPanel.visible;
+ }
+
+ function close() {
+ }
+
+ function hideToolBars() {
+ if (!controlBar.isMouseAbove && !parameterPanel.isMouseAbove && !effectSelectionPanel.isMouseAbove && content.videoPlayer.isPlaying)
+ controlBar.hide();
+ }
+}