From 147e3c90989fd51abe2e5e36d3b2c446eff04dfa Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sat, 5 Dec 2020 15:59:43 +0100 Subject: [PATCH] More fixes for the media player --- nymea-app/images.qrc | 2 + nymea-app/ui/components/MeaDialog.qml | 8 +- nymea-app/ui/components/MediaPlayer.qml | 141 ++++++++++++++++--- nymea-app/ui/images/media/ambeo.svg | 77 +++++++++++ nymea-app/ui/images/media/equalizer.svg | 174 ++++++++++++++++++++++++ 5 files changed, 383 insertions(+), 19 deletions(-) create mode 100644 nymea-app/ui/images/media/ambeo.svg create mode 100644 nymea-app/ui/images/media/equalizer.svg diff --git a/nymea-app/images.qrc b/nymea-app/images.qrc index 3782deca..91925329 100644 --- a/nymea-app/images.qrc +++ b/nymea-app/images.qrc @@ -249,5 +249,7 @@ ui/images/facebook.svg ui/images/help.svg ui/images/discord.svg + ui/images/media/equalizer.svg + ui/images/media/ambeo.svg diff --git a/nymea-app/ui/components/MeaDialog.qml b/nymea-app/ui/components/MeaDialog.qml index 2415bbcc..3ef50105 100644 --- a/nymea-app/ui/components/MeaDialog.qml +++ b/nymea-app/ui/components/MeaDialog.qml @@ -46,6 +46,11 @@ Dialog { onClosed: root.destroy() + Connections { + target: root.parent + onDestroyed: root.destroy() + } + MouseArea { parent: app.overlay anchors.fill: parent @@ -56,13 +61,14 @@ Dialog { header: Item { implicitHeight: headerRow.height + app.margins * 2 implicitWidth: parent.width + visible: root.title.length > 0 RowLayout { id: headerRow anchors { left: parent.left; right: parent.right; top: parent.top; margins: app.margins } spacing: app.margins ColorIcon { id: headerColorIcon - Layout.preferredHeight: app.iconSize * 2 + Layout.preferredHeight: app.hugeIconSize Layout.preferredWidth: height color: app.accentColor visible: name.length > 0 diff --git a/nymea-app/ui/components/MediaPlayer.qml b/nymea-app/ui/components/MediaPlayer.qml index feb64c20..af8b820f 100644 --- a/nymea-app/ui/components/MediaPlayer.qml +++ b/nymea-app/ui/components/MediaPlayer.qml @@ -35,6 +35,7 @@ import QtQuick.Layouts 1.2 import Nymea 1.0 import QtGraphicalEffects 1.0 import "../delegates" +import "../utils" Item { id: root @@ -56,8 +57,13 @@ Item { readonly property State volumeState: thing.stateByName("volume") readonly property State muteState: thing.stateByName("mute") + readonly property State equalizerPresetState: thing.stateByName("equalizerPreset") + readonly property State nightModeState: thing.stateByName("nightMode") readonly property State likeState: thing.stateByName("like") + // NOTE: This is not in any interface, special feature just for AMBEO + readonly property State ambeoModeState: thing.stateByName("ambeoMode") + readonly property bool hasNavigationPatd: thing.thingClass.interfaces.indexOf("navigationpad") >= 0 clip: true @@ -65,20 +71,21 @@ Item { QtObject { id: d property var browser: null - property int pendingInputSourceSelectId: -1 + property int pendingCallId: -1 } Connections { target: engine.thingManager onExecuteActionReply: { - if (commandId == d.pendingInputSourceSelectId) { + if (commandId == d.pendingCallId) { if (params.deviceError !== "DeviceErrorNoError") { var errorDialog = Qt.createComponent(Qt.resolvedUrl("../components/ErrorDialog.qml")); - var text - if (params.displayMessage.length > 0) { - text = params.displayMessage + var dialogParams = {} + dialogParams.errorCode = params.deviceError + if (params.displayMessage && params.displayMessage.length > 0) { + dialogParams.text = params.displayMessage } - var popup = errorDialog.createObject(app, {text: text}) + var popup = errorDialog.createObject(app, dialogParams) popup.open() } } @@ -231,8 +238,17 @@ Item { d.browser.show(); } } + ProgressButton { + Layout.preferredHeight: app.iconSize + Layout.preferredWidth: app.iconSize + longpressEnabled: false + visible: root.hasNavigationPatd + imageSource: "../images/navigationpad.svg" + onClicked: pageStack.push(navigationPadPage) + } RowLayout { ProgressButton { + id: inputSourceButton Layout.preferredHeight: app.iconSize Layout.preferredWidth: app.iconSize longpressEnabled: false @@ -246,23 +262,52 @@ Item { Label { Layout.fillWidth: true text: root.inputSourceState ? root.inputSourceState.value : "" + wrapMode: Text.WordWrap + elide: Text.ElideRight font.pixelSize: app.smallFont + MouseArea { anchors.fill: parent; onClicked: inputSourceButton.clicked() } + } + } + ColorIcon { + Layout.preferredHeight: app.iconSize + Layout.preferredWidth: app.iconSize * 3 + visible: root.ambeoModeState !== null + name: "../images/media/ambeo.svg" + color: root.ambeoModeState && root.ambeoModeState.value !== "Off" ? app.accentColor : keyColor + MouseArea { + anchors.fill: parent + onClicked: { + var popup = ambeoModeDialogComponent.createObject(root) + popup.open() + } } } ProgressButton { Layout.preferredHeight: app.iconSize Layout.preferredWidth: app.iconSize longpressEnabled: false - visible: root.hasNavigationPatd - imageSource: "../images/navigationpad.svg" - onClicked: pageStack.push(navigationPadPage) + visible: root.nightModeState !== null + imageSource: "../images/weathericons/weather-clear-night.svg" + color: root.nightModeState && root.nightModeState.value === true ? app.accentColor : keyColor + onClicked: d.pendingCallId = engine.thingManager.executeAction(root.thing.id, root.nightModeState.stateTypeId, [{paramTypeId: root.nightModeState.stateTypeId, value: !root.nightModeState.value}]) + } + ProgressButton { + Layout.preferredHeight: app.iconSize + Layout.preferredWidth: app.iconSize + longpressEnabled: false + visible: root.equalizerPresetState !== null + imageSource: "../images/media/equalizer.svg" + onClicked: { + var dialog = equalizerComponent.createObject(root) + dialog.open() + } } - ProgressButton { id: volumeButton Layout.preferredHeight: app.iconSize Layout.preferredWidth: app.iconSize visible: root.hasVolumeControl + longpressEnabled: false imageSource: root.muteState && root.muteState.value === true ? "../images/audio-speakers-muted-symbolic.svg" : "../images/audio-speakers-symbolic.svg" @@ -279,9 +324,6 @@ Item { var sliderPane = volumeSliderPaneComponent.createObject(root, props) sliderPane.open() } - onLongpressed: { - - } } } } @@ -297,7 +339,11 @@ Item { bottomPadding: app.margins / 2 modal: true - property int pendingVolumeValue: -1 + ActionQueue { + id: volumeActionQueue + thing: root.thing + stateType: root.thing.thingClass.stateTypes.findByName("volume") + } contentItem: ColumnLayout { ProgressButton { @@ -315,14 +361,14 @@ Item { onClicked: engine.thingManager.executeAction(root.thing.id, root.thing.thingClass.actionTypes.findByName("decreaseVolume").id); } - ThrottledSlider { + Slider { Layout.fillHeight: true visible: root.volumeState !== null from: 0 to: 100 - value: root.volumeState.value + value: volumeActionQueue.pendingValue || root.volumeState.value orientation: Qt.Vertical - onMoved: engine.thingManager.executeAction(root.thing.id, root.volumeState.stateTypeId, [{paramTypeId: root.volumeState.stateTypeId, value: value}]) + onMoved: volumeActionQueue.sendValue(value) } ProgressButton { @@ -442,6 +488,7 @@ Item { id: inputSourceSelectDialogComponent MeaDialog { id: inputSourceSelectDialog + headerIcon: "../images/state-in.svg" title: qsTr("Select input") standardButtons: Dialog.NoButton @@ -457,7 +504,7 @@ Item { text: modelData checked: root.inputSourceState.value === modelData onClicked: { - d.pendingInputSourceSelectId = engine.thingManager.executeAction(root.thing.id, root.inputSourceState.stateTypeId, [{paramTypeId: root.inputSourceState.stateTypeId, value: modelData}]) + d.pendingCallId = engine.thingManager.executeAction(root.thing.id, root.inputSourceState.stateTypeId, [{paramTypeId: root.inputSourceState.stateTypeId, value: modelData}]) inputSourceSelectDialog.close(); } } @@ -465,4 +512,62 @@ Item { } } + Component { + id: equalizerComponent + MeaDialog { + id: equalizer + headerIcon: "../images/media/equalizer.svg" + title: qsTr("Equalizer preset") + standardButtons: Dialog.NoButton + ListView { + id: inputSourceListView + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredHeight: 200 + clip: true + model: root.thing.thingClass.stateTypes.findByName("equalizerPreset").allowedValues + delegate: RadioDelegate { + width: inputSourceListView.width + text: modelData + checked: root.equalizerPresetState.value === modelData + onClicked: { + d.pendingCallId = engine.thingManager.executeAction(root.thing.id, root.equalizerPresetState.stateTypeId, [{paramTypeId: root.equalizerPresetState.stateTypeId, value: modelData}]) + equalizer.close(); + } + } + } + } + } + Component { + id: ambeoModeDialogComponent + MeaDialog { + id: ambeoModeDialog + standardButtons: Dialog.NoButton + ColorIcon { + Layout.preferredHeight: app.hugeIconSize + Layout.preferredWidth: app.hugeIconSize * 3 + Layout.alignment: Qt.AlignHCenter + name: "../images/media/ambeo.svg" + color: app.accentColor + } + + ListView { + id: ambeoModeListView + Layout.fillWidth: true + Layout.fillHeight: true + Layout.preferredHeight: 200 + clip: true + model: root.thing.thingClass.stateTypes.findByName("ambeoMode").allowedValues + delegate: RadioDelegate { + width: ambeoModeListView.width + text: modelData + checked: root.ambeoModeState.value === modelData + onClicked: { + d.pendingCallId = engine.thingManager.executeAction(root.thing.id, root.ambeoModeState.stateTypeId, [{paramTypeId: root.ambeoModeState.stateTypeId, value: modelData}]) + ambeoModeDialog.close(); + } + } + } + } + } } diff --git a/nymea-app/ui/images/media/ambeo.svg b/nymea-app/ui/images/media/ambeo.svg new file mode 100644 index 00000000..c5d6f609 --- /dev/null +++ b/nymea-app/ui/images/media/ambeo.svg @@ -0,0 +1,77 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/nymea-app/ui/images/media/equalizer.svg b/nymea-app/ui/images/media/equalizer.svg new file mode 100644 index 00000000..fe0300ce --- /dev/null +++ b/nymea-app/ui/images/media/equalizer.svg @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + +