~zsombi/ubuntu-ui-toolkit/listitemSelectModeBugs

« back to all changes in this revision

Viewing changes to src/Ubuntu/Components/plugin/uclistitemlayout.cpp

  • Committer: Zsombor Egri
  • Date: 2015-11-16 06:35:05 UTC
  • mfrom: (1664.1.1 listitemSelectModeBugs)
  • Revision ID: zsombor.egri@canonical.com-20151116063505-cwn2qfks7qzk10g9
re-sync

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2015 Canonical Ltd.
 
3
 *
 
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.
 
7
 *
 
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.
 
12
 *
 
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/>.
 
15
 *
 
16
 * Author: Andrea Bernabei <andrea.bernabei@canonical.com>
 
17
 */
 
18
 
 
19
#include "private/qqmldata_p.h"
 
20
#include <QtQml/QQmlEngine>
 
21
 
 
22
#include "privates/threelabelsslot_p.h"
 
23
#include "uclistitemlayout.h"
 
24
#include "uclabel.h"
 
25
 
 
26
/*!
 
27
    \qmltype ListItemLayout
 
28
    \instantiates UCListItemLayout
 
29
    \inqmlmodule Ubuntu.Components 1.3
 
30
    \inherits SlotsLayout
 
31
    \ingroup ubuntu
 
32
 
 
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.
 
36
 
 
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}).
 
42
 
 
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.
 
46
 
 
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
 
50
    a clean layout.
 
51
 
 
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}).
 
58
 
 
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.
 
62
 
 
63
    To read more about advanced slots positioning or how to handle
 
64
    input (mouse or touch) in ListItemLayout, see \l SlotsLayout
 
65
    documentation.
 
66
 
 
67
    If you don't need the features provided by \l {ListItem} (such as
 
68
    the swiping actions),
 
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}.
 
71
 
 
72
    The following code example shows how easy it is to create
 
73
    even non trivial list items using
 
74
    \l ListItem and ListItemLayout:
 
75
    \qml
 
76
    ListItem {
 
77
        height: layout.height + divider.height
 
78
        ListItemLayout {
 
79
            id: layout
 
80
            title.text: "Hello developers!"
 
81
            subtitle.text: "I'm a subtitle, I'm tiny!"
 
82
            summary.text: "Ubuntu!"
 
83
 
 
84
            CheckBox { SlotsLayout.position: SlotsLayout.Leading }
 
85
 
 
86
            Icon {
 
87
                name: "message"
 
88
                SlotsLayout.position: SlotsLayout.Trailing;
 
89
                width: units.gu(2)
 
90
            }
 
91
        }
 
92
    }
 
93
    \endqml
 
94
 
 
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.
 
102
 
 
103
    \qml
 
104
    ListItem {
 
105
        id: listItem
 
106
        height: layout.height + divider.height
 
107
 
 
108
        ListItemLayout {
 
109
            id: layout
 
110
            title.text: "Hello..."
 
111
            title.color: UbuntuColors.Orange
 
112
            subtitle.text: "...world!"
 
113
 
 
114
            Rectangle {
 
115
                SlotsLayout.position: SlotsLayout.Leading
 
116
                color: "pink"
 
117
                height: units.gu(6)
 
118
                width: height
 
119
            }
 
120
 
 
121
            Item {
 
122
                id: slot
 
123
                width: secondLabel.width
 
124
                height: parent.height
 
125
 
 
126
                //as we want to position labels to align with title and subtitle
 
127
                SlotsLayout.overrideVerticalPositioning: true
 
128
 
 
129
                Label {
 
130
                    id: firstLabel
 
131
                    anchors.right: secondLabel.right
 
132
                    text: "19:17"
 
133
                    fontSize: "small"
 
134
                    y: layout.mainSlot.y + layout.title.y
 
135
                       + layout.title.baselineOffset - baselineOffset
 
136
                }
 
137
 
 
138
                Label {
 
139
                    id: secondLabel
 
140
                    text: "Outgoing"
 
141
                    fontSize: "small"
 
142
                    y: layout.mainSlot.y + layout.subtitle.y
 
143
                       + layout.subtitle.baselineOffset - baselineOffset
 
144
                }
 
145
            }
 
146
        }
 
147
    }
 
148
    \endqml
 
149
    \sa SlotsLayout
 
150
    \sa ProgressionSlot
 
151
 
 
152
    \section1 Labels layout
 
153
 
 
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,
 
156
    respectively.
 
157
 
 
158
    The \l subtitle has its top anchored to \l {title}'s baseline, with a margin of
 
159
    4 DPs.
 
160
 
 
161
    The \l summary has its top tightly anchored to \l {subtitle}'s bottom.
 
162
 
 
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}.
 
167
 
 
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
 
170
    following example:
 
171
    \qml
 
172
    ListItemLayout {
 
173
        title.text: "Hello developers!"
 
174
        //NOTE: the whitespace
 
175
        subtitle.text: " "
 
176
    }
 
177
    \endqml
 
178
 
 
179
    That will make sure \l SlotsLayout::mainSlot is resized to accomodate the (currently empty)
 
180
    subtitle.
 
181
 
 
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.
 
185
 
 
186
    \section1 Optimizing memory consumption
 
187
 
 
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.
 
191
    \qml
 
192
    ListItemLayout {
 
193
        //NOTE: querying subtitle.text triggers allocation of subtitle Label
 
194
        Component.onCompleted: console.log(subtitle.text)
 
195
 
 
196
        title.text: "Hello developers!"
 
197
    }
 
198
    \endqml
 
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.
 
204
    \qml
 
205
    ListItemLayout {
 
206
        //no extra labels created
 
207
        title.text: "Hello developers!"
 
208
    }
 
209
    \endqml
 
210
 
 
211
*/
 
212
UCListItemLayout::UCListItemLayout(QQuickItem *parent)
 
213
    : UCSlotsLayout(parent)
 
214
{
 
215
 
 
216
}
 
217
 
 
218
/*!
 
219
    \qmlproperty Label ListItemLayout::title
 
220
 
 
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:
 
224
 
 
225
    \qml
 
226
    Item {
 
227
        ListItemLayout {
 
228
            title.text: "Hello"
 
229
            title.color: "yellow"
 
230
        }
 
231
    }
 
232
    \endqml
 
233
*/
 
234
UCLabel *UCListItemLayout::title()
 
235
{
 
236
    return qobject_cast<UCThreeLabelsSlot *>(mainSlot())->title();
 
237
}
 
238
 
 
239
/*!
 
240
    \qmlproperty Label ListItemLayout::subtitle
 
241
 
 
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.
 
245
*/
 
246
UCLabel *UCListItemLayout::subtitle()
 
247
{
 
248
    return qobject_cast<UCThreeLabelsSlot *>(mainSlot())->subtitle();
 
249
}
 
250
 
 
251
/*!
 
252
    \qmlproperty Label ListItemLayout::summary
 
253
 
 
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.
 
257
*/
 
258
UCLabel *UCListItemLayout::summary()
 
259
{
 
260
    return qobject_cast<UCThreeLabelsSlot *>(mainSlot())->summary();
 
261
}
 
262
 
 
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();
 
267
 
 
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);
 
272
 
 
273
        //this will also set the parentItem
 
274
        UCSlotsLayout::setMainSlot(main, false);
 
275
    }
 
276
 
 
277
    return UCSlotsLayout::mainSlot();
 
278
}
 
279
 
 
280
void UCListItemLayout::setMainSlot(QQuickItem *slot, bool fireSignal) {
 
281
    Q_UNUSED(slot);
 
282
    Q_UNUSED(fireSignal);
 
283
    qmlInfo(this) << "Setting a different mainSlot on ListItemLayout is not supported. Please use SlotsLayout instead.";
 
284
}