[vlc-devel] [PATCH 04/10] qml: add NetworkAddressbar widget

Prince Gupta guptaprince8832 at gmail.com
Fri Nov 20 18:29:37 CET 2020


---
 modules/gui/qt/Makefile.am                    |   2 +
 .../gui/qt/network/qml/AddressbarButton.qml   |  73 +++++
 .../gui/qt/network/qml/NetworkAddressbar.qml  | 304 ++++++++++++++++++
 modules/gui/qt/vlc.qrc                        |   2 +
 4 files changed, 381 insertions(+)
 create mode 100644 modules/gui/qt/network/qml/AddressbarButton.qml
 create mode 100644 modules/gui/qt/network/qml/NetworkAddressbar.qml

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 4fc86f7f27..3e5e3d163d 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -638,8 +638,10 @@ libqt_plugin_la_QML = \
 	gui/qt/menus/qml/GlobalShortcuts.qml \
 	gui/qt/menus/qml/GlobalShortcutsMedialib.qml \
 	gui/qt/menus/qml/Menubar.qml \
+	gui/qt/network/qml/AddressbarButton.qml \
 	gui/qt/network/qml/DiscoverDisplay.qml \
 	gui/qt/network/qml/DiscoverUrlDisplay.qml \
+	gui/qt/network/qml/NetworkAddressbar.qml \
 	gui/qt/network/qml/NetworkBrowseDisplay.qml \
 	gui/qt/network/qml/NetworkDisplay.qml \
 	gui/qt/network/qml/NetworkGridItem.qml \
diff --git a/modules/gui/qt/network/qml/AddressbarButton.qml b/modules/gui/qt/network/qml/AddressbarButton.qml
new file mode 100644
index 0000000000..fbc16afb51
--- /dev/null
+++ b/modules/gui/qt/network/qml/AddressbarButton.qml
@@ -0,0 +1,73 @@
+
+/*****************************************************************************
+ * 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 "qrc:///style/"
+import "qrc:///widgets/" as Widgets
+
+AbstractButton {
+    id: button
+
+    property bool onlyIcon: true
+    property bool highlighted: false
+
+    font.pixelSize: onlyIcon ? VLCIcons.pixelSize(VLCStyle.icon_normal) : VLCStyle.fontSize_large
+    padding: VLCStyle.margin_xxsmall
+    width: implicitWidth
+    height: implicitHeight
+
+    contentItem: contentLoader.item
+    background: Rectangle {
+        color: (button.hovered || button.activeFocus) ? VLCStyle.colors.accent : "transparent"
+    }
+
+    Loader {
+        id: contentLoader
+
+        sourceComponent: button.onlyIcon ? iconTextContent : textContent
+    }
+
+    Component {
+        id: iconTextContent
+
+        Widgets.IconLabel {
+            text: button.text
+            elide: Text.ElideRight
+            font.pixelSize: button.font.pixelSize
+            color: VLCStyle.colors.text
+            opacity: (button.highlighted  || button.hovered || button.activeFocus) ? 1 : .6
+            verticalAlignment: Text.AlignVCenter
+        }
+    }
+
+    Component {
+        id: textContent
+
+        Label {
+            text: button.text
+            elide: Text.ElideRight
+            font.pixelSize: button.font.pixelSize
+            font.weight: button.highlighted ? Font.DemiBold : Font.Normal
+            color: VLCStyle.colors.text
+            opacity: (button.highlighted || button.hovered || button.activeFocus) ? 1 : .6
+            verticalAlignment: Text.AlignVCenter
+        }
+    }
+}
diff --git a/modules/gui/qt/network/qml/NetworkAddressbar.qml b/modules/gui/qt/network/qml/NetworkAddressbar.qml
new file mode 100644
index 0000000000..59d4da14e4
--- /dev/null
+++ b/modules/gui/qt/network/qml/NetworkAddressbar.qml
@@ -0,0 +1,304 @@
+
+/*****************************************************************************
+ * 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 QtQml.Models 2.11
+
+import "qrc:///style/"
+import "qrc:///widgets/" as Widgets
+
+Control {
+    id: control
+
+    property var path
+    signal homeButtonClicked
+
+    property var _contentModel
+    property var _menuModel
+
+    onPathChanged: createContentModel()
+    onAvailableWidthChanged: createContentModel()
+    width: VLCStyle.bannerTabButton_width_large * 4
+    height: VLCStyle.dp(24, VLCStyle.scale)
+    focus: true
+    onActiveFocusChanged: if (activeFocus)
+                              contentItem.forceActiveFocus()
+
+    function changeTree(newTree) {
+        popup.close()
+        history.push(["mc", "network", {
+                          "tree": newTree
+                      }])
+    }
+
+    function createContentModel() {
+        var contentModel = []
+        var menuModel = []
+        if (path.length < 1)
+            return
+        var leftWidth = control.availableWidth
+        var i = path.length
+        while (--i >= 0) {
+            var textWidth = fontMetrics.advanceWidth(path[i].display)
+                    + (i !== path.length - 1 ? iconMetrics.advanceWidth(
+                                                    VLCIcons.back) : 0) + VLCStyle.margin_xsmall * 4
+
+            if (i < path.length - 1 && textWidth > leftWidth)
+                menuModel.push(path[i])
+            else
+                contentModel.unshift(path[i])
+            leftWidth -= textWidth
+        }
+        control._contentModel = contentModel
+        control._menuModel = menuModel
+    }
+
+    background: Rectangle {
+        border.width: VLCStyle.dp(1, VLCStyle.scale)
+        border.color: VLCStyle.colors.setColorAlpha(VLCStyle.colors.text, .4)
+        color: VLCStyle.colors.bg
+    }
+
+    contentItem: RowLayout {
+        spacing: VLCStyle.margin_xxsmall
+        width: control.availableWidth
+        onActiveFocusChanged: if (activeFocus)
+                                  homeButton.forceActiveFocus()
+
+        AddressbarButton {
+            id: homeButton
+
+            Layout.fillHeight: true
+            text: VLCIcons.home
+
+            onClicked: control.homeButtonClicked()
+            Keys.onPressed: {
+                if (event.accepted || event.key !== Qt.Key_Right)
+                    return
+                if (menuButton.visible)
+                    menuButton.forceActiveFocus()
+                else
+                    contentRepeater.itemAt(0).forceActiveFocus()
+                event.accepted = true
+            }
+        }
+
+        AddressbarButton {
+            id: menuButton
+
+            Layout.fillHeight: true
+            visible: !!control._menuModel && control._menuModel.length > 0
+            text: VLCIcons.back + VLCIcons.back
+            font.pixelSize: VLCIcons.pixelSize(VLCStyle.icon_small)
+            KeyNavigation.left: homeButton
+
+            onClicked: popup.open()
+            Keys.onPressed: {
+                if (event.accepted || event.key !== Qt.Key_Right)
+                    return
+                contentRepeater.itemAt(0).forceActiveFocus()
+                event.accepted = true
+            }
+        }
+
+        Repeater {
+            id: contentRepeater
+            model: control._contentModel
+            delegate: RowLayout {
+                Layout.fillHeight: true
+                Layout.fillWidth: true
+                Layout.minimumWidth: 0
+                Layout.maximumWidth: implicitWidth
+                focus: true
+                spacing: VLCStyle.margin_xxxsmall
+                onActiveFocusChanged: if (activeFocus)
+                                          btn.forceActiveFocus()
+                Keys.onPressed: {
+                    if (event.accepted)
+                        return
+                    if (event.key === Qt.Key_Right
+                            && index !== contentRepeater.count - 1) {
+                        contentRepeater.itemAt(index + 1).forceActiveFocus()
+                        event.accepted = true
+                    }
+                    else if (event.key === Qt.Key_Left) {
+                        if (index !== 0)
+                            contentRepeater.itemAt(index - 1).forceActiveFocus()
+                        else if (menuButton.visible)
+                            menuButton.forceActiveFocus()
+                        else
+                            homeButton.forceActiveFocus()
+                        event.accepted = true
+                    }
+                }
+
+                AddressbarButton {
+                    id: btn
+
+                    Layout.fillHeight: true
+                    Layout.fillWidth: true
+                    Layout.minimumWidth: 0
+                    text: modelData.display
+                    onlyIcon: false
+                    highlighted: index === contentRepeater.count - 1
+
+                    onClicked: changeTree(modelData.tree)
+                }
+
+                Widgets.IconLabel {
+                    Layout.fillHeight: true
+                    visible: index !== contentRepeater.count - 1
+                    text: VLCIcons.back
+                    rotation: 180
+                    font.pixelSize: VLCIcons.pixelSize(VLCStyle.icon_small)
+                    color: VLCStyle.colors.text
+                    opacity: .6
+                    verticalAlignment: Text.AlignVCenter
+                }
+            }
+        }
+
+        Item {
+            Layout.fillWidth: true
+        }
+    }
+
+    FontMetrics {
+        id: fontMetrics
+        font.pixelSize: VLCStyle.fontSize_large
+    }
+
+    FontMetrics {
+        id: iconMetrics
+        font {
+            pixelSize: VLCStyle.fontSize_large
+            family: VLCIcons.fontFamily
+        }
+    }
+
+    Popup {
+        id: popup
+
+        y: menuButton.height + VLCStyle.margin_xxsmall
+        closePolicy: Popup.CloseOnPressOutside | Popup.CloseOnEscape
+        width: VLCStyle.dp(150, VLCStyle.scale)
+        implicitHeight: contentItem.implicitHeight + padding * 2
+        leftPadding: 0
+        rightPadding: 0
+
+        onOpened: {
+            updateBgRect()
+
+            menuButton.KeyNavigation.down = optionList
+            menuButton.highlighted = true
+            optionList.forceActiveFocus()
+        }
+
+        onClosed: {
+            menuButton.KeyNavigation.down = null
+            menuButton.highlighted = false
+            menuButton.forceActiveFocus()
+        }
+
+        contentItem: ListView {
+            id: optionList
+
+            implicitHeight: contentHeight
+            model: control._menuModel
+            spacing: VLCStyle.margin_xxxsmall
+            delegate: ItemDelegate {
+                id: delegate
+
+                text: modelData.display
+                width: parent.width
+                background: Rectangle {
+                    color: VLCStyle.colors.accent
+                    visible: parent.hovered || parent.activeFocus
+                }
+
+                contentItem: Widgets.ListLabel {
+                    text: delegate.text
+                }
+
+                onClicked: {
+                    changeTree(modelData.tree)
+                }
+            }
+        }
+
+        function updateBgRect() {
+            glassEffect.popupGlobalPos = mainInterfaceRect.mapFromItem(control,
+                                                                       popup.x,
+                                                                       popup.y)
+        }
+
+        background: Rectangle {
+            border.width: VLCStyle.dp(1)
+            border.color: VLCStyle.colors.accent
+
+            Widgets.FrostedGlassEffect {
+                id: glassEffect
+                source: mainInterfaceRect
+
+                anchors.fill: parent
+                anchors.margins: VLCStyle.dp(1)
+
+                property point popupGlobalPos
+                sourceRect: Qt.rect(popupGlobalPos.x, popupGlobalPos.y,
+                                    glassEffect.width, glassEffect.height)
+
+                tint: VLCStyle.colors.bg
+                tintStrength: 0.3
+            }
+        }
+
+        Connections {
+            target: mainInterfaceRect
+
+            enabled: popup.visible
+
+            onWidthChanged: {
+                popup.updateBgRect()
+            }
+
+            onHeightChanged: {
+                popup.updateBgRect()
+            }
+        }
+
+        Connections {
+            target: mainInterface
+
+            enabled: popup.visible
+
+            onIntfScaleFactorChanged: {
+                popup.updateBgRect()
+            }
+        }
+
+        Connections {
+            target: playlistColumn
+
+            onWidthChanged: {
+                popup.updateBgRect()
+            }
+        }
+    }
+}
diff --git a/modules/gui/qt/vlc.qrc b/modules/gui/qt/vlc.qrc
index 34c6c8043e..7e69735d12 100644
--- a/modules/gui/qt/vlc.qrc
+++ b/modules/gui/qt/vlc.qrc
@@ -238,6 +238,7 @@
         <file alias="LocalTabBar.qml">widgets/qml/LocalTabBar.qml</file>
     </qresource>
     <qresource prefix="/network">
+        <file alias="AddressbarButton.qml">network/qml/AddressbarButton.qml</file>
         <file alias="DiscoverDisplay.qml">network/qml/DiscoverDisplay.qml</file>
         <file alias="DiscoverUrlDisplay.qml">network/qml/DiscoverUrlDisplay.qml</file>
         <file alias="NetworkDisplay.qml">network/qml/NetworkDisplay.qml</file>
@@ -247,6 +248,7 @@
         <file alias="NetworkGridItem.qml">network/qml/NetworkGridItem.qml</file>
         <file alias="NetworkListItem.qml">network/qml/NetworkListItem.qml</file>
         <file alias="NetworkThumbnailItem.qml">network/qml/NetworkThumbnailItem.qml</file>
+        <file alias="NetworkAddressbar.qml">network/qml/NetworkAddressbar.qml</file>
         <file alias="ServicesHomeDisplay.qml">network/qml/ServicesHomeDisplay.qml</file>
     </qresource>
     <qresource prefix="/medialibrary">
-- 
2.25.1



More information about the vlc-devel mailing list