@@ -50,25 +50,21 @@ Item {
50 row.setCurrentItemIndex(index);
50 row.setCurrentItemIndex(index);
53− function alignIndicatorsToLeft() {
53+ function alignIndicators() {
54− alignmentTimer.start()
54+ alignmentTimer.start();
57 function addScrollOffset(scrollAmmout) {
57 function addScrollOffset(scrollAmmout) {
58− var proposedScrollOffset = d.scrollOffset + scrollAmmout;
58+ if (scrollAmmout < 0) { // left scroll
59− var proposedCombinedOffset = d.combinedOffset - scrollAmmout;
59+ if (flickable.contentX < 0) return; // already off the left.
60−
60+ if (flickable.contentX + scrollAmmout < 0) scrollAmmout = -flickable.contentX; // going to be off the left
61− if (scrollAmmout < 0 && d.combinedOffset > (row.width - rowContainer.width)) return;
61+ } else { // right scroll
62−
62+ if (flickable.contentX + flickable.width > row.width) return; // already off the right.
63− if (scrollAmmout > 0 && proposedCombinedOffset < 0) {
63+ if (flickable.contentX + flickable.width + scrollAmmout > row.width) { // going to be off the right
64− // get the combined offset back to 0
64+ scrollAmmout = row.width - (flickable.contentX + flickable.width);
65− proposedScrollOffset = proposedScrollOffset + proposedCombinedOffset;
65+ }
66− } else if (scrollAmmout < 0 && proposedCombinedOffset > row.width - rowContainer.width) {
67− // get the combined offset back to max
68− proposedScrollOffset = proposedScrollOffset + (proposedCombinedOffset - (row.width - rowContainer.width));
70−
67+ d.scrollOffset = d.scrollOffset + scrollAmmout;
71− d.scrollOffset = proposedScrollOffset;
74 QtObject {
70 QtObject {
@@ -76,7 +72,6 @@ Item {
76 property var initialItem
72 property var initialItem
77 // the non-expanded distance from row offset to center of initial item
73 // the non-expanded distance from row offset to center of initial item
78 property real originalDistanceFromRight: -1
74 property real originalDistanceFromRight: -1
79− property real originalItemWidth: -1
81 // calculate the distance from row offset to center of initial item
76 // calculate the distance from row offset to center of initial item
82 property real distanceFromRight: {
77 property real distanceFromRight: {
@@ -87,37 +82,19 @@ Item {
88 // offset to the intially selected expanded item
83 // offset to the intially selected expanded item
89 property real rowOffset: 0
84 property real rowOffset: 0
90− property real alignmentAdjustment: 0
91 property real scrollOffset: 0
85 property real scrollOffset: 0
92− property real combinedOffset: rowOffset + alignmentAdjustment - scrollOffset
86+ property real alignmentAdjustment: 0
87+ property real combinedOffset: 0
94 // when the scroll offset changes, we need to reclaculate the relative lateral position
89 // when the scroll offset changes, we need to reclaculate the relative lateral position
95 onScrollOffsetChanged: root.lateralPositionChanged()
90 onScrollOffsetChanged: root.lateralPositionChanged()
97 onInitialItemChanged: {
92 onInitialItemChanged: {
99− originalItemWidth = initialItem.width;
100− originalDistanceFromRight = row.width - initialItem.x - initialItem.width/2;
93+ originalDistanceFromRight = initialItem ? (row.width - initialItem.x - initialItem.width/2) : -1;
102− originalItemWidth = -1;
103− originalDistanceFromRight = -1;
107 Behavior on alignmentAdjustment {
96 Behavior on alignmentAdjustment {
108− NumberAnimation { duration: UbuntuAnimation.SnapDuration; easing: UbuntuAnimation.StandardEasing}
97+ NumberAnimation { duration: UbuntuAnimation.BriskDuration; easing: UbuntuAnimation.StandardEasing}
112− onExpandedChanged: {
113− if (!expanded) flickable.moved = false;
118− onCurrentItemChanged: {
119− if (!row.currentItem) d.initialItem = undefined;
120− else if (!d.initialItem) d.initialItem = row.currentItem;
@@ -137,34 +114,15 @@ Item {
137 anchors.fill: parent
114 anchors.fill: parent
138 clip: expanded || row.width > rowContainer.width
115 clip: expanded || row.width > rowContainer.width
142− objectName: "indicatorItemRow"
145− bottom: parent.bottom
147− rightMargin: -d.combinedOffset
151− if (root.lateralPosition == -1) return -1;
153− var mapped = root.mapToItem(row, root.lateralPosition, 0);
154− return Math.min(Math.max(mapped.x, 0), row.width);
158 Flickable {
117 Flickable {
159 id: flickable
118 id: flickable
119+ objectName: "flickable"
160 anchors.fill: parent
121 anchors.fill: parent
161 contentWidth: row.width
122 contentWidth: row.width
162 interactive: root.expanded
123 interactive: root.expanded
163−
124+ // align right + offset from row selection + scrolling
164− property bool moved: false
125+ contentX: row.width - flickable.width - d.combinedOffset
169 rebound: Transition {
127 rebound: Transition {
170 NumberAnimation {
128 NumberAnimation {
@@ -174,21 +132,46 @@ Item {
137+ objectName: "indicatorItemRow"
140+ bottom: parent.bottom
144+ if (root.lateralPosition == -1) return -1;
146+ var mapped = root.mapToItem(row, root.lateralPosition, 0);
147+ return Math.min(Math.max(mapped.x, 0), row.width);
150+ onCurrentItemChanged: {
151+ if (!currentItem) d.initialItem = undefined;
152+ else if (!d.initialItem) d.initialItem = currentItem;
177− MouseArea {
155+ MouseArea {
178− anchors.fill: parent
156+ anchors.fill: parent
179− enabled: root.expanded
157+ enabled: root.expanded
180− onClicked: row.selectItemAt(mouse.x);
159+ row.selectItemAt(mouse.x);
186 id: alignmentTimer
169 id: alignmentTimer
187− interval: UbuntuAnimation.SnapDuration // enough for row animation.
170+ interval: UbuntuAnimation.FastDuration // enough for row animation.
188 repeat: false
171 repeat: false
189 onTriggered: {
172 onTriggered: {
190− if (expanded && row.x > 0) {
173+ if (expanded && !flickable.moving && row.width > flickable.width && flickable.contentX < 0) { // off the left.
191− d.alignmentAdjustment = -row.x;
174+ d.alignmentAdjustment += flickable.contentX;
@@ -200,14 +183,19 @@ Item {
200 PropertyChanges {
183 PropertyChanges {
201 target: d
184 target: d
202 rowOffset: 0
185 rowOffset: 0
203− alignmentAdjustment: 0
204 scrollOffset: 0
186 scrollOffset: 0
187+ alignmentAdjustment: 0
205 restoreEntryValues: false
188 restoreEntryValues: false
209 name: "expanded"
192 name: "expanded"
210− when: expanded && !flickable.moved
193+ when: expanded
197+ combinedOffset: rowOffset + alignmentAdjustment - scrollOffset
212 PropertyChanges {
200 PropertyChanges {
213 target: d
201 target: d
@@ -216,34 +204,10 @@ Item {
216 if (distanceFromRight - initialItem.width <= 0) return 0;
204 if (distanceFromRight - initialItem.width <= 0) return 0;
218 var rowOffset = distanceFromRight - originalDistanceFromRight;
206 var rowOffset = distanceFromRight - originalDistanceFromRight;
219− if (originalDistanceFromRight + originalItemWidth/2 > rowContainer.width) {
220− rowOffset = rowOffset + originalItemWidth;
222 return rowOffset;
207 return rowOffset;
225− // keep flickable inline with row
228− contentX: (flickable.contentWidth - flickable.width) - d.combinedOffset
229 restoreEntryValues: false
209 restoreEntryValues: false
234− when: expanded && flickable.moved
239− flickable.contentX = flickable.contentX;
245− anchors.rightMargin: - (flickable.contentWidth - flickable.width) + (flickable.contentX) + d.scrollOffset
@@ -251,25 +215,17 @@ Item {
251 Transition {
215 Transition {
252 from: "expanded"
216 from: "expanded"
253 to: "minimized"
217 to: "minimized"
220+ properties: "rowOffset, scrollOffset, alignmentAdjustment"
254 PropertyAnimation {
223 PropertyAnimation {
255− target: d;
224+ target: d
256− properties: "rowOffset, scrollOffset"
225+ properties: "combinedOffset"
257 duration: UbuntuAnimation.SnapDuration
226 duration: UbuntuAnimation.SnapDuration
258 easing: UbuntuAnimation.StandardEasing
227 easing: UbuntuAnimation.StandardEasing
264− SequentialAnimation {
265− PropertyAction { target: d; properties: "rowOffset, alignmentAdjustment, scrollOffset" }
268− properties: "anchors.rightMargin"
269− duration: UbuntuAnimation.SnapDuration
270− easing: UbuntuAnimation.StandardEasing