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/>.
17
#include "threelabelsslot_p.h"
20
#include "ucfontutils.h"
22
UCThreeLabelsSlotPrivate::UCThreeLabelsSlotPrivate()
25
, m_subtitle(Q_NULLPTR)
26
, m_summary(Q_NULLPTR)
30
void UCThreeLabelsSlotPrivate::init()
32
Q_Q(UCThreeLabelsSlot);
34
QObject::connect(&UCUnits::instance(), SIGNAL(gridUnitChanged()), q, SLOT(_q_onGuValueChanged()));
35
_q_onGuValueChanged();
38
void UCThreeLabelsSlotPrivate::setTitleProperties()
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);
48
void UCThreeLabelsSlotPrivate::setSubtitleProperties()
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);
58
void UCThreeLabelsSlotPrivate::setSummaryProperties()
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);
68
void UCThreeLabelsSlotPrivate::_q_onGuValueChanged()
70
if (m_title != Q_NULLPTR
71
|| m_subtitle != Q_NULLPTR
72
|| m_summary != Q_NULLPTR) {
73
_q_updateLabelsAnchorsAndBBoxHeight();
77
void UCThreeLabelsSlotPrivate::_q_updateLabelsAnchorsAndBBoxHeight()
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) {
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();
91
QQuickAnchors *titleAnchors = QQuickItemPrivate::get(m_title)->anchors();
92
titleAnchors->setTop(top());
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
99
QQuickAnchors *subtitleAnchors = QQuickItemPrivate::get(m_subtitle)->anchors();
100
subtitleAnchors->setTop(skipTitle
102
: QQuickItemPrivate::get(m_title)->baseline());
103
subtitleAnchors->setTopMargin(skipTitle
105
: UCUnits::instance().dp(LABELSBLOCK_SPACING_DP));
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))
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;
121
//We're assuming they're positioned in a column, title->subtitle->summary
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();
130
q->setImplicitHeight(labelsBoundingBoxHeight);
133
UCThreeLabelsSlot::UCThreeLabelsSlot(QQuickItem *parent)
134
: QQuickItem(*(new UCThreeLabelsSlotPrivate), parent)
136
setFlag(ItemHasContents);
137
Q_D(UCThreeLabelsSlot);
141
UCLabel *UCThreeLabelsSlot::title()
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));
149
QQuickAnchors *titleAnchors = QQuickItemPrivate::get(d->m_title)->anchors();
150
titleAnchors->setLeft(d->left());
151
titleAnchors->setRight(d->right());
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()));
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()));
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()));
172
d->setTitleProperties();
173
d->_q_updateLabelsAnchorsAndBBoxHeight();
178
UCLabel *UCThreeLabelsSlot::subtitle()
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();
186
QQuickAnchors *subtitleAnchors = QQuickItemPrivate::get(d->m_subtitle)->anchors();
187
subtitleAnchors->setLeft(d->left());
188
subtitleAnchors->setRight(d->right());
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()));
194
d->setSubtitleProperties();
195
d->_q_updateLabelsAnchorsAndBBoxHeight();
197
return d->m_subtitle;
200
UCLabel *UCThreeLabelsSlot::summary()
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();
208
QQuickAnchors *summaryAnchors = QQuickItemPrivate::get(d->m_summary)->anchors();
209
summaryAnchors->setLeft(d->left());
210
summaryAnchors->setRight(d->right());
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()));
216
d->setSummaryProperties();
217
d->_q_updateLabelsAnchorsAndBBoxHeight();