Merge lp:~zsombi/ubuntu-ui-toolkit/55-snap-options into lp:~zsombi/ubuntu-ui-toolkit/listitem-master

Proposed by Zsombor Egri
Status: Merged
Approved by: Tim Peeters
Approved revision: 1314
Merged at revision: 1276
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/55-snap-options
Merge into: lp:~zsombi/ubuntu-ui-toolkit/listitem-master
Prerequisite: lp:~zsombi/ubuntu-ui-toolkit/50-custom-delegates
Diff against target: 805 lines (+261/-109)
14 files modified
components.api (+2/-1)
modules/Ubuntu/Components/Themes/Ambiance/ListItemPanel.qml (+25/-2)
modules/Ubuntu/Components/Themes/Ambiance/ListItemStyle.qml (+5/-3)
modules/Ubuntu/Components/plugin/uclistitem.cpp (+76/-19)
modules/Ubuntu/Components/plugin/uclistitem.h (+2/-0)
modules/Ubuntu/Components/plugin/uclistitem_p.h (+5/-1)
modules/Ubuntu/Components/plugin/uclistitemactions.cpp (+5/-5)
modules/Ubuntu/Components/plugin/uclistitemactions.h (+0/-3)
modules/Ubuntu/Components/plugin/uclistitemactions_p.h (+1/-0)
modules/Ubuntu/Components/plugin/uclistitemactionsattached.cpp (+0/-24)
modules/Ubuntu/Components/plugin/uclistitemstyle.cpp (+12/-34)
modules/Ubuntu/Components/plugin/uclistitemstyle.h (+8/-9)
modules/Ubuntu/Test/UbuntuTestCase.qml (+3/-6)
tests/unit_x11/tst_components/tst_listitem.qml (+117/-2)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/55-snap-options
Reviewer Review Type Date Requested Status
Tim Peeters Approve
Review via email: mp+235172@code.launchpad.net

Commit message

Snap In/Out implementation.

To post a comment you must log in.
1261. By Zsombor Egri

prereq sync

1262. By Zsombor Egri

prereq sync

1263. By Zsombor Egri

prereq sync

1264. By Zsombor Egri

tests fixed

1265. By Zsombor Egri

prereq sync

1266. By Zsombor Egri

test fixes on naming

1267. By Zsombor Egri

prereq sync

1268. By Zsombor Egri

test fix

1269. By Zsombor Egri

prereq merge

1270. By Zsombor Egri

prereq sync

1271. By Zsombor Egri

prereq sync

1272. By Zsombor Egri

prereq sync

1273. By Zsombor Egri

prereq sync

1274. By Zsombor Egri

prereq sync

1275. By Zsombor Egri

prereq sync

1276. By Zsombor Egri

prereq sync

1277. By Zsombor Egri

overshoot

1278. By Zsombor Egri

overshoot completed

1279. By Zsombor Egri

test case fix

1280. By Zsombor Egri

prereq sync

1281. By Zsombor Egri

test cases adjusted to the new snapping logic

1282. By Zsombor Egri

snap out when actions list is changed

1283. By Zsombor Egri

provide a better name for rebounding with no animation

1284. By Zsombor Egri

prereq sync

1285. By Zsombor Egri

prereq sync

1286. By Zsombor Egri

tests fixed

1287. By Zsombor Egri

reboundTo renamed into snapTo

1288. By Zsombor Egri

prereq sync

1289. By Zsombor Egri

prereq sync

1290. By Zsombor Egri

prereq sync

1291. By Zsombor Egri

rename dragged to flicking as dragging will mean different thing

1292. By Zsombor Egri

test fixed

1293. By Zsombor Egri

test adjustments

1294. By Zsombor Egri

prereq sync

1295. By Zsombor Egri

fixing build and adjusting to prereq changes

1296. By Zsombor Egri

adding snap gesture test

1297. By Zsombor Egri

remove unneeded private slot

1298. By Zsombor Egri

prereq sync

1299. By Zsombor Egri

prereq sync

1300. By Zsombor Egri

prereq sync

1301. By Zsombor Egri

prereq sync

1302. By Zsombor Egri

prereq sync

1303. By Zsombor Egri

prereq sync

1304. By Zsombor Egri

leadingPAnel fixed

1305. By Zsombor Egri

prereq sync

1306. By Zsombor Egri

prereq sync

1307. By Zsombor Egri

prereq sync

Revision history for this message
Tim Peeters (tpeeters) wrote :

8 + // track drag dirrection, so we know in which direction we should snap

diRRection

Revision history for this message
Tim Peeters (tpeeters) wrote :

As a developer, I like to configure the overshoot when I use a custom delegate. Is that possible now? I have this delegate:

            delegate: Rectangle {
                color: delegateArea.pressed ? "orange" : "yellow"
                width: units.gu(10)
                ListItemActions.overshoot: 0
                Label {
                    text: action.text
                    anchors.centerIn: parent
                }
                MouseArea {
                    anchors.fill: parent
                    id: delegateArea
                    onPressed: print("press")
                }
            }

which is yellow, but when dragging I can pull a bit further and show the default white background of the panel. Can I disable the overshoot completely to avoid this?

Revision history for this message
Tim Peeters (tpeeters) wrote :

why is overshoot an attached property and not a property of ListItemActions directly?

Revision history for this message
Zsombor Egri (zsombi) wrote :

> As a developer, I like to configure the overshoot when I use a custom
> delegate. Is that possible now? I have this delegate:
>
> delegate: Rectangle {
> color: delegateArea.pressed ? "orange" : "yellow"
> width: units.gu(10)
> ListItemActions.overshoot: 0
> Label {
> text: action.text
> anchors.centerIn: parent
> }
> MouseArea {
> anchors.fill: parent
> id: delegateArea
> onPressed: print("press")
> }
> }
>
> which is yellow, but when dragging I can pull a bit further and show the
> default white background of the panel. Can I disable the overshoot completely
> to avoid this?

If you want to see the white background, you have to have a different actionsDelegate style component (perhaps we should name that differently?). Changing the overshoot to 0 would also mean that the panel cannot be dragged further than the panel size, so you won't see any background.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> why is overshoot an attached property and not a property of ListItemActions
> directly?

that property is needed for the panel for sure. I thought we should expose that in the style, but we can expose it as property to ListItem rather to ListItemActions. As it is not actions specific, it is more like ListItem specific.

1308. By Zsombor Egri

prereq sync

1309. By Zsombor Egri

typo fix

Revision history for this message
Tim Peeters (tpeeters) wrote :

> 8 + // track drag dirrection, so we know in which direction we should
> snap
>
> diRRection

I was highlighting the mistake, direction is with 1 r.

Revision history for this message
Tim Peeters (tpeeters) wrote :

add ListItem.swipeOvershoot, and the style can have a default value for that.

review: Needs Fixing
Revision history for this message
Zsombor Egri (zsombi) wrote :

> add ListItem.swipeOvershoot, and the style can have a default value for that.

Now, we have a slight problem with getting the value from the style... as the style component is loaded only when someone starts swiping the content... so I can only get the value from the style when the style is loaded. Of course this doesn't make any harm when a user value is set on ListItem, but may cause property changed signalled when the style gets loaded.

1310. By Zsombor Egri

swipeOvershoot added to ListItem, overshoot removed from ListItemActions attached properties. Styling added.

Revision history for this message
Tim Peeters (tpeeters) wrote :

286 + * \qmlproperty real ListItem::swipeOvershoot
287 + * The property configures the overshoot value on swiping. Its default value is configured by the style.
288 + */

You can link "style" to ListItemStyle

1311. By Zsombor Egri

overshoot fix

1312. By Zsombor Egri

overshoot fixes

1313. By Zsombor Egri

rogue print removed

1314. By Zsombor Egri

link to style component

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 286 + * \qmlproperty real ListItem::swipeOvershoot
> 287 + * The property configures the overshoot value on swiping. Its
> default value is configured by the style.
> 288 + */
>
> You can link "style" to ListItemStyle

Done.

Revision history for this message
Tim Peeters (tpeeters) wrote :

Perfect. >=0 overshoot works as expected now, and <0 overshoot sets the default value.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'components.api'
2--- components.api 2014-12-01 15:58:43 +0000
3+++ components.api 2014-12-01 15:58:45 +0000
4@@ -871,6 +871,7 @@
5 Property { name: "leadingActions"; type: "UCListItemActions"; isPointer: true }
6 Property { name: "trailingActions"; type: "UCListItemActions"; isPointer: true }
7 Property { name: "pressed"; type: "bool"; isReadonly: true }
8+ Property { name: "swipeOvershoot"; type: "double" }
9 Property { name: "contentMoving"; type: "bool"; isReadonly: true }
10 Property { name: "color"; type: "QColor" }
11 Property { name: "highlightColor"; type: "QColor" }
12@@ -900,7 +901,6 @@
13 Property { name: "offset"; type: "double"; isReadonly: true }
14 Property { name: "status"; type: "UCListItemActions::Status"; isReadonly: true }
15 Property { name: "swiping"; type: "bool"; isReadonly: true }
16- Property { name: "overshoot"; type: "double"; isReadonly: true }
17 Method {
18 name: "snapToPosition"
19 Parameter { name: "position"; type: "double" }
20@@ -919,6 +919,7 @@
21 Property { name: "selectionDelegate"; type: "QQmlComponent"; isPointer: true }
22 Property { name: "dragHandlerDelegate"; type: "QQmlComponent"; isPointer: true }
23 Property { name: "snapAnimation"; type: "QQuickPropertyAnimation"; isPointer: true }
24+ Property { name: "swipeOvershoot"; type: "double" }
25 name: "UCMouse"
26 prototype: "QObject"
27 exports: ["Mouse 0.1", "Mouse 1.0"]
28
29=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/ListItemPanel.qml'
30--- modules/Ubuntu/Components/Themes/Ambiance/ListItemPanel.qml 2014-12-01 15:58:43 +0000
31+++ modules/Ubuntu/Components/Themes/Ambiance/ListItemPanel.qml 2014-12-01 15:58:45 +0000
32@@ -70,8 +70,8 @@
33 anchors {
34 fill: parent
35 // add 4 times the overshoot margins to cover the background when tugged
36- leftMargin: leading ? -units.gu(4 * panel.ListItemActions.overshoot) : 0
37- rightMargin: leading ? 0 : -units.gu(4 * panel.ListItemActions.overshoot)
38+ leftMargin: (leading && panel.ListItemActions.listItem) ? -units.gu(4 * panel.ListItemActions.listItem.swipeOvershoot) : 0
39+ rightMargin: (!leading && panel.ListItemActions.listItem) ? -units.gu(4 * panel.ListItemActions.listItem.swipeOvershoot) : 0
40 }
41 color: panel.backgroundColor
42 }
43@@ -84,6 +84,29 @@
44 }
45 }
46
47+ // track drag direction, so we know in which direction we should snap
48+ property real prevX: 0.0
49+ property bool leftToRight: false
50+ onXChanged: {
51+ leftToRight = prevX < x;
52+ prevX = x;
53+ }
54+ // default snapping!
55+ ListItemActions.onSwipingChanged: {
56+ if (ListItemActions.swiping) {
57+ // the dragging got started, set prevX
58+ prevX = panel.x;
59+ return;
60+ }
61+ if (!visible) {
62+ return;
63+ }
64+ // snap in if the offset is bigger than the overshoot and the direction of the drag is to reveal the panel
65+ var snapPos = (ListItemActions.offset > ListItemActions.listItem.swipeOvershoot &&
66+ (leftToRight && leading || !leftToRight && !leading)) ? panel.width : 0.0;
67+ ListItemActions.snapToPosition(snapPos);
68+ }
69+
70 Row {
71 id: actionsRow
72 anchors {
73
74=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/ListItemStyle.qml'
75--- modules/Ubuntu/Components/Themes/Ambiance/ListItemStyle.qml 2014-12-01 15:58:43 +0000
76+++ modules/Ubuntu/Components/Themes/Ambiance/ListItemStyle.qml 2014-12-01 15:58:45 +0000
77@@ -1,6 +1,3 @@
78-import QtQuick 2.3
79-import Ubuntu.Components.Styles 1.2 as Styles
80-import Ubuntu.Components 1.2
81 /*
82 * Copyright 2014 Canonical Ltd.
83 *
84@@ -17,8 +14,13 @@
85 * along with this program. If not, see <http://www.gnu.org/licenses/>.
86 */
87
88+import QtQuick 2.3
89+import Ubuntu.Components.Styles 1.2 as Styles
90+import Ubuntu.Components 1.2
91+
92 Styles.ListItemStyle {
93
94+ swipeOvershoot: units.gu(2)
95 actionsDelegate: ListItemPanel{}
96
97 snapAnimation: PropertyAnimation {
98
99=== modified file 'modules/Ubuntu/Components/plugin/uclistitem.cpp'
100--- modules/Ubuntu/Components/plugin/uclistitem.cpp 2014-12-01 15:58:43 +0000
101+++ modules/Ubuntu/Components/plugin/uclistitem.cpp 2014-12-01 15:58:45 +0000
102@@ -22,6 +22,7 @@
103 #include "uclistitemactions_p.h"
104 #include "ucubuntuanimation.h"
105 #include "propertychange_p.h"
106+#include "i18n.h"
107 #include <QtQml/QQmlInfo>
108 #include <QtQuick/private/qquickitem_p.h>
109 #include <QtQuick/private/qquickflickable_p.h>
110@@ -164,9 +165,7 @@
111 QQuickPropertyAnimation *UCListItemSnapAnimator::getDefaultAnimation()
112 {
113 UCListItemPrivate *listItem = UCListItemPrivate::get(item);
114- if (!listItem->styleItem && listItem->loadStyle()) {
115- listItem->initStyleItem();
116- }
117+ listItem->initStyleItem();
118 return listItem->styleItem ? listItem->styleItem->m_snapAnimation : 0;
119 }
120
121@@ -334,8 +333,10 @@
122 , ready(false)
123 , customStyle(false)
124 , customColor(false)
125+ , customOvershoot(false)
126+ , flicked(false)
127 , xAxisMoveThresholdGU(1.5)
128- , overshoot(UCUnits::instance().gu(2))
129+ , overshoot(0)
130 , color(Qt::transparent)
131 , highlightColor(Qt::transparent)
132 , attachedProperties(0)
133@@ -384,7 +385,7 @@
134 highlightColor = getPaletteColor("selected", "background");
135 q->update();
136 }
137- loadStyle();
138+ loadStyle(true);
139 }
140
141 void UCListItemPrivate::_q_rebound()
142@@ -400,6 +401,7 @@
143 // rebound to zero
144 animator->snap(0);
145 }
146+
147 /*!
148 * \qmlproperty Component ListItem::style
149 * Holds the style of the component defining the components visualizing the leading/
150@@ -428,19 +430,19 @@
151 delete styleComponent;
152 customStyle = (delegate == 0);
153 styleComponent = delegate;
154- loadStyle();
155+ loadStyle(false);
156 Q_EMIT q->styleChanged();
157 }
158
159 // update themed components
160-bool UCListItemPrivate::loadStyle()
161+bool UCListItemPrivate::loadStyle(bool reload)
162 {
163 if (!ready) {
164 return false;
165 }
166- if (!customStyle && !styleComponent) {
167+ if (!customStyle) {
168 Q_Q(UCListItem);
169- if (styleItem) {
170+ if (reload && styleItem) {
171 delete styleItem;
172 styleItem = 0;
173 Q_EMIT q->__styleInstanceChanged();
174@@ -453,7 +455,7 @@
175 // creates the style item
176 void UCListItemPrivate::initStyleItem()
177 {
178- if (!styleComponent || styleItem) {
179+ if (!styleItem && !loadStyle(false)) {
180 return;
181 }
182 Q_Q(UCListItem);
183@@ -461,9 +463,18 @@
184 styleItem = qobject_cast<UCListItemStyle*>(object);
185 if (!styleItem) {
186 delete object;
187+ styleComponent->completeCreate();
188+ return;
189 }
190 QQml_setParent_noEvent(styleItem, q);
191 styleComponent->completeCreate();
192+ Q_EMIT q->__styleInstanceChanged();
193+
194+ // get the overshoot value from the style!
195+ if (!customOvershoot) {
196+ overshoot = styleItem->m_swipeOvershoot;
197+ Q_EMIT q->swipeOvershootChanged();
198+ }
199 }
200
201 /*!
202@@ -492,8 +503,6 @@
203 QQuickItem *owner = flickable ? flickable : parentItem;
204 q->setImplicitWidth(owner ? owner->width() : UCUnits::instance().gu(40));
205 q->setImplicitHeight(UCUnits::instance().gu(7));
206- // update overshoot value
207- overshoot = UCUnits::instance().gu(2);
208 }
209
210 // returns the index of the list item when used in model driven views,
211@@ -605,9 +614,9 @@
212 UCListItemActionsPrivate *trailing = UCListItemActionsPrivate::get(trailingActions);
213 x += dx;
214 // min cannot be less than the trailing's panel width
215- qreal min = (trailing && trailing->panelItem) ? -trailing->panelItem->width() : 0;
216+ qreal min = (trailing && trailing->panelItem) ? -trailing->panelItem->width() - overshoot: 0;
217 // max cannot be bigger than 0 or the leading's width in case we have leading panel
218- qreal max = (leading && leading->panelItem) ? leading->panelItem->width() : 0;
219+ qreal max = (leading && leading->panelItem) ? leading->panelItem->width() + overshoot: 0;
220 x = CLAMP(x, min, max);
221 }
222
223@@ -859,11 +868,6 @@
224 if (!d->suppressClick) {
225 Q_EMIT clicked();
226 d->_q_rebound();
227- } else if (d->contentItem->x() == 0.0) {
228- // if no actions list is connected, release flickable blockade
229- d->promptRebound();
230- } else {
231- d->setContentMoving(false);
232 }
233 }
234 d->setPressed(false);
235@@ -982,6 +986,8 @@
236 *
237 * The property holds the actions and its configuration to be revealed when swiped
238 * from left to right.
239+ *
240+ * \sa trailingActions
241 */
242 UCListItemActions *UCListItem::leadingActions() const
243 {
244@@ -994,7 +1000,18 @@
245 if (d->leadingActions == actions) {
246 return;
247 }
248+ // snap out before we change the actions
249+ d->promptRebound();
250+ // then delete panelItem
251+ if (d->leadingActions) {
252+ UCListItemActionsPrivate *list = UCListItemActionsPrivate::get(d->leadingActions);
253+ delete list->panelItem;
254+ list->panelItem = 0;
255+ }
256 d->leadingActions = actions;
257+ if (d->leadingActions == d->trailingActions && d->leadingActions) {
258+ qmlInfo(this) << UbuntuI18n::tr("leadingActions and trailingActions cannot share the same object!");
259+ }
260 Q_EMIT leadingActionsChanged();
261 }
262
263@@ -1003,6 +1020,8 @@
264 *
265 * The property holds the actions and its configuration to be revealed when swiped
266 * from right to left.
267+ *
268+ * \sa leadingActions
269 */
270 UCListItemActions *UCListItem::trailingActions() const
271 {
272@@ -1015,7 +1034,18 @@
273 if (d->trailingActions == actions) {
274 return;
275 }
276+ // snap out before we change the actions
277+ d->promptRebound();
278+ // then delete panelItem
279+ if (d->trailingActions) {
280+ UCListItemActionsPrivate *list = UCListItemActionsPrivate::get(d->trailingActions);
281+ delete list->panelItem;
282+ list->panelItem = 0;
283+ }
284 d->trailingActions = actions;
285+ if (d->leadingActions == d->trailingActions && d->trailingActions) {
286+ qmlInfo(this) << UbuntuI18n::tr("leadingActions and trailingActions cannot share the same object!");
287+ }
288 Q_EMIT trailingActionsChanged();
289 }
290
291@@ -1153,6 +1183,33 @@
292 }
293
294 /*!
295+ * \qmlproperty real ListItem::swipeOvershoot
296+ * The property configures the overshoot value on swiping. Its default value is
297+ * configured by the \l {ListItemStyle}{style}. Any positive value overrides the
298+ * default value, and any negative value resets it back to the default.
299+ */
300+qreal UCListItemPrivate::swipeOvershoot() const
301+{
302+ return overshoot;
303+}
304+void UCListItemPrivate::setSwipeOvershoot(qreal overshoot)
305+{
306+ // same value should be guarded only if the style hasn't been loaded yet
307+ // swipeOvershoot can be set to 0 prior the style is loaded.
308+ if (this->overshoot == overshoot && styleItem) {
309+ return;
310+ }
311+ customOvershoot = (overshoot >= 0.0);
312+ this->overshoot = (overshoot < 0.0) ?
313+ // reset, use style to get the overshoot value
314+ (styleItem ? styleItem->m_swipeOvershoot : 0.0) :
315+ overshoot;
316+ update();
317+ Q_Q(UCListItem);
318+ Q_EMIT q->swipeOvershootChanged();
319+}
320+
321+/*!
322 * \qmlproperty list<Object> ListItem::listItemData
323 * \default
324 * \internal
325
326=== modified file 'modules/Ubuntu/Components/plugin/uclistitem.h'
327--- modules/Ubuntu/Components/plugin/uclistitem.h 2014-12-01 15:58:43 +0000
328+++ modules/Ubuntu/Components/plugin/uclistitem.h 2014-12-01 15:58:45 +0000
329@@ -34,6 +34,7 @@
330 Q_PROPERTY(UCListItemActions *leadingActions READ leadingActions WRITE setLeadingActions NOTIFY leadingActionsChanged DESIGNABLE false)
331 Q_PROPERTY(UCListItemActions *trailingActions READ trailingActions WRITE setTrailingActions NOTIFY trailingActionsChanged DESIGNABLE false)
332 Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
333+ Q_PRIVATE_PROPERTY(UCListItem::d_func(), qreal swipeOvershoot READ swipeOvershoot WRITE setSwipeOvershoot NOTIFY swipeOvershootChanged)
334 Q_PRIVATE_PROPERTY(UCListItem::d_func(), bool contentMoving READ contentMoving NOTIFY contentMovingChanged)
335 Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
336 Q_PROPERTY(QColor highlightColor READ highlightColor WRITE setHighlightColor NOTIFY highlightColorChanged)
337@@ -76,6 +77,7 @@
338 void leadingActionsChanged();
339 void trailingActionsChanged();
340 void pressedChanged();
341+ void swipeOvershootChanged();
342 void contentMovingChanged();
343 void colorChanged();
344 void highlightColorChanged();
345
346=== modified file 'modules/Ubuntu/Components/plugin/uclistitem_p.h'
347--- modules/Ubuntu/Components/plugin/uclistitem_p.h 2014-12-01 15:58:43 +0000
348+++ modules/Ubuntu/Components/plugin/uclistitem_p.h 2014-12-01 15:58:45 +0000
349@@ -65,6 +65,8 @@
350 bool ready:1;
351 bool customStyle:1;
352 bool customColor:1;
353+ bool customOvershoot:1;
354+ bool flicked:1;
355 qreal xAxisMoveThresholdGU;
356 qreal overshoot;
357 QPointF lastPos;
358@@ -84,13 +86,15 @@
359 UCListItemStyle *styleItem;
360
361 // getters/setters
362+ qreal swipeOvershoot() const;
363+ void setSwipeOvershoot(qreal overshoot);
364 QQmlListProperty<QObject> data();
365 QQmlListProperty<QQuickItem> children();
366 bool contentMoving() const;
367 void setContentMoving(bool moved);
368 QQmlComponent *style() const;
369 void setStyle(QQmlComponent *delegate);
370- bool loadStyle();
371+ bool loadStyle(bool reload);
372 void initStyleItem();
373 QQuickItem *styleInstance() const;
374 };
375
376=== modified file 'modules/Ubuntu/Components/plugin/uclistitemactions.cpp'
377--- modules/Ubuntu/Components/plugin/uclistitemactions.cpp 2014-12-01 15:58:43 +0000
378+++ modules/Ubuntu/Components/plugin/uclistitemactions.cpp 2014-12-01 15:58:45 +0000
379@@ -22,12 +22,14 @@
380 #include "plugin.h"
381 #include <QtQml/QQmlInfo>
382 #include "ucaction.h"
383+#include "ucunits.h"
384 #include "uclistitemstyle.h"
385
386 UCListItemActionsPrivate::UCListItemActionsPrivate()
387 : QObjectPrivate()
388 , status(UCListItemActions::Disconnected)
389 , offsetDragged(0)
390+ , optionSlotWidth(0.0)
391 , delegate(0)
392 , panelDelegate(0)
393 , panelItem(0)
394@@ -89,10 +91,8 @@
395 }
396 // no parent set or panelItem yet, proceed with panel creation
397 UCListItemPrivate *pItem = UCListItemPrivate::get(listItem);
398- if (!pItem->styleItem && pItem->loadStyle()) {
399- pItem->initStyleItem();
400- }
401- if (pItem->styleItem && !_this->createPanelItem(pItem->styleItem->m_actionsDelegate)) {
402+ pItem->initStyleItem();
403+ if (!pItem->styleItem || (pItem->styleItem && !_this->createPanelItem(pItem->styleItem->m_actionsDelegate))) {
404 return false;
405 }
406
407@@ -398,7 +398,7 @@
408 * {ListItemStyle::actionsDelegate}{actionsDelegate} will be used.
409 *
410 * ListItemActions provides the \c action context property which contains the
411- * Action instance visualized. Using this property delegates can access
412+ * Action instance currently visualized. Using this property delegates can access
413 * the information to be visualized. The action is triggered by the panel item
414 * holding the visualized action, therefore only visualization is needed by the
415 * custom delegate. The other context property exposed to delegates is the \c
416
417=== modified file 'modules/Ubuntu/Components/plugin/uclistitemactions.h'
418--- modules/Ubuntu/Components/plugin/uclistitemactions.h 2014-12-01 15:58:43 +0000
419+++ modules/Ubuntu/Components/plugin/uclistitemactions.h 2014-12-01 15:58:45 +0000
420@@ -67,7 +67,6 @@
421 Q_PROPERTY(qreal offset READ offset NOTIFY offsetChanged)
422 Q_PROPERTY(UCListItemActions::Status status READ status NOTIFY statusChanged)
423 Q_PROPERTY(bool swiping READ swiping NOTIFY swipingChanged)
424- Q_PROPERTY(qreal overshoot READ overshoot NOTIFY overshootChanged)
425 public:
426 UCListItemActionsAttached(QObject *parent = 0);
427 ~UCListItemActionsAttached();
428@@ -84,7 +83,6 @@
429 bool swiping();
430 qreal offset();
431 UCListItemActions::Status status();
432- qreal overshoot();
433
434
435 public Q_SLOTS:
436@@ -98,7 +96,6 @@
437 void offsetChanged();
438 void statusChanged();
439 void swipingChanged();
440- void overshootChanged();
441
442 private:
443 QPointer<UCListItemActions> m_container;
444
445=== modified file 'modules/Ubuntu/Components/plugin/uclistitemactions_p.h'
446--- modules/Ubuntu/Components/plugin/uclistitemactions_p.h 2014-12-01 15:58:43 +0000
447+++ modules/Ubuntu/Components/plugin/uclistitemactions_p.h 2014-12-01 15:58:45 +0000
448@@ -33,6 +33,7 @@
449
450 UCListItemActions::Status status;
451 qreal offsetDragged;
452+ qreal optionSlotWidth;
453
454 QQmlComponent *delegate;
455 QQmlComponent *panelDelegate;
456
457=== modified file 'modules/Ubuntu/Components/plugin/uclistitemactionsattached.cpp'
458--- modules/Ubuntu/Components/plugin/uclistitemactionsattached.cpp 2014-12-01 15:58:43 +0000
459+++ modules/Ubuntu/Components/plugin/uclistitemactionsattached.cpp 2014-12-01 15:58:45 +0000
460@@ -51,8 +51,6 @@
461 this, &UCListItemActionsAttached::listItemChanged);
462 QObject::connect(m_container.data(), &UCListItemActions::statusChanged,
463 this, &UCListItemActionsAttached::listItemIndexChanged);
464- QObject::connect(m_container.data(), &UCListItemActions::statusChanged,
465- this, &UCListItemActionsAttached::overshootChanged);
466
467 UCListItemActionsPrivate *actions = UCListItemActionsPrivate::get(m_container.data());
468 // connect panel's xChanged to update the dragged offset
469@@ -212,28 +210,6 @@
470 }
471
472 /*!
473- * \qmlattachedproperty real ListItemActions::overshoot
474- * The property holds the overshoot value set for the list item.
475- */
476-qreal UCListItemActionsAttached::overshoot()
477-{
478- if (status() == UCListItemActions::Disconnected) {
479- return 0.0;
480- }
481- QQuickItem *panelItem = UCListItemActionsPrivate::get(m_container)->panelItem;
482- if (!panelItem) {
483- // we don't have the panel created yet
484- return 0.0;
485- }
486- UCListItem *item = static_cast<UCListItem*>(panelItem->parentItem());
487- if (!item) {
488- // no ListItem attached
489- return 0.0;
490- }
491- return UCListItemPrivate::get(item)->overshoot;
492-}
493-
494-/*!
495 * \qmlattachedmethod void ListItemActions::snapToPosition(real position)
496 * The function can be used to perform custom snapping, or to execute rebounding
497 * and also disconnecting from the connected \l ListItem. This can be achieved by
498
499=== modified file 'modules/Ubuntu/Components/plugin/uclistitemstyle.cpp'
500--- modules/Ubuntu/Components/plugin/uclistitemstyle.cpp 2014-12-01 15:58:43 +0000
501+++ modules/Ubuntu/Components/plugin/uclistitemstyle.cpp 2014-12-01 15:58:45 +0000
502@@ -34,8 +34,13 @@
503 * \li - ignores any other visuals defined in the style.
504 * \endlist
505 */
506-UCListItemStyle::UCListItemStyle(QQuickItem *parent) :
507- QQuickItem(parent)
508+UCListItemStyle::UCListItemStyle(QQuickItem *parent)
509+ : QQuickItem(parent)
510+ , m_actionsDelegate(0)
511+ , m_selectionDelegate(0)
512+ , m_dragHandlerDelegate(0)
513+ , m_snapAnimation(0)
514+ , m_swipeOvershoot(0)
515 {
516 }
517
518@@ -43,50 +48,23 @@
519 * \qmlproperty Component ListItemStyle::actionsDelegate
520 * Specifies the component visualizing the leading/trailing actions.
521 */
522-void UCListItemStyle::setActionsDelegate(QQmlComponent *delegate)
523-{
524- if (m_actionsDelegate == delegate) {
525- return;
526- }
527- m_actionsDelegate = delegate;
528- Q_EMIT actionsDelegateChanged();
529-}
530
531 /*!
532 * \qmlproperty Component ListItemStyle::selectionDelegate
533 * Holds the component handling the selection mode.
534 */
535-void UCListItemStyle::setSelectionDelegate(QQmlComponent *delegate)
536-{
537- if (m_selectionDelegate == delegate) {
538- return;
539- }
540- m_selectionDelegate = delegate;
541- Q_EMIT selectionDelegateChanged();
542-}
543
544 /*!
545 * \qmlproperty Component ListItemStyle::dragHandlerDelegate
546 * Holds the component shown when dragging mode is enabled.
547 */
548-void UCListItemStyle::setDragHandlerDelegate(QQmlComponent *delegate)
549-{
550- if (m_dragHandlerDelegate == delegate) {
551- return;
552- }
553- m_dragHandlerDelegate = delegate;
554- Q_EMIT dragHandlerDelegateChanged();
555-}
556
557 /*!
558 * \qmlproperty PropertyAnimation ListItemStyle::snapAnimation
559 * Holds the animation used in animating when snapped in or out.
560 */
561-void UCListItemStyle::setSnapAnimation(QQuickPropertyAnimation *animation)
562-{
563- if (m_snapAnimation == animation) {
564- return;
565- }
566- m_snapAnimation = animation;
567- Q_EMIT snapAnimationChanged();
568-}
569+
570+/*!
571+ * \qmlproperty real ListItemStyle::swipeOvershoot
572+ * The property specifies the overshoot value of the ListItem.
573+ */
574
575=== modified file 'modules/Ubuntu/Components/plugin/uclistitemstyle.h'
576--- modules/Ubuntu/Components/plugin/uclistitemstyle.h 2014-12-01 15:58:43 +0000
577+++ modules/Ubuntu/Components/plugin/uclistitemstyle.h 2014-12-01 15:58:45 +0000
578@@ -23,30 +23,29 @@
579 class UCListItemStyle : public QQuickItem
580 {
581 Q_OBJECT
582- Q_PROPERTY(QQmlComponent *actionsDelegate MEMBER m_actionsDelegate WRITE setActionsDelegate NOTIFY actionsDelegateChanged)
583- Q_PROPERTY(QQmlComponent *selectionDelegate MEMBER m_selectionDelegate WRITE setSelectionDelegate NOTIFY selectionDelegateChanged)
584- Q_PROPERTY(QQmlComponent *dragHandlerDelegate MEMBER m_dragHandlerDelegate WRITE setDragHandlerDelegate NOTIFY dragHandlerDelegateChanged)
585- Q_PROPERTY(QQuickPropertyAnimation *snapAnimation MEMBER m_snapAnimation WRITE setSnapAnimation NOTIFY snapAnimationChanged)
586+ Q_PROPERTY(QQmlComponent *actionsDelegate MEMBER m_actionsDelegate NOTIFY actionsDelegateChanged)
587+ Q_PROPERTY(QQmlComponent *selectionDelegate MEMBER m_selectionDelegate NOTIFY selectionDelegateChanged)
588+ Q_PROPERTY(QQmlComponent *dragHandlerDelegate MEMBER m_dragHandlerDelegate NOTIFY dragHandlerDelegateChanged)
589+ Q_PROPERTY(QQuickPropertyAnimation *snapAnimation MEMBER m_snapAnimation NOTIFY snapAnimationChanged)
590+ Q_PROPERTY(qreal swipeOvershoot MEMBER m_swipeOvershoot NOTIFY swipeOvershootChanged)
591 public:
592 explicit UCListItemStyle(QQuickItem *parent = 0);
593
594- void setActionsDelegate(QQmlComponent *delegate);
595- void setSelectionDelegate(QQmlComponent *delegate);
596- void setDragHandlerDelegate(QQmlComponent *delegate);
597- void setSnapAnimation(QQuickPropertyAnimation *animation);
598-
599 Q_SIGNALS:
600 void actionsDelegateChanged();
601 void selectionDelegateChanged();
602 void dragHandlerDelegateChanged();
603 void snapAnimationChanged();
604+ void swipeOvershootChanged();
605
606 private:
607 QQmlComponent *m_actionsDelegate;
608 QQmlComponent *m_selectionDelegate;
609 QQmlComponent *m_dragHandlerDelegate;
610 QQuickPropertyAnimation *m_snapAnimation;
611+ qreal m_swipeOvershoot;
612
613+ friend class UCListItemPrivate;
614 friend class UCListItemActionsPrivate;
615 friend class UCListItemSnapAnimator;
616 };
617
618=== modified file 'modules/Ubuntu/Test/UbuntuTestCase.qml'
619--- modules/Ubuntu/Test/UbuntuTestCase.qml 2014-10-10 16:49:22 +0000
620+++ modules/Ubuntu/Test/UbuntuTestCase.qml 2014-12-01 15:58:45 +0000
621@@ -163,12 +163,9 @@
622 if (pressTimeout !== undefined && pressTimeout > 0) {
623 wait(pressTimeout);
624 }
625- mouseMove(item, x, y, button, modifiers, delay);
626- for (var i = 1; i <= steps; i++) {
627- // mouse moves are all processed immediately, without delay in between events
628- mouseMove(item, x + i * ddx, y + i * ddy, -1, button);
629- }
630- mouseRelease(item, x + dx, y + dy, button, modifiers, delay);
631+ // mouse moves are all processed immediately, without delay in between events
632+ mouseMoveSlowly(item, x, y, dx, dy, steps, delay);
633+ mouseRelease(item, x + dx, y + dy, button, modifiers);
634 // empty event buffer
635 wait(200);
636 }
637
638=== modified file 'tests/unit_x11/tst_components/tst_listitem.qml'
639--- tests/unit_x11/tst_components/tst_listitem.qml 2014-12-01 15:58:43 +0000
640+++ tests/unit_x11/tst_components/tst_listitem.qml 2014-12-01 15:58:45 +0000
641@@ -152,6 +152,7 @@
642 movingSpy.clear();
643 pressedSpy.clear();
644 clickSpy.clear();
645+ interactiveSpy.clear();
646 listView.interactive = true;
647 // make sure we collapse
648 mouseClick(defaults, 0, 0)
649@@ -160,6 +161,7 @@
650 interactiveSpy.target = null;
651 interactiveSpy.clear();
652 trailing.delegate = null;
653+ listView.positionViewAtBeginning();
654 }
655
656 function test_0_defaults() {
657@@ -167,6 +169,7 @@
658 compare(defaults.color, "#000000", "Transparent by default");
659 compare(defaults.highlightColor, Theme.palette.selected.background, "Theme.palette.selected.background color by default")
660 compare(defaults.pressed, false, "Not pressed buy default");
661+ compare(defaults.swipeOvershoot, 0.0, "No overshoot till the style is loaded!");
662 compare(defaults.divider.visible, true, "divider is visible by default");
663 compare(defaults.divider.leftMargin, units.dp(2), "divider's left margin is 2GU");
664 compare(defaults.divider.rightMargin, units.dp(2), "divider's right margin is 2GU");
665@@ -317,12 +320,13 @@
666 }
667 function test_listview_not_interactive_while_tugged(data) {
668 listView.positionViewAtBeginning();
669+ compare(listView.interactive, true, "ListView is not interactive");
670 movingSpy.target = data.item;
671 interactiveSpy.target = listView;
672 if (data.mouse) {
673- flick(data.item, data.pos.x, data.pos.y, data.dx, 0);
674+ flick(data.item, data.pos.x, data.pos.y, data.dx, data.dy);
675 } else {
676- TestExtras.touchDrag(0, data.item, data.pos, Qt.point(data.dx, 0));
677+ TestExtras.touchDrag(0, data.item, data.pos, Qt.point(data.dx, data.dy));
678 }
679 movingSpy.wait();
680 // animation should no longer be running!
681@@ -399,13 +403,124 @@
682 trailing.delegate = customDelegate;
683 listView.positionViewAtBeginning();
684 var item = findChild(listView, "listItem0");
685+ movingSpy.target = item;
686 flick(item, centerOf(item).x, centerOf(item).y, -units.gu(20), 0);
687 var panel = panelItem(item, false);
688 verify(panel, "Panel is not visible");
689 var custom = findChild(panel, "custom_delegate");
690 verify(custom, "Custom delegate not in use");
691+ movingSpy.wait();
692 // cleanup
693 rebound(item);
694 }
695+
696+ // execute as last so we make sure we have the panel created
697+ function test_snap_data() {
698+ var listItem = findChild(listView, "listItem0");
699+ verify(listItem, "ListItem cannot be found");
700+
701+ return [
702+ // the list snaps out if the panel is dragged in > overshoot GU (hardcoded for now)
703+ {tag: "Snap out leading", item: listItem, dx: units.gu(2), snapIn: false},
704+ {tag: "Snap in leading", item: listItem, dx: units.gu(4), snapIn: true},
705+ {tag: "Snap out trailing", item: listItem, dx: -units.gu(2), snapIn: false},
706+ {tag: "Snap in trailing", item: listItem, dx: -units.gu(4), snapIn: true},
707+ ];
708+ }
709+ function test_snap(data) {
710+ movingSpy.target = data.item;
711+ flick(data.item, centerOf(data.item).x, centerOf(data.item).y, data.dx, 0);
712+ movingSpy.wait();
713+ waitForRendering(data.item, 400);
714+ movingSpy.clear();
715+ if (data.snapIn) {
716+ verify(data.item.contentItem.x != 0.0, "Not snapped to be visible");
717+ // cleanup
718+ rebound(data.item);
719+ } else {
720+ tryCompareFunction(function() { return data.item.contentItem.x; }, 0.0, 1000, "Not snapped back");
721+ }
722+ }
723+
724+ function test_snap_gesture_data() {
725+ var listItem = findChild(listView, "listItem0");
726+ var front = Qt.point(units.gu(1), listItem.height / 2);
727+ var rear = Qt.point(listItem.width - units.gu(1), listItem.height / 2);
728+ return [
729+ // the first dx must be big enough to drag the panel in, it is always the last dx value
730+ // which decides the snap direction
731+ {tag: "Snap out, leading", item: listItem, grabPos: front, dx: [units.gu(10), -units.gu(2)], snapIn: false},
732+ {tag: "Snap in, leading", item: listItem, grabPos: front, dx: [units.gu(10), -units.gu(1), units.gu(1)], snapIn: true},
733+ // have less first dx as the trailing panel is shorter
734+ {tag: "Snap out, trailing", item: listItem, grabPos: rear, dx: [-units.gu(5), units.gu(2)], snapIn: false},
735+ {tag: "Snap in, trailing", item: listItem, grabPos: rear, dx: [-units.gu(5), units.gu(1), -units.gu(1)], snapIn: true},
736+ ];
737+ }
738+ function test_snap_gesture(data) {
739+ // performe the moves
740+ movingSpy.target = data.item;
741+ var pos = data.grabPos;
742+ mousePress(data.item.contentItem, pos.x, pos.y);
743+ for (var i in data.dx) {
744+ var dx = data.dx[i];
745+ mouseMoveSlowly(data.item.contentItem, pos.x, pos.y, dx, 0, 5, 100);
746+ pos.x += dx;
747+ }
748+ mouseRelease(data.item.contentItem, pos.x, pos.y);
749+ movingSpy.wait();
750+
751+ if (data.snapIn) {
752+ // the contenTitem must be dragged in (snapIn)
753+ verify(data.item.contentItem.x != 0.0, "Not snapped in!");
754+ // dismiss
755+ rebound(data.item);
756+ } else {
757+ fuzzyCompare(data.item.contentItem.x, 0.0, 0.1, "Not snapped out!");
758+ }
759+ }
760+
761+ function test_overshoot_from_style() {
762+ // scroll to the last ListView element and test on that, to make sure we don't have the style loaded for that component
763+ listView.positionViewAtEnd();
764+ var listItem = findChild(listView, "listItem" + (listView.count - 1));
765+ verify(listItem, "Cannot get list item for testing");
766+
767+ compare(listItem.swipeOvershoot, 0.0, "No overshoot should be set yet!");
768+ // now swipe
769+ movingSpy.target = listItem;
770+ flick(listItem.contentItem, centerOf(listItem).x, centerOf(listItem).y, units.gu(5), 0);
771+ movingSpy.wait();
772+ compare(listItem.swipeOvershoot, listItem.__styleInstance.swipeOvershoot, "Overshoot not taken from style");
773+
774+ // cleanup
775+ rebound(listItem);
776+ }
777+
778+ function test_custom_overshoot_data() {
779+ // use different items to make sure the style doesn't update the overshoot values during the test
780+ return [
781+ {tag: "Positive value", index: listView.count - 1, value: units.gu(10), expected: units.gu(10)},
782+ {tag: "Zero value", index: listView.count - 2, value: 0, expected: 0},
783+ // synchronize the expected value with the one from Ambiance theme!
784+ {tag: "Negative value", index: listView.count - 3, value: -1, expected: units.gu(2)},
785+ ];
786+ }
787+ function test_custom_overshoot(data) {
788+ // scroll to the last ListView element and test on that, to make sure we don't have the style loaded for that component
789+ listView.positionViewAtEnd();
790+ var listItem = findChild(listView, "listItem" + data.index);
791+ verify(listItem, "Cannot get list item for testing");
792+
793+ compare(listItem.swipeOvershoot, 0.0, "No overshoot should be set yet!");
794+ listItem.swipeOvershoot = data.value;
795+ // now swipe
796+ movingSpy.target = listItem;
797+ flick(listItem.contentItem, centerOf(listItem).x, centerOf(listItem).y, units.gu(5), 0);
798+ movingSpy.wait();
799+ compare(listItem.swipeOvershoot, data.expected, "Overshoot differs from one set!");
800+
801+ // cleanup
802+ rebound(listItem);
803+ }
804 }
805 }

Subscribers

People subscribed via source and target branches

to all changes: