~bzoltan/ubuntu-ui-toolkit/new_list_item_01

« back to all changes in this revision

Viewing changes to modules/Ubuntu/Components/plugin/uclistitem.cpp

prereq

Show diffs side-by-side

added added

removed removed

Lines of Context:
131
131
    }
132
132
}
133
133
 
134
 
QSGNode *UCListItemDivider::paint(QSGNode *paintNode, const QRectF &rect)
 
134
QSGNode *UCListItemDivider::paint(const QRectF &rect)
135
135
{
136
136
    if (m_visible && !m_lastItem && (m_gradient.size() > 0)) {
137
 
        QSGRectangleNode *rectNode = static_cast<QSGRectangleNode *>(paintNode);
138
 
        if (!rectNode) {
139
 
            rectNode = m_listItem->sceneGraphContext()->createRectangleNode();
140
 
        }
 
137
        // the parent always recreates the node, so no worries for the existing child node
 
138
        QSGRectangleNode *rectNode = m_listItem->sceneGraphContext()->createRectangleNode();
141
139
        rectNode->setRect(QRectF(m_leftMargin, rect.height() - m_thickness,
142
140
                                 rect.width() - m_leftMargin - m_rightMargin, m_thickness));
143
141
        rectNode->setGradientStops(m_gradient);
144
142
        rectNode->update();
145
143
        return rectNode;
146
144
    } else {
147
 
        delete paintNode;
148
145
        return 0;
149
146
    }
150
147
}
205
202
}
206
203
 
207
204
/******************************************************************************
208
 
 * ListItemContent
209
 
 */
210
 
UCListItemContent::UCListItemContent(QQuickItem *parent)
211
 
    : QQuickItem(parent)
212
 
    , m_color(Qt::transparent)
213
 
    , m_pressedColor(Qt::yellow)
214
 
    , m_item(0)
215
 
{
216
 
    setFlag(QQuickItem::ItemHasContents);
217
 
    // catch theme palette changes
218
 
    connect(&UCTheme::instance(), &UCTheme::paletteChanged, this, &UCListItemContent::updateColors);
219
 
    updateColors();
220
 
}
221
 
 
222
 
UCListItemContent::~UCListItemContent()
223
 
{
224
 
}
225
 
 
226
 
void UCListItemContent::setColor(const QColor &color)
227
 
{
228
 
    if (m_color == color) {
229
 
        return;
230
 
    }
231
 
    m_color = color;
232
 
    update();
233
 
    Q_EMIT colorChanged();
234
 
}
235
 
 
236
 
void UCListItemContent::setPressedColor(const QColor &color)
237
 
{
238
 
    if (m_pressedColor == color) {
239
 
        return;
240
 
    }
241
 
    m_pressedColor = color;
242
 
    // no more theme change watch
243
 
    disconnect(&UCTheme::instance(), &UCTheme::paletteChanged, this, &UCListItemContent::updateColors);
244
 
    update();
245
 
    Q_EMIT pressedColorChanged();
246
 
}
247
 
 
248
 
void UCListItemContent::updateColors()
249
 
{
250
 
    m_pressedColor = getPaletteColor("selected", "background");
251
 
    update();
252
 
}
253
 
 
254
 
 
255
 
void UCListItemContent::itemChange(ItemChange change, const ItemChangeData &data)
256
 
{
257
 
    if (change == ItemParentHasChanged) {
258
 
        m_item = qobject_cast<UCListItem*>(data.item);
259
 
    }
260
 
    QQuickItem::itemChange(change, data);
261
 
}
262
 
 
263
 
QSGNode *UCListItemContent::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
264
 
{
265
 
    Q_UNUSED(data);
266
 
 
267
 
    UCListItemPrivate *dd = UCListItemPrivate::get(m_item);
268
 
    bool pressed = (dd && dd->pressed);
269
 
    bool selected = (dd && dd->selectable && dd->selected);
270
 
    QColor color = (pressed || selected) ? m_pressedColor : m_color;
271
 
 
272
 
    delete oldNode;
273
 
    if (width() <= 0 || height() <= 0 || (color.alpha() == 0)) {
274
 
        return 0;
275
 
    }
276
 
 
277
 
    QSGRectangleNode *rectNode = QQuickItemPrivate::get(this)->sceneGraphContext()->createRectangleNode();
278
 
    rectNode->setColor(color);
279
 
    rectNode->setRect(boundingRect());
280
 
    rectNode->update();
281
 
    return rectNode;
282
 
}
283
 
 
284
 
 
285
 
/******************************************************************************
286
 
 * ListItemBasePrivate
 
205
 * ListItemPrivate
287
206
 */
288
207
UCListItemPrivate::UCListItemPrivate()
289
208
    : UCStyledItemBasePrivate()
290
209
    , pressed(false)
 
210
    , pressedColorChanged(false)
291
211
    , moved(false)
292
212
    , ready(false)
293
213
    , selectable(false)
294
214
    , selected(false)
295
215
    , index(-1)
296
216
    , xAxisMoveThresholdGU(1.5)
 
217
    , color(Qt::transparent)
 
218
    , pressedColor(Qt::transparent)
297
219
    , reboundAnimation(0)
298
220
    , flickableInteractive(0)
 
221
    , contentItem(new QQuickItem)
299
222
    , disabledOpacity(0)
300
 
    , contentItem(new UCListItemContent)
301
223
    , divider(new UCListItemDivider)
302
224
    , leadingOptions(0)
303
225
    , trailingOptions(0)
319
241
    divider->init(q);
320
242
    // content will be redirected to the contentItem, therefore we must report
321
243
    // children changes as it would come from the main component
322
 
    QObject::connect(contentItem, &UCListItemContent::childrenChanged,
 
244
    QObject::connect(contentItem, &QQuickItem::childrenChanged,
323
245
                     q, &UCListItem::childrenChanged);
324
246
    q->setFlag(QQuickItem::ItemHasContents);
325
247
    // turn activeFocusOnPress on
326
248
    activeFocusOnPress = true;
327
249
    setFocusable();
328
250
 
 
251
    // catch theme palette changes
 
252
    QObject::connect(&UCTheme::instance(), SIGNAL(paletteChanged()), q, SLOT(_q_updateColors()));
 
253
    _q_updateColors();
 
254
 
329
255
    // watch size change and set implicit size;
330
256
    QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()), q, SLOT(_q_updateSize()));
331
257
    _q_updateSize();
345
271
 
346
272
void UCListItemPrivate::setFocusable()
347
273
{
348
 
    // alsways accept mouse events
 
274
    // always accept mouse events
349
275
    Q_Q(UCListItem);
350
276
    q->setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton);
351
277
    q->setFiltersChildMouseEvents(true);
352
278
}
353
279
 
 
280
void UCListItemPrivate::_q_updateColors()
 
281
{
 
282
    Q_Q(UCListItem);
 
283
    pressedColor = getPaletteColor("selected", "background");
 
284
    q->update();
 
285
}
 
286
 
354
287
void UCListItemPrivate::_q_dimmDisabled()
355
288
{
356
289
    Q_Q(UCListItem);
412
345
    Q_Q(UCListItem);
413
346
    bool checked = selectionPanel->property("checked").toBool();
414
347
    q->setSelected(checked);
415
 
    contentItem->update();
 
348
    update();
416
349
}
417
350
 
418
351
// the function performs a cleanup on mouse release without any rebound animation
437
370
    Q_Q(UCListItem);
438
371
    QQuickItem *owner = flickable ? flickable : parentItem;
439
372
    q->setImplicitWidth(owner ? owner->width() : UCUnits::instance().gu(40));
440
 
    q->setImplicitHeight(UCUnits::instance().gu(6));
 
373
    q->setImplicitHeight(UCUnits::instance().gu(7));
441
374
}
442
375
 
443
376
// set pressed flag and update contentItem
446
379
    if (this->pressed != pressed) {
447
380
        this->pressed = pressed;
448
381
        suppressClick = false;
449
 
        contentItem->update();
450
382
        Q_Q(UCListItem);
 
383
        q->update();
451
384
        Q_EMIT q->pressedChanged();
452
385
    }
453
386
}
598
531
/*!
599
532
 * \qmltype ListItem
600
533
 * \instantiates UCListItem
601
 
 * \inqmlmodule Ubuntu.Components 1.1
602
 
 * \ingroup ubuntu
 
534
 * \inqmlmodule Ubuntu.Components 1.2
 
535
 * \ingroup unstable-ubuntu-listitems
 
536
 * \since Ubuntu.Components 1.2
603
537
 * \brief The ListItem element provides Ubuntu design standards for list or grid
604
538
 * views.
605
539
 *
610
544
 * ways on it. However, when used in list views, the content must be carefully
611
545
 * chosen to in order to keep the kinetic behavior and the highest FPS possible.
612
546
 *
613
 
 * \c contentItem is an essential part of the component. Beside the fact that it
614
 
 * holds all components and resources declared as child to ListItem, it can also
615
 
 * configure the color of the background when in normal mode or when pressed. Being
616
 
 * an item, all other properties can be accessed or altered, with the exception
 
547
 * The component provides two color properties which configures the item's background
 
548
 * when normal or pressed. This can be configures through \l color and \l pressedColor
 
549
 * properties.
 
550
 *
 
551
 * \c contentItem holds all components and resources declared as child to ListItem.
 
552
 * Being an Item, all other properties can be accessed or altered, with the exception
617
553
 * of some:
618
554
 * \list A
619
555
 * \li do not alter \c x, \c y, \c width or \c height properties as those are
785
721
QSGNode *UCListItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
786
722
{
787
723
    Q_UNUSED(data);
 
724
 
788
725
    Q_D(UCListItem);
789
 
    if (width() <= 0 || height() <= 0 || !d->divider) {
790
 
        delete oldNode;
 
726
    QColor color = (d->pressed || (d->selectable && d->selected))? d->pressedColor : d->color;
 
727
 
 
728
    delete oldNode;
 
729
    if (width() <= 0 || height() <= 0) {
791
730
        return 0;
792
731
    }
793
 
    // paint divider
794
 
    return d->divider->paint(oldNode, boundingRect());
 
732
 
 
733
    QSGRectangleNode *rectNode = 0;
 
734
    if (color.alpha() > 0) {
 
735
        rectNode = QQuickItemPrivate::get(this)->sceneGraphContext()->createRectangleNode();
 
736
        rectNode->setColor(color);
 
737
        rectNode->setRect(boundingRect());
 
738
        rectNode->update();
 
739
    }
 
740
    oldNode = rectNode;
 
741
    if (d->divider && d->divider->m_visible) {
 
742
        QSGNode * dividerNode = d->divider->paint(boundingRect());
 
743
        if (dividerNode && oldNode) {
 
744
            oldNode->appendChildNode(dividerNode);
 
745
        } else if (dividerNode) {
 
746
            oldNode = dividerNode;
 
747
        }
 
748
    }
 
749
    return oldNode;
795
750
}
796
751
 
797
752
void UCListItem::mousePressEvent(QMouseEvent *event)
802
757
        // while moving, we cannot select or tug any items
803
758
        return;
804
759
    }
805
 
    d->setPressed(true);
806
 
    d->lastPos = d->pressedPos = event->localPos();
807
 
    // connect the Flickable to know when to rebound
808
 
    d->listenToRebind(true);
809
 
    // start pressandhold timer
810
 
    d->pressAndHoldTimer.start(DefaultPressAndHoldDelay, this);
811
 
    // accept the event so we get the rest of the events as well
812
 
    event->setAccepted(true);
 
760
    if (event->button() == Qt::LeftButton) {
 
761
        d->setPressed(true);
 
762
        d->lastPos = d->pressedPos = event->localPos();
 
763
        // connect the Flickable to know when to rebound
 
764
        d->listenToRebind(true);
 
765
        // start pressandhold timer
 
766
        d->pressAndHoldTimer.start(DefaultPressAndHoldDelay, this);
 
767
        // accept the event so we get the rest of the events as well
 
768
        event->setAccepted(true);
 
769
    }
813
770
}
814
771
 
815
772
void UCListItem::mouseReleaseEvent(QMouseEvent *event)
987
944
}
988
945
 
989
946
/*!
990
 
 * \qmlpropertygroup ::ListItem::contentItem
991
 
 * \qmlproperty color ListItem::contentItem.color
992
 
 * \qmlproperty color ListItem::contentItem.pressedColor
 
947
 * \qmlproperty Item ListItem::contentItem
993
948
 *
994
 
 * contentItem holds the components placed on a ListItem. \c color configures
995
 
 * the color of the normal contentItem, and \c pressedColor configures the color
996
 
 * when pressed.
 
949
 * contentItem holds the components placed on a ListItem.
997
950
 */
998
 
UCListItemContent* UCListItem::contentItem() const
 
951
QQuickItem* UCListItem::contentItem() const
999
952
{
1000
953
    Q_D(const UCListItem);
1001
954
    return d->contentItem;
1042
995
}
1043
996
 
1044
997
/*!
 
998
 * \qmlproperty color ListItem::color
 
999
 * Configures the color of the normal background. The default value is transparent.
 
1000
 */
 
1001
QColor UCListItem::color() const
 
1002
{
 
1003
    Q_D(const UCListItem);
 
1004
    return d->color;
 
1005
}
 
1006
void UCListItem::setColor(const QColor &color)
 
1007
{
 
1008
    Q_D(UCListItem);
 
1009
    if (d->color == color) {
 
1010
        return;
 
1011
    }
 
1012
    d->color = color;
 
1013
    update();
 
1014
    Q_EMIT colorChanged();
 
1015
}
 
1016
 
 
1017
/*!
 
1018
 * \qmlproperty color ListItem::pressedColor
 
1019
 * Configures the color when pressed. Defaults to the theme palette's background color.
 
1020
 */
 
1021
QColor UCListItem::pressedColor() const
 
1022
{
 
1023
    Q_D(const UCListItem);
 
1024
    return d->pressedColor;
 
1025
}
 
1026
void UCListItem::setPressedColor(const QColor &color)
 
1027
{
 
1028
    Q_D(UCListItem);
 
1029
    if (d->pressedColor == color) {
 
1030
        return;
 
1031
    }
 
1032
    d->pressedColor = color;
 
1033
    // no more theme change watch
 
1034
    disconnect(&UCTheme::instance(), SIGNAL(paletteChanged()), this, SLOT(_q_updateColors()));
 
1035
    update();
 
1036
    Q_EMIT pressedColorChanged();
 
1037
}
 
1038
 
 
1039
/*!
1045
1040
 * \qmlproperty bool ListItem::selectable
1046
1041
 * The property drives whether a list item is selectable or not. When set, the item
1047
1042
 * will show a check box on the leading side hanving the content item pushed towards
1091
1086
    Q_EMIT selectedChanged();
1092
1087
}
1093
1088
 
1094
 
 
1095
1089
/*!
1096
1090
 * \qmlproperty list<Object> ListItem::data
1097
1091
 * \default