Merge lp:~zsombi/ubuntu-ui-toolkit/20-divider into lp:ubuntu-ui-toolkit/staging
- 20-divider
- Merge into staging
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 |
Related bugs: | |
Related blueprints: |
SDK: Design a new ListItem and layouts
(Undefined)
|
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.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1181
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1185
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
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.
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. :|
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.
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.
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.
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
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1206
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1207
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1208. By Zsombor Egri
-
prereq merge
- 1209. By Zsombor Egri
-
prereq merge
- 1210. By Zsombor Egri
-
move divider updates internally
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1208
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1210
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1211. By Zsombor Egri
-
prereq merge
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1211
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1212. By Zsombor Egri
-
prereq merge
- 1213. By Zsombor Egri
-
documentation added
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1213
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1214. By Zsombor Egri
-
prereq merge
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1214
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1214
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1215. By Zsombor Egri
-
test fixed
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1215
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1216. By Zsombor Egri
-
prereq merge
- 1217. By Zsombor Egri
-
use ListItem private in divider
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1217
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1218. By Zsombor Egri
-
colors driving divider added
- 1219. By Zsombor Egri
-
API updated
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1218
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1219
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 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
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 | } |
FAILED: Continuous integration, rev:1180 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/710/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/2947 jenkins. qa.ubuntu. com/job/ generic- mediumtests- utopic/ 2335/console jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- utopic- amd64-ci/ 542 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- utopic- armhf-ci/ 542 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- utopic- armhf-ci/ 542/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- utopic- i386-ci/ 542 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/3007 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/4190 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/4190/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 10895 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/2601/ console
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/710/ rebuild
http://