[vlc-devel] [PATCH 14/16] qml: access directly to model data in ExpandGridView
Pierre Lamot
pierre at videolabs.io
Wed May 27 17:06:55 CEST 2020
---
.../gui/qt/medialibrary/qml/MusicGenres.qml | 3 +-
modules/gui/qt/widgets/qml/ExpandGridView.qml | 162 +++++++++++-------
2 files changed, 101 insertions(+), 64 deletions(-)
diff --git a/modules/gui/qt/medialibrary/qml/MusicGenres.qml b/modules/gui/qt/medialibrary/qml/MusicGenres.qml
index cdcb36a232..15ba25b560 100644
--- a/modules/gui/qt/medialibrary/qml/MusicGenres.qml
+++ b/modules/gui/qt/medialibrary/qml/MusicGenres.qml
@@ -107,7 +107,8 @@ Widgets.NavigableFocusScope {
if (delegateModelId.selectedGroup.count > 1) {
medialib.addAndPlay(model.getIdsForIndexes(delegateModelId.selectedIndexes()))
} else if (delegateModelId.selectedGroup.count === 1) {
- showAlbumView( delegateModelId.selectedGroup.get(0).model )
+ var sel = delegateModelId.selectedIndexes()[0]
+ showAlbumView( genreModel.getDataAt(sel) )
}
}
}
diff --git a/modules/gui/qt/widgets/qml/ExpandGridView.qml b/modules/gui/qt/widgets/qml/ExpandGridView.qml
index 7fecd16333..eb7332eaf9 100644
--- a/modules/gui/qt/widgets/qml/ExpandGridView.qml
+++ b/modules/gui/qt/widgets/qml/ExpandGridView.qml
@@ -40,6 +40,8 @@ NavigableFocusScope {
property alias contentX: flickable.contentX
property bool isAnimating: animateRetractItem.running || animateExpandItem.running
+ property int _count: 0
+
property bool _isInitialised: false
/// the id of the item to be expanded
@@ -66,7 +68,7 @@ NavigableFocusScope {
Accessible.role: Accessible.Table
function switchExpandItem(index) {
- if (delegateModel.count === 0)
+ if (_count === 0)
return
if (index === _expandIndex)
@@ -112,7 +114,7 @@ NavigableFocusScope {
if (index <= 0) {
animateFlickableContentY(0)
return
- } else if (index >= delegateModel.count) {
+ } else if (index >= _count) {
return
}
@@ -189,11 +191,90 @@ NavigableFocusScope {
var firstId = Math.max(rowId * root.getNbItemsPerRow(), 0)
rowId = Math.ceil((contentYWithoutExpand + heightWithoutExpand) / root.cellHeight)
- var lastId = Math.min(rowId * root.getNbItemsPerRow(), delegateModel.count)
+ var lastId = Math.min(rowId * root.getNbItemsPerRow(), _count)
return [firstId, lastId]
}
+ function _setupChild(id, ydelta) {
+ var item
+ var pos = root.getItemPos(id)
+
+ if (id in _idChildrenMap) {
+ // re-position
+
+ item = _idChildrenMap[id]
+ if (item === undefined)
+ throw "wrong child: " + id
+ //theses properties are always defined in Item
+ item.focus = (id === root.currentIndex) && (root._expandIndex === -1)
+ item.x = pos[0]
+ item.y = pos[1] + ydelta
+
+ } else if (_unusedItemList.length > 0) {
+ //recyle
+
+ item = _unusedItemList.pop()
+ if (item === undefined)
+ throw "wrong toRecycle child " + id + ", len " + toUse.length
+
+ _defineObjProperty(item, "index", id)
+ item.model = model.getDataAt(id)
+
+ item.focus = (id === root.currentIndex) && (root._expandIndex === -1)
+ item.x = pos[0]
+ item.y = pos[1] + ydelta
+ item.visible = true
+
+ _idChildrenMap[id] = item
+
+ } else {
+ //instanciate a new item
+
+ item = root.delegate.createObject( flickable.contentItem, {
+ model: model.getDataAt(id),
+ focus: (id === root.currentIndex) && (root._expandIndex === -1),
+ x: pos[0],
+ y: pos[1] + ydelta,
+ visible: true
+ });
+ if (item === undefined)
+ throw "wrong unable to instantiate child " + id
+ _defineObjProperty(item, "index", id)
+ _idChildrenMap[id] = item
+ }
+ return item
+ }
+
+ function _refreshData( iMin, iMax ) {
+ var f_l = _getFirstAndLastInstanciatedItemIds()
+ if (!iMin || iMin < f_l[0])
+ iMin = f_l[0]
+ if (!iMax || iMax > f_l[1])
+ iMax= f_l[1]
+
+ for (var id = iMin; id <= iMax; id++) {
+ var item = _idChildrenMap[id]
+ if (!item) {
+ continue
+ }
+ item.model = model.getDataAt(id)
+ }
+ }
+
+ function _onModelCountChanged() {
+ _count = model ? model.rowCount() : 0
+ if (!root._isInitialised)
+ return
+
+ // Hide the expandItem with no animation
+ _expandIndex = -1
+
+ // Regenerate the gridview layout
+ flickable.layout(true)
+ _refreshData()
+ }
+
Connections {
target: model
onDataChanged: {
@@ -202,10 +283,16 @@ NavigableFocusScope {
var f_l = _getFirstAndLastInstanciatedItemIds()
if (iMin <= f_l[1] && f_l[0] <= iMax) {
flickable.layout(true)
+ _refreshData(iMin, iMax)
}
}
+ onRowsInserted: _onModelCountChanged()
+ onRowsRemoved: _onModelCountChanged()
+ onModelReset: _onModelCountChanged()
}
+ onModelChanged: _onModelCountChanged()
+
//Gridview visible above the expanded item
Flickable {
id: flickable
@@ -258,40 +345,11 @@ NavigableFocusScope {
var rowId = rowCol[1] + 1
ret = rowId * root.getNbItemsPerRow()
} else {
- ret = delegateModel.count
+ ret = _count
}
return ret
}
- 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
- }
-
- function initialiseItem(item, i, ydelta) {
- var pos = root.getItemPos(i)
- _defineObjProperty(item, "index", i)
- //theses needs an actual binding
- item.model = delegateModel.items.get(i).model
-
- //theses properties are always defined in Item
- item.focus = (i === root.currentIndex) && (root._expandIndex === -1)
- item.x = pos[0]
- item.y = pos[1] + ydelta
- item.visible = true
- }
-
function layout(forceRelayout) {
if (flickable.width === 0 || flickable.height === 0)
return
@@ -323,14 +381,6 @@ NavigableFocusScope {
}
_idChildrenMap = toKeep
- // Create delegates if we do not have enough
- if (nbItems > _unusedItemList.length + Object.keys(toKeep).length) {
- var toCreate = nbItems - (_unusedItemList.length + Object.keys(toKeep).length)
- for (i = 0; i < toCreate; ++i) {
- val = root.delegate.createObject(contentItem);
- _unusedItemList.push(val)
- }
- }
var item
var pos
@@ -338,8 +388,7 @@ NavigableFocusScope {
for (i = firstId; i < topGridEndId; ++i) {
if (!forceRelayout && i in _idChildrenMap)
continue
- item = getChild(i, _unusedItemList)
- initialiseItem(item, i, 0)
+ _setupChild(i, 0)
}
if (root._expandIndex !== -1)
@@ -349,12 +398,11 @@ NavigableFocusScope {
for (i = topGridEndId; i < lastId; ++i) {
if (!forceRelayout && i in _idChildrenMap)
continue
- item = getChild(i, _unusedItemList)
- initialiseItem(item, i, expandItem.height)
+ _setupChild(i, expandItem.height)
}
// Calculate and set the contentHeight
- var newContentHeight = root.getItemPos(delegateModel.count - 1)[1] + root.cellHeight
+ var newContentHeight = root.getItemPos(_count - 1)[1] + root.cellHeight
if (root._expandIndex !== -1)
newContentHeight += expandItem.height
contentHeight = newContentHeight
@@ -363,18 +411,6 @@ NavigableFocusScope {
_updateSelected()
}
- Connections {
- target: delegateModel.items
- onChanged: {
- // Hide the expandItem with no animation
- _expandIndex = -1
-
- //expandItem.height = 0
- // Regenerate the gridview layout
- flickable.layout(true)
- }
- }
-
Connections {
target: expandItem
onHeightChanged: {
@@ -408,7 +444,7 @@ NavigableFocusScope {
_expandIndex = _newExpandIndex
if (_expandIndex === -1)
return
- expandItem.model = delegateModel.items.get(_expandIndex).model
+ expandItem.model = model.getDataAt(_expandIndex)
/* 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()
@@ -501,18 +537,18 @@ NavigableFocusScope {
var newIndex = -1
if (KeyHelper.matchRight(event)) {
if ((currentIndex + 1) % colCount !== 0) {//are we not at the end of line
- newIndex = Math.min(delegateModel.count - 1, currentIndex + 1)
+ newIndex = Math.min(_count - 1, currentIndex + 1)
}
} else if (KeyHelper.matchLeft(event)) {
if (currentIndex % colCount !== 0) {//are we not at the begining of line
newIndex = Math.max(0, currentIndex - 1)
}
} else if (KeyHelper.matchDown(event)) {
- if (Math.floor(currentIndex / colCount) !== Math.floor(delegateModel.count / colCount)) { //we are not on the last line
- newIndex = Math.min(delegateModel.count - 1, currentIndex + colCount)
+ if (Math.floor(currentIndex / colCount) !== Math.floor(_count / colCount)) { //we are not on the last line
+ newIndex = Math.min(_count - 1, currentIndex + colCount)
}
} else if (KeyHelper.matchPageDown(event)) {
- newIndex = Math.min(delegateModel.count - 1, currentIndex + colCount * 5)
+ newIndex = Math.min(_count - 1, currentIndex + colCount * 5)
} else if (KeyHelper.matchUp(event)) {
if (Math.floor(currentIndex / colCount) !== 0) { //we are not on the first line
newIndex = Math.max(0, currentIndex - colCount)
--
2.25.1
More information about the vlc-devel
mailing list