[vlc-devel] [RFC 77/82] qml: add views to browse network drives

Pierre Lamot pierre at videolabs.io
Fri Feb 1 14:02:21 CET 2019


---
 modules/gui/qt/Makefile.am                    |   4 +
 .../qt/qml/mediacenter/MCNetworkDisplay.qml   | 114 ++++++++++++++++++
 .../qml/mediacenter/NetworkDriveDisplay.qml   |  71 +++++++++++
 .../qt/qml/mediacenter/NetworkFileDisplay.qml |  57 +++++++++
 .../qt/qml/mediacenter/NetworkListItem.qml    |  92 ++++++++++++++
 modules/gui/qt/vlc.qrc                        |   4 +
 6 files changed, 342 insertions(+)
 create mode 100644 modules/gui/qt/qml/mediacenter/MCNetworkDisplay.qml
 create mode 100644 modules/gui/qt/qml/mediacenter/NetworkDriveDisplay.qml
 create mode 100644 modules/gui/qt/qml/mediacenter/NetworkFileDisplay.qml
 create mode 100644 modules/gui/qt/qml/mediacenter/NetworkListItem.qml

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 581bf169bf..2e90beb62f 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -565,12 +565,16 @@ libqt_plugin_la_RES = \
 	gui/qt/qml/mediacenter/ArtistTopBanner.qml \
 	gui/qt/qml/mediacenter/MCMusicDisplay.qml \
 	gui/qt/qml/mediacenter/MCVideoDisplay.qml \
+	gui/qt/qml/mediacenter/MCNetworkDisplay.qml \
 	gui/qt/qml/mediacenter/MusicAlbumsDisplay.qml \
 	gui/qt/qml/mediacenter/MusicAlbumsGridExpandDelegate.qml \
 	gui/qt/qml/mediacenter/MusicArtistsDisplay.qml \
 	gui/qt/qml/mediacenter/MusicGenresDisplay.qml \
 	gui/qt/qml/mediacenter/MusicTracksDisplay.qml \
 	gui/qt/qml/mediacenter/MusicTrackListDisplay.qml \
+	gui/qt/qml/mediacenter/NetworkDriveDisplay.qml \
+	gui/qt/qml/mediacenter/NetworkFileDisplay.qml \
+	gui/qt/qml/mediacenter/NetworkListItem.qml \
 	gui/qt/qml/playlist/PlaylistListView.qml \
 	gui/qt/qml/playlist/PLItem.qml \
 	gui/qt/qml/playlist/PLItemFooter.qml \
diff --git a/modules/gui/qt/qml/mediacenter/MCNetworkDisplay.qml b/modules/gui/qt/qml/mediacenter/MCNetworkDisplay.qml
new file mode 100644
index 0000000000..672473b5f7
--- /dev/null
+++ b/modules/gui/qt/qml/mediacenter/MCNetworkDisplay.qml
@@ -0,0 +1,114 @@
+/*****************************************************************************
+ * 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 QtQml.Models 2.2
+
+import org.videolan.vlc 0.1
+import org.videolan.medialib 0.1
+
+import "qrc:///utils/" as Utils
+import "qrc:///style/"
+
+Utils.NavigableFocusScope {
+    id: root
+
+    property string mrl
+
+    Utils.SelectableDelegateModel {
+        id: delegateModel
+
+        model:  MLNetworkModel {
+            Component.onCompleted: {
+                setContext(mainctx, root.mrl)
+            }
+        }
+
+        delegate: Package {
+            id: element
+            Loader {
+                id: delegateLoader
+                focus: true
+                Package.name: "list"
+                source: model.type == MLNetworkModel.TYPE_FILE ?
+                            "qrc:///mediacenter/NetworkFileDisplay.qml" :
+                            "qrc:///mediacenter/NetworkDriveDisplay.qml";
+            }
+            Connections {
+                target: delegateLoader.item
+                onActionLeft: root.actionLeft(0)
+                onActionRight: root.actionRight(0)
+            }
+
+        }
+
+        function actionAtIndex(index) {
+            if ( delegateModel.selectedGroup.count > 1 ) {
+                var list = []
+                for (var i = 0; i < delegateModel.selectedGroup.count; i++) {
+                    var type = delegateModel.selectedGroup.get(i).model.type;
+                    var mrl = delegateModel.selectedGroup.get(i).model.mrl;
+                    if (type == MLNetworkModel.TYPE_FILE)
+                        list.push(mrl)
+                }
+                medialib.addAndPlay( list )
+            } else {
+                if (delegateModel.items.get(index).model.type != MLNetworkModel.TYPE_FILE)  {
+                    history.push(["mc", "network", { mrl: delegateModel.items.get(index).model.mrl }], History.Go);
+                } else {
+                    medialib.addAndPlay( delegateModel.items.get(index).model.mrl );
+                }
+            }
+        }
+    }
+
+    /*
+     *define the intial position/selection
+     * This is done on activeFocus rather than Component.onCompleted because delegateModel.
+     * selectedGroup update itself after this event
+     */
+    onActiveFocusChanged: {
+        if (activeFocus && delegateModel.items.count > 0 && delegateModel.selectedGroup.count === 0) {
+            var initialIndex = 0
+            if (view.currentIndex !== -1)
+                initialIndex = view.currentIndex
+            delegateModel.items.get(initialIndex).inSelected = true
+            view.currentIndex = initialIndex
+        }
+    }
+
+    Utils.KeyNavigableListView {
+        id: view
+        anchors.fill: parent
+        model: delegateModel.parts.list
+        modelCount: delegateModel.items.count
+
+        focus: true
+        spacing: VLCStyle.margin_xxxsmall
+
+        onSelectAll: delegateModel.selectAll()
+        onSelectionUpdated: delegateModel.updateSelection( keyModifiers, oldIndex, newIndex )
+        onActionAtIndex: delegateModel.actionAtIndex(index)
+
+        onActionLeft: root.actionLeft(index)
+        onActionRight: root.actionRight(index)
+        onActionDown: root.actionDown(index)
+        onActionUp: root.actionUp(index)
+        onActionCancel: root.actionCancel(index)
+    }
+}
diff --git a/modules/gui/qt/qml/mediacenter/NetworkDriveDisplay.qml b/modules/gui/qt/qml/mediacenter/NetworkDriveDisplay.qml
new file mode 100644
index 0000000000..e3782c009c
--- /dev/null
+++ b/modules/gui/qt/qml/mediacenter/NetworkDriveDisplay.qml
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * 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 QtQml.Models 2.2
+
+import org.videolan.vlc 0.1
+import org.videolan.medialib 0.1
+
+import "qrc:///utils/" as Utils
+import "qrc:///style/"
+
+Utils.ListItem {
+    id: item
+
+    width: root.width
+    height: VLCStyle.icon_normal
+
+    focus: true
+
+    color: VLCStyle.colors.getBgColor(element.DelegateModel.inSelected, this.hovered, this.activeFocus)
+
+    cover: Image {
+        id: cover_obj
+        fillMode: Image.PreserveAspectFit
+        source: model.type == MLNetworkModel.TYPE_SHARE ?
+            "qrc:///type/network.svg" : "qrc:///type/directory.svg";
+    }
+    line1: model.name || qsTr("Unknown share")
+    line2: model.protocol + " / " + model.mrl
+
+    onItemClicked : {
+        delegateModel.updateSelection( modifier, view.currentIndex, index )
+        view.currentIndex = index
+        this.forceActiveFocus()
+    }
+    onItemDoubleClicked: {
+        history.push( ["mc", "network", { mrl: model.mrl } ], History.Go)
+    }
+
+    Component {
+        id: actionAdd
+        Utils.IconToolButton {
+            size: VLCStyle.icon_normal
+            text: model.indexed ? VLCIcons.remove : VLCIcons.add
+
+            focus: true
+
+            highlightColor: activeFocus ? VLCStyle.colors.buttonText : "transparent"
+
+            onClicked: model.indexed = !model.indexed
+        }
+    }
+
+    actionButtons: model.can_index ? [actionAdd] : []
+}
diff --git a/modules/gui/qt/qml/mediacenter/NetworkFileDisplay.qml b/modules/gui/qt/qml/mediacenter/NetworkFileDisplay.qml
new file mode 100644
index 0000000000..7a59c90601
--- /dev/null
+++ b/modules/gui/qt/qml/mediacenter/NetworkFileDisplay.qml
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * 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 QtQml.Models 2.2
+
+import org.videolan.medialib 0.1
+
+import "qrc:///utils/" as Utils
+import "qrc:///style/"
+
+Utils.ListItem {
+    width: root.width
+    height: VLCStyle.icon_normal
+
+    focus: true
+
+    color: VLCStyle.colors.getBgColor(element.DelegateModel.inSelected, this.hovered, this.activeFocus)
+
+    cover: Image {
+        id: cover_obj
+        fillMode: Image.PreserveAspectFit
+        source: "qrc:///type/file-asym.svg"
+    }
+    line1: model.name || qsTr("Unknown share")
+    line2: model.mrl
+
+    onItemClicked : {
+        delegateModel.updateSelection( modifier, view.currentIndex, index )
+        view.currentIndex = index
+        this.forceActiveFocus()
+    }
+    onItemDoubleClicked: {
+        medialib.addAndPlay( model.mrl )
+    }
+    onPlayClicked: {
+        medialib.addAndPlay( model.mrl )
+    }
+    onAddToPlaylistClicked: {
+        medialib.addToPlaylist( model.mrl );
+    }
+}
diff --git a/modules/gui/qt/qml/mediacenter/NetworkListItem.qml b/modules/gui/qt/qml/mediacenter/NetworkListItem.qml
new file mode 100644
index 0000000000..594c915a99
--- /dev/null
+++ b/modules/gui/qt/qml/mediacenter/NetworkListItem.qml
@@ -0,0 +1,92 @@
+/*****************************************************************************
+ * 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.Layouts 1.3
+import QtQuick.Controls 2.4
+
+import "qrc:///utils/" as Utils
+import "qrc:///style/"
+
+Rectangle {
+    id: root
+    signal indexClicked
+    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
+
+    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
+        }
+        Column {
+            Text{
+                id: line1_text
+                font.bold: true
+                elide: Text.ElideRight
+                color: VLCStyle.colors.text
+                font.pixelSize: VLCStyle.fontSize_normal
+                enabled: text !== ""
+            }
+            Text{
+                id: line2_text
+                text: ""
+                elide: Text.ElideRight
+                color: VLCStyle.colors.text
+                font.pixelSize: VLCStyle.fontSize_xsmall
+                enabled: text !== ""
+            }
+        }
+
+        Item {
+            Layout.fillWidth: true
+        }
+
+        Utils.ImageToolButton {
+            id: indexButton
+            visible: model.can_index
+            Layout.preferredHeight: VLCStyle.icon_normal
+            Layout.preferredWidth: VLCStyle.icon_normal
+            imageSource: !model.indexed ? "qrc:///buttons/playlist/playlist_add.svg" :
+                ((mouse.containsMouse || activeFocus) ? "qrc:///toolbar/clear.svg" :
+                                       "qrc:///valid.svg" )
+            onClicked: {
+                root.indexClicked(mouse.buttons, mouse.modifiers);
+            }
+        }
+    }
+}
diff --git a/modules/gui/qt/vlc.qrc b/modules/gui/qt/vlc.qrc
index 21b4468358..5b7cebf212 100644
--- a/modules/gui/qt/vlc.qrc
+++ b/modules/gui/qt/vlc.qrc
@@ -182,6 +182,7 @@
     <qresource prefix="/mediacenter">
         <file alias="MCMusicDisplay.qml">qml/mediacenter/MCMusicDisplay.qml</file>
         <file alias="MCVideoDisplay.qml">qml/mediacenter/MCVideoDisplay.qml</file>
+        <file alias="MCNetworkDisplay.qml">qml/mediacenter/MCNetworkDisplay.qml</file>
         <file alias="MusicAlbumsDisplay.qml">qml/mediacenter/MusicAlbumsDisplay.qml</file>
         <file alias="MusicAlbumsGridExpandDelegate.qml">qml/mediacenter/MusicAlbumsGridExpandDelegate.qml</file>
         <file alias="MusicArtistsDisplay.qml">qml/mediacenter/MusicArtistsDisplay.qml</file>
@@ -191,6 +192,9 @@
         <file alias="ArtistListView.qml">qml/mediacenter/ArtistListView.qml</file>
         <file alias="MusicTrackListDisplay.qml">qml/mediacenter/MusicTrackListDisplay.qml</file>
         <file alias="ArtistTopBanner.qml">qml/mediacenter/ArtistTopBanner.qml</file>
+        <file alias="NetworkDriveDisplay.qml">qml/mediacenter/NetworkDriveDisplay.qml</file>
+        <file alias="NetworkFileDisplay.qml">qml/mediacenter/NetworkFileDisplay.qml</file>
+        <file alias="NetworkListItem.qml">qml/mediacenter/NetworkListItem.qml</file>
     </qresource>
     <qresource prefix="/style">
         <file alias="qmldir">qml/style/qmldir</file>
-- 
2.19.1



More information about the vlc-devel mailing list