~zsombi/ubuntu-ui-toolkit/listitemSelectModeBugs

« back to all changes in this revision

Viewing changes to src/Ubuntu/Components/plugin/privates/threelabelsslot_p.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
 
 
17
#include "threelabelsslot_p.h"
 
18
#include "uclabel.h"
 
19
#include "ucunits.h"
 
20
#include "ucfontutils.h"
 
21
 
 
22
UCThreeLabelsSlotPrivate::UCThreeLabelsSlotPrivate()
 
23
    : QQuickItemPrivate()
 
24
    , m_title(Q_NULLPTR)
 
25
    , m_subtitle(Q_NULLPTR)
 
26
    , m_summary(Q_NULLPTR)
 
27
{
 
28
}
 
29
 
 
30
void UCThreeLabelsSlotPrivate::init()
 
31
{
 
32
    Q_Q(UCThreeLabelsSlot);
 
33
 
 
34
    QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()), q, SLOT(_q_onGuValueChanged()));
 
35
    _q_onGuValueChanged();
 
36
}
 
37
 
 
38
void UCThreeLabelsSlotPrivate::setTitleProperties()
 
39
{
 
40
    if (m_title != Q_NULLPTR) {
 
41
        m_title->setWrapMode(UCLabel::WordWrap);
 
42
        m_title->setElideMode(UCLabel::ElideRight);
 
43
        m_title->setMaximumLineCount(1);
 
44
        m_title->setTextSize(UCLabel::Medium);
 
45
    }
 
46
}
 
47
 
 
48
void UCThreeLabelsSlotPrivate::setSubtitleProperties()
 
49
{
 
50
    if (m_subtitle != Q_NULLPTR) {
 
51
        m_subtitle->setWrapMode(UCLabel::WordWrap);
 
52
        m_subtitle->setElideMode(UCLabel::ElideRight);
 
53
        m_subtitle->setMaximumLineCount(1);
 
54
        m_subtitle->setTextSize(UCLabel::Small);
 
55
    }
 
56
}
 
57
 
 
58
void UCThreeLabelsSlotPrivate::setSummaryProperties()
 
59
{
 
60
    if (m_summary != Q_NULLPTR) {
 
61
        m_summary->setWrapMode(UCLabel::WordWrap);
 
62
        m_summary->setElideMode(UCLabel::ElideRight);
 
63
        m_summary->setMaximumLineCount(2);
 
64
        m_summary->setTextSize(UCLabel::Small);
 
65
    }
 
66
}
 
67
 
 
68
void UCThreeLabelsSlotPrivate::_q_onGuValueChanged()
 
69
{
 
70
    if (m_title != Q_NULLPTR
 
71
            || m_subtitle != Q_NULLPTR
 
72
            || m_summary != Q_NULLPTR) {
 
73
        _q_updateLabelsAnchorsAndBBoxHeight();
 
74
    }
 
75
}
 
76
 
 
77
void UCThreeLabelsSlotPrivate::_q_updateLabelsAnchorsAndBBoxHeight()
 
78
{
 
79
    //if the component is not ready the QML properties may not have been evaluated yet,
 
80
    //it's not worth doing anything if that's the case
 
81
    if (!componentComplete) {
 
82
        return;
 
83
    }
 
84
 
 
85
    Q_Q(UCThreeLabelsSlot);
 
86
    bool skipTitle = m_title == Q_NULLPTR || m_title->text().isEmpty() || !m_title->isVisible();
 
87
    bool skipSubtitle = m_subtitle == Q_NULLPTR || m_subtitle->text().isEmpty() || !m_subtitle->isVisible();
 
88
    bool skipSummary = m_summary == Q_NULLPTR || m_summary->text().isEmpty() || !m_summary->isVisible();
 
89
 
 
90
    if (!skipTitle) {
 
91
        QQuickAnchors *titleAnchors = QQuickItemPrivate::get(m_title)->anchors();
 
92
        titleAnchors->setTop(top());
 
93
    }
 
94
 
 
95
    //even if a UCLabel is empty it will have height as if it had one character, so we can't rely
 
96
    //on just anchoring to bottom of the text above us (title in this case) because that will lead
 
97
    //to wrong positioning when title is empty
 
98
    if (!skipSubtitle) {
 
99
        QQuickAnchors *subtitleAnchors = QQuickItemPrivate::get(m_subtitle)->anchors();
 
100
        subtitleAnchors->setTop(skipTitle
 
101
                                ? top()
 
102
                                : QQuickItemPrivate::get(m_title)->baseline());
 
103
        subtitleAnchors->setTopMargin(skipTitle
 
104
                                      ? 0
 
105
                                      : UCUnits::instance().dp(LABELSBLOCK_SPACING_DP));
 
106
    }
 
107
 
 
108
    if (!skipSummary) {
 
109
        QQuickAnchors *summaryAnchors = QQuickItemPrivate::get(m_summary)->anchors();
 
110
        summaryAnchors->setTop(skipSubtitle
 
111
                               ? (skipTitle ? top() : QQuickItemPrivate::get(m_title)->baseline())
 
112
                               : QQuickItemPrivate::get(m_subtitle)->bottom());
 
113
        summaryAnchors->setTopMargin(skipSubtitle
 
114
                                     ? (skipTitle ? 0 : UCUnits::instance().dp(LABELSBLOCK_SPACING_DP))
 
115
                                     : 0);
 
116
    }
 
117
    //Update height of the labels box
 
118
    //NOTE (FIXME? it's stuff in Qt): height is not 0 when the string is empty, its default value is "fontHeight"!
 
119
    qreal labelsBoundingBoxHeight = 0;
 
120
 
 
121
    //We're assuming they're positioned in a column, title->subtitle->summary
 
122
    if (!skipSummary) {
 
123
        labelsBoundingBoxHeight = m_summary->y() + m_summary->height();
 
124
    } else if (!skipSubtitle) {
 
125
        labelsBoundingBoxHeight = m_subtitle->y() + m_subtitle->height();
 
126
    } else if (!skipTitle) {
 
127
        labelsBoundingBoxHeight = m_title->y() + m_title->height();
 
128
    }
 
129
 
 
130
    q->setImplicitHeight(labelsBoundingBoxHeight);
 
131
}
 
132
 
 
133
UCThreeLabelsSlot::UCThreeLabelsSlot(QQuickItem *parent)
 
134
    : QQuickItem(*(new UCThreeLabelsSlotPrivate), parent)
 
135
{
 
136
    setFlag(ItemHasContents);
 
137
    Q_D(UCThreeLabelsSlot);
 
138
    d->init();
 
139
}
 
140
 
 
141
UCLabel *UCThreeLabelsSlot::title()
 
142
{
 
143
    Q_D(UCThreeLabelsSlot);
 
144
    if (d->m_title == Q_NULLPTR) {
 
145
        d->m_title = new UCLabel(this);
 
146
        QQmlEngine::setContextForObject(d->m_title, qmlContext(this));
 
147
        d->m_title->init();
 
148
 
 
149
        QQuickAnchors *titleAnchors = QQuickItemPrivate::get(d->m_title)->anchors();
 
150
        titleAnchors->setLeft(d->left());
 
151
        titleAnchors->setRight(d->right());
 
152
 
 
153
        //we need this to know when any of the labels is empty. In that case, we'll have to change the
 
154
        //anchors because even if a UCLabel has empty text, its height will not be 0 but "fontHeight",
 
155
        //so anchoring to text's bottom will result in the wrong outcome as a consequence.
 
156
        //FIXME: updating anchors just because text changes is too much, we should probably just
 
157
        //have variables signal when a label becomes empty
 
158
        QObject::connect(d->m_title, SIGNAL(textChanged(QString)), this, SLOT(_q_updateLabelsAnchorsAndBBoxHeight()));
 
159
 
 
160
        //the height may change for many reasons, for instance:
 
161
        //- change of fontsize
 
162
        //- or resizing the layout until text wrapping is triggered
 
163
        //so we have to monitor height change as well
 
164
        QObject::connect(d->m_title, SIGNAL(heightChanged()), this, SLOT(_q_updateLabelsAnchorsAndBBoxHeight()));
 
165
        QObject::connect(d->m_title, SIGNAL(visibleChanged()), this, SLOT(_q_updateLabelsAnchorsAndBBoxHeight()));
 
166
 
 
167
        //When changing fontsize of the title, heightChanged triggers an update of the height of "this", but at that point
 
168
        //baseline anchor and baselineOffset are not updated yet, so the height computed is not correct.
 
169
        //For that reason, we have to update the height of the item also when baselineOffset changes
 
170
        QObject::connect(d->m_title, SIGNAL(baselineOffsetChanged(qreal)), this, SLOT(_q_updateLabelsAnchorsAndBBoxHeight()));
 
171
 
 
172
        d->setTitleProperties();
 
173
        d->_q_updateLabelsAnchorsAndBBoxHeight();
 
174
    }
 
175
    return d->m_title;
 
176
}
 
177
 
 
178
UCLabel *UCThreeLabelsSlot::subtitle()
 
179
{
 
180
    Q_D(UCThreeLabelsSlot);
 
181
    if (d->m_subtitle == Q_NULLPTR) {
 
182
        d->m_subtitle = new UCLabel(this);
 
183
        QQmlEngine::setContextForObject(d->m_subtitle, qmlContext(this));
 
184
        d->m_subtitle->init();
 
185
 
 
186
        QQuickAnchors *subtitleAnchors = QQuickItemPrivate::get(d->m_subtitle)->anchors();
 
187
        subtitleAnchors->setLeft(d->left());
 
188
        subtitleAnchors->setRight(d->right());
 
189
 
 
190
        QObject::connect(d->m_subtitle, SIGNAL(textChanged(QString)), this, SLOT(_q_updateLabelsAnchorsAndBBoxHeight()));
 
191
        QObject::connect(d->m_subtitle, SIGNAL(heightChanged()), this, SLOT(_q_updateLabelsAnchorsAndBBoxHeight()));
 
192
        QObject::connect(d->m_subtitle, SIGNAL(visibleChanged()), this, SLOT(_q_updateLabelsAnchorsAndBBoxHeight()));
 
193
 
 
194
        d->setSubtitleProperties();
 
195
        d->_q_updateLabelsAnchorsAndBBoxHeight();
 
196
    }
 
197
    return d->m_subtitle;
 
198
}
 
199
 
 
200
UCLabel *UCThreeLabelsSlot::summary()
 
201
{
 
202
    Q_D(UCThreeLabelsSlot);
 
203
    if (d->m_summary == Q_NULLPTR) {
 
204
        d->m_summary = new UCLabel(this);
 
205
        QQmlEngine::setContextForObject(d->m_summary, qmlContext(this));
 
206
        d->m_summary->init();
 
207
 
 
208
        QQuickAnchors *summaryAnchors = QQuickItemPrivate::get(d->m_summary)->anchors();
 
209
        summaryAnchors->setLeft(d->left());
 
210
        summaryAnchors->setRight(d->right());
 
211
 
 
212
        QObject::connect(d->m_summary, SIGNAL(textChanged(QString)), this, SLOT(_q_updateLabelsAnchorsAndBBoxHeight()));
 
213
        QObject::connect(d->m_summary, SIGNAL(heightChanged()), this, SLOT(_q_updateLabelsAnchorsAndBBoxHeight()));
 
214
        QObject::connect(d->m_summary, SIGNAL(visibleChanged()), this, SLOT(_q_updateLabelsAnchorsAndBBoxHeight()));
 
215
 
 
216
        d->setSummaryProperties();
 
217
        d->_q_updateLabelsAnchorsAndBBoxHeight();
 
218
    }
 
219
    return d->m_summary;
 
220
}