on xenial help sign in
Compensate for PanelItemRow's origin changing

The QtQuick Flickable documentation [1] states that, "If you flick back to the origin, after the rebound animation, contentX will settle to the same value as originX. These are usually (0,0), however ListView and GridView may have an arbitrary origin..." This was causing problems for us in the Indicators. Some events, such as a manual 'show()' of the PanelMenu, could cause the ListView's origin to shift. When this occured, the highlight would be incorrect and other interactions would not work correctly. For example, trying to select the rightmost indicator would cause the leftmost to be selected. To fix this, use the PanelItemRow's contentX to compensate some values of X for the difference. Fixes https://github.com/ubports/ubuntu-touch/issues/1364 [1] https://doc.qt.io/qt-5/qml-qtquick-flickable.html#contentX-prop

commitb7f044eae73cfaa21059efa1be3fd2ee3aa8a752 authorRatchanan Srirattanamet <ratchanan@ubports.com> dateWed 4 Mar 2020, 10:29 (7 years ago) parent58d9a03
4 files changed+21−12
qml/Panel/Panel.qml+1−1 qml/Panel/PanelBar.qml+10−8 qml/Panel/PanelItemRow.qml+5−3 qml/Panel/PanelMenu.qml+5
qml/Panel/Panel.qml+1−1
@@ -411,7 +411,7 @@ Item {
411411 objectName: identifier+"-panelItem"
412412
413413 property int ownIndex: index
414− readonly property bool overflow: parent.width - x > __indicators.overFlowWidth
414+ readonly property bool overflow: parent.width - (x - __indicators.rowContentX) > __indicators.overFlowWidth
415415 readonly property bool hidden: !expanded && (overflow || !indicatorVisible || hideSessionIndicator || hideKeyboardIndicator)
416416 // HACK for indicator-session
417417 readonly property bool hideSessionIndicator: identifier == "indicator-session" && Math.min(Screen.width, Screen.height) <= units.gu(60)
qml/Panel/PanelBar.qml+10−8
@@ -1,5 +1,6 @@
11/*
22 * Copyright (C) 2014 Canonical, Ltd.
3+ * Copyright (C) 2020 UBports Foundation
34 *
45 * This program is free software; you can redistribute it and/or modify
56 * it under the terms of the GNU General Public License as published by
@@ -29,6 +30,7 @@ Item {
2930 readonly property alias currentItemIndex: row.currentItemIndex
3031 property real lateralPosition: -1
3132 property int alignment: Qt.AlignRight
33+ readonly property int rowContentX: row.contentX
3234
3335 property alias hideRow: row.hideRow
3436 property alias rowItemDelegate: row.delegate
@@ -133,12 +135,12 @@ Item {
133135
134136 if (root.alignment == Qt.AlignLeft) {
135137 // current item overlap on left
136− if (row.currentItem && flickable.contentX > row.currentItem.x) {
137− d.alignmentAdjustment -= (flickable.contentX - row.currentItem.x);
138+ if (row.currentItem && flickable.contentX > (row.currentItem.x - row.contentX)) {
139+ d.alignmentAdjustment -= (flickable.contentX - (row.currentItem.x - row.contentX));
138140
139141 // current item overlap on right
140− } else if (row.currentItem && flickable.contentX + flickable.width < row.currentItem.x + row.currentItem.width) {
141− d.alignmentAdjustment += (row.currentItem.x + row.currentItem.width) - (flickable.contentX + flickable.width);
142+ } else if (row.currentItem && flickable.contentX + flickable.width < (row.currentItem.x - row.contentX) + row.currentItem.width) {
143+ d.alignmentAdjustment += ((row.currentItem.x - row.contentX) + row.currentItem.width) - (flickable.contentX + flickable.width);
142144 }
143145 } else {
144146 // gap between left and row?
@@ -155,12 +157,12 @@ Item {
155157 d.alignmentAdjustment -= flickable.contentX;
156158
157159 // current item overlap on left
158− } else if (row.currentItem && (flickable.contentX + flickable.width) < (row.width - row.currentItem.x)) {
159− d.alignmentAdjustment += ((row.width - row.currentItem.x) - (flickable.contentX + flickable.width));
160+ } else if (row.currentItem && (flickable.contentX + flickable.width) < (row.width - (row.currentItem.x - row.contentX))) {
161+ d.alignmentAdjustment += ((row.width - (row.currentItem.x - row.contentX)) - (flickable.contentX + flickable.width));
160162
161163 // current item overlap on right
162− } else if (row.currentItem && flickable.contentX > (row.width - row.currentItem.x - row.currentItem.width)) {
163− d.alignmentAdjustment -= flickable.contentX - (row.width - row.currentItem.x - row.currentItem.width);
164+ } else if (row.currentItem && flickable.contentX > (row.width - (row.currentItem.x - row.contentX) - row.currentItem.width)) {
165+ d.alignmentAdjustment -= flickable.contentX - (row.width - (row.currentItem.x - row.contentX) - row.currentItem.width);
164166 }
165167 }
166168 }
qml/Panel/PanelItemRow.qml+5−3
@@ -1,5 +1,6 @@
11/*
22 * Copyright (C) 2013-2014 Canonical, Ltd.
3+ * Copyright (C) 2020 UBports Foundation
34 *
45 * This program is free software; you can redistribute it and/or modify
56 * it under the terms of the GNU General Public License as published by
@@ -36,6 +37,7 @@ Item {
3637 property color hightlightColor: "#ffffff"
3738
3839 property alias delegate: row.delegate
40+ property alias contentX: row.contentX
3941
4042 property real lateralPosition: -1
4143 onLateralPositionChanged: {
@@ -85,7 +87,7 @@ Item {
8587 }
8688
8789 function indicatorAt(x, y) {
88− var item = row.itemAt(x, y);
90+ var item = row.itemAt(x + row.contentX, y);
8991 return item && item.hasOwnProperty("ownIndex") ? item : null;
9092 }
9193
@@ -184,7 +186,7 @@ Item {
184186 ScriptAction {
185187 script: {
186188 d.forceAlignmentAnimationDisabled = true;
187− highlight.currentItemX = Qt.binding(function() { return currentItem ? currentItem.x : 0 });
189+ highlight.currentItemX = Qt.binding(function() { return currentItem ? currentItem.x - row.contentX : 0 });
188190 d.forceAlignmentAnimationDisabled = false;
189191 }
190192 }
@@ -235,7 +237,7 @@ Item {
235237 NumberAnimation { duration: UbuntuAnimation.FastDuration; easing: UbuntuAnimation.StandardEasing }
236238 }
237239
238− property real currentItemX: currentItem ? currentItem.x : 0
240+ property real currentItemX: currentItem ? currentItem.x - row.contentX : 0
239241 Behavior on currentItemX {
240242 id: currentItemXBehavior
241243 enabled: !d.firstItemSwitch && expanded && !d.forceAlignmentAnimationDisabled
qml/Panel/PanelMenu.qml+5
@@ -49,6 +49,11 @@ Showable {
4949 readonly property int barWidth: bar.width
5050 readonly property alias currentMenuIndex: bar.currentItemIndex
5151
52+ // Exposes the current contentX of the PanelBar's internal ListView. This
53+ // must be used to offset absolute x values against the ListView, since
54+ // we commonly add or remove elements and cause the contentX to change.
55+ readonly property int rowContentX: bar.rowContentX
56+
5257 // The user tapped the panel and did not move.
5358 // Note that this does not fire on mouse events, only touch events.
5459 signal showTapped()