Merge lp:~zsombi/ubuntu-ui-toolkit/20-divider into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Superseded
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/20-divider
Merge into: lp:ubuntu-ui-toolkit/staging
Prerequisite: lp:~zsombi/ubuntu-ui-toolkit/10-viewitem
Diff against target: 551 lines (+332/-11)
7 files modified
components.api (+8/-0)
modules/Ubuntu/Components/plugin/plugin.cpp (+1/-0)
modules/Ubuntu/Components/plugin/uclistitem.cpp (+231/-9)
modules/Ubuntu/Components/plugin/uclistitem.h (+5/-0)
modules/Ubuntu/Components/plugin/uclistitem_p.h (+58/-0)
tests/resources/listitems/ListItemTest.qml (+13/-2)
tests/unit_x11/tst_components/tst_listitem.qml (+16/-0)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/20-divider
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Michał Sawicz Needs Information
Tim Peeters Pending
Review via email: mp+229317@code.launchpad.net

Commit message

Divider configuration.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

In the dash we have the need to override the dividers' colors, could you expose those as properties?

FWIW what I planned to do is also to build, into Theme or so, some smartness on how the divider should look like on dark backgrounds (as it should be reversed).

One more thing - using just two gradient stops and dp(2) results in a gradiented rectangle ~4.5 pixel high, which is not how the divider should look like - it should be crisp and sharp.

I planned an approach with 4 gradient stops at 0, 0.49, 0.50, 1, when at 2dp only a grid of more than 160 pixels per unit would cause the gradient to appear. At 0, 0.4, 0.5, 1 it'd show up at ~36px per unit, which I don't think is impossible to encounter in real life.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Zsombor Egri (zsombi) wrote :

> In the dash we have the need to override the dividers' colors, could you
> expose those as properties?
>
> FWIW what I planned to do is also to build, into Theme or so, some smartness
> on how the divider should look like on dark backgrounds (as it should be
> reversed).
>
> One more thing - using just two gradient stops and dp(2) results in a
> gradiented rectangle ~4.5 pixel high, which is not how the divider should look
> like - it should be crisp and sharp.
>
> I planned an approach with 4 gradient stops at 0, 0.49, 0.50, 1, when at 2dp
> only a grid of more than 160 pixels per unit would cause the gradient to
> appear. At 0, 0.4, 0.5, 1 it'd show up at ~36px per unit, which I don't think
> is impossible to encounter in real life.

Checked with design, and the decision was to go for 1DP thick divider with solid fill. The API however will give the possibility to set either solid colour or gradient. Thickness is already configurable.

Revision history for this message
Michał Sawicz (saviq) wrote :

Do we really need so complicated a component? Can we not decide how a divider should look like and keep to it across the platform?

A divider with 6 properties... we could very well just use a Rectangle directly. :|

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

> Do we really need so complicated a component? Can we not decide how a divider
> should look like and keep to it across the platform?
>
> A divider with 6 properties... we could very well just use a Rectangle
> directly. :|

If we use the ThinDivider for instance that is made in QML, the performance decreases 6 times. That's why we are doing it in C++.

The same for the ListItem itself. The QML part we have is only meant to keep the bindings to the size and the colors. We prototyped a QML ListItem as well and it was - at the stage we are now - 7 times slower than this.

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

> > Do we really need so complicated a component? Can we not decide how a
> divider
> > should look like and keep to it across the platform?
> >
> > A divider with 6 properties... we could very well just use a Rectangle
> > directly. :|
>
> If we use the ThinDivider for instance that is made in QML, the performance
> decreases 6 times. That's why we are doing it in C++.
>
> The same for the ListItem itself. The QML part we have is only meant to keep
> the bindings to the size and the colors. We prototyped a QML ListItem as well
> and it was - at the stage we are now - 7 times slower than this.

Ah, and one more thing: the thickness, left and right margins might not be needed, however I see that it would be the first thing to add once the component gets released, because of some use case in some app than needs to start the divider from the edge, be thicker than 1DP, etc.

Revision history for this message
Michał Sawicz (saviq) wrote :

I'd venture to say that it should be an SDK design decision how much flexibility this has.

While I can understand margins... thickness and either of color or gradient should go away. And even for gradient, I'd say we need back/foreground color instead of direct gradient.

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

> I'd venture to say that it should be an SDK design decision how much
> flexibility this has.
>
> While I can understand margins... thickness and either of color or gradient
> should go away. And even for gradient, I'd say we need back/foreground color
> instead of direct gradient.

Ok, you convinced me :) for now I've removed the thickness, but also the colours. I have a FIXME there to get the colors from the theme once we get the palette shaped to support colouring of the dividers. Yet, the colours are chosen based on the theme's normal background luminance.

1207. By Zsombor Egri

luminance fix

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
1208. By Zsombor Egri

prereq merge

1209. By Zsombor Egri

prereq merge

1210. By Zsombor Egri

move divider updates internally

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1211. By Zsombor Egri

prereq merge

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1212. By Zsombor Egri

prereq merge

1213. By Zsombor Egri

documentation added

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1214. By Zsombor Egri

prereq merge

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1215. By Zsombor Egri

test fixed

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
1216. By Zsombor Egri

prereq merge

1217. By Zsombor Egri

use ListItem private in divider

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
1218. By Zsombor Egri

colors driving divider added

1219. By Zsombor Egri

API updated

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1220. By Zsombor Egri

prereq

1221. By Zsombor Egri

prereq merge

1222. By Zsombor Egri

prereq updated

1223. By Zsombor Egri

prereq merge

1224. By Zsombor Egri

divider paint fixed

1225. By Zsombor Egri

prereq

1226. By Zsombor Egri

colroFrom and colorTo documented

1227. By Zsombor Egri

background colored only on the contentItem area

1228. By Zsombor Egri

divider to paint edge-to-edge when pressed

1229. By Zsombor Egri

prereq sync

1230. By Zsombor Egri

prereq sync

1231. By Zsombor Egri

prereq sync

1232. By Zsombor Egri

prereq sync

1233. By Zsombor Egri

prereq sync

1234. By Zsombor Egri

2GU to 2DP teft and rigth margins on divider

1235. By Zsombor Egri

prereq sync

1236. By Zsombor Egri

prereq sync

1237. By Zsombor Egri

prereq sync

1238. By Zsombor Egri

prereq sync

Unmerged revisions

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-09-11 07:28:57 +0000
3+++ components.api 2014-09-11 07:28:57 +0000
4@@ -818,6 +818,7 @@
5 prototype: "UCStyledItemBase"
6 exports: ["ListItem 1.1"]
7 Property { name: "contentItem"; type: "UCListItemContent"; isReadonly: true; isPointer: true }
8+ Property { name: "divider"; type: "UCListItemDivider"; isReadonly: true; isPointer: true }
9 Property { name: "pressed"; type: "bool"; isReadonly: true }
10 Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
11 Property { name: "children"; type: "QQuickItem"; isList: true; isReadonly: true }
12@@ -826,6 +827,13 @@
13 prototype: "QQuickItem"
14 Property { name: "color"; type: "QColor" }
15 Property { name: "pressedColor"; type: "QColor" }
16+ name: "UCListItemDivider"
17+ prototype: "QObject"
18+ Property { name: "visible"; type: "bool" }
19+ Property { name: "leftMargin"; type: "double" }
20+ Property { name: "rightMargin"; type: "double" }
21+ Property { name: "colorFrom"; type: "QColor" }
22+ Property { name: "colorTo"; type: "QColor" }
23 name: "UCMouse"
24 prototype: "QObject"
25 exports: ["Mouse 0.1", "Mouse 1.0"]
26
27=== modified file 'modules/Ubuntu/Components/plugin/plugin.cpp'
28--- modules/Ubuntu/Components/plugin/plugin.cpp 2014-09-11 07:28:57 +0000
29+++ modules/Ubuntu/Components/plugin/plugin.cpp 2014-09-11 07:28:57 +0000
30@@ -162,6 +162,7 @@
31 // ListItem and related types
32 qmlRegisterType<UCListItem, 1>(uri, 1, 1, "ListItem");
33 qmlRegisterType<UCListItemContent>();
34+ qmlRegisterType<UCListItemDivider>();
35 }
36
37 void UbuntuComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
38
39=== modified file 'modules/Ubuntu/Components/plugin/uclistitem.cpp'
40--- modules/Ubuntu/Components/plugin/uclistitem.cpp 2014-09-11 07:28:57 +0000
41+++ modules/Ubuntu/Components/plugin/uclistitem.cpp 2014-09-11 07:28:57 +0000
42@@ -35,7 +35,155 @@
43 }
44 return result;
45 }
46-
47+/******************************************************************************
48+ * Divider
49+ */
50+UCListItemDivider::UCListItemDivider(QObject *parent)
51+ : QObject(parent)
52+ , m_visible(true)
53+ , m_leftMarginChanged(false)
54+ , m_rightMarginChanged(false)
55+ , m_colorFromChanged(false)
56+ , m_colorToChanged(false)
57+ , m_thickness(0)
58+ , m_leftMargin(0)
59+ , m_rightMargin(0)
60+ , m_listItem(0)
61+{
62+ connect(&UCUnits::instance(), &UCUnits::gridUnitChanged, this, &UCListItemDivider::unitsChanged);
63+ connect(&UCTheme::instance(), &UCTheme::paletteChanged, this, &UCListItemDivider::paletteChanged);
64+ unitsChanged();
65+ paletteChanged();
66+}
67+UCListItemDivider::~UCListItemDivider()
68+{
69+}
70+
71+void UCListItemDivider::init(UCListItem *listItem)
72+{
73+ QQml_setParent_noEvent(this, listItem);
74+ m_listItem = UCListItemPrivate::get(listItem);
75+}
76+
77+void UCListItemDivider::unitsChanged()
78+{
79+ m_thickness = UCUnits::instance().dp(2);
80+ if (!m_leftMarginChanged) {
81+ m_leftMargin = UCUnits::instance().gu(2);
82+ }
83+ if (!m_rightMarginChanged) {
84+ m_rightMargin = UCUnits::instance().gu(2);
85+ }
86+ if (m_listItem) {
87+ m_listItem->update();
88+ }
89+}
90+
91+void UCListItemDivider::paletteChanged()
92+{
93+ QColor background = getPaletteColor("normal", "background");
94+ if (!background.isValid()) {
95+ return;
96+ }
97+ // FIXME: we need a palette value for divider colors, till then base on the background
98+ // luminance
99+ if (!m_colorFromChanged || !m_colorToChanged) {
100+ qreal luminance = (background.red()*212 + background.green()*715 + background.blue()*73)/1000.0/255.0;
101+ bool lightBackground = (luminance > 0.85);
102+ if (!m_colorFromChanged) {
103+ m_colorFrom = lightBackground ? QColor("#26000000") : QColor("#26FFFFFF");
104+ }
105+ if (!m_colorToChanged) {
106+ m_colorTo = lightBackground ? QColor("#14FFFFFF") : QColor("#14000000");
107+ }
108+ updateGradient();
109+ }
110+}
111+
112+void UCListItemDivider::updateGradient()
113+{
114+ m_gradient.clear();
115+ m_gradient.append(QGradientStop(0.0, m_colorFrom));
116+ m_gradient.append(QGradientStop(0.49, m_colorFrom));
117+ m_gradient.append(QGradientStop(0.5, m_colorTo));
118+ m_gradient.append(QGradientStop(1.0, m_colorTo));
119+ if (m_listItem) {
120+ m_listItem->update();
121+ }
122+}
123+
124+QSGNode *UCListItemDivider::paint(QSGNode *paintNode, const QRectF &rect)
125+{
126+ if (m_visible && (m_gradient.size() > 0)) {
127+ QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(paintNode);
128+ if (!rectNode) {
129+ rectNode = m_listItem->sceneGraphContext()->createRectangleNode();
130+ }
131+ rectNode->setRect(QRectF(m_leftMargin, rect.height() - m_thickness,
132+ rect.width() - m_leftMargin - m_rightMargin, m_thickness));
133+ rectNode->setGradientStops(m_gradient);
134+ rectNode->update();
135+ return rectNode;
136+ } else {
137+ delete paintNode;
138+ return 0;
139+ }
140+}
141+
142+void UCListItemDivider::setVisible(bool visible)
143+{
144+ if (m_visible == visible) {
145+ return;
146+ }
147+ m_visible = visible;
148+ m_listItem->resize();
149+ m_listItem->update();
150+ Q_EMIT visibleChanged();
151+}
152+
153+void UCListItemDivider::setLeftMargin(qreal leftMargin)
154+{
155+ if (m_leftMargin == leftMargin) {
156+ return;
157+ }
158+ m_leftMargin = leftMargin;
159+ m_leftMarginChanged = true;
160+ m_listItem->update();
161+ Q_EMIT leftMarginChanged();
162+}
163+
164+void UCListItemDivider::setRightMargin(qreal rightMargin)
165+{
166+ if (m_rightMargin == rightMargin) {
167+ return;
168+ }
169+ m_rightMargin = rightMargin;
170+ m_rightMarginChanged = true;
171+ m_listItem->update();
172+ Q_EMIT rightMarginChanged();
173+}
174+
175+void UCListItemDivider::setColorFrom(const QColor &color)
176+{
177+ if (m_colorFrom == color) {
178+ return;
179+ }
180+ m_colorFrom = color;
181+ m_colorFromChanged = true;
182+ updateGradient();
183+ Q_EMIT colorFromChanged();
184+}
185+
186+void UCListItemDivider::setColorTo(const QColor &color)
187+{
188+ if (m_colorTo == color) {
189+ return;
190+ }
191+ m_colorTo = color;
192+ m_colorToChanged = true;
193+ updateGradient();
194+ Q_EMIT colorToChanged();
195+}
196
197 /******************************************************************************
198 * ListItemContent
199@@ -114,10 +262,14 @@
200 }
201
202
203+/******************************************************************************
204+ * ListItemBasePrivate
205+ */
206 UCListItemPrivate::UCListItemPrivate()
207 : UCStyledItemBasePrivate()
208 , pressed(false)
209 , contentItem(new UCListItemContent)
210+ , divider(new UCListItemDivider)
211 {
212 }
213 UCListItemPrivate::~UCListItemPrivate()
214@@ -130,6 +282,7 @@
215 contentItem->setObjectName("ListItemHolder");
216 QQml_setParent_noEvent(contentItem, q);
217 contentItem->setParentItem(q);
218+ divider->init(q);
219 // content will be redirected to the contentItem, therefore we must report
220 // children changes as it would come from the main component
221 QObject::connect(contentItem, &UCListItemContent::childrenChanged,
222@@ -185,11 +338,31 @@
223 if (flickable.isNull()) {
224 return;
225 }
226+ Q_Q(UCListItem);
227 if (listen) {
228- QObject::connect(flickable.data(), SIGNAL(movementStarted()), q_ptr, SLOT(_q_rebound()));
229+ QObject::connect(flickable.data(), SIGNAL(movementStarted()), q, SLOT(_q_rebound()));
230 } else {
231- QObject::disconnect(flickable.data(), SIGNAL(movementStarted()), q_ptr, SLOT(_q_rebound()));
232- }
233+ QObject::disconnect(flickable.data(), SIGNAL(movementStarted()), q, SLOT(_q_rebound()));
234+ }
235+}
236+
237+void UCListItemPrivate::resize()
238+{
239+ Q_Q(UCListItem);
240+ QRectF rect(q->boundingRect());
241+ if (divider && divider->m_visible) {
242+ rect.setHeight(rect.height() - divider->m_thickness);
243+ }
244+ contentItem->setSize(rect.size());
245+}
246+
247+void UCListItemPrivate::update()
248+{
249+ if (!ready) {
250+ return;
251+ }
252+ Q_Q(UCListItem);
253+ q->update();
254 }
255
256 /*!
257@@ -218,6 +391,10 @@
258 * revealed and thus will destroy your logic
259 * \li never anchor left or right anchor lines as it will block revealing the options.
260 * \endlist
261+ *
262+ * Each ListItem has a thin divider shown on the bottom of the component. This
263+ * divider can be configured through the \l divider grouped property, which can
264+ * configure its margins from the edges of the ListItem as well as its visibility.
265 */
266
267 /*!
268@@ -238,6 +415,12 @@
269 {
270 }
271
272+void UCListItem::componentComplete()
273+{
274+ UCStyledItemBase::componentComplete();
275+ d_func()->ready = true;
276+}
277+
278 void UCListItem::itemChange(ItemChange change, const ItemChangeData &data)
279 {
280 UCStyledItemBase::itemChange(change, data);
281@@ -269,11 +452,23 @@
282 void UCListItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
283 {
284 UCStyledItemBase::geometryChanged(newGeometry, oldGeometry);
285- // resize contentItem item
286- Q_D(UCListItem);
287- QRectF rect(boundingRect());
288- d->contentItem->setSize(rect.size());
289-}
290+ // resize background item
291+ Q_D(UCListItem);
292+ d->resize();
293+}
294+
295+QSGNode *UCListItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
296+{
297+ Q_UNUSED(data);
298+ Q_D(UCListItem);
299+ if (width() <= 0 || height() <= 0 || !d->divider) {
300+ delete oldNode;
301+ return 0;
302+ }
303+ // paint divider
304+ return d->divider->paint(oldNode, boundingRect());
305+}
306+
307 void UCListItem::mousePressEvent(QMouseEvent *event)
308 {
309 UCStyledItemBase::mousePressEvent(event);
310@@ -319,6 +514,33 @@
311 }
312
313 /*!
314+ * \qmlpropertygroup ::ListItem::divider
315+ * \qmlproperty bool ListItem::divider.visible
316+ * \qmlproperty real ListItem::divider.leftMargin
317+ * \qmlproperty real ListItem::divider.rightMargin
318+ *
319+ * This grouped property configures the thin divider shown in the bottom of the
320+ * component. Configures the visibility and the margins from the left and right
321+ * of the ListItem. When tugged (swiped left or right to reveal the options),
322+ * it is not moved together with the content.
323+ *
324+ * When \c visible is true, the ListItem's content size gets thinner with the
325+ * divider's \c thickness.
326+ *
327+ * The default values for the properties are:
328+ * \list
329+ * \li \c visible: true
330+ * \li \c leftMargin: 2 GU
331+ * \li \c rightMargin: 2 GU
332+ * \endlist
333+ */
334+UCListItemDivider* UCListItem::divider() const
335+{
336+ Q_D(const UCListItem);
337+ return d->divider;
338+}
339+
340+/*!
341 * \qmlproperty bool ListItem::pressed
342 * True when the item is pressed. The items stays pressed when the mouse or touch
343 * is moved horizontally. When in Flickable (or ListView), the item gets un-pressed
344
345=== modified file 'modules/Ubuntu/Components/plugin/uclistitem.h'
346--- modules/Ubuntu/Components/plugin/uclistitem.h 2014-09-11 07:28:57 +0000
347+++ modules/Ubuntu/Components/plugin/uclistitem.h 2014-09-11 07:28:57 +0000
348@@ -21,11 +21,13 @@
349 #include "ucstyleditembase.h"
350
351 class UCListItemContent;
352+class UCListItemDivider;
353 class UCListItemPrivate;
354 class UCListItem : public UCStyledItemBase
355 {
356 Q_OBJECT
357 Q_PROPERTY(UCListItemContent *contentItem READ contentItem CONSTANT)
358+ Q_PROPERTY(UCListItemDivider *divider READ divider CONSTANT)
359 Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged)
360 Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false)
361 Q_PROPERTY(QQmlListProperty<QQuickItem> children READ children NOTIFY childrenChanged DESIGNABLE false)
362@@ -35,10 +37,13 @@
363 ~UCListItem();
364
365 UCListItemContent *contentItem() const;
366+ UCListItemDivider *divider() const;
367 bool pressed() const;
368
369 protected:
370+ void componentComplete();
371 void itemChange(ItemChange change, const ItemChangeData &data);
372+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data);
373 void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
374 void mousePressEvent(QMouseEvent *event);
375 void mouseReleaseEvent(QMouseEvent *event);
376
377=== modified file 'modules/Ubuntu/Components/plugin/uclistitem_p.h'
378--- modules/Ubuntu/Components/plugin/uclistitem_p.h 2014-09-11 07:28:57 +0000
379+++ modules/Ubuntu/Components/plugin/uclistitem_p.h 2014-09-11 07:28:57 +0000
380@@ -20,9 +20,11 @@
381 #include "uclistitem.h"
382 #include "ucstyleditembase_p.h"
383 #include <QtCore/QPointer>
384+#include <QtQuick/private/qquickrectangle_p.h>
385
386 class QQuickFlickable;
387 class UCListItemContent;
388+class UCListItemDivider;
389 class UCListItemPrivate : public UCStyledItemBasePrivate
390 {
391 Q_DECLARE_PUBLIC(UCListItem)
392@@ -44,10 +46,14 @@
393 void _q_updateSize();
394 void setPressed(bool pressed);
395 void listenToRebind(bool listen);
396+ void resize();
397+ void update();
398
399 bool pressed:1;
400+ bool ready:1;
401 QPointer<QQuickFlickable> flickable;
402 UCListItemContent *contentItem;
403+ UCListItemDivider *divider;
404 };
405
406 class UCListItemContent : public QQuickItem
407@@ -80,8 +86,60 @@
408 bool m_pressedColorChanged:1;
409 };
410
411+class UCListItemDivider : public QObject
412+{
413+ Q_OBJECT
414+ Q_PROPERTY(bool visible MEMBER m_visible WRITE setVisible NOTIFY visibleChanged)
415+ Q_PROPERTY(qreal leftMargin MEMBER m_leftMargin WRITE setLeftMargin NOTIFY leftMarginChanged)
416+ Q_PROPERTY(qreal rightMargin MEMBER m_rightMargin WRITE setRightMargin NOTIFY rightMarginChanged)
417+ Q_PROPERTY(QColor colorFrom MEMBER m_colorFrom WRITE setColorFrom NOTIFY colorFromChanged)
418+ Q_PROPERTY(QColor colorTo MEMBER m_colorTo WRITE setColorTo NOTIFY colorToChanged)
419+public:
420+ explicit UCListItemDivider(QObject *parent = 0);
421+ ~UCListItemDivider();
422+ void init(UCListItem *listItem);
423+
424+Q_SIGNALS:
425+ void visibleChanged();
426+ void leftMarginChanged();
427+ void rightMarginChanged();
428+ void colorFromChanged();
429+ void colorToChanged();
430+
431+protected:
432+ QSGNode *paint(QSGNode *paintNode, const QRectF &rect);
433+
434+private Q_SLOTS:
435+ void unitsChanged();
436+ void paletteChanged();
437+
438+private:
439+ void updateGradient();
440+ void setVisible(bool visible);
441+ void setLeftMargin(qreal leftMargin);
442+ void setRightMargin(qreal rightMargin);
443+ void setColorFrom(const QColor &color);
444+ void setColorTo(const QColor &color);
445+
446+ bool m_visible:1;
447+ bool m_leftMarginChanged:1;
448+ bool m_rightMarginChanged:1;
449+ bool m_colorFromChanged:1;
450+ bool m_colorToChanged:1;
451+ qreal m_thickness;
452+ qreal m_leftMargin;
453+ qreal m_rightMargin;
454+ QColor m_colorFrom;
455+ QColor m_colorTo;
456+ QGradientStops m_gradient;
457+ UCListItemPrivate *m_listItem;
458+ friend class UCListItem;
459+ friend class UCListItemPrivate;
460+};
461+
462 QColor getPaletteColor(const char *profile, const char *color);
463
464 QML_DECLARE_TYPE(UCListItemContent)
465+QML_DECLARE_TYPE(UCListItemDivider)
466
467 #endif // UCVIEWITEM_P_H
468
469=== modified file 'tests/resources/listitems/ListItemTest.qml'
470--- tests/resources/listitems/ListItemTest.qml 2014-09-11 07:28:57 +0000
471+++ tests/resources/listitems/ListItemTest.qml 2014-09-11 07:28:57 +0000
472@@ -37,18 +37,23 @@
473 print("click")
474 main.override = !main.override
475 }
476+ Label {
477+ anchors.fill: parent
478+ text: units.gridUnit + "PX/unit"
479+ }
480 }
481
482 ListView {
483 id: view
484 clip: true
485 width: parent.width
486- height: units.gu(40)
487+ height: units.gu(20)
488 model: 100
489 pressDelay: 0
490 delegate: ListItem {
491 id: listItem
492 onClicked: print(" clicked")
493+
494 Label {
495 text: modelData + " item"
496 }
497@@ -65,7 +70,7 @@
498 Flickable {
499 id: flicker
500 width: parent.width
501- height: units.gu(40)
502+ height: units.gu(20)
503 clip: true
504 contentHeight: column.childrenRect.height
505 Column {
506@@ -78,6 +83,12 @@
507 color: "red"
508 pressedColor: "lime"
509 }
510+ divider.colorFrom: UbuntuColors.green
511+
512+ Label {
513+ text: modelData + " Flickable item"
514+ }
515+ onClicked: divider.visible = !divider.visible
516 }
517 }
518 }
519
520=== modified file 'tests/unit_x11/tst_components/tst_listitem.qml'
521--- tests/unit_x11/tst_components/tst_listitem.qml 2014-09-11 07:28:57 +0000
522+++ tests/unit_x11/tst_components/tst_listitem.qml 2014-09-11 07:28:57 +0000
523@@ -87,6 +87,13 @@
524 compare(defaults.contentItem.color, "#000000", "Transparent by default");
525 compare(defaults.contentItem.pressedColor, Theme.palette.selected.background, "Theme.palette.selected.background color by default")
526 compare(defaults.pressed, false, "Not pressed buy default");
527+ compare(defaults.divider.visible, true, "divider is visible by default");
528+ compare(defaults.divider.leftMargin, units.gu(2), "divider's left margin is 2GU");
529+ compare(defaults.divider.rightMargin, units.gu(2), "divider's right margin is 2GU");
530+ compare(defaults.divider.colorFrom, "#000000", "colorFrom differs.");
531+ fuzzyCompare(defaults.divider.colorFrom.a, 0.14, 0.01, "colorFrom alpha differs");
532+ compare(defaults.divider.colorTo, "#ffffff", "colorTo differs.");
533+ fuzzyCompare(defaults.divider.colorTo.a, 0.07, 0.01, "colorTo alpha differs");
534 }
535
536 function test_children_in_content_item() {
537@@ -145,5 +152,14 @@
538 compare(listItem.pressed, false, "Item is pressed still!");
539 TestExtras.touchRelease(0, listItem, Qt.point(listItem.width / 2, dy));
540 }
541+
542+ function test_background_height_change_on_divider_visible() {
543+ // make sure the testItem's divider is shown
544+ testItem.divider.visible = true;
545+ verify(testItem.contentItem.height < testItem.height, "ListItem's background height must be less than the item itself.");
546+ testItem.divider.visible = false;
547+ compare(testItem.contentItem.height, testItem.height, "ListItem's background height must be the same as the item itself.");
548+ testItem.divider.visible = true;
549+ }
550 }
551 }

Subscribers

People subscribed via source and target branches