[vlc-devel] [RFC 67/82] qml: provide common class to serve as delegate for list and grid view
Pierre Lamot
pierre at videolabs.io
Fri Feb 1 14:02:11 CET 2019
---
modules/gui/qt/Makefile.am | 2 +
modules/gui/qt/qml/utils/GridItem.qml | 240 ++++++++++++++++++++++++++
modules/gui/qt/qml/utils/ListItem.qml | 173 +++++++++++++++++++
modules/gui/qt/vlc.qrc | 2 +
4 files changed, 417 insertions(+)
create mode 100644 modules/gui/qt/qml/utils/GridItem.qml
create mode 100644 modules/gui/qt/qml/utils/ListItem.qml
diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 36e2699f86..0e8124c19a 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -525,11 +525,13 @@ libqt_plugin_la_RES = \
gui/qt/qml/utils/DNDLabel.qml \
gui/qt/qml/utils/ToolTipArea.qml \
gui/qt/qml/utils/ExpandGridView.qml \
+ gui/qt/qml/utils/GridItem.qml \
gui/qt/qml/utils/IconToolButton.qml \
gui/qt/qml/utils/ImageToolButton.qml \
gui/qt/qml/utils/TextToolButton.qml \
gui/qt/qml/utils/MenuExt.qml \
gui/qt/qml/utils/MenuItemExt.qml \
+ gui/qt/qml/utils/ListItem.qml \
gui/qt/qml/utils/MultiCoverPreview.qml \
gui/qt/qml/utils/NavigableFocusScope.qml \
gui/qt/qml/utils/KeyNavigableGridView.qml \
diff --git a/modules/gui/qt/qml/utils/GridItem.qml b/modules/gui/qt/qml/utils/GridItem.qml
new file mode 100644
index 0000000000..4421abba25
--- /dev/null
+++ b/modules/gui/qt/qml/utils/GridItem.qml
@@ -0,0 +1,240 @@
+/*****************************************************************************
+ * Copyright (C) 2019 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 QtQml.Models 2.2
+import QtGraphicalEffects 1.0
+import org.videolan.medialib 0.1
+
+
+import "qrc:///utils/" as Utils
+import "qrc:///style/"
+
+Item {
+ id: root
+ width: VLCStyle.cover_normal
+ height: VLCStyle.cover_normal
+ + VLCStyle.fontHeight_normal
+ + VLCStyle.fontHeight_small
+ + VLCStyle.margin_xsmall
+
+ property url image: VLCStyle.noArtCover
+ property string title: ""
+ property string subtitle: ""
+ property bool selected: false
+ property int shiftX: 0
+ property bool noActionButtons: false
+
+ signal playClicked
+ signal addToPlaylistClicked
+ signal itemClicked(int keys, int modifier)
+ signal itemDoubleClicked(int keys, int modifier)
+
+ Item {
+ x: shiftX
+ width: parent.width
+ height: parent.height
+
+ MouseArea {
+
+ id: mouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: root.itemClicked(mouse.buttons, mouse.modifiers)
+ onDoubleClicked: root.itemDoubleClicked(mouse.buttons, mouse.modifiers);
+
+ ColumnLayout {
+ anchors.fill: parent
+ Item {
+ id: picture
+ width: VLCStyle.cover_normal
+ height: VLCStyle.cover_normal
+ property bool highlighted: selected || mouseArea.containsMouse
+
+ RectangularGlow {
+ visible: picture.highlighted
+ anchors.fill: coverPlaceHolder
+ cornerRadius: 25
+ spread: 0.2
+ glowRadius: VLCStyle.margin_xsmall
+ color: VLCStyle.colors.getBgColor( selected, mouseArea.containsMouse, root.activeFocus )
+ }
+
+ Item {
+ id: coverPlaceHolder
+ x: cover.x + (cover.width - cover.paintedWidth) / 2
+ y: cover.y +(cover.height - cover.paintedHeight) / 2
+ width: cover.paintedWidth
+ height: cover.paintedHeight
+ }
+
+ Image {
+ id: cover
+ width: VLCStyle.cover_small
+ height: VLCStyle.cover_small
+ Behavior on width { SmoothedAnimation { velocity: 100 } }
+ Behavior on height { SmoothedAnimation { velocity: 100 } }
+ anchors.centerIn: parent
+ source: image
+ fillMode: Image.PreserveAspectFit
+
+ Rectangle {
+ id: overlay
+ anchors.fill: parent
+ visible: mouseArea.containsMouse
+ color: "black" //darken the image below
+
+ RowLayout {
+ anchors.fill: parent
+ visible: !noActionButtons
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ /* A addToPlaylist button visible when hovered */
+ Text {
+ property int iconSize: VLCStyle.icon_large
+ Behavior on iconSize { SmoothedAnimation { velocity: 100 } }
+ Binding on iconSize {
+ value: VLCStyle.icon_large * 1.2
+ when: mouseAreaAdd.containsMouse
+ }
+
+ //Layout.alignment: Qt.AlignCenter
+ anchors.centerIn: parent
+ text: VLCIcons.add
+ font.family: VLCIcons.fontFamily
+ horizontalAlignment: Text.AlignHCenter
+ color: mouseAreaAdd.containsMouse ? "white" : "lightgray"
+ font.pixelSize: iconSize
+
+ MouseArea {
+ id: mouseAreaAdd
+ anchors.fill: parent
+ hoverEnabled: true
+ propagateComposedEvents: true
+ onClicked: root.addToPlaylistClicked()
+ }
+ }
+ }
+
+ /* A play button visible when hovered */
+ Item {
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ Text {
+ property int iconSize: VLCStyle.icon_large
+ Behavior on iconSize {
+ SmoothedAnimation { velocity: 100 }
+ }
+ Binding on iconSize {
+ value: VLCStyle.icon_large * 1.2
+ when: mouseAreaPlay.containsMouse
+ }
+
+ anchors.centerIn: parent
+ text: VLCIcons.play
+ font.family: VLCIcons.fontFamily
+ horizontalAlignment: Text.AlignHCenter
+ color: mouseAreaPlay.containsMouse ? "white" : "lightgray"
+ font.pixelSize: iconSize
+
+ MouseArea {
+ id: mouseAreaPlay
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: root.playClicked()
+ }
+ }
+ }
+ }
+ }
+ states: [
+ State {
+ name: "visible"
+ PropertyChanges { target: overlay; visible: true }
+ when: mouseArea.containsMouse
+ },
+ State {
+ name: "hidden"
+ PropertyChanges { target: overlay; visible: false }
+ when: !mouseArea.containsMouse
+ }
+ ]
+ transitions: [
+ Transition {
+ from: "hidden"; to: "visible"
+ NumberAnimation {
+ target: overlay
+ properties: "opacity"
+ from: 0; to: 0.8; duration: 300
+ }
+ }
+ ]
+ }
+
+ states: [
+ State {
+ name: "big"
+ when: picture.highlighted
+ PropertyChanges {
+ target: cover
+ width: VLCStyle.cover_normal - 2 * VLCStyle.margin_xsmall
+ height: VLCStyle.cover_normal - 2 * VLCStyle.margin_xsmall
+ }
+ },
+ State {
+ name: "small"
+ when: !picture.highlighted
+ PropertyChanges {
+ target: cover
+ width: VLCStyle.cover_normal - 2 * VLCStyle.margin_small
+ height: VLCStyle.cover_normal - 2 * VLCStyle.margin_small
+ }
+ }
+ ]
+ }
+ Text {
+ Layout.fillWidth: true
+ Layout.leftMargin: VLCStyle.margin_small
+ Layout.rightMargin: VLCStyle.margin_small
+
+ text: root.title
+
+ elide: Text.ElideRight
+ font.pixelSize: VLCStyle.fontSize_normal
+ font.bold: true
+ color: VLCStyle.colors.text
+ }
+ Text {
+ Layout.fillWidth: true
+ Layout.leftMargin: VLCStyle.margin_small
+ Layout.rightMargin: VLCStyle.margin_small
+
+ text : root.subtitle
+
+ elide: Text.ElideRight
+ font.pixelSize: VLCStyle.fontSize_small
+ color: VLCStyle.colors.text
+ }
+ }
+ }
+ }
+}
diff --git a/modules/gui/qt/qml/utils/ListItem.qml b/modules/gui/qt/qml/utils/ListItem.qml
new file mode 100644
index 0000000000..39863544f8
--- /dev/null
+++ b/modules/gui/qt/qml/utils/ListItem.qml
@@ -0,0 +1,173 @@
+/*****************************************************************************
+ * Copyright (C) 2019 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:///style/"
+
+NavigableFocusScope {
+ id: root
+ signal playClicked
+ signal addToPlaylistClicked
+ signal itemClicked(int keys, int modifier)
+ signal itemDoubleClicked(int keys, int modifier)
+
+ property alias hovered: mouse.containsMouse
+
+ property Component cover: Item {}
+ property alias line1: line1_text.text
+ property alias line2: line2_text.text
+
+ property alias color: linerect.color
+
+ Component {
+ id: actionAdd
+ IconToolButton {
+ size: VLCStyle.icon_normal
+ text: VLCIcons.add
+
+ focus: true
+
+ highlightColor: activeFocus ? VLCStyle.colors.buttonText : "transparent"
+
+ //visible: mouse.containsMouse || root.activeFocus
+ onClicked: root.addToPlaylistClicked()
+ }
+ }
+
+
+ Component {
+ id: actionPlay
+ IconToolButton {
+ id: add_and_play_icon
+ size: VLCStyle.icon_normal
+ //visible: mouse.containsMouse || root.activeFocus
+ text: VLCIcons.play
+
+ focus: true
+
+ highlightColor: add_and_play_icon.activeFocus ? VLCStyle.colors.buttonText : "transparent"
+ onClicked: root.playClicked()
+ }
+ }
+
+ property var actionButtons: [ actionAdd, actionPlay ]
+
+ Rectangle {
+ id: linerect
+ anchors.fill: parent
+ color: "transparent"
+
+ MouseArea {
+ id: mouse
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: {
+ root.itemClicked(mouse.buttons, mouse.modifiers);
+ }
+ onDoubleClicked: {
+ root.itemDoubleClicked(mouse.buttons, mouse.modifiers);
+ }
+ }
+
+ RowLayout {
+ anchors.fill: parent
+
+ Loader {
+ Layout.preferredWidth: VLCStyle.icon_normal
+ Layout.preferredHeight: VLCStyle.icon_normal
+ sourceComponent: root.cover
+ }
+ FocusScope {
+ id: presentation
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ focus: true
+
+ Column {
+ anchors.fill: parent
+
+ Text{
+ id: line1_text
+ font.bold: true
+ width: parent.width
+ elide: Text.ElideRight
+ color: VLCStyle.colors.text
+ font.pixelSize: VLCStyle.fontSize_normal
+ enabled: text !== ""
+ }
+ Text{
+ id: line2_text
+ width: parent.width
+ text: ""
+ elide: Text.ElideRight
+ color: VLCStyle.colors.text
+ font.pixelSize: VLCStyle.fontSize_xsmall
+ enabled: text !== ""
+ }
+ }
+
+ Keys.onRightPressed: {
+ if (actionButtons.length === 0)
+ root.actionRight(0)
+ else
+ toolButtons.focus = true
+ }
+ Keys.onLeftPressed: {
+ root.actionLeft(0)
+ }
+ }
+
+ FocusScope {
+ id: toolButtons
+ Layout.preferredHeight: VLCStyle.icon_normal
+ Layout.preferredWidth: toolButtonsRow.implicitWidth
+ Layout.alignment: Qt.AlignVCenter
+ visible: mouse.containsMouse || root.activeFocus
+ property int focusIndex: 0
+ Row {
+ id: toolButtonsRow
+ anchors.fill: parent
+ Repeater {
+ id: buttons
+ model: actionButtons
+ delegate: Loader {
+ sourceComponent: modelData
+ focus: index === toolButtons.focusIndex
+ }
+ }
+ }
+ Keys.onLeftPressed: {
+ if (focusIndex === 0)
+ presentation.focus = true
+ else {
+ focusIndex -= 1
+ }
+ }
+ Keys.onRightPressed: {
+ if (focusIndex === actionButtons.length - 1)
+ root.actionRight(0)
+ else {
+ focusIndex += 1
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/modules/gui/qt/vlc.qrc b/modules/gui/qt/vlc.qrc
index e7b5110013..1a12e86b13 100644
--- a/modules/gui/qt/vlc.qrc
+++ b/modules/gui/qt/vlc.qrc
@@ -160,6 +160,8 @@
</qresource>
<qresource prefix="/utils">
<file alias="MultiCoverPreview.qml">qml/utils/MultiCoverPreview.qml</file>
+ <file alias="GridItem.qml">qml/utils/GridItem.qml</file>
+ <file alias="ListItem.qml">qml/utils/ListItem.qml</file>
<file alias="SelectableDelegateModel.qml">qml/utils/SelectableDelegateModel.qml</file>
<file alias="KeyNavigableGridView.qml">qml/utils/KeyNavigableGridView.qml</file>
<file alias="KeyNavigableListView.qml">qml/utils/KeyNavigableListView.qml</file>
--
2.19.1
More information about the vlc-devel
mailing list