[vlc-devel] [PATCH 10/32] QML: reimplement ExpandGridView starting from a Flickable
Adrien Maglo
magsoft at videolan.org
Wed Jun 12 14:30:13 CEST 2019
This fixes the resizing issues of the previous implementation based on
two GridViews.
---
.../qt/qml/mediacenter/MusicAlbumsDisplay.qml | 97 ++--
.../MusicAlbumsGridExpandDelegate.qml | 20 +-
modules/gui/qt/qml/utils/ExpandGridView.qml | 525 ++++++++++--------
.../gui/qt/qml/utils/KeyNavigableListView.qml | 1 +
.../qt/qml/utils/KeyNavigableTableView.qml | 3 +
5 files changed, 369 insertions(+), 277 deletions(-)
diff --git a/modules/gui/qt/qml/mediacenter/MusicAlbumsDisplay.qml b/modules/gui/qt/qml/mediacenter/MusicAlbumsDisplay.qml
index c421e241f7..c99ffa4634 100644
--- a/modules/gui/qt/qml/mediacenter/MusicAlbumsDisplay.qml
+++ b/modules/gui/qt/qml/mediacenter/MusicAlbumsDisplay.qml
@@ -48,46 +48,10 @@ Utils.NavigableFocusScope {
ml: medialib
}
+
delegate: Package {
id: element
- Utils.GridItem {
- Package.name: "gridTop"
- image: model.cover || VLCStyle.noArtAlbum
- title: model.title || qsTr("Unknown title")
- subtitle: model.main_artist || qsTr("Unknown artist")
- selected: element.DelegateModel.inSelected || view.currentItem.currentIndex === index
- shiftX: view.currentItem.shiftX(model.index)
-
- onItemClicked : {
- view._switchExpandItem( index )
- delegateModel.updateSelection( modifier , view.currentItem.currentIndex, index)
- view.currentItem.currentIndex = index
- view.currentItem.forceActiveFocus()
-
- }
- onPlayClicked: medialib.addAndPlay( model.id )
- onAddToPlaylistClicked : medialib.addToPlaylist( model.id )
- }
-
- Utils.GridItem {
- Package.name: "gridBottom"
- image: model.cover || VLCStyle.noArtAlbum
- title: model.title || qsTr("Unknown title")
- subtitle: model.main_artist || qsTr("Unknown artist")
- selected: element.DelegateModel.inSelected || view.currentItem.currentIndex === index
- shiftX: view.currentItem.shiftX(model.index)
-
- onItemClicked : {
- view._switchExpandItem( index )
- delegateModel.updateSelection( modifier , view.currentItem.currentIndex, index)
- view.currentItem.currentIndex = index
- view.currentItem.forceActiveFocus()
- }
- onPlayClicked: medialib.addAndPlay( model.id )
- onAddToPlaylistClicked : medialib.addToPlaylist( model.id )
- }
-
Utils.ListItem {
Package.name: "list"
width: root.width
@@ -152,40 +116,57 @@ Utils.NavigableFocusScope {
cellWidth: VLCStyle.cover_normal + VLCStyle.margin_small
cellHeight: VLCStyle.cover_normal + VLCStyle.fontHeight_normal * 2 + VLCStyle.margin_small
+ gridDelegate: Utils.GridItem {
+ property variant delegateModelItem: ({
+ model: ({}),
+ itemsIndex: 0,
+ inSelected: false
+ })
+
+ shiftX: view.currentItem.shiftX(delegateModelItem.itemsIndex)
+ image: delegateModelItem.model.cover || VLCStyle.noArtAlbum
+ title: delegateModelItem.model.title || qsTr("Unknown title")
+ subtitle: delegateModelItem.model.main_artist || qsTr("Unknown artist")
+ selected: delegateModelItem.inSelected
+ onItemClicked : {
+ delegateModel.updateSelection( modifier , view.currentItem.currentIndex, delegateModelItem.itemsIndex)
+ view.currentItem.currentIndex = delegateModelItem.itemsIndex
+ //view.currentItem.forceActiveFocus()
+ view._switchExpandItem( delegateModelItem.itemsIndex )
+
+ }
+ onPlayClicked: medialib.addAndPlay( delegateModelItem.model.id )
+ onAddToPlaylistClicked : medialib.addToPlaylist( delegateModelItem.model.id )
+ }
+
expandDelegate: Rectangle {
id: expandDelegateId
- height: albumDetail.implicitHeight
+ implicitHeight: albumDetail.implicitHeight
width: root.width
color: VLCStyle.colors.bgAlt
property int currentId: -1
property alias model : albumDetail.model
+ property alias currentItemY: albumDetail.currentItemY
+ property alias currentItemHeight: albumDetail.currentItemHeight
+
+ onActiveFocusChanged: {
+ if (activeFocus)
+ albumDetail.forceActiveFocus()
+ }
MusicAlbumsGridExpandDelegate {
id: albumDetail
anchors.fill: parent
- visible: true
- focus: true
- model: delegateModel.items.get(gridView_id.expandIndex).model
- onActionCancel: gridView_id.expandIndex = -1
- onActionUp: gridView_id.expandIndex = -1
- onActionDown: gridView_id.expandIndex = -1
+ onActionCancel: gridView_id.retract()
+ onActionUp: gridView_id.retract()
+ onActionDown: gridView_id.retract()
onActionLeft: root.actionLeft(index)
onActionRight: root.actionRight(index)
}
-
- Connections {
- target: gridView_id
- onExpandIndexChanged: {
- if (gridView_id.expandIndex !== -1)
- {
- expandDelegateId.model = delegateModel.items.get(gridView_id.expandIndex).model
- }
- }
- }
}
+ model: delegateModel
modelTop: delegateModel.parts.gridTop
- modelBottom: delegateModel.parts.gridBottom
modelCount: delegateModel.items.count
onActionAtIndex: {
@@ -250,10 +231,12 @@ Utils.NavigableFocusScope {
}
function _switchExpandItem(index) {
- if (view.currentItem.expandIndex === index)
+ view.currentItem.switchExpandItem(index)
+
+ /*if (view.currentItem.expandIndex === index)
view.currentItem.expandIndex = -1
else
- view.currentItem.expandIndex = index
+ view.currentItem.expandIndex = index*/
}
}
diff --git a/modules/gui/qt/qml/mediacenter/MusicAlbumsGridExpandDelegate.qml b/modules/gui/qt/qml/mediacenter/MusicAlbumsGridExpandDelegate.qml
index 701907f036..b7afd83cae 100644
--- a/modules/gui/qt/qml/mediacenter/MusicAlbumsGridExpandDelegate.qml
+++ b/modules/gui/qt/qml/mediacenter/MusicAlbumsGridExpandDelegate.qml
@@ -26,9 +26,15 @@ import "qrc:///style/"
Utils.NavigableFocusScope {
id: root
- property var model: []
+ property variant model: MLAlbumModel{}
//color: VLCStyle.colors.bg
implicitHeight: layout.height
+ clip: true
+
+ width: parent.width
+
+ property int currentItemY
+ property int currentItemHeight
Row {
id: layout
@@ -181,6 +187,18 @@ Utils.NavigableFocusScope {
interactive: false
parentId : root.model.id
+ onParentIdChanged: {
+ currentIndex = 0
+ focus = true
+ }
+
+ onCurrentItemChanged: {
+ if (currentItem != undefined) {
+ root.currentItemY = expand_infos_id.y + expand_track_id.y + currentItem.y
+ root.currentItemHeight = currentItem.height
+ }
+ }
+
sortModel: ListModel {
ListElement{ criteria: "track_number"; width:0.10; visible: true; text: qsTr("#"); showSection: "" }
ListElement{ criteria: "title"; width:0.70; visible: true; text: qsTr("Title"); showSection: "" }
diff --git a/modules/gui/qt/qml/utils/ExpandGridView.qml b/modules/gui/qt/qml/utils/ExpandGridView.qml
index 40b4aa6430..ad18c9b582 100644
--- a/modules/gui/qt/qml/utils/ExpandGridView.qml
+++ b/modules/gui/qt/qml/utils/ExpandGridView.qml
@@ -31,18 +31,18 @@ NavigableFocusScope {
property int marginTop: root.cellHeight / 3
//model to be rendered, model has to be passed twice, as they cannot be shared between views
- property alias modelTop: topView.model
- property alias modelBottom: bottomView.model
+ property alias model: flickable.model
+ property variant modelTop
property int modelCount: 0
- property alias delegateTop: topView.delegate
- property alias delegateBottom: bottomView.delegate
-
property int currentIndex: 0
/// the id of the item to be expanded
- property int expandIndex: -1
+ property int _expandIndex: -1
+ property int _newExpandIndex: -1
+
//delegate to display the extended item
+ property Component gridDelegate: Item{}
property Component expandDelegate: Item{}
//signals emitted when selected items is updated from keyboard
@@ -50,273 +50,360 @@ NavigableFocusScope {
signal selectAll()
signal actionAtIndex(int index)
- property alias contentY: flickable.contentY
- property alias interactive: flickable.interactive
- property alias clip: flickable.clip
- property alias contentHeight: flickable.contentHeight
- property alias contentWidth: flickable.contentWidth
+ property double _expandRetractSpeed: 1.
+
+ function shiftX(index) {
+ var colCount = flickable.getNbItemsPerRow()
+ var rightSpace = width - colCount * root.cellWidth
+ return ((index % colCount) + 1) * (rightSpace / (colCount + 1))
+ }
+
+ function switchExpandItem(index) {
+ if (index === _expandIndex)
+ _newExpandIndex = -1
+ else
+ _newExpandIndex = index
+
+ if (_expandIndex !== -1)
+ flickable.retract()
+ else
+ flickable.expand()
+ }
- //compute a delta that can be applied to grid elements to obtain an horizontal distribution
- function shiftX( index ) {
- var rightSpace = width - (flickable._colCount * root.cellWidth)
- return ((index % flickable._colCount) + 1) * (rightSpace / (flickable._colCount + 1))
+ function retract() {
+ _newExpandIndex = -1
+ flickable.retract()
}
+ //Gridview visible above the expanded item
Flickable {
id: flickable
-
- anchors.fill: parent
clip: true
- //ScrollBar.vertical: ScrollBar { }
- //disable bound behaviors to avoid visual artifacts around the expand delegate
- boundsBehavior: Flickable.StopAtBounds
+ property variant model
+ property Item expandItem: root.expandDelegate.createObject(contentItem, {"height": 0})
+ anchors.fill: parent
- // number of elements per row, for internal computation
- property int _colCount: Math.floor(width / root.cellWidth)
- property int topContentY: flickable.contentY
- property int bottomContentY: flickable.contentY + flickable.height
+ onWidthChanged: { layout() }
+ onHeightChanged: { layout() }
+ onContentYChanged: { layout() }
- property int _oldExpandIndex: -1
- property bool _expandActive: root.expandIndex !== -1
+ function getNbItemsPerRow() {
+ return Math.max(Math.floor(width / root.cellWidth), 1)
+ }
- function _rowOfIndex( index ) {
- return Math.ceil( (index + 1) / flickable._colCount) - 1
+ function getItemRowCol(id) {
+ var nbItemsPerRow = getNbItemsPerRow()
+ var rowId = Math.floor(id / nbItemsPerRow)
+ var colId = id % nbItemsPerRow
+ return [colId, rowId]
}
- //from KeyNavigableGridView
- function _yOfIndex( index ) {
- if ( root.expandIndex != -1
- && (index > (flickable._rowOfIndex( root.expandIndex ) + 1) * flickable._colCount ) )
- return flickable._rowOfIndex(root.currentIndex) * root.cellHeight + expandItem.height
- else
- return flickable._rowOfIndex(root.currentIndex) * root.cellHeight
+ function getItemPos(id) {
+ var rowCol = getItemRowCol(id)
+ return [rowCol[0] * root.cellWidth, rowCol[1] * root.cellHeight]
}
- Connections {
- target: root
- onExpandIndexChanged: {
- flickable._updateExpandPosition()
+ function getExpandItemGridId() {
+ var ret
+ if (root._expandIndex !== -1) {
+ var rowCol = getItemRowCol(root._expandIndex)
+ var rowId = rowCol[1] + 1
+ ret = rowId * getNbItemsPerRow()
+ } else {
+ ret = model.count
}
+ return ret
}
- on_ColCountChanged: _updateExpandPosition()
- function _updateExpandPosition() {
- expandItem.y = root.cellHeight * (Math.floor(root.expandIndex / flickable._colCount) + 1)
- _oldExpandIndex = root.expandIndex
+
+ property variant idChildrenMap: ({})
+
+ function getFirstAndLastInstanciatedItemIds() {
+ var contentYWithoutExpand = contentY
+ var heightWithoutExpand = height
+ if (root._expandIndex !== -1) {
+ if (contentY >= expandItem.y && contentY < expandItem.y + expandItem.height)
+ contentYWithoutExpand = expandItem.y
+ if (contentY >= expandItem.y + expandItem.height)
+ contentYWithoutExpand = contentY - expandItem.height
+
+ var expandYStart = Math.max(contentY, expandItem.y)
+ var expandYEnd = Math.min(contentY + height, expandItem.y + expandItem.height)
+ var expandDisplayedHeight = Math.max(expandYEnd - expandYStart, 0)
+ heightWithoutExpand -= expandDisplayedHeight
+ }
+
+ var rowId = Math.floor(contentYWithoutExpand / root.cellHeight)
+ var firstId = Math.max(rowId * getNbItemsPerRow(), 0)
+
+ rowId = Math.ceil((contentYWithoutExpand + heightWithoutExpand) / root.cellHeight)
+ var lastId = Math.min(rowId * getNbItemsPerRow(), model.count)
+
+ return [firstId, lastId]
}
+ function getChild(id, toUse) {
+ var ret
+ if (id in idChildrenMap) {
+ ret = idChildrenMap[id]
+ if (ret === undefined)
+ throw "wrong child: " + id
+ }
+ else {
+ ret = toUse.pop()
+ if (ret === undefined)
+ throw "wrong toRecycle child " + id + ", len " + toUse.length
+ idChildrenMap[id] = ret
+ }
+ return ret
+ }
- states: [
- State {
- name: "-expand"
- when: ! flickable._expandActive
- PropertyChanges {
- target: flickable
- topContentY: flickable.contentY
- contentHeight: root.cellHeight * Math.ceil(root.modelCount / flickable._colCount)
- }
- },
- State {
- name: "+expand"
- when: flickable._expandActive
- PropertyChanges {
- target: flickable
- topContentY: flickable.contentY
- contentHeight: root.cellHeight * Math.ceil(root.modelCount / flickable._colCount) + expandItem.height
+ function layout() {
+ var i
+ var expandItemGridId = getExpandItemGridId()
+
+ var f_l = getFirstAndLastInstanciatedItemIds()
+ var nbItems = f_l[1] - f_l[0]
+ var firstId = f_l[0]
+ var lastId = f_l[1]
+
+ var topGridEndId = Math.max(Math.min(expandItemGridId, lastId), firstId)
+
+ // Clean the no longer used ids
+ var toKeep = {}
+ var toUse = []
+ for (var id in idChildrenMap) {
+ var val = idChildrenMap[id]
+ if (id >= firstId && id < lastId)
+ toKeep[id] = val
+ else {
+ toUse.push(val)
+ val.visible = false
}
}
- ]
-
- //Gridview visible above the expanded item
- GridView {
- id: topView
- clip: true
- interactive: false
-
- focus: !flickable._expandActive
-
- highlightFollowsCurrentItem: false
- currentIndex: root.currentIndex
-
- cellWidth: root.cellWidth
- cellHeight: root.cellHeight
-
- anchors.left: parent.left
- anchors.right: parent.right
-
- states: [
- //expand is unactive or below the view
- State {
- name: "visible_noexpand"
- when: !flickable._expandActive || expandItem.y >= flickable.bottomContentY
- PropertyChanges {
- target: topView
- y: flickable.topContentY
-
- height:flickable.height
- //FIXME: should we add + originY? this seemed to fix some issues but has performance impacts
- //OriginY, seems to change randomly on grid resize
- contentY: flickable.topContentY
- visible: true
- enabled: true
- }
- },
- //expand is active and within the view
- State {
- name: "visible_expand"
- when: flickable._expandActive && (expandItem.y >= flickable.contentY) && (expandItem.y < flickable.bottomContentY)
- PropertyChanges {
- target: topView
- y: flickable.contentY
- height: expandItem.y - flickable.topContentY
- //FIXME: should we add + originY? this seemed to fix some issues but has performance impacts
- //OriginY, seems to change randomly on grid resize
- contentY: flickable.topContentY
- visible: true
- enabled: true
- }
- },
- //expand is active and above the view
- State {
- name: "hidden"
- when: flickable._expandActive && (expandItem.y < flickable.contentY)
- PropertyChanges {
- target: topView
- visible: false
- enabled: false
- height: 1
- y: 0
- contentY: 0
- }
+ idChildrenMap = toKeep
+
+ // Create delegates if we do not have enough
+ if (nbItems > toUse.length + Object.keys(toKeep).length) {
+ var toCreate = nbItems - (toUse.length + Object.keys(toKeep).length)
+ for (i = 0; i < toCreate; ++i) {
+ val = root.gridDelegate.createObject(contentItem);
+ toUse.push(val)
}
- ]
+ }
+
+ // Place the delegates before the expandItem
+ for (i = firstId; i < topGridEndId; ++i) {
+ var pos = getItemPos(i)
+ var item = getChild(i, toUse)
+ item.delegateModelItem = model.items.get(i)
+ item.x = pos[0]
+ item.y = pos[1]
+ item.visible = true
+ }
+
+ expandItem.y = getItemPos(expandItemGridId)[1]
+
+ // Place the delegates after the expandItem
+ for (i = topGridEndId; i < lastId; ++i) {
+ pos = getItemPos(i)
+ item = getChild(i, toUse)
+ item.delegateModelItem = model.items.get(i)
+ item.x = pos[0]
+ item.y = pos[1] + expandItem.height
+ item.visible = true
+ }
+
+ // Calculate and set the contentHeight
+ var newContentHeight = getItemPos(model.count - 1)[1] + root.cellHeight
+ if (root._expandIndex !== -1)
+ newContentHeight += expandItem.height
+ contentHeight = newContentHeight
+ setCurrentItemFocus()
}
- //Expanded item view
- Loader {
- id: expandItem
- sourceComponent: root.expandDelegate
- active: flickable._expandActive
- focus: flickable._expandActive
- y: 0 //updated by _updateExpandPosition
- property int bottomY: y + height
- anchors.left: parent.left
- anchors.right: parent.right
+ Connections {
+ target: model.items
+ onChanged: {
+ // Hide the expandItem with no animation
+ _expandIndex = -1
+ flickable.expandItem.height = 0
+ // Regenerate the gridview layout
+ flickable.layout()
+ }
}
- //Gridview visible below the expand item
- GridView {
- id: bottomView
- clip: true
- interactive: false
- highlightFollowsCurrentItem: false
- //don't bind the current index, otherwise it reposition the contentY on it's own
- //currentIndex: root.currentIndex
-
- cellWidth: root.cellWidth
- cellHeight: root.cellHeight
-
- anchors.left: parent.left
- anchors.right: parent.right
-
- property bool hidden: !flickable._expandActive
- || (expandItem.bottomY >= flickable.bottomContentY)
- || flickable._rowOfIndex(root.expandIndex) === flickable._rowOfIndex(root.modelCount - 1)
- states: [
- //expand is visible and above the view
- State {
- name: "visible_noexpand"
- when: !bottomView.hidden && (expandItem.bottomY < flickable.contentY)
- PropertyChanges {
- target: bottomView
- enabled: true
- visible: true
- height: flickable.height
- y: flickable.contentY
- contentY: expandItem.y + flickable.contentY - expandItem.bottomY
- }
- },
- //expand is visible and within the view
- State {
- name: "visible_expand"
- when: !bottomView.hidden && (expandItem.bottomY > flickable.contentY) && (expandItem.bottomY < flickable.bottomContentY)
- PropertyChanges {
- target: bottomView
- enabled: true
- visible: true
- height: Math.min(flickable.bottomContentY - expandItem.bottomY, root.cellHeight * ( flickable._rowOfIndex(root.modelCount - 1) - flickable._rowOfIndex(root.expandIndex)))
- y: expandItem.bottomY
- contentY: expandItem.y
- }
- },
- //expand is inactive or below the view
- State {
- name: "hidden"
- when: bottomView.hidden
- PropertyChanges {
- target: bottomView
- enabled: false
- visible: false
- height: 1
- y: 0
- contentY: 0
- }
+ Connections {
+ target: flickable.expandItem
+ onHeightChanged: {
+ flickable.layout()
+ }
+ onImplicitHeightChanged: {
+ /* This is the only event we have after the expandItem height content was resized.
+ We can trigger here the expand animation with the right final height. */
+ if (root._expandIndex !== -1)
+ flickable.expandAnimation()
+ }
+ onCurrentItemYChanged: {
+ var newContentY = flickable.contentY;
+ var currentItemYPos = flickable.getItemPos(currentIndex)[1] + cellHeight + flickable.expandItem.currentItemY
+ if (currentItemYPos + flickable.expandItem.currentItemHeight > flickable.contentY + flickable.height) {
+ //move viewport to see current item bottom
+ newContentY = Math.min(
+ currentItemYPos + flickable.expandItem.currentItemHeight - flickable.height,
+ flickable.contentHeight - flickable.height)
+ } else if (currentItemYPos < flickable.contentY) {
+ //move viewport to see current item top
+ newContentY = Math.max(currentItemYPos, 0)
}
- ]
+
+ if (newContentY !== flickable.contentY)
+ animateFlickableContentY(newContentY)
+ }
+ }
+
+ function expand() {
+ _expandIndex = _newExpandIndex
+ expandItem.model = model.items.get(_expandIndex).model
+ /* We must also start the expand animation here since the expandItem implicitHeight is not
+ changed if it had the same height at previous opening. */
+ expandAnimation()
+ }
+
+ function expandAnimation() {
+ var expandItemHeight = flickable.expandItem.implicitHeight;
+
+ // Expand animation
+
+ flickable.expandItem.focus = true
+ // The animation may have already been triggered, we must stop it.
+ animateExpandItem.stop()
+ animateExpandItem.to = expandItemHeight
+ animateExpandItem.start()
+
+ // Sliding animation
+
+ var newContentY = flickable.contentY;
+ var currentItemYPos = flickable.getItemPos(currentIndex)[1]
+ if (currentItemYPos + cellHeight + expandItemHeight > flickable.contentY + flickable.height) {
+ if (cellHeight + expandItemHeight > flickable.height)
+ newContentY = currentItemYPos
+ else
+ newContentY = Math.min(
+ currentItemYPos + cellHeight + expandItemHeight - flickable.height,
+ flickable.contentHeight + expandItemHeight - flickable.height)
+ }
+
+ if (newContentY !== flickable.contentY)
+ animateFlickableContentY(newContentY)
+ }
+
+ function retract() {
+ animateRetractItem.start()
+ }
+
+ PropertyAnimation {
+ id: animateRetractItem;
+ target: flickable.expandItem;
+ properties: "height"
+ easing.type: Easing.OutQuad
+ duration: 250
+ to: 0
+ onStopped: {
+ _expandIndex = -1
+ flickable.setCurrentItemFocus()
+ root.animateToCurrentIndex()
+ if (_newExpandIndex !== -1)
+ flickable.expand()
+ }
+ }
+
+ PropertyAnimation {
+ id: animateExpandItem;
+ target: flickable.expandItem;
+ properties: "height"
+ easing.type: Easing.InQuad
+ duration: 250
+ from: 0
+ }
+
+ function setCurrentItemFocus() {
+ var child
+ if (currentIndex in idChildrenMap)
+ child = idChildrenMap[currentIndex]
+ if (child !== undefined && _expandIndex === -1)
+ child.focus = true
}
}
- onCurrentIndexChanged: {
- if ( flickable._yOfIndex(root.currentIndex) + root.cellHeight > flickable.bottomContentY) {
- //move viewport to see expanded item bottom
- flickable.contentY = Math.min(
- flickable._yOfIndex(root.currentIndex) + root.cellHeight - flickable.height, // + flickable.marginBottom,
+ PropertyAnimation {
+ id: animateContentY;
+ target: flickable;
+ properties: "contentY"
+ }
+
+ function animateFlickableContentY( newContentY ) {
+ animateContentY.stop()
+ animateContentY.duration = 250
+ animateContentY.to = newContentY
+ animateContentY.start()
+ }
+
+ function animateToCurrentIndex() {
+ var newContentY = flickable.contentY;
+ var currentItemYPos = flickable.getItemPos(currentIndex)[1]
+ if (currentItemYPos + cellHeight > flickable.contentY + flickable.height) {
+ //move viewport to see current item bottom
+ newContentY = Math.min(
+ currentItemYPos + cellHeight - flickable.height,
flickable.contentHeight - flickable.height)
- } else if (flickable._yOfIndex(root.currentIndex) < flickable.contentY) {
- //move viewport to see expanded item at top
- flickable.contentY = Math.max(
- flickable._yOfIndex(root.currentIndex) - root.marginTop,
- 0)
+ } else if (currentItemYPos < flickable.contentY) {
+ //move viewport to see current item top
+ newContentY = Math.max(currentItemYPos, 0)
}
+
+ if (newContentY !== flickable.contentY)
+ animateFlickableContentY(newContentY)
}
- onExpandIndexChanged: {
- if (expandIndex != -1) {
- //move viewport to see expanded item at top
- flickable.contentY = Math.max( (flickable._rowOfIndex( root.expandIndex ) * root.cellHeight) - root.marginTop, 0)
- }
+ onCurrentIndexChanged: {
+ flickable.setCurrentItemFocus()
+ animateToCurrentIndex()
}
Keys.onPressed: {
+ var colCount = flickable.getNbItemsPerRow()
+
var newIndex = -1
if (event.key === Qt.Key_Right || event.matches(StandardKey.MoveToNextChar)) {
- if ((root.currentIndex + 1) % flickable._colCount !== 0) {//are we not at the end of line
- newIndex = Math.min(root.modelCount - 1, root.currentIndex + 1)
+ if ((currentIndex + 1) % colCount !== 0) {//are we not at the end of line
+ newIndex = Math.min(root.modelCount - 1, currentIndex + 1)
}
} else if (event.key === Qt.Key_Left || event.matches(StandardKey.MoveToPreviousChar)) {
- if (root.currentIndex % flickable._colCount !== 0) {//are we not at the begining of line
- newIndex = Math.max(0, root.currentIndex - 1)
+ if (currentIndex % colCount !== 0) {//are we not at the begining of line
+ newIndex = Math.max(0, currentIndex - 1)
}
} else if (event.key === Qt.Key_Down || event.matches(StandardKey.MoveToNextLine) ||event.matches(StandardKey.SelectNextLine) ) {
- if (Math.floor(root.currentIndex / flickable._colCount) !== Math.floor(root.modelCount / flickable._colCount)) { //we are not on the last line
- newIndex = Math.min(root.modelCount - 1, root.currentIndex + flickable._colCount)
+ if (Math.floor(currentIndex / colCount) !== Math.floor(root.modelCount / colCount)) { //we are not on the last line
+ newIndex = Math.min(root.modelCount - 1, currentIndex + colCount)
}
} else if (event.key === Qt.Key_PageDown || event.matches(StandardKey.MoveToNextPage) ||event.matches(StandardKey.SelectNextPage)) {
- newIndex = Math.min(root.modelCount - 1, root.currentIndex + flickable._colCount * 5)
+ newIndex = Math.min(root.modelCount - 1, currentIndex + colCount * 5)
} else if (event.key === Qt.Key_Up || event.matches(StandardKey.MoveToPreviousLine) ||event.matches(StandardKey.SelectPreviousLine)) {
- if (Math.floor(root.currentIndex / flickable._colCount) !== 0) { //we are not on the first line
- newIndex = Math.max(0, root.currentIndex - flickable._colCount)
+ if (Math.floor(currentIndex / colCount) !== 0) { //we are not on the first line
+ newIndex = Math.max(0, currentIndex - colCount)
}
} else if (event.key === Qt.Key_PageUp || event.matches(StandardKey.MoveToPreviousPage) ||event.matches(StandardKey.SelectPreviousPage)) {
- newIndex = Math.max(0, root.currentIndex - flickable._colCount * 5)
+ newIndex = Math.max(0, currentIndex - colCount * 5)
}
- if (newIndex != -1 && newIndex != root.currentIndex) {
+ if (newIndex != -1 && newIndex != currentIndex) {
event.accepted = true
var oldIndex = currentIndex
currentIndex = newIndex
root.selectionUpdated(event.modifiers, oldIndex, newIndex)
+ flickable.layout()
}
if (!event.accepted)
@@ -329,7 +416,7 @@ NavigableFocusScope {
root.selectAll()
} else if (event.key === Qt.Key_Space || event.matches(StandardKey.InsertParagraphSeparator)) { //enter/return/space
event.accepted = true
- root.actionAtIndex(root.currentIndex)
+ root.actionAtIndex(currentIndex)
}
}
}
diff --git a/modules/gui/qt/qml/utils/KeyNavigableListView.qml b/modules/gui/qt/qml/utils/KeyNavigableListView.qml
index c5eb93d240..4490282d91 100644
--- a/modules/gui/qt/qml/utils/KeyNavigableListView.qml
+++ b/modules/gui/qt/qml/utils/KeyNavigableListView.qml
@@ -51,6 +51,7 @@ NavigableFocusScope {
property alias headerItem: view.headerItem
property alias currentIndex: view.currentIndex
+ property alias currentItem: view.currentItem
property alias highlightMoveVelocity: view.highlightMoveVelocity
diff --git a/modules/gui/qt/qml/utils/KeyNavigableTableView.qml b/modules/gui/qt/qml/utils/KeyNavigableTableView.qml
index 3be87f7709..178ab54c86 100644
--- a/modules/gui/qt/qml/utils/KeyNavigableTableView.qml
+++ b/modules/gui/qt/qml/utils/KeyNavigableTableView.qml
@@ -40,6 +40,9 @@ NavigableFocusScope {
property alias section: view.section
+ property alias currentIndex: view.currentIndex
+ property alias currentItem: view.currentItem
+
Utils.SelectableDelegateModel {
id: delegateModel
--
2.20.1
More information about the vlc-devel
mailing list