[vlc-commits] [Git][videolan/vlc][master] 11 commits: qml: OverlayMenu correct focus handling
Hugo Beauzée-Luyssen (@chouquette)
gitlab at videolan.org
Mon Jan 10 14:04:51 UTC 2022
Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC
Commits:
898cdd87 by Fatih Uzunoglu at 2022-01-10T13:43:45+00:00
qml: OverlayMenu correct focus handling
- - - - -
3b61c479 by Fatih Uzunoglu at 2022-01-10T13:43:45+00:00
qml: don't use loader for trivial type
- - - - -
ebea08c5 by Fatih Uzunoglu at 2022-01-10T13:43:45+00:00
qml: fix OverlayMenu delegate scaling
- - - - -
143ba5fc by Fatih Uzunoglu at 2022-01-10T13:43:45+00:00
qml: OverlayMenu remember index when going back
- - - - -
0bd7cae1 by Fatih Uzunoglu at 2022-01-10T13:43:45+00:00
qml: key actions consider menu placement in OverlayMenu
- - - - -
b3d4bbf7 by Fatih Uzunoglu at 2022-01-10T13:43:45+00:00
qml: add missing 'readonly' specifiers to properties
- - - - -
c4c43902 by Fatih Uzunoglu at 2022-01-10T13:43:45+00:00
qml: base list view don't accept key event when index doesn't change
- - - - -
99a1a53e by Fatih Uzunoglu at 2022-01-10T13:43:45+00:00
qml: respect enabled property in OverlayMenu delegate
- - - - -
463aa54f by Fatih Uzunoglu at 2022-01-10T13:43:45+00:00
qml: set enabled when applicable in pl overlay menu actions
- - - - -
4c594f35 by Fatih Uzunoglu at 2022-01-10T13:43:45+00:00
qml: use plain ListView in OverlayMenu
- - - - -
ae390cea by Fatih Uzunoglu at 2022-01-10T13:43:45+00:00
qml: add scroll bar to OverlayMenu
- - - - -
4 changed files:
- modules/gui/qt/playlist/qml/PlaylistListView.qml
- modules/gui/qt/playlist/qml/PlaylistOverlayMenu.qml
- modules/gui/qt/widgets/qml/KeyNavigableListView.qml
- modules/gui/qt/widgets/qml/OverlayMenu.qml
Changes:
=====================================
modules/gui/qt/playlist/qml/PlaylistListView.qml
=====================================
@@ -124,6 +124,13 @@ Control {
active: MainCtx.playlistDocked
+ focus: shown ? item.focus : false
+
+ onFocusChanged: {
+ if (!focus)
+ listView.forceActiveFocus(Qt.BacktabFocusReason)
+ }
+
readonly property bool shown: (status === Loader.Ready) ? item.visible : false
function open() {
@@ -138,7 +145,6 @@ Control {
rightPadding: VLCStyle.margin_xsmall + VLCStyle.applicationHorizontalMargin
bottomPadding: VLCStyle.margin_large + root.bottomPadding
- itemParent: listView
effectSource: contentItem
}
}
=====================================
modules/gui/qt/playlist/qml/PlaylistOverlayMenu.qml
=====================================
@@ -30,14 +30,14 @@ Widgets.OverlayMenu {
id: playAction
text: I18n.qtr("Play")
onTriggered: mainPlaylistController.goTo(root.model.getSelection()[0], true)
- property string fontIcon: VLCIcons.play
+ readonly property string fontIcon: VLCIcons.play
}
Action {
id: streamAction
text: I18n.qtr("Stream")
onTriggered: DialogsProvider.streamingDialog(root.model.getSelection().map(function(i) { return root.model.itemAt(i).url; }), false)
- property string fontIcon: VLCIcons.stream
+ readonly property string fontIcon: VLCIcons.stream
}
Action {
@@ -64,21 +64,21 @@ Widgets.OverlayMenu {
id: addFileAction
text: I18n.qtr("Add File...")
onTriggered: DialogsProvider.simpleOpenDialog(false)
- property string fontIcon: VLCIcons.add
+ readonly property string fontIcon: VLCIcons.add
}
Action {
id: addDirAction
text: I18n.qtr("Add Directory...")
onTriggered: DialogsProvider.PLAppendDir()
- property string fontIcon: VLCIcons.add
+ readonly property string fontIcon: VLCIcons.add
}
Action {
id: addAdvancedAction
text: I18n.qtr("Advanced Open...")
onTriggered: DialogsProvider.PLAppendDialog()
- property string fontIcon: VLCIcons.add
+ readonly property string fontIcon: VLCIcons.add
}
Action {
@@ -104,7 +104,7 @@ Widgets.OverlayMenu {
id: shuffleAction
text: I18n.qtr("Shuffle Playlist")
onTriggered: mainPlaylistController.shuffle()
- property string fontIcon: VLCIcons.shuffle_on
+ readonly property string fontIcon: VLCIcons.shuffle_on
}
Action {
@@ -117,12 +117,14 @@ Widgets.OverlayMenu {
id: selectTracksAction
text: I18n.qtr("Select Tracks")
onTriggered: root.mode = PlaylistListView.Mode.Select
+ enabled: (root.mode !== PlaylistListView.Mode.Select)
}
Action {
id: moveTracksAction
text: I18n.qtr("Move Selection")
onTriggered: root.mode = PlaylistListView.Mode.Move
+ enabled: (root.mode !== PlaylistListView.Mode.Move)
}
Action {
@@ -131,50 +133,49 @@ Widgets.OverlayMenu {
onTriggered: listView.onDelete()
}
- property var rootMenu: ({
-
- title: I18n.qtr("Playlist Menu"),
- entries: [
- playAction,
- streamAction,
- saveAction,
- infoAction,
- exploreAction,
- addFileAction,
- addDirAction,
- addAdvancedAction,
- savePlAction,
- clearAllAction,
- selectAllAction,
- shuffleAction,
- sortAction,
- selectTracksAction,
- moveTracksAction,
- deleteAction
- ]
- })
-
- property var rootMenu_PLEmpty: ({
- title: I18n.qtr("Playlist Menu"),
- entries: [
- addFileAction,
- addDirAction,
- addAdvancedAction
- ]
+ readonly property var rootMenu: ({
+ title: I18n.qtr("Playlist Menu"),
+ entries: [
+ playAction,
+ streamAction,
+ saveAction,
+ infoAction,
+ exploreAction,
+ addFileAction,
+ addDirAction,
+ addAdvancedAction,
+ savePlAction,
+ clearAllAction,
+ selectAllAction,
+ shuffleAction,
+ sortAction,
+ selectTracksAction,
+ moveTracksAction,
+ deleteAction
+ ]
})
- property var rootMenu_noSelection: ({
- title: I18n.qtr("Playlist Menu"),
- entries: [
- addFileAction,
- addDirAction,
- addAdvancedAction,
- savePlAction,
- clearAllAction,
- sortAction,
- selectTracksAction
- ]
- })
+ readonly property var rootMenu_PLEmpty: ({
+ title: I18n.qtr("Playlist Menu"),
+ entries: [
+ addFileAction,
+ addDirAction,
+ addAdvancedAction
+ ]
+ })
+
+ readonly property var rootMenu_noSelection: ({
+ title: I18n.qtr("Playlist Menu"),
+ entries: [
+ addFileAction,
+ addDirAction,
+ addAdvancedAction,
+ savePlAction,
+ clearAllAction,
+ sortAction,
+ selectTracksAction
+ ]
+ })
model: {
if (root.model.count === 0)
@@ -187,24 +188,25 @@ Widgets.OverlayMenu {
// Sort menu:
- property var sortMenu: ({
- title: I18n.qtr("Sort Menu"),
- entries: []
- })
+ readonly property var sortMenu: ({
+ title: I18n.qtr("Sort Menu"),
+ entries: []
+ })
Component {
id: sortActionDelegate
Action {
- property int key: undefined
+ property int key
+
readonly property string marking: {
if (key === mainPlaylistController.sortKey) {
return (mainPlaylistController.sortOrder === PlaylistControllerModel.SORT_ORDER_ASC ? "↓" : "↑")
- }
- else {
+ } else {
return null
}
}
+
readonly property bool tickMark: (key === mainPlaylistController.sortKey)
onTriggered: mainPlaylistController.sort(key)
@@ -215,7 +217,6 @@ Widgets.OverlayMenu {
model: mainPlaylistController.sortKeyTitleList
delegate: Loader {
- asynchronous: true
sourceComponent: sortActionDelegate
onLoaded: {
=====================================
modules/gui/qt/widgets/qml/KeyNavigableListView.qml
=====================================
@@ -347,11 +347,10 @@ FocusScope {
event.accepted = true
}
- if (newIndex >= 0 && newIndex < modelCount) {
+ var oldIndex = currentIndex
+ if (newIndex >= 0 && newIndex < modelCount && newIndex !== oldIndex) {
event.accepted = true;
- var oldIndex = currentIndex;
-
currentIndex = newIndex;
selectionUpdated(event.modifiers, oldIndex, newIndex);
=====================================
modules/gui/qt/widgets/qml/OverlayMenu.qml
=====================================
@@ -17,12 +17,13 @@
*****************************************************************************/
import QtQuick 2.11
import QtQuick.Controls 2.4
+import QtQuick.Templates 2.4 as T
import QtQuick.Layouts 1.11
import org.videolan.vlc 0.1
import "qrc:///style/"
-Item {
+FocusScope {
id: root
property real widthRatio: (3 / 4)
@@ -56,23 +57,28 @@ Item {
listView.resetStack()
}
- /* required */ property var itemParent
property alias effectSource: effect.source
+ property alias scrollBarActive: scrollBar.active
+
visible: false
function open() {
- listView.currentModel = root.model;
-
- visible = true;
-
- listView.forceActiveFocus(Qt.TabFocusReason);
+ listView.currentModel = root.model
+ visible = true
+ focus = true
}
function close() {
- visible = false;
+ visible = false
+ focus = false
+ }
- itemParent.forceActiveFocus(Qt.BacktabFocusReason);
+ Keys.onPressed: {
+ if (KeyHelper.matchCancel(event)) {
+ close()
+ event.accepted = true
+ }
}
Rectangle {
@@ -127,17 +133,22 @@ Item {
exclusionStrength: 0.1
}
- KeyNavigableListView {
+ ListView {
id: listView
anchors.fill: parent
anchors.topMargin: root.topPadding
anchors.bottomMargin: root.bottomPadding
+ ScrollBar.vertical: ScrollBar { id: scrollBar; active: true }
+
+ focus: true
+
keyNavigationWraps: true
property var stack: []
property var currentModel: root.model
+ property int oldCurrentIndex
model: currentModel.entries
@@ -158,17 +169,26 @@ Item {
if (stack.length > 1) {
stack.pop()
currentModel = stack[stack.length - 1]
- }
- else {
+ listView.currentIndex = listView.oldCurrentIndex
+ } else {
root.close()
}
}
function loadModel(_model) {
+ listView.oldCurrentIndex = listView.currentIndex
listView.stack.push(_model)
listView.currentModel = _model
}
+ Keys.onPressed: {
+ if (root.isRight ? KeyHelper.matchLeft(event)
+ : KeyHelper.matchRight(event)) {
+ goBack()
+ event.accepted = true
+ }
+ }
+
header: MenuLabel {
font.pixelSize: VLCStyle.fontSize_xlarge
text: listView.currentModel.title
@@ -180,21 +200,32 @@ Item {
bottomPadding: VLCStyle.margin_normal
}
- delegate: Button {
+ delegate: T.AbstractButton {
id: button
+ implicitWidth: Math.max(background ? background.implicitWidth : 0,
+ (contentItem ? contentItem.implicitWidth : 0) + leftPadding + rightPadding)
+ implicitHeight: Math.max(background ? background.implicitHeight : 0,
+ (contentItem ? contentItem.implicitHeight : 0) + topPadding + bottomPadding)
+ baselineOffset: contentItem ? contentItem.y + contentItem.baselineOffset : 0
+
readonly property bool yieldsAnotherModel: (!!modelData.model)
+ enabled: modelData.enabled
+
width: listView.width
+ topPadding: VLCStyle.margin_xsmall
+ bottomPadding: VLCStyle.margin_xsmall
leftPadding: root.leftPadding
rightPadding: root.rightPadding
+ spacing: VLCStyle.margin_xsmall
+
function trigger(triggerEnabled) {
if (yieldsAnotherModel) {
listView.loadModel(modelData.model)
- }
- else if (triggerEnabled) {
+ } else if (triggerEnabled) {
modelData.trigger()
root.close()
}
@@ -203,68 +234,64 @@ Item {
onClicked: trigger(true)
Keys.onPressed: {
- if (KeyHelper.matchRight(event)) {
+ if (root.isRight ? KeyHelper.matchRight(event)
+ : KeyHelper.matchLeft(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 {
+ opacity: enabled ? 1.0 : 0.5
+ spacing: button.spacing
+
+ width: scrollBar.active ? (parent.width - scrollBar.width)
+ : parent.width
+
+ Loader {
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
+ active: (!!modelData.icon.source || !!modelData.fontIcon || modelData.tickMark === true)
- Component {
- id: imageIcon
- Image {
- sourceSize: Qt.size(icon.width, icon.height)
- source: modelData.icon.source
- }
+ 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: colors.text
- }
+ Component {
+ id: fontIcon
+ IconLabel {
+ horizontalAlignment: Text.AlignHCenter
+ text: modelData.fontIcon
+ color: colors.text
}
+ }
- Component {
- id: tickMark
- ListLabel {
- horizontalAlignment: Text.AlignHCenter
- text: "✓"
- color: colors.text
- }
+ Component {
+ id: tickMark
+ ListLabel {
+ horizontalAlignment: Text.AlignHCenter
+ text: "✓"
+ color: colors.text
}
+ }
- sourceComponent: {
- if (modelData.tickMark === true)
- tickMark
- else if (!!modelData.fontIcon)
- fontIcon
- else
- imageIcon
- }
+ sourceComponent: {
+ if (modelData.tickMark === true)
+ tickMark
+ else if (!!modelData.fontIcon)
+ fontIcon
+ else
+ imageIcon
}
}
@@ -279,31 +306,29 @@ Item {
color: colors.text
}
- Loader {
- active: (button.yieldsAnotherModel ||
- ( (!!modelData.marking) && (modelData.marking.length >= 1) ))
+ ListLabel {
+ Layout.alignment: Qt.AlignHCenter
- sourceComponent: ListLabel {
- Layout.alignment: Qt.AlignHCenter
+ horizontalAlignment: Text.AlignHCenter
- text: {
- if (button.yieldsAnotherModel)
- "⮕"
- else if (!!modelData.marking)
- modelData.marking
- }
+ visible: text.length > 0
- color: colors.text
- }
+ text: (typeof modelData.marking === 'string') ? modelData.marking
+ : button.yieldsAnotherModel ? "➜"
+ : ""
+
+ color: colors.text
}
}
+ }
- background: Rectangle {
- visible: button.activeFocus
- color: colors.accent
- opacity: 0.8
- }
+ highlight: Rectangle {
+ color: colors.accent
+ opacity: 0.8
}
+
+ highlightResizeDuration: 0
+ highlightMoveDuration: 0
}
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/454b57b76a64516b0f9175909dd9571cd294baf7...ae390cea9f60ec5a51230d7ee31332306dca68a1
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/454b57b76a64516b0f9175909dd9571cd294baf7...ae390cea9f60ec5a51230d7ee31332306dca68a1
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list