2
* Copyright 2015 Canonical Ltd.
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU Lesser General Public License as published by
6
* the Free Software Foundation; version 3.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Author: Andrea Bernabei <andrea.bernabei@canonical.com>
19
#include "private/qqmldata_p.h"
20
#include <QtQml/QQmlEngine>
22
#include "privates/threelabelsslot_p.h"
23
#include "uclistitemlayout.h"
27
\qmltype ListItemLayout
28
\instantiates UCListItemLayout
29
\inqmlmodule Ubuntu.Components 1.3
33
\brief ListItemLayout provides an easy way to create list items which follow
34
Ubuntu design standards, thus making them visually appealing and
35
consistent with the rest of the platform without effort.
37
ListItemLayout is essentially a \l {SlotsLayout} with a predefined
38
\l {SlotsLayout::mainSlot} that provides (up to) 3 Labels automatically laid out
39
according to our UI guidelines.
40
This main slot has been optimized to cover most of the usecases
41
without compromising performance (read more in \l {Optimizing memory consumption}).
43
We're aware there could be usecases which the \l SlotsLayout::mainSlot provided by
44
ListItemLayout doesn't cover. If that is the case, please use \l SlotsLayout
45
instead of \l ListItemLayout and provide your own \l SlotsLayout::mainSlot.
47
ListItemLayout works similarly to QtQuick's Row, but while
48
Row just positions its children in a horizontal formation,
49
ListItemLayout also tweaks their vertical position to ensure
52
We will call ListItemLayout's visual children "slots".
53
ListItemLayout positions its slots automatically, following the visual rules
54
specified by the Ubuntu Design team.
55
Because we think flexibility is an important value of our UI components,
56
we made it possible to tweak the position of each slot by modifying
57
its attached properties (see \l {Advanced layout tweaks}).
59
If you need a progression symbol in your list item,
60
just add \l ProgressionSlot as a child of your ListItemLayout.
61
No manual positioning is needed, the layout will handle it for you.
63
To read more about advanced slots positioning or how to handle
64
input (mouse or touch) in ListItemLayout, see \l SlotsLayout
67
If you don't need the features provided by \l {ListItem} (such as
69
you can also use \l ListItemLayout directly as root of your list view delegate
70
or inside a MouseArea, as explained in \l {Input handling}.
72
The following code example shows how easy it is to create
73
even non trivial list items using
74
\l ListItem and ListItemLayout:
77
height: layout.height + divider.height
80
title.text: "Hello developers!"
81
subtitle.text: "I'm a subtitle, I'm tiny!"
82
summary.text: "Ubuntu!"
84
CheckBox { SlotsLayout.position: SlotsLayout.Leading }
88
SlotsLayout.position: SlotsLayout.Trailing;
95
Although ListItemLayout covers most of the usecases, there might be
96
times where you might want to tweak the position of one or more slots.
97
The following example shows one way to implement a list
98
item with a trailing slot holding two labels. What is special about
99
this example is that we want the baseline of one label inside the
100
trailing slot to align to \l {title}'s baseline and the baseline of
101
the other label to align to \l {subtitle}'s baseline.
106
height: layout.height + divider.height
110
title.text: "Hello..."
111
title.color: UbuntuColors.Orange
112
subtitle.text: "...world!"
115
SlotsLayout.position: SlotsLayout.Leading
123
width: secondLabel.width
124
height: parent.height
126
//as we want to position labels to align with title and subtitle
127
SlotsLayout.overrideVerticalPositioning: true
131
anchors.right: secondLabel.right
134
y: layout.mainSlot.y + layout.title.y
135
+ layout.title.baselineOffset - baselineOffset
142
y: layout.mainSlot.y + layout.subtitle.y
143
+ layout.subtitle.baselineOffset - baselineOffset
152
\section1 Labels layout
154
The labels in ListItemLayout's default \l SlotsLayout::mainSlot are laid out in a column.
155
The \l title is positioned at the top, followed by \l subtitle and \l summary,
158
The \l subtitle has its top anchored to \l {title}'s baseline, with a margin of
161
The \l summary has its top tightly anchored to \l {subtitle}'s bottom.
163
The height of the default \l SlotsLayout::mainSlot provided with ListItemLayout
164
is the minimum height required to accomodate the \b visible and \b {non-empty}
165
labels it holds. If only \l {title} is visible and has a non-empty text set, for instance,
166
the height of the main slot will be \c {title.height}.
168
If you wish to have the layout process accomodate a label which doesn't have a
169
defined text yet, you should set its text property to " ", as shown in the
173
title.text: "Hello developers!"
174
//NOTE: the whitespace
179
That will make sure \l SlotsLayout::mainSlot is resized to accomodate the (currently empty)
182
This is useful, for instance, if you want all list items in a list view
183
to have the same height even without having to fill \l subtitle's (or summary's)
184
text with dummy content.
186
\section1 Optimizing memory consumption
188
In order to minimize memory consumption, the Labels in the \l SlotsLayout::mainSlot
189
are only allocated in memory on demand, i.e. the first time one of their
190
properties is queried.
193
//NOTE: querying subtitle.text triggers allocation of subtitle Label
194
Component.onCompleted: console.log(subtitle.text)
196
title.text: "Hello developers!"
199
In the example above, querying subtitle.text will trigger the
200
allocation in memory of the subtitle Label, which we don't actually use.
201
We \b recommend avoiding querying properties of labels that we
202
don't plan to use in the layout, in order to minimize memory consumption
203
and maximize the scrolling performance of our list views.
206
//no extra labels created
207
title.text: "Hello developers!"
212
UCListItemLayout::UCListItemLayout(QQuickItem *parent)
213
: UCSlotsLayout(parent)
219
\qmlproperty Label ListItemLayout::title
221
This property defines the title label and its properties.
222
Styling and font properties can be set just like on any other
223
Text component, as shown in the following example:
229
title.color: "yellow"
234
UCLabel *UCListItemLayout::title()
236
return qobject_cast<UCThreeLabelsSlot *>(mainSlot())->title();
240
\qmlproperty Label ListItemLayout::subtitle
242
This property defines the subtitle label and its properties.
243
Styling and font properties can be set by using the prefix
244
\c {subtitle.} in a similar way as shown in \l title.
246
UCLabel *UCListItemLayout::subtitle()
248
return qobject_cast<UCThreeLabelsSlot *>(mainSlot())->subtitle();
252
\qmlproperty Label ListItemLayout::summary
254
This property defines the subtitle label and its properties.
255
Styling and font properties can be set by using the prefix
256
\c {summary.} in a similar way as shown in \l title.
258
UCLabel *UCListItemLayout::summary()
260
return qobject_cast<UCThreeLabelsSlot *>(mainSlot())->summary();
263
QQuickItem *UCListItemLayout::mainSlot() {
264
if (UCSlotsLayout::mainSlot() == Q_NULLPTR) {
265
//don't set the parent, we have to create qqmldata first
266
UCThreeLabelsSlot *main = new UCThreeLabelsSlot();
268
//create QML data for mainSlot otherwise qmlAttachedProperties
269
//calls in SlotsLayout will fail (setContextForObject will create the QQmlData)
270
QQmlEngine::setContextForObject(main, qmlContext(this));
271
main->setParent(this);
273
//this will also set the parentItem
274
UCSlotsLayout::setMainSlot(main, false);
277
return UCSlotsLayout::mainSlot();
280
void UCListItemLayout::setMainSlot(QQuickItem *slot, bool fireSignal) {
282
Q_UNUSED(fireSignal);
283
qmlInfo(this) << "Setting a different mainSlot on ListItemLayout is not supported. Please use SlotsLayout instead.";