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