[vlc-commits] [Git][videolan/vlc][master] 5 commits: qml: fix search shortcut doesn't gives the searchbox focus

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Mon Sep 13 13:25:12 UTC 2021



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
1d8be346 by Pierre Lamot at 2021-09-13T12:55:52+00:00
qml: fix search shortcut doesn't gives the searchbox focus

the active focus handler of the local banner was triggered when the search box
got focus through a shortcut and force the focus on another component.

Making the local banner a control fixes the issue. The initial reason of the
change was to be able to check the focus reason in the focus handler, but this
seems unnecessary.

- - - - -
668b0875 by Pierre Lamot at 2021-09-13T12:55:52+00:00
qml: remove coupling from contentModel to SearchBox

- - - - -
e6bdb6f3 by Pierre Lamot at 2021-09-13T12:55:52+00:00
qml: minor refactor in SearchBox

- - - - -
96d5906d by Pierre Lamot at 2021-09-13T12:55:52+00:00
qml: remove the 3 char limit warning in SearchBox

the limit no longer exists in the medialibrary

- - - - -
10d1e173 by Pierre Lamot at 2021-09-13T12:55:52+00:00
qml: fix backspace close the SearchBox on Windows

fix: #26043

- - - - -


2 changed files:

- modules/gui/qt/maininterface/qml/BannerSources.qml
- modules/gui/qt/widgets/qml/SearchBox.qml


Changes:

=====================================
modules/gui/qt/maininterface/qml/BannerSources.qml
=====================================
@@ -56,8 +56,14 @@ FocusScope {
     }
 
     function search() {
-        if (searchBox.visible)
-            searchBox.expanded = true
+        searchBox.reqExpand()
+    }
+
+    Binding {
+        target: contentModel
+        property: "searchPattern"
+        value: searchBox.searchPattern
+        when: !!contentModel
     }
 
     Widgets.AcrylicBackground {
@@ -65,7 +71,7 @@ FocusScope {
         anchors.fill: parent
     }
 
-     Item {
+    Item {
         id: pLBannerSources
 
         property alias model: globalMenuGroup.model
@@ -187,7 +193,7 @@ FocusScope {
                 }
             }
 
-            FocusScope {
+            Control {
                 id: localToolbar
 
                 width: parent.width
@@ -206,216 +212,219 @@ FocusScope {
                     }
                 }
 
-                Rectangle {
+                background: Rectangle {
                     id: localToolbarBg
 
-                    anchors.fill: parent
                     color: VLCStyle.colors.lowerBanner
-                }
-
-                Rectangle {
-                    anchors.left : localToolbarBg.left
-                    anchors.right: localToolbarBg.right
-                    anchors.top  : localToolbarBg.bottom
+                    Rectangle {
+                        anchors.left : parent.left
+                        anchors.right: parent.right
+                        anchors.top  : parent.bottom
 
-                    height: VLCStyle.border
+                        height: VLCStyle.border
 
-                    color: VLCStyle.colors.border
+                        color: VLCStyle.colors.border
+                    }
                 }
 
-                Widgets.NavigableRow {
-                    id: localContextGroup
-                    anchors {
-                        verticalCenter: parent.verticalCenter
-                        left: parent.left
-                        leftMargin: VLCStyle.applicationHorizontalMargin + VLCStyle.margin_xsmall
-                    }
-                    enabled: list_grid_btn.visible || sortControl.visible
 
-                    model: ObjectModel {
-                        id: localContextModel
+                contentItem: Item {
+                    id: localToolbarContent
 
-                        property int countExtra: 0
+                    Widgets.NavigableRow {
+                        id: localContextGroup
+                        anchors {
+                            verticalCenter: parent.verticalCenter
+                            left: parent.left
+                            leftMargin: VLCStyle.applicationHorizontalMargin + VLCStyle.margin_xsmall
+                        }
+                        enabled: list_grid_btn.visible || sortControl.visible
 
-                        Widgets.IconToolButton {
-                            id: list_grid_btn
+                        model: ObjectModel {
+                            id: localContextModel
 
-                            width: VLCStyle.bannerButton_width
-                            height: VLCStyle.bannerButton_height
-                            size: VLCStyle.banner_icon_size
-                            iconText: mainInterface.gridView ? VLCIcons.list : VLCIcons.grid
-                            text: i18n.qtr("List/Grid")
-                            onClicked: mainInterface.gridView = !mainInterface.gridView
-                            enabled: true
-                        }
+                            property int countExtra: 0
+
+                            Widgets.IconToolButton {
+                                id: list_grid_btn
+
+                                width: VLCStyle.bannerButton_width
+                                height: VLCStyle.bannerButton_height
+                                size: VLCStyle.banner_icon_size
+                                iconText: mainInterface.gridView ? VLCIcons.list : VLCIcons.grid
+                                text: i18n.qtr("List/Grid")
+                                onClicked: mainInterface.gridView = !mainInterface.gridView
+                                enabled: true
+                            }
 
-                        Widgets.SortControl {
-                            id: sortControl
+                            Widgets.SortControl {
+                                id: sortControl
 
-                            textRole: "text"
-                            criteriaRole: "criteria"
+                                textRole: "text"
+                                criteriaRole: "criteria"
 
-                            width: VLCStyle.bannerButton_width
-                            height: VLCStyle.bannerButton_height
-                            iconSize: VLCStyle.banner_icon_size
+                                width: VLCStyle.bannerButton_width
+                                height: VLCStyle.bannerButton_height
+                                iconSize: VLCStyle.banner_icon_size
 
-                            visible: root.sortModel !== undefined && root.sortModel.length > 1
-                            enabled: visible
+                                visible: root.sortModel !== undefined && root.sortModel.length > 1
+                                enabled: visible
 
-                            onSortSelected: {
-                                if (contentModel !== undefined) {
-                                    contentModel.sortCriteria = type
+                                onSortSelected: {
+                                    if (contentModel !== undefined) {
+                                        contentModel.sortCriteria = type
+                                    }
                                 }
-                            }
 
-                            onSortOrderSelected: {
-                                if (contentModel !== undefined) {
-                                    contentModel.sortOrder = type
+                                onSortOrderSelected: {
+                                    if (contentModel !== undefined) {
+                                        contentModel.sortOrder = type
+                                    }
                                 }
-                            }
 
-                            sortKey: contentModel ? contentModel.sortCriteria : PlaylistControllerModel.SORT_KEY_NONE
-                            sortOrder: contentModel ? contentModel.sortOrder : undefined
+                                sortKey: contentModel ? contentModel.sortCriteria : PlaylistControllerModel.SORT_KEY_NONE
+                                sortOrder: contentModel ? contentModel.sortOrder : undefined
+                            }
                         }
-                    }
 
-                    Connections {
-                        target: root
-                        onExtraLocalActionsChanged : {
-                            for (var i = 0; i < localContextModel.countExtra; i++) {
-                                localContextModel.remove(localContextModel.count - localContextModel.countExtra, localContextModel.countExtra)
-                            }
+                        Connections {
+                            target: root
+                            onExtraLocalActionsChanged : {
+                                for (var i = 0; i < localContextModel.countExtra; i++) {
+                                    localContextModel.remove(localContextModel.count - localContextModel.countExtra, localContextModel.countExtra)
+                                }
 
-                            if (root.extraLocalActions && root.extraLocalActions instanceof ObjectModel) {
-                                for (i = 0; i < root.extraLocalActions.count; i++)
-                                    localContextModel.append(root.extraLocalActions.get(i))
-                                localContextModel.countExtra = root.extraLocalActions.count
-                            } else {
-                                localContextModel.countExtra = 0
+                                if (root.extraLocalActions && root.extraLocalActions instanceof ObjectModel) {
+                                    for (i = 0; i < root.extraLocalActions.count; i++)
+                                        localContextModel.append(root.extraLocalActions.get(i))
+                                    localContextModel.countExtra = root.extraLocalActions.count
+                                } else {
+                                    localContextModel.countExtra = 0
+                                }
                             }
                         }
-                    }
 
-                    Navigation.parentItem: root
-                    Navigation.rightItem: localMenuGroup.visible ? localMenuGroup : playlistGroup
-                    Navigation.upItem: globalMenuGroup
-                }
-
-                Flickable {
-                    id: localMenuView
-
-                    readonly property int availableWidth: parent.width
-                                                          - (localContextGroup.width + playlistGroup.width)
-                                                          - (VLCStyle.applicationHorizontalMargin * 2)
-                                                          - (VLCStyle.margin_xsmall * 2)
-                                                          - (VLCStyle.margin_xxsmall * 2)
-                    readonly property bool _alignHCenter: ((localToolbar.width - contentWidth) / 2) + contentWidth < playlistGroup.x
-
-                    width: Math.min(contentWidth, availableWidth)
-                    height: VLCStyle.localToolbar_height
-                    clip: true
-                    contentWidth: localMenuGroup.width
-                    contentHeight: VLCStyle.localToolbar_height // don't allow vertical flickering
-                    anchors.rightMargin: VLCStyle.margin_xxsmall // only applied when right aligned
-
-                    on_AlignHCenterChanged: {
-                        if (_alignHCenter) {
-                            anchors.horizontalCenter = localToolbar.horizontalCenter
-                            anchors.right = undefined
-                        } else {
-                            anchors.horizontalCenter = undefined
-                            anchors.right = playlistGroup.left
-                        }
+                        Navigation.parentItem: root
+                        Navigation.rightItem: localMenuGroup.visible ? localMenuGroup : playlistGroup
+                        Navigation.upItem: globalMenuGroup
                     }
 
-                    Loader {
-                        id: localMenuGroup
-
-                        focus: !!item && item.focus && item.visible
-                        visible: !!item
-                        enabled: status === Loader.Ready
-                        y: status === Loader.Ready ? (VLCStyle.localToolbar_height - item.height) / 2 : 0
-                        width: !!item
-                               ? Helpers.clamp(localMenuView.availableWidth,
-                                               localMenuGroup.item.minimumWidth || localMenuGroup.item.implicitWidth,
-                                               localMenuGroup.item.maximumWidth || localMenuGroup.item.implicitWidth)
-                               : 0
-
-                        onVisibleChanged: {
-                            //reset the focus on the global group when the local group is hidden,
-                            //this avoids losing the focus if the subview changes
-                            // FIXME: This block needs refactor for keyboard focus.
-                            if (!visible && localMenuGroup.focus) {
-                                localMenuGroup.focus = false
-                                globalMenuGroup.focus = true
+                    Flickable {
+                        id: localMenuView
+
+                        readonly property int availableWidth: parent.width
+                                                              - (localContextGroup.width + playlistGroup.width)
+                                                              - (VLCStyle.applicationHorizontalMargin * 2)
+                                                              - (VLCStyle.margin_xsmall * 2)
+                                                              - (VLCStyle.margin_xxsmall * 2)
+                        readonly property bool _alignHCenter: ((localToolbarContent.width - contentWidth) / 2) + contentWidth < playlistGroup.x
+
+                        width: Math.min(contentWidth, availableWidth)
+                        height: VLCStyle.localToolbar_height
+                        clip: true
+                        contentWidth: localMenuGroup.width
+                        contentHeight: VLCStyle.localToolbar_height // don't allow vertical flickering
+                        anchors.rightMargin: VLCStyle.margin_xxsmall // only applied when right aligned
+
+                        on_AlignHCenterChanged: {
+                            if (_alignHCenter) {
+                                anchors.horizontalCenter = localToolbarContent.horizontalCenter
+                                anchors.right = undefined
+                            } else {
+                                anchors.horizontalCenter = undefined
+                                anchors.right = playlistGroup.left
                             }
                         }
 
-                        onItemChanged: {
-                            if (!item)
-                                return
-                            item.Navigation.parentItem = root
-                            item.Navigation.leftItem = Qt.binding(function(){ return localContextGroup.enabled ? localContextGroup : null})
-                            item.Navigation.rightItem = Qt.binding(function(){ return playlistGroup.enabled ? playlistGroup : null})
-                            item.Navigation.upItem = globalMenuGroup
+                        Loader {
+                            id: localMenuGroup
+
+                            focus: !!item && item.focus && item.visible
+                            visible: !!item
+                            enabled: status === Loader.Ready
+                            y: status === Loader.Ready ? (VLCStyle.localToolbar_height - item.height) / 2 : 0
+                            width: !!item
+                                   ? Helpers.clamp(localMenuView.availableWidth,
+                                                   localMenuGroup.item.minimumWidth || localMenuGroup.item.implicitWidth,
+                                                   localMenuGroup.item.maximumWidth || localMenuGroup.item.implicitWidth)
+                                   : 0
+
+                            onVisibleChanged: {
+                                //reset the focus on the global group when the local group is hidden,
+                                //this avoids losing the focus if the subview changes
+                                // FIXME: This block needs refactor for keyboard focus.
+                                if (!visible && localMenuGroup.focus) {
+                                    localMenuGroup.focus = false
+                                    globalMenuGroup.focus = true
+                                }
+                            }
+
+                            onItemChanged: {
+                                if (!item)
+                                    return
+                                item.Navigation.parentItem = root
+                                item.Navigation.leftItem = Qt.binding(function(){ return localContextGroup.enabled ? localContextGroup : null})
+                                item.Navigation.rightItem = Qt.binding(function(){ return playlistGroup.enabled ? playlistGroup : null})
+                                item.Navigation.upItem = globalMenuGroup
+                            }
                         }
                     }
-                }
 
-                Widgets.NavigableRow {
-                    id: playlistGroup
-                    anchors {
-                        verticalCenter: parent.verticalCenter
-                        right: parent.right
-                        rightMargin: VLCStyle.applicationHorizontalMargin + VLCStyle.margin_xsmall
-                    }
-                    spacing: VLCStyle.margin_xxxsmall
+                    Widgets.NavigableRow {
+                        id: playlistGroup
+                        anchors {
+                            verticalCenter: parent.verticalCenter
+                            right: parent.right
+                            rightMargin: VLCStyle.applicationHorizontalMargin + VLCStyle.margin_xsmall
+                        }
+                        spacing: VLCStyle.margin_xxxsmall
 
-                    model: ObjectModel {
+                        model: ObjectModel {
 
-                        Widgets.SearchBox {
-                            id: searchBox
-                            contentModel: root.contentModel
-                            visible: root.contentModel !== undefined
-                            enabled: visible
-                            height: VLCStyle.bannerButton_height
-                            buttonWidth: VLCStyle.bannerButton_width
-                        }
+                            Widgets.SearchBox {
+                                id: searchBox
+                                visible: root.contentModel !== undefined
+                                enabled: visible
+                                height: VLCStyle.bannerButton_height
+                                width: searchBox.implicitWith
+                                buttonWidth: VLCStyle.bannerButton_width
+                            }
 
-                        Widgets.IconToolButton {
-                            id: playlist_btn
+                            Widgets.IconToolButton {
+                                id: playlist_btn
 
-                            size: VLCStyle.banner_icon_size
-                            iconText: VLCIcons.playlist
-                            text: i18n.qtr("Playlist")
-                            width: VLCStyle.bannerButton_width
-                            height: VLCStyle.bannerButton_height
-                            highlighted: mainInterface.playlistVisible
+                                size: VLCStyle.banner_icon_size
+                                iconText: VLCIcons.playlist
+                                text: i18n.qtr("Playlist")
+                                width: VLCStyle.bannerButton_width
+                                height: VLCStyle.bannerButton_height
+                                highlighted: mainInterface.playlistVisible
 
-                            onClicked:  mainInterface.playlistVisible = !mainInterface.playlistVisible
-                        }
+                                onClicked:  mainInterface.playlistVisible = !mainInterface.playlistVisible
+                            }
 
-                        Widgets.IconToolButton {
-                            id: menu_selector
+                            Widgets.IconToolButton {
+                                id: menu_selector
 
-                            size: VLCStyle.banner_icon_size
-                            iconText: VLCIcons.ellipsis
-                            text: i18n.qtr("Menu")
-                            width: VLCStyle.bannerButton_width
-                            height: VLCStyle.bannerButton_height
+                                size: VLCStyle.banner_icon_size
+                                iconText: VLCIcons.ellipsis
+                                text: i18n.qtr("Menu")
+                                width: VLCStyle.bannerButton_width
+                                height: VLCStyle.bannerButton_height
 
-                            onClicked: contextMenu.popup(this.mapToGlobal(0, height))
+                                onClicked: contextMenu.popup(this.mapToGlobal(0, height))
 
-                            QmlGlobalMenu {
-                                id: contextMenu
-                                ctx: mainctx
+                                QmlGlobalMenu {
+                                    id: contextMenu
+                                    ctx: mainctx
+                                }
                             }
                         }
-                    }
 
-                    Navigation.parentItem: root
-                    Navigation.leftItem: localMenuGroup.visible ? localMenuGroup : localContextGroup
-                    Navigation.upItem: globalMenuGroup
+                        Navigation.parentItem: root
+                        Navigation.leftItem: localMenuGroup.visible ? localMenuGroup : localContextGroup
+                        Navigation.upItem: globalMenuGroup
+                    }
                 }
             }
         }


=====================================
modules/gui/qt/widgets/qml/SearchBox.qml
=====================================
@@ -27,51 +27,50 @@ import "qrc:///widgets/" as Widgets
 FocusScope {
     id: root
 
-    width: content.width
+    implicitWidth: content.implicitWidth
 
-    property variant contentModel
     property alias buttonWidth: icon.width
+    property alias searchPattern: searchBox.text
 
-    property bool expanded: false
+    property bool _expanded: false
 
-    onExpandedChanged: {
-        if (expanded) {
-            searchBox.forceActiveFocus()
-            icon.Navigation.rightItem = searchBox
+    function reqExpand() {
+        if (visible)
+            _expanded = true
+    }
+
+    on_ExpandedChanged: {
+        if (_expanded) {
+            searchBox.forceActiveFocus(Qt.ShortcutFocusReason)
             animateExpand.start()
-        }
-        else {
-            searchBox.placeholderText = ""
-            searchBox.text = ""
+        } else {
+            searchBox.clear()
             icon.focus = true
             searchBox.focus = false
-            icon.Navigation.rightItem = null
             animateRetract.start()
         }
     }
 
     onActiveFocusChanged: {
-        if (!activeFocus && searchBox.text == "")
-            expanded = false
+        if (!activeFocus && searchBox.text == "") {
+            _expanded = false
+        }
     }
 
     SmoothedAnimation {
         id: animateExpand;
         target: searchBoxRect;
         properties: "width"
-        duration: VLCStyle.ms125
+        duration: VLCStyle.duration_faster
         to: VLCStyle.widthSearchInput
         easing.type: Easing.InSine
-        onStopped: {
-            searchBox.placeholderText = i18n.qtr("filter")
-        }
     }
 
     SmoothedAnimation {
         id: animateRetract;
         target: searchBoxRect;
         properties: "width"
-        duration: VLCStyle.ms125
+        duration: VLCStyle.duration_faster
         to: 0
         easing.type: Easing.OutSine
     }
@@ -91,15 +90,12 @@ FocusScope {
             focus: true
 
             onClicked: {
-                if (searchBox.text == "")
-                    expanded = !expanded
-                else {
-                    searchBox.clear()
-                    expanded = !expanded
-                }
+                searchBox.clear()
+                _expanded = !_expanded
             }
 
             Navigation.parentItem: root
+            Navigation.rightItem: _expanded ? searchBox : nullptr
             Keys.priority: Keys.AfterItem
             Keys.onPressed: Navigation.defaultKeyAction(event)
         }
@@ -113,19 +109,12 @@ FocusScope {
             width: 0
             implicitHeight: searchBox.height
 
-            border.color: {
-                if ( searchBox.text.length < 3 && searchBox.text.length !== 0 )
-                    return VLCStyle.colors.alert
-                else if ( searchBox.activeFocus )
-                    return VLCStyle.colors.accent
-                else
-                    return VLCStyle.colors.buttonBorder
-            }
+            border.color: searchBox.activeFocus ? VLCStyle.colors.accent : VLCStyle.colors.buttonBorder
 
             TextField {
                 id: searchBox
 
-                enabled: root.expanded
+                enabled: root._expanded
 
                 anchors.fill: searchBoxRect
                 anchors.rightMargin: clearButton.visible ? (VLCStyle.margin_xxsmall + clearButton.width) : 0
@@ -138,39 +127,27 @@ FocusScope {
 
                 selectByMouse: true
 
-                background: Rectangle { color: "transparent" }
+                placeholderText: i18n.qtr("filter")
 
-                onTextChanged: {
-                    if (contentModel !== undefined)
-                        contentModel.searchPattern = text;
-                }
+                background: Rectangle { color: "transparent" }
 
                 Navigation.parentItem: root
                 Navigation.leftItem: icon
                 Navigation.rightItem: clearButton.visible ? clearButton : null
+                Navigation.cancelAction: function() { _expanded = false }
                 Keys.priority: Keys.AfterItem
                 Keys.onPressed: {
-                    //don't use KeyHelper.matchCancel here as we don't want to match Backspace
-                    if (event.key === Qt.Key_Back
-                        || event.key === Qt.Key_Cancel
-                        || event.matches(StandardKey.Back)
-                        || event.matches(StandardKey.Cancel))
-                    {
-                        event.accepted = true
+                    //we don't want Navigation.cancelAction to match Backspace
+                    if (event.matches(StandardKey.Backspace)) {
+                        return
                     }
                     Navigation.defaultKeyAction(event)
                 }
 
                 Keys.onReleased: {
-                    //don't use KeyHelper.matchCancel here as we don't want to match Backspace
-                    if (event.key === Qt.Key_Back
-                        || event.key === Qt.Key_Cancel
-                        || event.matches(StandardKey.Back)
-                        || event.matches(StandardKey.Cancel))
-                    {
-                        text = ""
-                        expanded = false
-                        event.accepted = true
+                    //we don't want Navigation.cancelAction to match Backspace
+                    if (event.matches(StandardKey.Backspace)) {
+                        return
                     }
                     Navigation.defaultKeyReleaseAction(event)
                 }
@@ -186,7 +163,7 @@ FocusScope {
                 size: VLCStyle.icon_small
                 iconText: VLCIcons.close
 
-                visible: ( expanded && searchBox.text.length > 0 )
+                visible: ( _expanded && searchBox.text.length > 0 )
                 enabled: visible
 
                 onClicked: {



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/3a163f8190319c09db3b4c31640f0f53fbbe885f...10d1e17325e6058e0448081d5b68bdb29d9cf440

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/3a163f8190319c09db3b4c31640f0f53fbbe885f...10d1e17325e6058e0448081d5b68bdb29d9cf440
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list