vlc | branch: master | Fatih Uzunoglu <[email protected]> | Fri Jan 8 00:36:14 2021 +0300| [8d0737f1ed1548198ab1b67ba9cadec884169571] | committer: Pierre Lamot
qml: add OverlayMenu Overlay menu (PlaylistMenu) from Playlist is refactored and exported to make it reusable. Signed-off-by: Pierre Lamot <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8d0737f1ed1548198ab1b67ba9cadec884169571 --- modules/gui/qt/Makefile.am | 3 +- modules/gui/qt/vlc.qrc | 1 + modules/gui/qt/widgets/qml/OverlayMenu.qml | 342 +++++++++++++++++++++++++++++ 3 files changed, 345 insertions(+), 1 deletion(-) diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am index 37984f3a95..af4758f88c 100644 --- a/modules/gui/qt/Makefile.am +++ b/modules/gui/qt/Makefile.am @@ -747,7 +747,8 @@ libqt_plugin_la_QML = \ gui/qt/widgets/qml/VideoQualityLabel.qml \ gui/qt/widgets/qml/ListSubtitleLabel.qml \ gui/qt/widgets/qml/PointingTooltip.qml \ - gui/qt/widgets/qml/FrostedGlassEffect.qml + gui/qt/widgets/qml/FrostedGlassEffect.qml \ + gui/qt/widgets/qml/OverlayMenu.qml EXTRA_DIST += gui/qt/vlc.qrc $(libqt_plugin_la_RES) diff --git a/modules/gui/qt/vlc.qrc b/modules/gui/qt/vlc.qrc index 70a72ac09e..d836a59a45 100644 --- a/modules/gui/qt/vlc.qrc +++ b/modules/gui/qt/vlc.qrc @@ -243,6 +243,7 @@ <file alias="DragItem.qml">widgets/qml/DragItem.qml</file> <file alias="CoverShadow.qml">widgets/qml/CoverShadow.qml</file> <file alias="ListCoverShadow.qml">widgets/qml/ListCoverShadow.qml</file> + <file alias="OverlayMenu.qml">widgets/qml/OverlayMenu.qml</file> </qresource> <qresource prefix="/network"> <file alias="AddressbarButton.qml">network/qml/AddressbarButton.qml</file> diff --git a/modules/gui/qt/widgets/qml/OverlayMenu.qml b/modules/gui/qt/widgets/qml/OverlayMenu.qml new file mode 100644 index 0000000000..3d32b8bfff --- /dev/null +++ b/modules/gui/qt/widgets/qml/OverlayMenu.qml @@ -0,0 +1,342 @@ +/***************************************************************************** + * Copyright (C) 2020 VLC authors and VideoLAN + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * ( at your option ) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ +import QtQuick 2.11 +import QtQuick.Controls 2.4 +import QtQuick.Layouts 1.3 + +import "qrc:///util/KeyHelper.js" as KeyHelper +import "qrc:///style/" + +Item { + id: root + + VLCColors { + id: vlcNightColors + state: "night" + } + + property real widthRatio: (3 / 4) + property bool isRight: true // when set, menu is placed on the right side + + property real leftPadding: VLCStyle.margin_xsmall + property real rightPadding: VLCStyle.margin_xsmall + property real topPadding: VLCStyle.margin_large + property real bottomPadding: VLCStyle.margin_large + + // Sample model: + // { + // title : "Sample Overlay Menu", + // entries : [] + // } + // + // Entries are intended to be an instance of Action + // Nested structure (menus inside menus) is supported: + // if an entry contains 'model' property, it yields another menu. + // If 'icon.source' is used, Image will be used, but + // fontIcon property can also be used for loading icon from icon font family. + // if tickMark property is 'true', a tick mark will be shown on the icon area + // 'marking' is a string property that can be used to show a label on the right side + // Example usage can be found in 'Playlist/PlaylistOverlayMenu.qml' file + property var model: undefined + + onModelChanged: { + listView.currentModel = model + listView.resetStack() + } + + property var backgroundItem: undefined + + property bool _active: false + visible: _active + + function open() { + listView.currentModel = root.model + _active = true + listView.forceActiveFocus() + } + + function close() { + _active = false + backgroundItem.forceActiveFocus() + } + + Rectangle { + color: "black" + anchors { + top: parent.top + bottom: parent.bottom + + left: isRight ? parent.left : undefined + right: isRight ? undefined : parent.right + } + width: parent.width - parentItem.width + opacity: 0.5 + + MouseArea { + anchors.fill: parent + hoverEnabled: true + + onClicked: { + root.close() + } + } + } + + Item { + id: parentItem + + anchors { + top: parent.top + bottom: parent.bottom + + right: isRight ? parent.right : undefined + left: isRight ? undefined : parent.left + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + + acceptedButtons: Qt.NoButton + } + + FrostedGlassEffect { + source: backgroundItem + + anchors.fill: parent + + readonly property point overlayPos: backgroundItem.mapFromItem(root, parentItem.x, parentItem.y) + sourceRect: Qt.rect(overlayPos.x, overlayPos.y, width, height) + + tint: VLCStyle.colors.blendColors(vlcNightColors.black, vlcNightColors.banner, 0.85) + } + + KeyNavigableListView { + id: listView + + anchors.fill: parent + anchors.topMargin: root.topPadding + anchors.bottomMargin: root.bottomPadding + + keyNavigationWraps: true + + property var stack: [] + property var currentModel: root.model + + model: currentModel.entries + + Component.onCompleted: { + resetStack() + } + + onActiveFocusChanged: { + if (!activeFocus) { + root.close() + } + } + + function resetStack() { + if (stack.length > 0) + stack = [] + + stack.push(currentModel) + } + + function goBack() { + if (stack.length > 1) { + stack.pop() + currentModel = stack[stack.length - 1] + } + else { + root.close() + } + } + + function loadModel(_model) { + listView.stack.push(_model) + listView.currentModel = _model + } + + header: MenuLabel { + font.pixelSize: VLCStyle.fontSize_xlarge + text: listView.currentModel.title + + color: vlcNightColors.text + + leftPadding: root.leftPadding + rightPadding: root.rightPadding + bottomPadding: VLCStyle.margin_normal + } + + delegate: Button { + id: button + + readonly property bool yieldsAnotherModel: (!!modelData.model) + + width: listView.width + + leftPadding: root.leftPadding + rightPadding: root.rightPadding + + function trigger(triggerEnabled) { + if (yieldsAnotherModel) { + listView.loadModel(modelData.model) + } + else if (triggerEnabled) { + modelData.trigger() + root.close() + } + } + + onClicked: trigger(true) + + Keys.onPressed: { + if (KeyHelper.matchRight(event)) { + trigger(false) + event.accepted = true + } + else if (KeyHelper.matchLeft(event)) { + listView.goBack() + event.accepted = true + } + else if (KeyHelper.matchCancel(event)) { + root.close() + event.accepted = true + } + } + + contentItem: RowLayout { + id: rowLayout + + Item { + id: icon + + Layout.preferredWidth: VLCStyle.icon_small + Layout.preferredHeight: VLCStyle.icon_small + Layout.alignment: Qt.AlignHCenter + + Loader { + active: (!!modelData.icon.source || !!modelData.fontIcon || modelData.tickMark === true) + anchors.fill: parent + + Component { + id: imageIcon + Image { + sourceSize: Qt.size(icon.width, icon.height) + source: modelData.icon.source + } + } + + Component { + id: fontIcon + IconLabel { + horizontalAlignment: Text.AlignHCenter + text: modelData.fontIcon + color: vlcNightColors.text + } + } + + Component { + id: tickMark + ListLabel { + horizontalAlignment: Text.AlignHCenter + text: "✓" + color: vlcNightColors.text + } + } + + sourceComponent: { + if (modelData.tickMark === true) + tickMark + else if (!!modelData.fontIcon) + fontIcon + else + imageIcon + } + } + } + + ListLabel { + id: textLabel + + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + + font.weight: Font.Normal + text: modelData.text + color: vlcNightColors.text + } + + ListLabel { + visible: modelData.marking.length >= 1 + + Layout.alignment: Qt.AlignHCenter + + text: { + if (button.yieldsAnotherModel) + "⮕" + else if (!!modelData.marking) + modelData.marking + } + color: vlcNightColors.text + } + } + + background: Rectangle { + visible: button.activeFocus + color: VLCStyle.colors.accent + opacity: 0.8 + } + } + } + } + + states: [ + State { + name: "visible" + when: _active + + PropertyChanges { + target: parentItem + width: root.width * root.widthRatio + } + }, + State { + name: "hidden" + when: !_active + + PropertyChanges { + target: parentItem + width: 0 + } + } + ] + + transitions: [ + Transition { + from: "hidden" + to: "visible" + + NumberAnimation { + property: "width" + duration: 125 + easing.type: Easing.InOutSine + } + } + ] +} _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
