[vlc-commits] [Git][videolan/vlc][master] 9 commits: qml: implement MainViewLoader
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Mon Mar 20 10:20:31 UTC 2023
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
ecf0c9ce by Prince Gupta at 2023-03-20T10:02:14+00:00
qml: implement MainViewLoader
- - - - -
b0ae61dd by Prince Gupta at 2023-03-20T10:02:14+00:00
qml: check nullability in Helpers.get
- - - - -
a9e02b66 by Prince Gupta at 2023-03-20T10:02:14+00:00
qml: use MainViewLoader in VideoAll
- - - - -
ea0eaffa by Prince Gupta at 2023-03-20T10:02:14+00:00
qml: use MainViewLoader for PlaylistMediaList
- - - - -
4643f556 by Prince Gupta at 2023-03-20T10:02:14+00:00
qml: use MainViewLoader in MusicAllArtists component
- - - - -
e3b13a68 by Prince Gupta at 2023-03-20T10:02:14+00:00
qml: use MainViewLoader in MusicAlbums component
- - - - -
84a5bed6 by Prince Gupta at 2023-03-20T10:02:14+00:00
qml: use MainViewLoader in MusicGenres component
- - - - -
62e94c6d by Prince Gupta at 2023-03-20T10:02:14+00:00
qt: allow navigation functions to fallback to default behaviour
- - - - -
f5d79535 by Prince Gupta at 2023-03-20T10:02:14+00:00
qml: handle Navigation Cancel in MainViewLoader
- - - - -
13 changed files:
- modules/gui/qt/Makefile.am
- + modules/gui/qt/maininterface/qml/MainViewLoader.qml
- modules/gui/qt/medialibrary/qml/MusicAlbums.qml
- modules/gui/qt/medialibrary/qml/MusicAllArtists.qml
- modules/gui/qt/medialibrary/qml/MusicGenres.qml
- modules/gui/qt/medialibrary/qml/MusicPlaylistsDisplay.qml
- modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
- modules/gui/qt/medialibrary/qml/VideoAll.qml
- modules/gui/qt/medialibrary/qml/VideoAllSubDisplay.qml
- modules/gui/qt/medialibrary/qml/VideoPlaylistsDisplay.qml
- modules/gui/qt/util/qml/Helpers.js
- modules/gui/qt/vlc.qrc
- modules/gui/qt/widgets/native/navigation_attached.cpp
Changes:
=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -848,6 +848,7 @@ libqt_plugin_la_QML = \
gui/qt/dialogs/toolbar/qml/ToolbarEditorButtonList.qml \
gui/qt/maininterface/qml/BannerSources.qml \
gui/qt/maininterface/qml/MainInterface.qml \
+ gui/qt/maininterface/qml/MainViewLoader.qml \
gui/qt/maininterface/qml/MainDisplay.qml \
gui/qt/maininterface/qml/MainGridView.qml \
gui/qt/maininterface/qml/MainTableView.qml \
=====================================
modules/gui/qt/maininterface/qml/MainViewLoader.qml
=====================================
@@ -0,0 +1,147 @@
+/*****************************************************************************
+ * Copyright (C) 2023 VLC authors and VideoLAN
+ *
+ * Author: Prince Gupta <guptaprince8832 at gmail.com>
+ *
+ * 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 QtQml.Models 2.11
+
+import org.videolan.vlc 0.1
+
+import "qrc:///widgets/" as Widgets
+import "qrc:///util/" as Util
+import "qrc:///util/Helpers.js" as Helpers
+
+
+Widgets.StackViewExt {
+ id: root
+
+ /*
+ A component for loading view subtypes depending on model or user preferences.
+ It also handles common actions across sub views such as -
+ restoring of initialIndex when view is reloaded and navigation cancel.
+
+ Following are required inputs -
+ */
+
+ // components to load depending on MainCtx.gridView
+ /* required */ property Component grid
+ /* required */ property Component list
+
+ // component to load when provided model is empty
+ /* required */ property Component emptyLabel
+
+ // view's model
+ /* required */ property var model
+
+
+
+ property var selectionModel: Util.SelectableDelegateModel {
+ model: root.model
+ }
+
+ readonly property ColorContext colorContext: ColorContext {
+ id: theme
+
+ colorSet: ColorContext.View
+ }
+
+ // the index to "go to" when the view is loaded
+ property int initialIndex: -1
+
+ // used in custom focus management for explicit "focusReason" transfer
+ readonly property var setCurrentItemFocus: {
+ return Helpers.get(currentItem, "setCurrentItemFocus", _setCurrentItemFocusDefault)
+ }
+
+ property var currentComponent: {
+ if (typeof model === "undefined" || !model)
+ return null // invalid state
+ if (!model.ready && model.count === 0)
+ return emptyLabel
+ else if (MainCtx.gridView)
+ return grid
+ else
+ return list
+ }
+
+ onCurrentComponentChanged: {
+ _loadCurrentViewType()
+ }
+
+ onModelChanged: resetFocus()
+
+ onInitialIndexChanged: resetFocus()
+
+ Connections {
+ target: model
+
+ onCountChanged: {
+ if (model.count === 0 || selectionModel.hasSelection)
+ return
+
+ resetFocus()
+ }
+ }
+
+ function _setCurrentItemFocusDefault(reason) {
+ if (currentItem)
+ currentItem.forceActiveFocus(reason)
+ }
+
+ function _loadCurrentViewType() {
+ if (typeof currentComponent === "undefined" || !currentComponent) {
+ // invalid case, don't show anything
+ clear()
+ return
+ }
+
+ replace(null, currentComponent)
+ }
+
+ // makes the views currentIndex initial index and position view at that index
+ function resetFocus() {
+ if (!model || model.count === 0) return
+
+ var initialIndex = root.initialIndex
+ if (initialIndex >= model.count)
+ initialIndex = 0
+
+ selectionModel.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
+ if (currentItem && currentItem.hasOwnProperty("positionViewAtIndex")) {
+ currentItem.positionViewAtIndex(initialIndex, ItemView.Contain)
+
+ // Table View require this for focus handling
+ if (!MainCtx.gridView)
+ currentItem.currentIndex = initialIndex
+ }
+ }
+
+ // handle cancelAction, if currentIndex is set reset it to 0
+ // otherwise perform default Navigation action
+ Navigation.cancelAction: function () {
+ if (Helpers.get(currentItem, "currentIndex", 0) <= 0) {
+ return false // transfer cancel action to parent
+ }
+
+ currentItem.currentIndex = 0
+ currentItem.positionViewAtIndex(0, ItemView.Contain)
+ return true
+ }
+
+}
=====================================
modules/gui/qt/medialibrary/qml/MusicAlbums.qml
=====================================
@@ -16,31 +16,31 @@
* 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.11
-import QtQml.Models 2.2
+
import org.videolan.medialib 0.1
import org.videolan.vlc 0.1
import "qrc:///util/" as Util
import "qrc:///widgets/" as Widgets
import "qrc:///main/" as MainInterface
+import "qrc:///util/Helpers.js" as Helpers
import "qrc:///style/"
-FocusScope {
+MainInterface.MainViewLoader {
id: root
// Properties
- //the index to "go to" when the view is loaded
- property int initialIndex: 0
property int gridViewMarginTop: VLCStyle.margin_large
- property var gridViewRowX: MainCtx.gridView ? _currentView.rowX : undefined
+ property var gridViewRowX: Helpers.get(currentItem, "rowX", 0)
+
+ readonly property var currentIndex: Helpers.get(currentItem, "currentIndex", - 1)
- readonly property var currentIndex: _currentView.currentIndex
+ property Component header: Item {}
+ readonly property Item headerItem: Helpers.get(currentItem, "headerItem", null)
- property Component header: Item{}
- readonly property Item headerItem: _currentView ? _currentView.headerItem : null
+ readonly property int contentLeftMargin: Helpers.get(currentItem, "contentLeftMargin", 0)
+ readonly property int contentRightMargin: Helpers.get(currentItem, "contentRightMargin", 0)
property var sortModel: [
{ text: I18n.qtr("Alphabetic"), criteria: "title"},
@@ -49,39 +49,16 @@ FocusScope {
{ text: I18n.qtr("Artist"), criteria: "main_artist" },
]
- // Aliases
-
- property alias leftPadding: view.leftPadding
- property alias rightPadding: view.rightPadding
-
- property alias model: albumModelId
property alias parentId: albumModelId.parentId
- readonly property int contentLeftMargin: _currentView ? _currentView.contentLeftMargin : 0
- readonly property int contentRightMargin: _currentView ? _currentView.contentRightMargin : 0
+ model: albumModelId
- property alias _currentView: view.currentItem
+ grid: gridComponent
+ list: tableComponent
+ emptyLabel: emptyLabelComponent
- onInitialIndexChanged: resetFocus()
- onModelChanged: resetFocus()
onParentIdChanged: resetFocus()
- function resetFocus() {
- if (albumModelId.count === 0) {
- return
- }
- var initialIndex = root.initialIndex
- if (initialIndex >= albumModelId.count)
- initialIndex = 0
- selectionModel.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
- if (_currentView)
- _currentView.positionViewAtIndex(initialIndex, ItemView.Contain)
- }
-
- function setCurrentItemFocus(reason) {
- _currentView.setCurrentItemFocus(reason);
- }
-
function _actionAtIndex(index) {
if (selectionModel.selectedIndexes.length > 1) {
MediaLib.addAndPlay( model.getIdsForIndexes( selectionModel.selectedIndexes ) )
@@ -90,30 +67,10 @@ FocusScope {
}
}
- function _onNavigationCancel() {
- if (_currentView.currentIndex <= 0) {
- root.Navigation.defaultNavigationCancel()
- } else {
- _currentView.currentIndex = 0;
- _currentView.positionViewAtIndex(0, ItemView.Contain)
- }
- }
-
-
MLAlbumModel {
id: albumModelId
- ml: MediaLib
- onCountChanged: {
- if (albumModelId.count > 0 && !selectionModel.hasSelection) {
- root.resetFocus()
- }
- }
- }
-
- Util.SelectableDelegateModel {
- id: selectionModel
- model: albumModelId
+ ml: MediaLib
}
Widgets.MLDragItem {
@@ -201,7 +158,6 @@ FocusScope {
}
Navigation.parentItem: root
- Navigation.cancelAction: root._onNavigationCancel
Connections {
target: contextMenu
@@ -282,8 +238,6 @@ FocusScope {
sortModel: (availableRowWidth < VLCStyle.colWidth(4)) ? _modelSmall
: _modelMedium
- Navigation.cancelAction: root._onNavigationCancel
-
onContextMenuButtonClicked: contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
onRightClick: contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
onItemDoubleClicked: MediaLib.addAndPlay( model.id )
@@ -310,32 +264,13 @@ FocusScope {
}
}
- Widgets.StackViewExt {
- id: view
-
- anchors.fill: parent
-
- focus: albumModelId.count !== 0
-
- initialItem: MainCtx.gridView ? gridComponent : tableComponent
+ Component {
+ id: emptyLabelComponent
- Connections {
- target: MainCtx
- onGridViewChanged: {
- if (MainCtx.gridView)
- view.replace(gridComponent)
- else
- view.replace(tableComponent)
- }
+ EmptyLabelButton {
+ text: I18n.qtr("No albums found\nPlease try adding sources, by going to the Browse tab")
+ Navigation.parentItem: root
+ cover: VLCStyle.noArtAlbumCover
}
}
-
- EmptyLabelButton {
- anchors.fill: parent
- visible: albumModelId.isReady && (albumModelId.count <= 0)
- focus: visible
- text: I18n.qtr("No albums found\nPlease try adding sources, by going to the Browse tab")
- Navigation.parentItem: root
- cover: VLCStyle.noArtAlbumCover
- }
}
=====================================
modules/gui/qt/medialibrary/qml/MusicAllArtists.qml
=====================================
@@ -16,10 +16,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
-import QtQuick.Controls 2.4
import QtQuick 2.11
-import QtQml.Models 2.2
-import QtQuick.Layouts 1.3
import org.videolan.medialib 0.1
import org.videolan.vlc 0.1
@@ -27,71 +24,26 @@ import org.videolan.vlc 0.1
import "qrc:///util/" as Util
import "qrc:///widgets/" as Widgets
import "qrc:///main/" as MainInterface
+import "qrc:///util/Helpers.js" as Helpers
import "qrc:///style/"
-FocusScope {
+MainInterface.MainViewLoader {
id: root
// Properties
- readonly property int currentIndex: _currentView.currentIndex
- property int initialIndex: 0
-
- // Aliases
-
- property alias leftPadding: view.leftPadding
- property alias rightPadding: view.rightPadding
-
- property alias model: artistModel
-
- property alias _currentView: view.currentItem
-
- onInitialIndexChanged: resetFocus()
+ readonly property int currentIndex: Helpers.get(currentItem, "currentIndex", - 1)
signal requestArtistAlbumView(int reason)
- function resetFocus() {
- if (artistModel.count === 0)
- return
-
- var initialIndex = root.initialIndex
- if (initialIndex >= artistModel.count)
- initialIndex = 0
- selectionModel.select(artistModel.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
- if (_currentView) {
- _currentView.currentIndex = initialIndex
- _currentView.positionViewAtIndex(initialIndex, ItemView.Contain)
- }
- }
-
- function setCurrentItemFocus(reason) {
- _currentView.setCurrentItemFocus(reason);
- }
-
- function _onNavigationCancel() {
- if (_currentView.currentIndex <= 0) {
- root.Navigation.defaultNavigationCancel()
- } else {
- _currentView.currentIndex = 0;
- _currentView.positionViewAtIndex(0, ItemView.Contain);
- }
- }
-
- MLArtistModel {
+ model: MLArtistModel {
id: artistModel
ml: MediaLib
-
- onCountChanged: {
- if (artistModel.count > 0 && !selectionModel.hasSelection) {
- root.resetFocus()
- }
- }
}
- Util.SelectableDelegateModel {
- id: selectionModel
- model: artistModel
- }
+ grid: gridComponent
+ list: tableComponent
+ emptyLabel: emptyLabelComponent
Util.MLContextMenu {
id: contextMenu
@@ -114,7 +66,6 @@ FocusScope {
MainInterface.MainGridView {
id: artistGrid
- anchors.fill: parent
topMargin: VLCStyle.margin_large
selectionDelegateModel: selectionModel
model: artistModel
@@ -123,13 +74,12 @@ FocusScope {
cellHeight: VLCStyle.gridItem_music_height
Navigation.parentItem: root
- Navigation.cancelAction: root._onNavigationCancel
onActionAtIndex: {
if (selectionModel.selectedIndexes.length > 1) {
MediaLib.addAndPlay( artistModel.getIdsForIndexes( selectionModel.selectedIndexes ) )
} else {
- _currentView.currentIndex = index
+ currentIndex = index
requestArtistAlbumView(Qt.TabFocusReason)
}
}
@@ -214,7 +164,6 @@ FocusScope {
}
}]
- anchors.fill: parent
selectionDelegateModel: selectionModel
model: artistModel
focus: true
@@ -223,13 +172,13 @@ FocusScope {
headerTopPadding: VLCStyle.margin_normal
Navigation.parentItem: root
- Navigation.cancelAction: root._onNavigationCancel
onActionForSelection: {
if (selection.length > 1) {
MediaLib.addAndPlay( artistModel.getIdsForIndexes( selection ) )
} else if ( selection.length === 1) {
requestArtistAlbumView(Qt.TabFocusReason)
+ // FIX ME - requestArtistAlbumView will destroy this view
MediaLib.addAndPlay( artistModel.getIdForIndex( selection[0] ) )
}
}
@@ -250,33 +199,13 @@ FocusScope {
}
}
- Widgets.StackViewExt {
- id: view
-
- anchors.fill: parent
-
- visible: artistModel.count > 0
- focus: artistModel.count > 0
- initialItem: MainCtx.gridView ? gridComponent : tableComponent
- }
+ Component {
+ id: emptyLabelComponent
- Connections {
- target: MainCtx
- onGridViewChanged: {
- if (MainCtx.gridView) {
- view.replace(gridComponent)
- } else {
- view.replace(tableComponent)
- }
+ EmptyLabelButton {
+ text: I18n.qtr("No artists found\nPlease try adding sources, by going to the Browse tab")
+ Navigation.parentItem: root
+ cover: VLCStyle.noArtArtistCover
}
}
-
- EmptyLabelButton {
- anchors.fill: parent
- visible: artistModel.isReady && (artistModel.count <= 0)
- focus: visible
- text: I18n.qtr("No artists found\nPlease try adding sources, by going to the Browse tab")
- Navigation.parentItem: root
- cover: VLCStyle.noArtArtistCover
- }
}
=====================================
modules/gui/qt/medialibrary/qml/MusicGenres.qml
=====================================
@@ -19,15 +19,17 @@ import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Templates 2.4 as T
import QtQml.Models 2.2
+
import org.videolan.vlc 0.1
import org.videolan.medialib 0.1
import "qrc:///util/" as Util
import "qrc:///widgets/" as Widgets
import "qrc:///main/" as MainInterface
+import "qrc:///util/Helpers.js" as Helpers
import "qrc:///style/"
-FocusScope {
+MainInterface.MainViewLoader {
id: root
// Properties
@@ -36,47 +38,18 @@ FocusScope {
{ text: I18n.qtr("Alphabetic"), criteria: "title" }
]
- readonly property var currentIndex: _currentView.currentIndex
-
- //the index to "go to" when the view is loaded
- property int initialIndex: 0
-
- // Aliases
-
- property alias leftPadding: view.leftPadding
- property alias rightPadding: view.rightPadding
+ readonly property var currentIndex: Helpers.get(currentItem, "currentIndex", - 1)
- property alias model: genreModel
-
- property alias _currentView: view.currentItem
+ // FIXME: remove this
+ property var _currentView: currentItem
signal showAlbumView(var id, string name, int reason)
- onInitialIndexChanged: resetFocus()
-
- function loadView() {
- if (MainCtx.gridView) {
- view.replace(gridComponent)
- } else {
- view.replace(tableComponent)
- }
- }
-
- function resetFocus() {
- if (genreModel.count === 0) {
- return
- }
- var initialIndex = root.initialIndex
- if (initialIndex >= genreModel.count)
- initialIndex = 0
- selectionModel.select(genreModel.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
- if (_currentView)
- _currentView.positionViewAtIndex(initialIndex, ItemView.Contain)
- }
+ model: genreModel
- function setCurrentItemFocus(reason) {
- _currentView.setCurrentItemFocus(reason);
- }
+ list: tableComponent
+ grid: gridComponent
+ emptyLabel: emptyLabelComponent
MLGenreModel {
id: genreModel
@@ -101,12 +74,6 @@ FocusScope {
}
}
- Util.SelectableDelegateModel {
- id: selectionModel
-
- model: genreModel
- }
-
Widgets.MLDragItem {
id: genreDragItem
@@ -125,10 +92,11 @@ FocusScope {
onActiveFocusChanged: {
if (activeFocus && genreModel.count > 0 && !selectionModel.hasSelection) {
var initialIndex = 0
- if (_currentView.currentIndex !== -1)
- initialIndex = _currentView.currentIndex
+ if (currentIndex !== -1)
+ initialIndex = currentIndex
+
selectionModel.select(genreModel.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
- _currentView.currentIndex = initialIndex
+ currentItem.currentIndex = initialIndex
}
}
@@ -221,12 +189,6 @@ FocusScope {
onActionAtIndex: _actionAtIndex(index)
Navigation.parentItem: root
- Navigation.cancelAction: function() {
- if (_currentView.currentIndex <= 0)
- root.Navigation.defaultNavigationCancel()
- else
- _currentView.currentIndex = 0;
- }
}
}
@@ -289,12 +251,6 @@ FocusScope {
focus: true
onActionForSelection: _actionAtIndex(selection)
Navigation.parentItem: root
- Navigation.cancelAction: function() {
- if (_currentView.currentIndex <= 0)
- root.Navigation.defaultNavigationCancel()
- else
- _currentView.currentIndex = 0;
- }
dragItem: genreDragItem
rowHeight: VLCStyle.tableCoverRow_height
headerTopPadding: VLCStyle.margin_normal
@@ -319,33 +275,14 @@ FocusScope {
}
}
- Widgets.StackViewExt {
- id: view
-
- anchors.fill: parent
-
- initialItem: MainCtx.gridView ? gridComponent : tableComponent
- focus: genreModel.count !== 0
- }
+ Component {
+ id: emptyLabelComponent
- Connections {
- target: MainCtx
- onGridViewChanged: {
- if (MainCtx.gridView) {
- view.replace(gridComponent)
- } else {
- view.replace(tableComponent)
- }
+ EmptyLabelButton {
+ text: I18n.qtr("No genres found\nPlease try adding sources, by going to the Browse tab")
+ Navigation.parentItem: root
+ cover: VLCStyle.noArtAlbumCover
}
}
-
- EmptyLabelButton {
- anchors.fill: parent
- visible: genreModel.isReady && (genreModel.count <= 0)
- focus: visible
- text: I18n.qtr("No genres found\nPlease try adding sources, by going to the Browse tab")
- Navigation.parentItem: root
- cover: VLCStyle.noArtAlbumCover
- }
}
=====================================
modules/gui/qt/medialibrary/qml/MusicPlaylistsDisplay.qml
=====================================
@@ -102,7 +102,6 @@ Widgets.PageLoader {
History.push(["mc", "music", "playlists", "list",
{ parentId: model.id, name: model.name }]);
- stackView.currentItem.setCurrentItemFocus(reason);
}
}
}
=====================================
modules/gui/qt/medialibrary/qml/PlaylistMediaList.qml
=====================================
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (C) 2021 VLC authors and VideoLAN
+ * Copyright (C) 2021-23 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
@@ -27,9 +27,10 @@ import org.videolan.vlc 0.1
import "qrc:///widgets/" as Widgets
import "qrc:///main/" as MainInterface
import "qrc:///util/" as Util
+import "qrc:///util/Helpers.js" as Helpers
import "qrc:///style/"
-FocusScope {
+MainInterface.MainViewLoader {
id: root
//---------------------------------------------------------------------------------------------
@@ -38,9 +39,7 @@ FocusScope {
property bool isMusic: false
- readonly property int currentIndex: _currentView.currentIndex
-
- property int initialIndex: 0
+ readonly property int currentIndex: Helpers.get(currentItem, "currentIndex", -1)
property var sortModel: [{ text: I18n.qtr("Alphabetic"), criteria: "title" }]
@@ -62,16 +61,8 @@ FocusScope {
property string _placeHolder: (isMusic) ? VLCStyle.noArtAlbumCover
: VLCStyle.noArtVideoCover
- //---------------------------------------------------------------------------------------------
- // Alias
- //---------------------------------------------------------------------------------------------
-
- property alias leftPadding: view.leftPadding
- property alias rightPadding: view.rightPadding
-
- property alias model: model
-
- property alias _currentView: view.currentItem
+ // FIXME: remove this
+ property var _currentView: currentItem
//---------------------------------------------------------------------------------------------
// Signals
@@ -84,75 +75,44 @@ FocusScope {
//---------------------------------------------------------------------------------------------
// NOTE: Define the initial position and selection. This is done on activeFocus rather than
- // Component.onCompleted because modelSelect.selectedGroup update itself after this
+ // Component.onCompleted because selectionModel.selectedGroup update itself after this
// event.
onActiveFocusChanged: {
- if (activeFocus == false || model.count === 0 || modelSelect.hasSelection)
+ if (activeFocus == false || model.count === 0 || selectionModel.hasSelection)
return;
- var initialIndex = 0;
-
- if (_currentView.currentIndex !== -1) {
- initialIndex = _currentView.currentIndex;
- }
-
- modelSelect.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect);
-
- _currentView.currentIndex = initialIndex;
+ resetFocus()
}
- onInitialIndexChanged: resetFocus()
//---------------------------------------------------------------------------------------------
- // Connections
- //---------------------------------------------------------------------------------------------
-
- Connections {
- target: MainCtx
-
- onGridViewChanged: {
- if (MainCtx.gridView) view.replace(grid);
- else view.replace(table);
- }
- }
-
- //---------------------------------------------------------------------------------------------
- // Functions
- //---------------------------------------------------------------------------------------------
-
- function resetFocus() {
- if (model.count === 0)
- return;
+ // Private
- var initialIndex = root.initialIndex;
+ grid: grid
+ list: table
+ emptyLabel: emptyLabel
- if (initialIndex >= model.count)
- initialIndex = 0;
+ model: MLPlaylistListModel {
+ ml: MediaLib
- modelSelect.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect);
+ coverSize: (isMusic) ? Qt.size(512, 512)
+ : Qt.size(1024, 640)
- if (_currentView)
- _currentView.positionViewAtIndex(initialIndex, ItemView.Contain);
- }
+ coverDefault: root._placeHolder
- function setCurrentItemFocus(reason) {
- _currentView.setCurrentItemFocus(reason);
+ coverPrefix: (isMusic) ? "playlist-music" : "playlist-video"
}
- //---------------------------------------------------------------------------------------------
- // Private
-
function _actionAtIndex() {
- if (modelSelect.selectedIndexes.length > 1) {
- MediaLib.addAndPlay(model.getIdsForIndexes(modelSelect.selectedIndexes));
- } else if (modelSelect.selectedIndexes.length === 1) {
- var index = modelSelect.selectedIndexes[0];
+ if (root.selectionModel.selectedIndexes.length > 1) {
+ MediaLib.addAndPlay(model.getIdsForIndexes(selectionModel.selectedIndexes));
+ } else if (root.selectionModel.selectedIndexes.length === 1) {
+ var index = selectionModel.selectedIndexes[0];
showList(model.getDataAt(index), Qt.TabFocusReason);
}
}
- function _getCount(model)
- {
+ function _getCount(model) {
var count = model.count;
if (count < 100)
@@ -161,55 +121,17 @@ FocusScope {
return I18n.qtr("99+");
}
- function _onNavigationCancel() {
- if (_currentView.currentIndex <= 0) {
- Navigation.defaultNavigationCancel()
- } else {
- _currentView.currentIndex = 0;
- _currentView.positionViewAtIndex(0, ItemView.Contain);
- }
- }
-
//---------------------------------------------------------------------------------------------
// Childs
//---------------------------------------------------------------------------------------------
- MLPlaylistListModel {
- id: model
-
- ml: MediaLib
-
- coverSize: (isMusic) ? Qt.size(512, 512)
- : Qt.size(1024, 640)
-
- coverDefault: root._placeHolder
-
- coverPrefix: (isMusic) ? "playlist-music" : "playlist-video"
-
- onCountChanged: {
- if (count === 0 || modelSelect.hasSelection)
- return;
-
- resetFocus();
- }
- }
-
- Widgets.StackViewExt {
- id: view
-
- anchors.fill: parent
-
- initialItem: (MainCtx.gridView) ? grid : table
-
- focus: (model.count !== 0)
- }
Widgets.MLDragItem {
id: dragItemPlaylist
mlModel: model
- indexes: modelSelect.selectedIndexes
+ indexes: selectionModel.selectedIndexes
coverRole: "thumbnail"
@@ -218,12 +140,6 @@ FocusScope {
titleRole: "name"
}
- Util.SelectableDelegateModel {
- id: modelSelect
-
- model: root.model
- }
-
PlaylistListContextMenu {
id: contextMenu
@@ -247,12 +163,10 @@ FocusScope {
model: root.model
- selectionDelegateModel: modelSelect
+ selectionDelegateModel: selectionModel
Navigation.parentItem: root
- Navigation.cancelAction: root._onNavigationCancel
-
delegate: VideoGridItem {
//---------------------------------------------------------------------------------
// Properties
@@ -288,7 +202,7 @@ FocusScope {
onContextMenuButtonClicked: {
gridView.rightClickOnItem(index);
- contextMenu.popup(modelSelect.selectedIndexes, globalMousePos);
+ contextMenu.popup(selectionModel.selectedIndexes, globalMousePos);
}
//---------------------------------------------------------------------------------
@@ -301,13 +215,13 @@ FocusScope {
// Events
// NOTE: Define the initial position and selection. This is done on activeFocus rather
- // than Component.onCompleted because modelSelect.selectedGroup update itself
+ // than Component.onCompleted because selectionModel.selectedGroup update itself
// after this event.
onActiveFocusChanged: {
- if (activeFocus == false || model.count === 0 || modelSelect.hasSelection)
+ if (activeFocus == false || model.count === 0 || selectionModel.hasSelection)
return;
- modelSelect.select(model.index(0,0), ItemSelectionModel.ClearAndSelect)
+ selectionModel.select(model.index(0,0), ItemSelectionModel.ClearAndSelect)
}
onActionAtIndex: _actionAtIndex()
@@ -383,12 +297,11 @@ FocusScope {
sortModel: (availableRowWidth < VLCStyle.colWidth(4)) ? _modelSmall
: _modelMedium
- selectionDelegateModel: modelSelect
+ selectionDelegateModel: selectionModel
dragItem: dragItemPlaylist
Navigation.parentItem: root
- Navigation.cancelAction: root._onNavigationCancel
//-------------------------------------------------------------------------------------
// Events
@@ -397,10 +310,10 @@ FocusScope {
onItemDoubleClicked: showList(model, Qt.MouseFocusReason)
- onContextMenuButtonClicked: contextMenu.popup(modelSelect.selectedIndexes,
+ onContextMenuButtonClicked: contextMenu.popup(selectionModel.selectedIndexes,
globalMousePos)
- onRightClick: contextMenu.popup(modelSelect.selectedIndexes, globalMousePos)
+ onRightClick: contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
//-------------------------------------------------------------------------------------
// Childs
@@ -435,16 +348,18 @@ FocusScope {
}
}
- EmptyLabelHint {
- anchors.fill: parent
+ Component {
+ id: emptyLabel
- visible: (model.count === 0)
+ EmptyLabelHint {
+ visible: (model.count === 0)
- focus: visible
+ focus: true
- text: I18n.qtr("No playlists found")
- hint: I18n.qtr("Right click on a media to add it to a playlist")
+ text: I18n.qtr("No playlists found")
+ hint: I18n.qtr("Right click on a media to add it to a playlist")
- cover: VLCStyle.noArtAlbumCover
+ cover: VLCStyle.noArtAlbumCover
+ }
}
}
=====================================
modules/gui/qt/medialibrary/qml/VideoAll.qml
=====================================
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (C) 2021 VLC authors and VideoLAN
+ * Copyright (C) 2021-23 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
@@ -30,23 +30,19 @@ import "qrc:///util/" as Util
import "qrc:///util/Helpers.js" as Helpers
import "qrc:///style/"
-FocusScope {
+MainInterface.MainViewLoader {
id: root
// Properties
- readonly property int contentMargin: (_currentView) ? _currentView.contentLeftMargin : 0
+ readonly property int contentMargin: Helpers.get(currentItem, "contentLeftMargin", 0)
// NOTE: Specify an optional header for the view.
property Component header: null
- property Item headerItem: (_currentView) ? _currentView.headerItem : null
+ property Item headerItem: Helpers.get(currentItem, "headerItem", null)
- readonly property int currentIndex: _currentView.currentIndex
-
- property int initialIndex: 0
-
- /* required */ property var model
+ readonly property int currentIndex: Helpers.get(currentItem, "currentIndex", -1)
// NOTE: The ContextMenu depends on the model so we have to provide it too.
/* required */ property var contextMenu
@@ -56,69 +52,12 @@ FocusScope {
{ text: I18n.qtr("Duration"), criteria: "duration" }
]
- // Aliases
-
- property alias leftPadding: view.leftPadding
- property alias rightPadding: view.rightPadding
-
property alias dragItem: dragItem
- // Private
-
- property alias _currentView: view.currentItem
-
- // Events
-
- onModelChanged: resetFocus()
-
- onInitialIndexChanged: resetFocus()
-
- // Connections
-
- Connections {
- target: MainCtx
-
- onGridViewChanged: {
- if (MainCtx.gridView) view.replace(grid)
- else view.replace(list)
- }
- }
-
- Connections {
- target: model
-
- onCountChanged: {
- if (model.count === 0 || modelSelect.hasSelection)
- return;
-
- resetFocus();
- }
- }
-
- // Functions
-
- function setCurrentItemFocus(reason) {
- _currentView.setCurrentItemFocus(reason);
- }
-
- function resetFocus() {
- if (!model || model.count === 0) return
-
- var initialIndex = root.initialIndex
-
- if (initialIndex >= model.count)
- initialIndex = 0
+ list: list
+ grid: grid
+ emptyLabel: emptylabel
- modelSelect.select(model.index(initialIndex, 0), ItemSelectionModel.ClearAndSelect)
-
- if (_currentView) {
- _currentView.positionViewAtIndex(initialIndex, ItemView.Contain)
-
- // Table View require this for focus handling
- if (!MainCtx.gridView)
- _currentView.currentIndex = initialIndex
- }
- }
function getLabel(model) {
if (!model) return ""
@@ -158,51 +97,18 @@ FocusScope {
Navigation.defaultNavigationUp()
}
- function _onNavigationCancel() {
- if (_currentView.currentIndex <= 0) {
- Navigation.defaultNavigationCancel()
- } else {
- _currentView.currentIndex = 0
-
- _currentView.positionViewAtIndex(0, ItemView.Contain)
- }
- }
-
- // Children
-
- readonly property ColorContext colorContext: ColorContext {
- id: theme
- colorSet: ColorContext.View
- }
-
- Widgets.StackViewExt {
- id: view
-
- anchors.fill: parent
-
- focus: (model.count !== 0)
-
- initialItem: (MainCtx.gridView) ? grid : list
- }
-
Widgets.MLDragItem {
id: dragItem
mlModel: root.model
- indexes: modelSelect.selectedIndexes
+ indexes: selectionModel.selectedIndexes
coverRole: "thumbnail"
defaultCover: VLCStyle.noArtVideoCover
}
- Util.SelectableDelegateModel {
- id: modelSelect
-
- model: root.model
- }
-
Component {
id: grid
@@ -218,7 +124,7 @@ FocusScope {
model: root.model
- selectionDelegateModel: modelSelect
+ selectionDelegateModel: selectionModel
headerDelegate: root.header
@@ -230,22 +136,19 @@ FocusScope {
Navigation.upAction: _onNavigationUp
- // NOTE: cancelAction takes a function, we pass it directly.
- Navigation.cancelAction: root._onNavigationCancel
-
// Events
// NOTE: Define the initial position and selection. This is done on activeFocus rather
- // than Component.onCompleted because modelSelect.selectedGroup update itself
+ // than Component.onCompleted because selectionModel.selectedGroup update itself
// after this event.
onActiveFocusChanged: {
- if (activeFocus == false || model.count === 0 || modelSelect.hasSelection)
+ if (activeFocus == false || model.count === 0 || selectionModel.hasSelection)
return;
resetFocus() // restores initialIndex
}
- onActionAtIndex: root.onAction(modelSelect.selectedIndexes)
+ onActionAtIndex: root.onAction(selectionModel.selectedIndexes)
// Connections
@@ -296,7 +199,7 @@ FocusScope {
if (root.isInfoExpandPanelAvailable(model))
options["information"] = index
- root.contextMenu.popup(modelSelect.selectedIndexes, globalMousePos, options);
+ root.contextMenu.popup(selectionModel.selectedIndexes, globalMousePos, options);
}
// Animations
@@ -336,7 +239,7 @@ FocusScope {
model: root.model
- selectionDelegateModel: modelSelect
+ selectionDelegateModel: selectionModel
dragItem: root.dragItem
@@ -354,18 +257,15 @@ FocusScope {
Navigation.upAction: _onNavigationUp
- //cancelAction takes a *function* pass it directly
- Navigation.cancelAction: root._onNavigationCancel
-
// Events
- onActionForSelection: root.onAction(modelSelect.selectedIndexes)
+ onActionForSelection: root.onAction(selectionModel.selectedIndexes)
onItemDoubleClicked: root.onDoubleClick(model)
- onContextMenuButtonClicked: root.contextMenu.popup(modelSelect.selectedIndexes, globalMousePos)
+ onContextMenuButtonClicked: root.contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
- onRightClick: root.contextMenu.popup(modelSelect.selectedIndexes, globalMousePos)
+ onRightClick: root.contextMenu.popup(selectionModel.selectedIndexes, globalMousePos)
// Functions
@@ -373,20 +273,20 @@ FocusScope {
}
}
- EmptyLabelButton {
- anchors.fill: parent
-
- coverWidth : VLCStyle.dp(182, VLCStyle.scale)
- coverHeight: VLCStyle.dp(114, VLCStyle.scale)
+ Component {
+ id: emptylabel
- visible: model.isReady && (model.count <= 0)
+ EmptyLabelButton {
+ coverWidth : VLCStyle.dp(182, VLCStyle.scale)
+ coverHeight: VLCStyle.dp(114, VLCStyle.scale)
- focus: visible
+ focus: true
- text: I18n.qtr("No video found\nPlease try adding sources, by going to the Browse tab")
+ text: I18n.qtr("No video found\nPlease try adding sources, by going to the Browse tab")
- cover: VLCStyle.noArtVideoCover
+ cover: VLCStyle.noArtVideoCover
- Navigation.parentItem: root
+ Navigation.parentItem: root
+ }
}
}
=====================================
modules/gui/qt/medialibrary/qml/VideoAllSubDisplay.qml
=====================================
@@ -91,7 +91,7 @@ VideoAll {
if (headerItem && headerItem.focus)
headerItem.forceActiveFocus(reason)
else
- _currentView.setCurrentItemFocus(reason)
+ currentItem.setCurrentItemFocus(reason)
}
// VideoAll events reimplementation
@@ -234,7 +234,7 @@ VideoAll {
Navigation.parentItem: root
Navigation.downAction: function() {
- _currentView.setCurrentItemFocus(Qt.TabFocusReason);
+ currentItem.setCurrentItemFocus(Qt.TabFocusReason)
}
onImplicitHeightChanged: {
=====================================
modules/gui/qt/medialibrary/qml/VideoPlaylistsDisplay.qml
=====================================
@@ -102,8 +102,6 @@ Widgets.PageLoader {
onShowList: {
History.push(["mc", "video", "playlists", "list",
{ parentId: model.id, name: model.name }]);
-
- stackView.currentItem.setCurrentItemFocus(reason);
}
}
}
=====================================
modules/gui/qt/util/qml/Helpers.js
=====================================
@@ -30,7 +30,7 @@ function isValidInstanceOf(object, type) {
// If the hash contains no item with the key,
// or the value is invalid, returns defaultValue
function get(dict, key, defaultValue) {
- var v = typeof dict !== "undefined" ? dict[key] : undefined
+ var v = typeof dict !== "undefined" && !!dict ? dict[key] : undefined
return typeof v === "undefined" ? defaultValue : v
}
=====================================
modules/gui/qt/vlc.qrc
=====================================
@@ -151,6 +151,7 @@
<file alias="NoMedialibHome.qml">maininterface/qml/NoMedialibHome.qml</file>
<file alias="MainTableView.qml">maininterface/qml/MainTableView.qml</file>
<file alias="MainGridView.qml">maininterface/qml/MainGridView.qml</file>
+ <file alias="MainViewLoader.qml">maininterface/qml/MainViewLoader.qml</file>
</qresource>
<qresource prefix="/widgets">
<file alias="ActionButtonOverlay.qml">widgets/qml/ActionButtonOverlay.qml</file>
=====================================
modules/gui/qt/widgets/native/navigation_attached.cpp
=====================================
@@ -36,9 +36,16 @@ void NavigationAttached::defaultNavigationGeneric(QJSValue& jsCallback, QQuickIt
Qt::FocusReason reason)
{
if (jsCallback.isCallable()) {
- jsCallback.call();
+ const auto ret = jsCallback.call();
+
+ // if the function returns nothing or true, the action has been handled, stop the traversal
+ // if the function returns a false explictly, continue traversal
+ if (!ret.isBool() || ret.toBool())
+ return;
}
- else if (directionItem)
+
+
+ if (directionItem)
{
NavigationAttached* nextItem = qobject_cast<NavigationAttached*>(qmlAttachedPropertiesObject<NavigationAttached>(directionItem));
if (directionItem->isVisible()
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/869a03432a03189e31338827ad5dd56aa900a7a5...f5d795355e4dab5e4d8853a042aba038c3332fa0
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/869a03432a03189e31338827ad5dd56aa900a7a5...f5d795355e4dab5e4d8853a042aba038c3332fa0
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list