Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qcommandlinkbutton.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include "qstylepainter.h"
6#include "qstyleoption.h"
7#include "qtextdocument.h"
8#include "qtextlayout.h"
9#include "qcolor.h"
10#include "qfont.h"
11#include <qmath.h>
12
13#include "private/qpushbutton_p.h"
14
16
58{
59 Q_DECLARE_PUBLIC(QCommandLinkButton)
60
61public:
64
65 void init();
67 bool usingVistaStyle() const;
68
69 QFont titleFont() const;
70 QFont descriptionFont() const;
71
72 QRect titleRect() const;
73 QRect descriptionRect() const;
74
75 int textOffset() const;
76 int descriptionOffset() const;
77 int descriptionHeight(int width) const;
78 QColor mergedColors(const QColor &a, const QColor &b, int value) const;
79
80 int topMargin() const { return 10; }
81 int leftMargin() const { return 7; }
82 int rightMargin() const { return 4; }
83 int bottomMargin() const { return 10; }
84
87};
88
89// Mix colors a and b with a ratio in the range [0-255]
91{
92 Q_ASSERT(value >= 0);
93 Q_ASSERT(value <= 255);
94 QColor tmp = a;
95 tmp.setRed((tmp.red() * value) / 255 + (b.red() * (255 - value)) / 255);
96 tmp.setGreen((tmp.green() * value) / 255 + (b.green() * (255 - value)) / 255);
97 tmp.setBlue((tmp.blue() * value) / 255 + (b.blue() * (255 - value)) / 255);
98 return tmp;
99}
100
102{
103 Q_Q(const QCommandLinkButton);
104 QFont font = q->font();
105 if (usingVistaStyle()) {
106 font.setPointSizeF(12.0);
107 } else {
108 font.setBold(true);
109 font.setPointSizeF(9.0);
110 }
111
112 // Note the font will be resolved against
113 // QPainters font, so we need to restore the mask
114 int resolve_mask = font.resolve_mask;
115 QFont modifiedFont = q->font().resolve(font);
116 modifiedFont.detach();
117 modifiedFont.resolve_mask = resolve_mask;
118 return modifiedFont;
119}
120
122{
123 Q_Q(const QCommandLinkButton);
124 QFont font = q->font();
125 font.setPointSizeF(9.0);
126
127 // Note the font will be resolved against
128 // QPainters font, so we need to restore the mask
129 int resolve_mask = font.resolve_mask;
130 QFont modifiedFont = q->font().resolve(font);
131 modifiedFont.detach();
132 modifiedFont.resolve_mask = resolve_mask;
133 return modifiedFont;
134}
135
137{
138 Q_Q(const QCommandLinkButton);
139 QRect r = q->rect().adjusted(textOffset(), topMargin(), -rightMargin(), 0);
140 if (description.isEmpty())
141 {
143 r.setTop(r.top() + qMax(0, (q->icon().actualSize(q->iconSize()).height()
144 - fm.height()) / 2));
145 }
146
147 return r;
148}
149
151{
152 Q_Q(const QCommandLinkButton);
153 return q->rect().adjusted(textOffset(), descriptionOffset(),
155}
156
158{
159 Q_Q(const QCommandLinkButton);
160 return q->icon().actualSize(q->iconSize()).width() + leftMargin() + 6;
161}
162
164{
166 return topMargin() + fm.height();
167}
168
170{
171 Q_Q(const QCommandLinkButton);
172 //### This is a hack to detect if we are indeed running Vista style themed and not in classic
173 // When we add api to query for this, we should change this implementation to use it.
174 return q->property("_qt_usingVistaStyle").toBool()
175 && q->style()->pixelMetric(QStyle::PM_ButtonShiftHorizontal, nullptr, q) == 0;
176}
177
179{
182 q->setAttribute(Qt::WA_Hover);
183 q->setAttribute(Qt::WA_MacShowFocusRect, false);
184
187 q->setSizePolicy(policy);
188
189 q->setIconSize(QSize(20, 20));
191 q->initStyleOption(&opt);
192 q->setIcon(q->style()->standardIcon(QStyle::SP_CommandLink, &opt, q));
193}
194
195// Calculates the height of the description text based on widget width
197{
198 // Calc width of actual paragraph
199 int lineWidth = widgetWidth - textOffset() - rightMargin();
200
201 qreal descriptionheight = 0;
202 if (!description.isEmpty()) {
204 layout.setFont(descriptionFont());
205 layout.beginLayout();
206 while (true) {
207 QTextLine line = layout.createLine();
208 if (!line.isValid())
209 break;
210 line.setLineWidth(lineWidth);
211 line.setPosition(QPointF(0, descriptionheight));
212 descriptionheight += line.height();
213 }
214 layout.endLayout();
215 }
216 return qCeil(descriptionheight);
217}
218
223{
224 Q_D(const QCommandLinkButton);
225 QSize size = sizeHint();
226 int minimumHeight = qMax(d->descriptionOffset() + d->bottomMargin(),
227 icon().actualSize(iconSize()).height() + d->topMargin());
228 size.setHeight(minimumHeight);
229 return size;
230}
231
237
248
259
264 : QCommandLinkButton(text, parent)
265{
267}
268
275
278{
279 return QPushButton::event(e);
280}
281
284{
285// Standard size hints from UI specs
286// Without note: 135, 41
287// With note: 135, 60
288 Q_D(const QCommandLinkButton);
289
291 QFontMetrics fm(d->titleFont());
292 int textWidth = qMax(fm.horizontalAdvance(text()), 135);
293 int buttonWidth = textWidth + d->textOffset() + d->rightMargin();
294 int heightWithoutDescription = d->descriptionOffset() + d->bottomMargin();
295
296 size.setWidth(qMax(size.width(), buttonWidth));
297 size.setHeight(qMax(d->description.isEmpty() ? 41 : 60,
298 heightWithoutDescription + d->descriptionHeight(buttonWidth)));
299 return size;
300}
301
304{
305 Q_D(const QCommandLinkButton);
306 int heightWithoutDescription = d->descriptionOffset() + d->bottomMargin();
307 // find the width available for the description area
308 return qMax(heightWithoutDescription + d->descriptionHeight(width),
309 icon().actualSize(iconSize()).height() + d->topMargin() +
310 d->bottomMargin());
311}
312
315{
317 QStylePainter p(this);
318 p.save();
319
322
323 option.text = QString();
324 option.icon = QIcon(); //we draw this ourselves
325 QSize pixmapSize = icon().actualSize(iconSize());
326
327 const int vOffset = isDown()
329 const int hOffset = isDown()
331
332 //Draw icon
333 p.drawControl(QStyle::CE_PushButton, option);
334 if (!icon().isNull())
335 p.drawPixmap(d->leftMargin() + hOffset, d->topMargin() + vOffset,
338
339 //Draw title
340 QColor textColor = palette().buttonText().color();
341 if (isEnabled() && d->usingVistaStyle()) {
342 textColor = option.palette.buttonText().color();
343 if (underMouse() && !isDown())
344 textColor = option.palette.brightText().color();
345 //A simple text color transition
346 d->currentColor = d->mergedColors(textColor, d->currentColor, 60);
347 option.palette.setColor(QPalette::ButtonText, d->currentColor);
348 }
349
350 int textflags = Qt::TextShowMnemonic;
351 if (!style()->styleHint(QStyle::SH_UnderlineShortcut, &option, this))
352 textflags |= Qt::TextHideMnemonic;
353
354 p.setFont(d->titleFont());
355 p.drawItemText(d->titleRect().translated(hOffset, vOffset),
356 textflags, option.palette, isEnabled(), text(), QPalette::ButtonText);
357
358 //Draw description
359 textflags |= Qt::TextWordWrap | Qt::ElideRight;
360 p.setFont(d->descriptionFont());
361 p.drawItemText(d->descriptionRect().translated(hOffset, vOffset), textflags,
363 p.restore();
364}
365
367{
369 d->description = description;
371 update();
372}
373
375{
376 Q_D(const QCommandLinkButton);
377 return d->description;
378}
379
381
382#include "moc_qcommandlinkbutton.cpp"
QIcon icon
the icon shown on the button
void setText(const QString &text)
bool isChecked() const
QSize iconSize
the icon size used for this button.
QString text
the text shown on the button
const QColor & color() const
Returns the brush color.
Definition qbrush.h:121
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
void setGreen(int green)
Sets the green color component of this color to green.
Definition qcolor.cpp:1568
void setBlue(int blue)
Sets the blue color component of this color to blue.
Definition qcolor.cpp:1597
int red() const noexcept
Returns the red color component of this color.
Definition qcolor.cpp:1528
int blue() const noexcept
Returns the blue color component of this color.
Definition qcolor.cpp:1583
int green() const noexcept
Returns the green color component of this color.
Definition qcolor.cpp:1555
void setRed(int red)
Sets the red color component of this color to red.
Definition qcolor.cpp:1541
int descriptionHeight(int width) const
QColor mergedColors(const QColor &a, const QColor &b, int value) const
The QCommandLinkButton widget provides a Vista style command link button.
QString description
A descriptive label to complement the button text.
void initStyleOption(QStyleOptionButton *option) const override
Initialize option with the values from this QPushButton.
void setDescription(const QString &description)
int heightForWidth(int) const override
\reimp
QSize sizeHint() const override
\reimp
QSize minimumSizeHint() const override
\reimp
QCommandLinkButton(QWidget *parent=nullptr)
Constructs a command link with no text and a parent.
void paintEvent(QPaintEvent *) override
\reimp
bool event(QEvent *e) override
\reimp
\inmodule QtCore
Definition qcoreevent.h:45
\reentrant \inmodule QtGui
\reentrant
Definition qfont.h:22
QFont resolve(const QFont &) const
Returns a new QFont that has attributes copied from other that have not been previously set on this f...
Definition qfont.cpp:1893
void setBold(bool)
If enable is true sets the font's weight to \l{Weight}{QFont::Bold}; otherwise sets the weight to \l{...
Definition qfont.h:373
void setPointSizeF(qreal)
Sets the point size to pointSize.
Definition qfont.cpp:1010
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
@ Disabled
Definition qicon.h:22
@ Normal
Definition qicon.h:22
@ Off
Definition qicon.h:23
@ On
Definition qicon.h:23
QSize actualSize(const QSize &size, Mode mode=Normal, State state=Off) const
Returns the actual size of the icon for the requested size, mode, and state.
Definition qicon.cpp:926
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:486
@ ButtonText
Definition qpalette.h:52
const QBrush & buttonText() const
Returns the button text foreground brush of the current color group.
Definition qpalette.h:96
\inmodule QtCore\reentrant
Definition qpoint.h:217
The QPushButton widget provides a command button.
Definition qpushbutton.h:20
virtual void initStyleOption(QStyleOptionButton *option) const
Initialize option with the values from this QPushButton.
QSize sizeHint() const override
\reimp
bool event(QEvent *e) override
\reimp
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr QRect adjusted(int x1, int y1, int x2, int y2) const noexcept
Returns a new rectangle with dx1, dy1, dx2 and dy2 added respectively to the existing coordinates of ...
Definition qrect.h:370
The QSizePolicy class is a layout attribute describing horizontal and vertical resizing policy.
Definition qsizepolicy.h:18
constexpr void setHeightForWidth(bool b) noexcept
Sets the flag determining whether the widget's preferred height depends on its width,...
Definition qsizepolicy.h:80
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
\variable QStyleOptionHeaderV2::textElideMode
The QStylePainter class is a convenience class for drawing QStyle elements inside a widget.
@ SH_UnderlineShortcut
Definition qstyle.h:626
@ SP_CommandLink
Definition qstyle.h:774
@ CE_PushButton
Definition qstyle.h:171
@ PM_ButtonShiftHorizontal
Definition qstyle.h:417
@ PM_ButtonShiftVertical
Definition qstyle.h:418
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const =0
Returns the value of the given pixel metric.
\reentrant
Definition qtextlayout.h:70
\reentrant
QLayout * layout
Definition qwidget_p.h:651
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void updateGeometry()
Notifies the layout system that this widget has changed and may need to change geometry.
int minimumHeight
the widget's minimum height in pixels
Definition qwidget.h:125
QSize size
the size of the widget excluding any window frame
Definition qwidget.h:113
QPalette palette
the widget's palette
Definition qwidget.h:132
int height
the height of the widget excluding any window frame
Definition qwidget.h:115
bool isEnabled() const
Definition qwidget.h:814
void update()
Updates the widget unless updates are disabled or the widget is hidden.
QStyle * style() const
Definition qwidget.cpp:2600
bool underMouse() const
Returns true if the widget is under the mouse cursor; otherwise returns false.
Definition qwidget.h:859
QString text
QStyleOptionButton opt
Combined button and popup list for selecting options.
@ WA_Hover
Definition qnamespace.h:340
@ WA_MacShowFocusRect
Definition qnamespace.h:359
@ TextWordWrap
Definition qnamespace.h:174
@ TextHideMnemonic
Definition qnamespace.h:178
@ TextShowMnemonic
Definition qnamespace.h:173
@ ElideRight
Definition qnamespace.h:190
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
int qCeil(T v)
Definition qmath.h:36
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLint GLsizei width
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
GLuint GLenum option
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
double qreal
Definition qtypes.h:187
widget render & pixmap
QSizePolicy policy