[vlc-commits] [Git][videolan/vlc][master] 18 commits: qml/ExpandGridView: Fix keyboard navigation issue
Steve Lhomme (@robUx4)
gitlab at videolan.org
Mon Oct 31 06:30:53 UTC 2022
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
168f6a65 by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml/ExpandGridView: Fix keyboard navigation issue
When pressing down on the last row we were selecting the last item of the list.
- - - - -
5667dfff by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml/ExpandGridView: Add the 'getItemY' function
Also make rowHeight and nbItemPerRow public, that's useful to determine the Grid item position.
- - - - -
cdee0d9c by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml/KeyNavigableListView: Refactor the settings
- - - - -
ecb58f6c by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml/KeyNavigableTableView: Add the 'getItemY' function
- - - - -
bab34f45 by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml/NetworkGridItem: Add the 'ExpandGridView' delegate default properties
- - - - -
67a50339 by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml/TextToolButton: Add Navigation support
- - - - -
1cec54ff by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml: Create BrowseDeviceHeader
- - - - -
d2b9b5a3 by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml: Create BrowseDeviceView
- - - - -
b87baae8 by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml/NetworkHomeDisplay: Update to 'BrowseDeviceView' implementation
- - - - -
3e2a7075 by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml: Remove NetworkHomeDeviceListView
- - - - -
b77ac7f9 by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml/NetworkDisplay: Add the 'device' page
This will display the extended view for a given device category.
- - - - -
c68b00c8 by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml: Rename NetworkDisplay to BrowseDisplay
- - - - -
b46d7035 by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml: Rename NetworkHomeDisplay to BrowseHomeDisplay
- - - - -
a6316701 by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml: Rename NetworkBrowseDisplay to BrowseTreeDisplay
- - - - -
35c5994c by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml/BrowseTreeDisplay: Update 'cancelAction' implementation
- - - - -
91ff23c1 by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml/BrowseDisplay: Update 'browseComponent' cancel implementation
- - - - -
2b01be3b by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qt/sortfilterproxymodel: Remove unused m_sortOrder
- - - - -
8e16f8dd by Benjamin Arnaud at 2022-10-31T06:04:14+00:00
qml/NetworkCustomCover: Handle null model
- - - - -
17 changed files:
- modules/gui/qt/Makefile.am
- modules/gui/qt/maininterface/qml/MainDisplay.qml
- modules/gui/qt/network/qml/NetworkHomeDeviceListView.qml â modules/gui/qt/network/qml/BrowseDeviceHeader.qml
- + modules/gui/qt/network/qml/BrowseDeviceView.qml
- modules/gui/qt/network/qml/NetworkDisplay.qml â modules/gui/qt/network/qml/BrowseDisplay.qml
- modules/gui/qt/network/qml/NetworkHomeDisplay.qml â modules/gui/qt/network/qml/BrowseHomeDisplay.qml
- modules/gui/qt/network/qml/NetworkBrowseDisplay.qml â modules/gui/qt/network/qml/BrowseTreeDisplay.qml
- modules/gui/qt/network/qml/NetworkCustomCover.qml
- modules/gui/qt/network/qml/NetworkGridItem.qml
- modules/gui/qt/network/qml/ServicesHomeDisplay.qml
- modules/gui/qt/util/sortfilterproxymodel.hpp
- modules/gui/qt/vlc.qrc
- modules/gui/qt/widgets/qml/ExpandGridView.qml
- modules/gui/qt/widgets/qml/KeyNavigableListView.qml
- modules/gui/qt/widgets/qml/KeyNavigableTableView.qml
- modules/gui/qt/widgets/qml/TextToolButton.qml
- po/POTFILES.in
Changes:
=====================================
modules/gui/qt/Makefile.am
=====================================
@@ -848,15 +848,16 @@ libqt_plugin_la_QML = \
gui/qt/menus/qml/Menubar.qml \
gui/qt/menus/qml/ShortcutExt.qml \
gui/qt/network/qml/AddressbarButton.qml \
+ gui/qt/network/qml/BrowseDeviceHeader.qml \
+ gui/qt/network/qml/BrowseDeviceView.qml \
+ gui/qt/network/qml/BrowseDisplay.qml \
+ gui/qt/network/qml/BrowseHomeDisplay.qml \
+ gui/qt/network/qml/BrowseTreeDisplay.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/NetworkCustomCover.qml \
- gui/qt/network/qml/NetworkDisplay.qml \
gui/qt/network/qml/NetworkGridItem.qml \
- gui/qt/network/qml/NetworkHomeDisplay.qml \
- gui/qt/network/qml/NetworkHomeDeviceListView.qml \
gui/qt/network/qml/NetworkListItem.qml \
gui/qt/network/qml/NetworkThumbnailItem.qml \
gui/qt/network/qml/ServicesHomeDisplay.qml \
=====================================
modules/gui/qt/maininterface/qml/MainDisplay.qml
=====================================
@@ -161,7 +161,7 @@ FocusScope {
displayText: I18n.qtr("Browse"),
icon: VLCIcons.topbar_network,
name: "network",
- url: "qrc:///network/NetworkDisplay.qml"
+ url: "qrc:///network/BrowseDisplay.qml"
}, {
listed: true,
displayText: I18n.qtr("Discover"),
=====================================
modules/gui/qt/network/qml/NetworkHomeDeviceListView.qml â modules/gui/qt/network/qml/BrowseDeviceHeader.qml
=====================================
@@ -1,6 +1,8 @@
/*****************************************************************************
* Copyright (C) 2020 VLC authors and VideoLAN
*
+ * Authors: Benjamin Arnaud <bunjee at omega.gg>
+ *
* 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
@@ -15,108 +17,73 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
+
import QtQuick 2.11
-import QtQuick.Controls 2.4
-import QtQml.Models 2.2
+import QtQuick.Layouts 1.11
import org.videolan.vlc 0.1
-import "qrc:///widgets/" as Widgets
-import "qrc:///util/" as Util
import "qrc:///style/"
+import "qrc:///widgets/" as Widgets
FocusScope {
id: root
- height: deviceListView.implicitHeight
+ // Properties
- property alias ctx: deviceModel.ctx
- property alias sd_source: deviceModel.sd_source
- property alias model: deviceModel
- property int leftPadding: VLCStyle.margin_xlarge
+ /* required */ property var view
- property int _currentIndex: -1
+ // Aliases
- signal browse(var tree, int reason)
+ property alias text: label.text
- on_CurrentIndexChanged: {
- deviceListView.currentIndex = _currentIndex
- }
+ property alias label: label
+ property alias button: button
- function setCurrentItemFocus(reason) {
- deviceListView.setCurrentItemFocus(reason);
- }
+ // Signals
- function _actionAtIndex(index, model, selectionModel) {
- var data = model.getDataAt(index);
+ signal clicked(int reason)
- if (data.type === NetworkMediaModel.TYPE_DIRECTORY
- ||
- data.type === NetworkMediaModel.TYPE_NODE)
- browse(data.tree, Qt.TabFocusReason);
- else
- model.addAndPlay( selectionModel.selectedIndexes);
- }
+ // Settings
- onFocusChanged: {
- if (activeFocus && root._currentIndex === -1 && deviceModel.count > 0)
- root._currentIndex = 0
- }
+ width: view.width
+ height: label.height
- NetworkDeviceModel {
- id: deviceModel
+ Navigation.navigable: button.visible
- source_name: "*"
- }
+ // Children
- Util.SelectableDelegateModel {
- id: deviceSelection
- model: deviceModel
- }
+ RowLayout {
+ id: row
- Widgets.KeyNavigableListView {
- id: deviceListView
+ anchors.fill: parent
- focus: true
+ anchors.leftMargin: root.view.contentMargin
+ anchors.rightMargin: anchors.leftMargin
- currentIndex: root._currentIndex
+ Widgets.SubtitleLabel {
+ id: label
- implicitHeight: VLCStyle.gridItem_network_height + VLCStyle.gridItemSelectedBorder + VLCStyle.margin_large
- orientation: ListView.Horizontal
- anchors.fill: parent
- spacing: VLCStyle.column_margin_width
+ Layout.fillWidth: true
- header: Item {
- width: root.leftPadding
+ topPadding: VLCStyle.margin_large
+ bottomPadding: VLCStyle.margin_normal
}
- model: deviceModel
- delegate: NetworkGridItem {
+ Widgets.TextToolButton {
+ id: button
+
+ Layout.preferredWidth: implicitWidth
+
focus: true
- x: selectedBorderWidth
- y: selectedBorderWidth
-
- onItemClicked : {
- deviceSelection.updateSelection( modifier , deviceSelection.currentIndex, index)
- root._currentIndex = index
- forceActiveFocus()
- }
-
- onPlayClicked: deviceModel.addAndPlay( index )
-
- onItemDoubleClicked: {
- if (model.type === NetworkMediaModel.TYPE_NODE
- ||
- model.type === NetworkMediaModel.TYPE_DIRECTORY)
- browse(model.tree, Qt.MouseFocusReason);
- else
- deviceModel.addAndPlay(index);
- }
- }
- onActionAtIndex: {
- _actionAtIndex(index, deviceModel, deviceSelection)
+ text: I18n.qtr("See All")
+
+ font.pixelSize: VLCStyle.fontSize_large
+
+ Navigation.parentItem: root
+
+ onClicked: root.clicked(focusReason)
}
- Navigation.parentItem: root
}
}
=====================================
modules/gui/qt/network/qml/BrowseDeviceView.qml
=====================================
@@ -0,0 +1,379 @@
+/*****************************************************************************
+ * Copyright (C) 2020 VLC authors and VideoLAN
+ *
+ * Authors: Benjamin Arnaud <bunjee at omega.gg>
+ *
+ * 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 org.videolan.vlc 0.1
+
+import "qrc:///style/"
+import "qrc:///main/" as MainInterface
+import "qrc:///widgets/" as Widgets
+import "qrc:///util/" as Util
+
+FocusScope {
+ id: root
+
+ // Properties
+
+ /* required */ property var model
+
+ property var parentFilter: null
+
+ readonly property int rowHeight: (_currentView) ? _currentView.rowHeight : 0
+
+ readonly property int contentHeight: (_currentView) ? _currentView.contentHeight : 0
+
+ readonly property int contentMargin: (_currentView) ? _currentView.contentMargin : 0
+
+ property int displayMarginEnd: 0
+
+ readonly property int currentIndex: (_currentView) ? _currentView.currentIndex : -1
+
+ property int maximumRows: -1
+
+ readonly property int maximumCount: (_currentView) ? _currentView.maximumCount : -1
+
+ readonly property int nbItemPerRow: (_currentView) ? _currentView.nbItemPerRow : 1
+
+ property Component header: BrowseDeviceHeader {
+ view: root
+
+ text: root.title
+
+ button.visible: root.sourceModel.hasMoreItems
+
+ Navigation.parentItem: root
+
+ Navigation.downAction: function() {
+ view.setCurrentItemFocus(Qt.TabFocusReason)
+ }
+
+ onClicked: root.seeAll(reason)
+ }
+
+ property string title
+
+ // Aliases
+
+ property alias modelFilter: modelFilter
+
+ property alias sourceModel: modelFilter.sourceModel
+
+ // Private
+
+ property alias _currentView: view.currentItem
+
+ // Signals
+
+ signal browse(var tree, int reason)
+
+ signal seeAll(int reason)
+
+ // Events
+
+ onFocusChanged: {
+ if (activeFocus === false || model.count === 0 || model.currentIndex !== -1)
+ return
+
+ model.currentIndex = 0
+ }
+
+ onParentFilterChanged: {
+ if (parentFilter === null || sourceModel === null)
+ return
+
+ sourceModel.searchRole = parentFilter.searchRole
+
+ sourceModel.searchPattern = parentFilter.searchPattern
+
+ sourceModel.sortCriteria = parentFilter.sortCriteria
+
+ sourceModel.sortOrder = parentFilter.sortOrder
+ }
+
+ // Connections
+
+ Connections {
+ target: MainCtx
+
+ onGridViewChanged: {
+ if (MainCtx.gridView) view.replace(grid)
+ else view.replace(list)
+ }
+ }
+
+ // NOTE: If it exists, we're applying 'parentFilter' properties to fit the sorting options.
+ Connections {
+ target: parentFilter
+
+ onSearchRoleChanged: sourceModel.searchRole = parentFilter.searchRole
+
+ onSearchPatternChanged: sourceModel.searchPattern = parentFilter.searchPattern
+
+ onSortCriteriaChanged: sourceModel.sortCriteria = parentFilter.sortCriteria
+
+ onSortOrderChanged: sourceModel.sortOrder = parentFilter.sortOrder
+ }
+
+ // Functions
+
+ function playAt(index) {
+ model.addAndPlay(modelFilter.mapIndexToSource(index))
+ }
+
+ function setCurrentItemFocus(reason) {
+ _currentView.setCurrentItemFocus(reason)
+ }
+
+ function getItemY(index) {
+ if (_currentView === null)
+ return 0
+
+ return _currentView.getItemY(index)
+ }
+
+ // Events
+
+ function onAction(index) {
+ var indexes = modelSelect.selectedIndexes
+
+ if (indexes.length > 1) {
+ model.addAndPlay(modelFilter.mapIndexesToSource(indexes))
+
+ return
+ }
+
+ var data = modelFilter.getDataAt(index)
+
+ if (data.type === NetworkMediaModel.TYPE_DIRECTORY
+ ||
+ data.type === NetworkMediaModel.TYPE_NODE)
+ browse(data.tree, Qt.TabFocusReason);
+ else
+ playAt(index);
+ }
+
+ function onClicked(model, index, modifier) {
+ modelSelect.updateSelection(modifier, model.currentIndex, index)
+
+ model.currentIndex = index
+
+ forceActiveFocus()
+ }
+
+ function onDoubleClicked(model, index) {
+ if (model.type === NetworkMediaModel.TYPE_NODE
+ ||
+ model.type === NetworkMediaModel.TYPE_DIRECTORY)
+ browse(model.tree, Qt.MouseFocusReason);
+ else
+ playAt(index);
+ }
+
+ // Children
+
+ Util.SelectableDelegateModel {
+ id: modelSelect
+
+ model: modelFilter
+ }
+
+ SortFilterProxyModel {
+ id: modelFilter
+
+ sourceModel: root.model
+
+ searchRole: "name"
+
+ // TODO: Handle the searchPattern on a partial list.
+ searchPattern: (sourceModel && maximumRows === -1) ? sourceModel.searchPattern : ""
+ }
+
+ Widgets.StackViewExt {
+ id: view
+
+ anchors.fill: parent
+
+ focus: (model.count !== 0)
+
+ initialItem: (MainCtx.gridView) ? grid : list
+ }
+
+ Component {
+ id: grid
+
+ Widgets.ExpandGridView {
+ id: gridView
+
+ readonly property int maximumCount: (root.maximumRows === -1)
+ ? -1
+ : root.maximumRows * nbItemPerRow
+
+ cellWidth: VLCStyle.gridItem_network_width
+ cellHeight: VLCStyle.gridItem_network_height
+
+ displayMarginEnd: root.displayMarginEnd
+
+ model: modelFilter
+
+ headerDelegate: root.header
+
+ selectionDelegateModel: modelSelect
+
+ Navigation.parentItem: root
+
+ Navigation.upItem: headerItem
+
+ onActionAtIndex: root.onAction(index)
+
+ delegate: NetworkGridItem {
+ onItemClicked: root.onClicked(model, index, modifier)
+
+ onItemDoubleClicked: root.onDoubleClicked(model, index)
+
+ onPlayClicked: root.playAt(index)
+ }
+ }
+ }
+
+ Component {
+ id: list
+
+ Widgets.KeyNavigableTableView {
+ id: listView
+
+ readonly property real contentMargin: VLCStyle.margin_normal
+
+ readonly property int maximumCount: root.maximumRows
+
+ readonly property int nbItemPerRow: 1
+
+ readonly property int _nbCols: VLCStyle.gridColumnsForWidth(listView.availableRowWidth)
+
+ readonly property int _nameColSpan: Math.max((_nbCols - 1) / 2, 1)
+
+ rowHeight: VLCStyle.tableCoverRow_height
+
+ displayMarginEnd: root.displayMarginEnd
+
+ model: modelFilter
+
+ sortModel: [{
+ criteria: "artwork",
+
+ width: VLCStyle.colWidth(1),
+
+ headerDelegate: artworkHeader,
+ colDelegate : artworkColumn
+ }, {
+ isPrimary: true,
+ criteria: "name",
+
+ width: VLCStyle.colWidth(listView._nameColSpan),
+
+ text: I18n.qtr("Name")
+ }, {
+ criteria: "mrl",
+
+ width: VLCStyle.colWidth(Math.max(listView._nbCols - listView._nameColSpan - 1), 1),
+
+ text: I18n.qtr("Url"),
+
+ colDelegate: mrlColumn
+ }]
+
+ header: root.header
+
+ headerColor: VLCStyle.colors.bg
+
+ selectionDelegateModel: modelSelect
+
+ Navigation.parentItem: root
+
+ Navigation.upItem: headerItem
+
+ onActionForSelection: root.onAction(selection[0].row)
+
+ onItemDoubleClicked: root.onDoubleClicked(model, index)
+
+ Component {
+ id: artworkHeader
+
+ Item {
+ Widgets.IconLabel {
+ width: VLCStyle.listAlbumCover_width
+ height: VLCStyle.listAlbumCover_height
+
+ horizontalAlignment: Text.AlignHCenter
+
+ color: VLCStyle.colors.caption
+ }
+ }
+ }
+
+ Component {
+ id: artworkColumn
+
+ NetworkThumbnailItem { onPlayClicked: root.playAt(index) }
+ }
+
+ Component {
+ id: mrlColumn
+
+ Widgets.ScrollingText {
+ id: itemText
+
+ property var rowModel: parent.rowModel
+ property var colModel: parent.colModel
+
+ property color foregroundColor: parent.foregroundColor
+
+ width: parent.width
+
+ clip: scrolling
+
+ label: itemLabel
+
+ forceScroll: parent.currentlyFocused
+
+ Widgets.ListLabel {
+ id: itemLabel
+
+ anchors.verticalCenter: parent.verticalCenter
+
+ text: {
+ if (itemText.rowModel === null)
+ return ""
+
+ var text = itemText.rowModel[itemText.colModel.criteria]
+
+ if (text.toString() === "vlc://nop")
+ return ""
+ else
+ return text
+ }
+
+ color: itemText.foregroundColor
+ }
+ }
+ }
+ }
+ }
+}
=====================================
modules/gui/qt/network/qml/NetworkDisplay.qml â modules/gui/qt/network/qml/BrowseDisplay.qml
=====================================
@@ -40,7 +40,10 @@ Widgets.PageLoader {
pageModel: [{
name: "home",
- url: "qrc:///network/NetworkHomeDisplay.qml"
+ url: "qrc:///network/BrowseHomeDisplay.qml"
+ }, {
+ name: "device",
+ component: browseDevice,
}, {
name: "browse",
component: browseComponent,
@@ -61,29 +64,66 @@ Widgets.PageLoader {
||
currentItem.isViewMultiView);
- if (view.name === "browse")
- localMenuDelegate = componentBar
- else
+ if (view.name === "home")
localMenuDelegate = null
+ else
+ localMenuDelegate = componentBar
}
// Connections
+ Connections {
+ target: (stackView.currentItem instanceof BrowseHomeDisplay) ? stackView.currentItem
+ : null
+
+ onSeeAll: {
+ History.push(["mc", "network", "device", { title: title, sd_source: sd_source }])
+
+ stackView.currentItem.setCurrentItemFocus(reason)
+ }
+ }
Connections {
target: stackView.currentItem
onBrowse: {
- History.push(["mc", "network", "browse", { tree: tree }]);
- stackView.currentItem.setCurrentItemFocus(reason);
+ History.push(["mc", "network", "browse", { tree: tree }])
+
+ stackView.currentItem.setCurrentItemFocus(reason)
}
}
// Children
+ Component {
+ id: browseDevice
+
+ BrowseDeviceView {
+ id: viewDevice
+
+ property var sd_source
+
+ property var sortModel: [
+ { text: I18n.qtr("Alphabetic"), criteria: "name" },
+ { text: I18n.qtr("Url"), criteria: "mrl" }
+ ]
+
+ displayMarginEnd: g_mainDisplay.displayMargin
+
+ model: modelFilter
+
+ sourceModel: NetworkDeviceModel {
+ ctx: MainCtx
+
+ sd_source: viewDevice.sd_source
+ source_name: "*"
+ }
+ }
+ }
+
Component {
id: browseComponent
- NetworkBrowseDisplay {
+ BrowseTreeDisplay {
providerModel: NetworkMediaModel {
ctx: MainCtx
}
@@ -91,6 +131,12 @@ Widgets.PageLoader {
contextMenu: NetworkMediaContextMenu {
model: providerModel
}
+
+ Navigation.cancelAction: function() {
+ History.previous()
+
+ stackView.currentItem.setCurrentItemFocus(Qt.BacktabFocusReason)
+ }
}
}
=====================================
modules/gui/qt/network/qml/NetworkHomeDisplay.qml â modules/gui/qt/network/qml/BrowseHomeDisplay.qml
=====================================
@@ -29,10 +29,20 @@ import "qrc:///util/" as Util
import "qrc:///style/"
FocusScope {
- id: topFocusScope
+ id: root
+
+ property int maximumRows: (MainCtx.gridView) ? 2 : 5
+
+ property var sortModel: [
+ { text: I18n.qtr("Alphabetic"), criteria: "name"},
+ { text: I18n.qtr("Url"), criteria: "mrl" }
+ ]
+
+ property alias model: deviceSection.model
+
focus: true
- readonly property bool isViewMultiView: false
+ signal seeAll(var title, var sd_source, int reason)
signal browse(var tree, int reason)
@@ -43,7 +53,27 @@ FocusScope {
deviceSection.setCurrentItemFocus(reason);
}
- function _centerFlickableOnItem(minY, maxY) {
+ function _centerFlickableOnItem(item) {
+ if (item.activeFocus === false)
+ return
+
+ var minY
+ var maxY
+
+ var index = item.currentIndex
+
+ // NOTE: We want to include the header when we're on the first row.
+ if ((MainCtx.gridView && index < item.nbItemPerRow) || index < 1) {
+ minY = item.y
+
+ maxY = minY + item.getItemY(index) + item.rowHeight
+ } else {
+ minY = item.y + item.getItemY(index)
+
+ maxY = minY + item.rowHeight
+ }
+
+ // TODO: We could implement a scrolling animation like in ExpandGridView.
if (maxY > flickable.contentItem.contentY + flickable.height) {
flickable.contentItem.contentY = maxY - flickable.height
} else if (minY < flickable.contentItem.contentY) {
@@ -56,7 +86,7 @@ FocusScope {
anchors.centerIn: parent
visible: (deviceSection.model.count === 0 && lanSection.model.count === 0 )
font.pixelSize: VLCStyle.fontHeight_xxlarge
- color: topFocusScope.activeFocus ? VLCStyle.colors.accent : VLCStyle.colors.text
+ color: root.activeFocus ? VLCStyle.colors.accent : VLCStyle.colors.text
text: I18n.qtr("No network shares found")
}
@@ -69,79 +99,86 @@ FocusScope {
width: parent.width
height: implicitHeight
- topPadding: VLCStyle.margin_large
spacing: VLCStyle.margin_small
- Widgets.SubtitleLabel {
- id: deviceLabel
- text: I18n.qtr("My Machine")
- width: flickable.width
- visible: deviceSection.model.count !== 0
- leftPadding: VLCStyle.margin_xlarge
- }
-
- NetworkHomeDeviceListView {
+ BrowseDeviceView {
id: deviceSection
- ctx: MainCtx
- sd_source: NetworkDeviceModel.CAT_DEVICES
width: flickable.width
- visible: deviceSection.model.count !== 0
- onVisibleChanged: topFocusScope.resetFocus()
+ height: contentHeight
- onBrowse: topFocusScope.browse(tree, reason)
+ maximumRows: root.maximumRows
- Navigation.parentItem: topFocusScope
+ visible: (model.count !== 0)
- Navigation.downAction: function() {
- if (lanSection.visible == false)
- return;
+ model: NetworkDeviceModel {
+ ctx: MainCtx
- lanSection.setCurrentItemFocus(Qt.TabFocusReason);
+ sd_source: NetworkDeviceModel.CAT_DEVICES
+ source_name: "*"
+
+ maximumCount: deviceSection.maximumCount
}
- onActiveFocusChanged: {
- if (activeFocus)
- _centerFlickableOnItem(deviceLabel.y, deviceSection.y + deviceSection.height)
+ title: I18n.qtr("My Machine")
+
+ Navigation.parentItem: root
+
+ Navigation.downAction: function() {
+ if (lanSection.visible)
+ lanSection.setCurrentItemFocus(Qt.TabFocusReason)
+ else
+ root.Navigation.defaultNavigationDown()
}
- }
- Widgets.SubtitleLabel {
- id: lanLabel
- text: I18n.qtr("My LAN")
- width: flickable.width
- visible: lanSection.model.count !== 0
- leftPadding: VLCStyle.margin_xlarge
- topPadding: deviceLabel.visible ? VLCStyle.margin_small : 0
+ onBrowse: root.browse(tree, reason)
+
+ onSeeAll: root.seeAll(title, model.sd_source, reason)
+
+ onActiveFocusChanged: _centerFlickableOnItem(deviceSection)
+ onCurrentIndexChanged: _centerFlickableOnItem(deviceSection)
}
- NetworkHomeDeviceListView {
+ BrowseDeviceView {
id: lanSection
- ctx: MainCtx
- sd_source: NetworkDeviceModel.CAT_LAN
width: flickable.width
- visible: lanSection.model.count !== 0
- onVisibleChanged: topFocusScope.resetFocus()
+ height: contentHeight
- onBrowse: topFocusScope.browse(tree, reason)
+ maximumRows: root.maximumRows
- Navigation.parentItem: topFocusScope
+ visible: (model.count !== 0)
- Navigation.upAction: function() {
- if (deviceSection.visible == false)
- return;
+ model: NetworkDeviceModel {
+ ctx: MainCtx
+
+ sd_source: NetworkDeviceModel.CAT_LAN
+ source_name: "*"
- deviceSection.setCurrentItemFocus(Qt.TabFocusReason);
+ maximumCount: lanSection.maximumCount
}
- onActiveFocusChanged: {
- if (activeFocus)
- _centerFlickableOnItem(lanLabel.y, lanSection.y + lanSection.height)
+ title: I18n.qtr("My LAN")
+
+ parentFilter: deviceSection.modelFilter
+
+ Navigation.parentItem: root
+
+ Navigation.upAction: function() {
+ if (deviceSection.visible)
+ deviceSection.setCurrentItemFocus(Qt.TabFocusReason)
+ else
+ root.Navigation.defaultNavigationUp()
}
+
+ onBrowse: root.browse(tree, reason)
+
+ onSeeAll: root.seeAll(title, model.sd_source, reason)
+
+ onActiveFocusChanged: _centerFlickableOnItem(lanSection)
+ onCurrentIndexChanged: _centerFlickableOnItem(lanSection)
}
}
-
}
function resetFocus() {
=====================================
modules/gui/qt/network/qml/NetworkBrowseDisplay.qml â modules/gui/qt/network/qml/BrowseTreeDisplay.qml
=====================================
@@ -51,6 +51,10 @@ FocusScope {
signal browse(var tree, int reason)
+ Navigation.cancelAction: function() {
+ History.previous()
+ }
+
onTreeChanged: providerModel.tree = tree
function playSelected() {
@@ -198,9 +202,6 @@ FocusScope {
delegate: NetworkGridItem {
id: delegateGrid
- property var model: ({})
- property int index: -1
-
subtitle: ""
height: VLCStyle.gridCover_network_height + VLCStyle.margin_xsmall + VLCStyle.fontHeight_normal
dragItem: networkDragItem
@@ -225,9 +226,6 @@ FocusScope {
Navigation.parentItem: root
Navigation.upItem: gridView.headerItem
- Navigation.cancelAction: function() {
- History.previous()
- }
}
}
@@ -262,9 +260,6 @@ FocusScope {
headerColor: VLCStyle.colors.bg
Navigation.parentItem: root
Navigation.upItem: tableView.headerItem
- Navigation.cancelAction: function() {
- History.previous()
- }
rowHeight: VLCStyle.tableCoverRow_height
=====================================
modules/gui/qt/network/qml/NetworkCustomCover.qml
=====================================
@@ -32,6 +32,9 @@ Widgets.ScaledImage {
sourceSize: Qt.size(width, height)
source: {
+ if (networkModel === null)
+ return ""
+
if (!!networkModel.artwork && networkModel.artwork.length > 0)
return networkModel.artwork
=====================================
modules/gui/qt/network/qml/NetworkGridItem.qml
=====================================
@@ -28,6 +28,9 @@ import "qrc:///style/"
Widgets.GridItem {
id: root
+ property var model: ({})
+ property int index: -1
+
width: VLCStyle.gridItem_network_width
height: VLCStyle.gridItem_network_height
=====================================
modules/gui/qt/network/qml/ServicesHomeDisplay.qml
=====================================
@@ -69,7 +69,7 @@ Widgets.PageLoader {
Component {
id: sourceRootComponent
- NetworkBrowseDisplay {
+ BrowseTreeDisplay {
property alias source_name: deviceModel.source_name
property Component addressBar: NetworkAddressbar {
@@ -111,7 +111,7 @@ Widgets.PageLoader {
Component {
id: sourceBrowseComponent
- NetworkBrowseDisplay {
+ BrowseTreeDisplay {
property string root_name
property string source_name
=====================================
modules/gui/qt/util/sortfilterproxymodel.hpp
=====================================
@@ -71,7 +71,6 @@ private slots:
private:
QByteArray m_searchRole;
QString m_sortCriteria;
- Qt::SortOrder m_sortOrder;
};
#endif // SORT_FILTER_PROXY_MODEL
=====================================
modules/gui/qt/vlc.qrc
=====================================
@@ -219,13 +219,14 @@
</qresource>
<qresource prefix="/network">
<file alias="AddressbarButton.qml">network/qml/AddressbarButton.qml</file>
+ <file alias="BrowseDeviceHeader.qml">network/qml/BrowseDeviceHeader.qml</file>
+ <file alias="BrowseDeviceView.qml">network/qml/BrowseDeviceView.qml</file>
+ <file alias="BrowseDisplay.qml">network/qml/BrowseDisplay.qml</file>
+ <file alias="BrowseHomeDisplay.qml">network/qml/BrowseHomeDisplay.qml</file>
+ <file alias="BrowseTreeDisplay.qml">network/qml/BrowseTreeDisplay.qml</file>
<file alias="DiscoverDisplay.qml">network/qml/DiscoverDisplay.qml</file>
<file alias="DiscoverUrlDisplay.qml">network/qml/DiscoverUrlDisplay.qml</file>
<file alias="NetworkCustomCover.qml">network/qml/NetworkCustomCover.qml</file>
- <file alias="NetworkDisplay.qml">network/qml/NetworkDisplay.qml</file>
- <file alias="NetworkHomeDeviceListView.qml">network/qml/NetworkHomeDeviceListView.qml</file>
- <file alias="NetworkHomeDisplay.qml">network/qml/NetworkHomeDisplay.qml</file>
- <file alias="NetworkBrowseDisplay.qml">network/qml/NetworkBrowseDisplay.qml</file>
<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>
=====================================
modules/gui/qt/widgets/qml/ExpandGridView.qml
=====================================
@@ -42,25 +42,26 @@ FocusScope {
property int rightMargin: VLCStyle.margin_normal
// NOTE: The grid margin for the item(s) horizontal positioning.
- readonly property int contentMargin: (_contentWidth - _nbItemPerRow * _effectiveCellWidth
+ readonly property int contentMargin: (_contentWidth - nbItemPerRow * _effectiveCellWidth
+
horizontalSpacing) / 2
+ readonly property int rowHeight: cellHeight + verticalSpacing
+
property int rowX: 0
property int horizontalSpacing: VLCStyle.column_margin_width
property int verticalSpacing: VLCStyle.column_margin_width
property int displayMarginEnd: 0
+ readonly property int nbItemPerRow: Math.max(Math.floor((_contentWidth + horizontalSpacing)
+ /
+ _effectiveCellWidth), 1)
+
readonly property int _effectiveCellWidth: cellWidth + horizontalSpacing
- readonly property int _effectiveCellHeight: cellHeight + verticalSpacing
readonly property int _contentWidth: width - rightMargin - leftMargin
- readonly property int _nbItemPerRow: Math.max(Math.floor((_contentWidth + horizontalSpacing)
- /
- _effectiveCellWidth), 1)
-
property Util.SelectableDelegateModel selectionDelegateModel
property QtAbstractItemModel model
@@ -150,26 +151,29 @@ FocusScope {
Keys.onPressed: {
var newIndex = -1
if (KeyHelper.matchRight(event)) {
- if ((currentIndex + 1) % _nbItemPerRow !== 0) {//are we not at the end of line
+ if ((currentIndex + 1) % nbItemPerRow !== 0) {//are we not at the end of line
newIndex = Math.min(_count - 1, currentIndex + 1)
}
} else if (KeyHelper.matchLeft(event)) {
- if (currentIndex % _nbItemPerRow !== 0) {//are we not at the beginning of line
+ if (currentIndex % nbItemPerRow !== 0) {//are we not at the beginning of line
newIndex = Math.max(0, currentIndex - 1)
}
} else if (KeyHelper.matchDown(event)) {
+ var lastIndex = _count - 1
// we are not on the last line
- if (Math.floor(currentIndex / _nbItemPerRow) !== Math.floor(_count / _nbItemPerRow)) {
- newIndex = Math.min(_count - 1, currentIndex + _nbItemPerRow)
+ if (Math.floor(currentIndex / nbItemPerRow)
+ !==
+ Math.floor(lastIndex / nbItemPerRow)) {
+ newIndex = Math.min(lastIndex, currentIndex + nbItemPerRow)
}
} else if (KeyHelper.matchPageDown(event)) {
- newIndex = Math.min(_count - 1, currentIndex + _nbItemPerRow * 5)
+ newIndex = Math.min(_count - 1, currentIndex + nbItemPerRow * 5)
} else if (KeyHelper.matchUp(event)) {
- if (Math.floor(currentIndex / _nbItemPerRow) !== 0) { //we are not on the first line
- newIndex = Math.max(0, currentIndex - _nbItemPerRow)
+ if (Math.floor(currentIndex / nbItemPerRow) !== 0) { //we are not on the first line
+ newIndex = Math.max(0, currentIndex - nbItemPerRow)
}
} else if (KeyHelper.matchPageUp(event)) {
- newIndex = Math.max(0, currentIndex - _nbItemPerRow * 5)
+ newIndex = Math.max(0, currentIndex - nbItemPerRow * 5)
} else if (KeyHelper.matchOk(event) || event.matches(StandardKey.SelectAll) ) {
//these events are matched on release
event.accepted = true
@@ -324,9 +328,13 @@ FocusScope {
flickable.retract()
}
+ function getItemY(index) {
+ return Math.floor(index / nbItemPerRow) * rowHeight + headerHeight + topMargin
+ }
+
function getItemRowCol(id) {
- var rowId = Math.floor(id / _nbItemPerRow)
- var colId = id % _nbItemPerRow
+ var rowId = Math.floor(id / nbItemPerRow)
+ var colId = id % nbItemPerRow
return [colId, rowId]
}
@@ -335,7 +343,7 @@ FocusScope {
var x = rowCol[0] * _effectiveCellWidth + contentMargin + leftMargin;
- var y = rowCol[1] * _effectiveCellHeight + headerHeight + topMargin;
+ var y = rowCol[1] * rowHeight + headerHeight + topMargin;
// NOTE: Position needs to be integer based if we want to avoid visual artifacts like
// wrong alignments or blurry texture rendering.
@@ -351,7 +359,7 @@ FocusScope {
return
var itemTopY = getItemPos(index)[1]
- var itemBottomY = itemTopY + _effectiveCellHeight
+ var itemBottomY = itemTopY + rowHeight
var viewTopY = flickable.contentY
var viewBottomY = viewTopY + flickable.height
@@ -431,11 +439,11 @@ FocusScope {
}
var onlyGridContentY = contentYWithoutExpand - headerHeight - topMargin
- var rowId = Math.floor(onlyGridContentY / _effectiveCellHeight)
- var firstId = Math.max(rowId * _nbItemPerRow, 0)
+ var rowId = Math.floor(onlyGridContentY / rowHeight)
+ var firstId = Math.max(rowId * nbItemPerRow, 0)
- rowId = Math.ceil((onlyGridContentY + heightWithoutExpand) / _effectiveCellHeight)
- var lastId = Math.min(rowId * _nbItemPerRow, _count)
+ rowId = Math.ceil((onlyGridContentY + heightWithoutExpand) / rowHeight)
+ var lastId = Math.min(rowId * nbItemPerRow, _count)
return [firstId, lastId]
}
@@ -590,7 +598,7 @@ FocusScope {
}
}
}
-
+
Util.FlickableScrollHandler { }
Loader {
@@ -600,7 +608,7 @@ FocusScope {
y: root.topMargin
//load the header early (when the first row is visible)
- visible: flickable.contentY < (root.headerHeight + root._effectiveCellHeight + root.topMargin)
+ visible: flickable.contentY < (root.headerHeight + root.rowHeight + root.topMargin)
focus: (status === Loader.Ready) ? item.focus : false
}
@@ -610,7 +618,7 @@ FocusScope {
focus: (status === Loader.Ready) ? item.focus : false
- y: root.topMargin + root.headerHeight + (root._effectiveCellHeight * (Math.ceil(model.count / root._nbItemPerRow))) +
+ y: root.topMargin + root.headerHeight + (root.rowHeight * (Math.ceil(model.count / root.nbItemPerRow))) +
root._expandItemVerticalSpace
}
@@ -669,7 +677,7 @@ FocusScope {
if (root.expandIndex !== -1) {
var rowCol = root.getItemRowCol(root.expandIndex)
var rowId = rowCol[1] + 1
- ret = rowId * root._nbItemPerRow
+ ret = rowId * root.nbItemPerRow
} else {
ret = root._count
}
@@ -758,10 +766,10 @@ FocusScope {
_setupIndexes(forceRelayout, [topGridEndId, lastId], root._expandItemVerticalSpace)
// update contentWidth and contentHeight
- var gridContentWidth = root._effectiveCellWidth * root._nbItemPerRow - root.horizontalSpacing
+ var gridContentWidth = root._effectiveCellWidth * root.nbItemPerRow - root.horizontalSpacing
contentWidth = root.leftMargin + gridContentWidth + root.rightMargin
- var gridContentHeight = root.getItemPos(root._count - 1)[1] + root._effectiveCellHeight + root._expandItemVerticalSpace
+ var gridContentHeight = root.getItemPos(root._count - 1)[1] + root.rowHeight + root._expandItemVerticalSpace
contentHeight = gridContentHeight
+ (footerItemLoader.item ? footerItemLoader.item.height : 0)
+ root.bottomMargin // topMargin and headerHeight is included in root.getItemPos
@@ -804,7 +812,7 @@ FocusScope {
// Sliding animation
var currentItemYPos = root.getItemPos(root.expandIndex)[1]
- currentItemYPos += root._effectiveCellHeight / 2
+ currentItemYPos += root.rowHeight / 2
animateFlickableContentY(currentItemYPos)
}
=====================================
modules/gui/qt/widgets/qml/KeyNavigableListView.qml
=====================================
@@ -35,7 +35,7 @@ FadingEdgeListView {
readonly property int scrollBarWidth: scroll_id.visible ? scroll_id.width : 0
- property bool keyNavigationWraps : false
+ property bool keyNavigationWraps: false
// Private
@@ -69,13 +69,38 @@ FadingEdgeListView {
property int _currentFocusReason: Qt.OtherFocusReason
-
// Settings
+ focus: true
+
+ //key navigation is reimplemented for item selection
+ keyNavigationEnabled: false
+
+ ScrollBar.vertical: ScrollBar { id: scroll_id; visible: root.contentHeight > root.height }
+ ScrollBar.horizontal: ScrollBar { visible: root.contentWidth > root.width }
+
+ highlightMoveDuration: 300 //ms
+ highlightMoveVelocity: 1000 //px/s
+
+ section.property: ""
+ section.criteria: ViewSection.FullString
+ section.delegate: sectionHeading
+
+ disableBeginningFade: (dragAutoScrollHandler.scrollingDirection
+ ===
+ Util.ViewDragAutoScrollHandler.Backward)
+
+ disableEndFade: (dragAutoScrollHandler.scrollingDirection
+ ===
+ Util.ViewDragAutoScrollHandler.Forward)
+
Accessible.role: Accessible.List
// Events
+ // NOTE: We always want a valid 'currentIndex' by default.
+ onCountChanged: if (count && currentIndex === -1) currentIndex = 0
+
onCurrentItemChanged: {
if (_currentFocusReason === Qt.OtherFocusReason)
return;
@@ -116,27 +141,6 @@ FadingEdgeListView {
root.contentX -= Math.min(root.width,root.contentX - root.originX)
}
- focus: true
-
- //key navigation is reimplemented for item selection
- keyNavigationEnabled: false
-
- ScrollBar.vertical: ScrollBar { id: scroll_id; visible: root.contentHeight > root.height }
- ScrollBar.horizontal: ScrollBar { visible: root.contentWidth > root.width }
-
- highlightMoveDuration: 300 //ms
- highlightMoveVelocity: 1000 //px/s
-
- section.property: ""
- section.criteria: ViewSection.FullString
- section.delegate: sectionHeading
-
- // NOTE: We always want a valid 'currentIndex' by default.
- onCountChanged: if (count && currentIndex === -1) currentIndex = 0
-
- disableBeginningFade: (dragAutoScrollHandler.scrollingDirection === Util.ViewDragAutoScrollHandler.Backward)
- disableEndFade: (dragAutoScrollHandler.scrollingDirection === Util.ViewDragAutoScrollHandler.Forward)
-
Keys.onPressed: {
var newIndex = -1
=====================================
modules/gui/qt/widgets/qml/KeyNavigableTableView.qml
=====================================
@@ -146,6 +146,17 @@ FocusScope {
view.positionViewAtBeginning()
}
+ function getItemY(index) {
+ var size = index * rowHeight + topMargin
+
+ if (tableHeaderItem)
+ size += tableHeaderItem.height
+
+ return size
+ }
+
+ // Private
+
function _qtAvoidSectionUpdate() {
// Qt SEG. FAULT WORKAROUND
=====================================
modules/gui/qt/widgets/qml/TextToolButton.qml
=====================================
@@ -18,6 +18,8 @@
import QtQuick 2.11
import QtQuick.Templates 2.4 as T
+import org.videolan.vlc 0.1
+
import "qrc:///style/"
T.ToolButton {
@@ -30,6 +32,12 @@ T.ToolButton {
padding: VLCStyle.margin_xxsmall
+ // Keys
+
+ Keys.priority: Keys.AfterItem
+
+ Keys.onPressed: Navigation.defaultKeyAction(event)
+
contentItem: T.Label {
text: control.text
font: control.font
=====================================
po/POTFILES.in
=====================================
@@ -830,11 +830,14 @@ modules/gui/qt/menus/menus.hpp
modules/gui/qt/menus/qml/Menubar.qml
modules/gui/qt/menus/qml_menu_wrapper.cpp
modules/gui/qt/menus/qml_menu_wrapper.hpp
+modules/gui/qt/network/qml/BrowseDeviceHeader.qml
+modules/gui/qt/network/qml/BrowseDeviceView.qml
+modules/gui/qt/network/qml/BrowseDisplay.qml
+modules/gui/qt/network/qml/BrowseHomeDisplay.qml
+modules/gui/qt/network/qml/BrowseTreeDisplay.qml
modules/gui/qt/network/qml/DiscoverDisplay.qml
modules/gui/qt/network/qml/DiscoverUrlDisplay.qml
-modules/gui/qt/network/qml/NetworkBrowseDisplay.qml
modules/gui/qt/network/qml/NetworkGridItem.qml
-modules/gui/qt/network/qml/NetworkHomeDisplay.qml
modules/gui/qt/network/qml/NetworkListItem.qml
modules/gui/qt/network/qml/ServicesHomeDisplay.qml
modules/gui/qt/player/control_list_filter.cpp
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b8a8ff969338da801a83304bb19c52ed12849a9b...8e16f8ddfc555d210acecc6b99da7fd6a38cc2c6
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b8a8ff969338da801a83304bb19c52ed12849a9b...8e16f8ddfc555d210acecc6b99da7fd6a38cc2c6
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