1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtWidgets module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qradiobutton.h"
41#include "qapplication.h"
42#include "qbitmap.h"
43#if QT_CONFIG(buttongroup)
44#include "qbuttongroup.h"
45#endif
46#include "qstylepainter.h"
47#include "qstyle.h"
48#include "qstyleoption.h"
49#include "qevent.h"
50
51#include "private/qabstractbutton_p.h"
52
53QT_BEGIN_NAMESPACE
54
55class QRadioButtonPrivate : public QAbstractButtonPrivate
56{
57 Q_DECLARE_PUBLIC(QRadioButton)
58
59public:
60 QRadioButtonPrivate() : QAbstractButtonPrivate(QSizePolicy::RadioButton), hovering(true) {}
61 void init();
62 uint hovering : 1;
63};
64
65/*
66 Initializes the radio button.
67*/
68void QRadioButtonPrivate::init()
69{
70 Q_Q(QRadioButton);
71 q->setCheckable(true);
72 q->setAutoExclusive(true);
73 q->setMouseTracking(true);
74 q->setForegroundRole(QPalette::WindowText);
75 q->setAttribute(Qt::WA_MacShowFocusRect);
76 setLayoutItemMargins(element: QStyle::SE_RadioButtonLayoutItem);
77}
78
79/*!
80 \class QRadioButton
81 \brief The QRadioButton widget provides a radio button with a text label.
82
83 \ingroup basicwidgets
84 \inmodule QtWidgets
85
86 \image windows-radiobutton.png
87
88 A QRadioButton is an option button that can be switched on (checked) or
89 off (unchecked). Radio buttons typically present the user with a "one
90 of many" choice. In a group of radio buttons, only one radio button at
91 a time can be checked; if the user selects another button, the
92 previously selected button is switched off.
93
94 Radio buttons are autoExclusive by default. If auto-exclusive is
95 enabled, radio buttons that belong to the same parent widget
96 behave as if they were part of the same exclusive button group. If
97 you need multiple exclusive button groups for radio buttons that
98 belong to the same parent widget, put them into a QButtonGroup.
99
100 Whenever a button is switched on or off, it emits the toggled() signal.
101 Connect to this signal if you want to trigger an action each time the
102 button changes state. Use isChecked() to see if a particular button is
103 selected.
104
105 Just like QPushButton, a radio button displays text, and
106 optionally a small icon. The icon is set with setIcon(). The text
107 can be set in the constructor or with setText(). A shortcut key
108 can be specified by preceding the preferred character with an
109 ampersand in the text. For example:
110
111 \snippet code/src_gui_widgets_qradiobutton.cpp 0
112
113 In this example the shortcut is \e{Alt+c}. See the \l
114 {QShortcut#mnemonic}{QShortcut} documentation for details. To
115 display an actual ampersand, use '&&'.
116
117 Important inherited members: text(), setText(), text(),
118 setDown(), isDown(), autoRepeat(), group(), setAutoRepeat(),
119 toggle(), pressed(), released(), clicked(), and toggled().
120
121 \sa QPushButton, QToolButton, QCheckBox, {fowler}{GUI Design Handbook: Radio Button},
122 {Group Box Example}
123*/
124
125
126/*!
127 Constructs a radio button with the given \a parent, but with no text or
128 pixmap.
129
130 The \a parent argument is passed on to the QAbstractButton constructor.
131*/
132
133QRadioButton::QRadioButton(QWidget *parent)
134 : QAbstractButton(*new QRadioButtonPrivate, parent)
135{
136 Q_D(QRadioButton);
137 d->init();
138}
139
140/*!
141 Destructor.
142*/
143QRadioButton::~QRadioButton()
144{
145}
146
147/*!
148 Constructs a radio button with the given \a parent and \a text string.
149
150 The \a parent argument is passed on to the QAbstractButton constructor.
151*/
152
153QRadioButton::QRadioButton(const QString &text, QWidget *parent)
154 : QRadioButton(parent)
155{
156 setText(text);
157}
158
159/*!
160 Initialize \a option with the values from this QRadioButton. This method is useful
161 for subclasses when they need a QStyleOptionButton, but don't want to fill
162 in all the information themselves.
163
164 \sa QStyleOption::initFrom()
165*/
166void QRadioButton::initStyleOption(QStyleOptionButton *option) const
167{
168 if (!option)
169 return;
170 Q_D(const QRadioButton);
171 option->initFrom(w: this);
172 option->text = d->text;
173 option->icon = d->icon;
174 option->iconSize = iconSize();
175 if (d->down)
176 option->state |= QStyle::State_Sunken;
177 option->state |= (d->checked) ? QStyle::State_On : QStyle::State_Off;
178 if (testAttribute(attribute: Qt::WA_Hover) && underMouse()) {
179 option->state.setFlag(flag: QStyle::State_MouseOver, on: d->hovering);
180 }
181}
182
183/*!
184 \reimp
185*/
186QSize QRadioButton::sizeHint() const
187{
188 Q_D(const QRadioButton);
189 if (d->sizeHint.isValid())
190 return d->sizeHint;
191 ensurePolished();
192 QStyleOptionButton opt;
193 initStyleOption(option: &opt);
194 QSize sz = style()->itemTextRect(fm: fontMetrics(), r: QRect(), flags: Qt::TextShowMnemonic,
195 enabled: false, text: text()).size();
196 if (!opt.icon.isNull())
197 sz = QSize(sz.width() + opt.iconSize.width() + 4, qMax(a: sz.height(), b: opt.iconSize.height()));
198 d->sizeHint = (style()->sizeFromContents(ct: QStyle::CT_RadioButton, opt: &opt, contentsSize: sz, w: this).
199 expandedTo(otherSize: QApplication::globalStrut()));
200 return d->sizeHint;
201}
202
203/*!
204 \reimp
205*/
206QSize QRadioButton::minimumSizeHint() const
207{
208 return sizeHint();
209}
210
211/*!
212 \reimp
213*/
214bool QRadioButton::hitButton(const QPoint &pos) const
215{
216 QStyleOptionButton opt;
217 initStyleOption(option: &opt);
218 return style()->subElementRect(subElement: QStyle::SE_RadioButtonClickRect, option: &opt, widget: this).contains(p: pos);
219}
220
221/*!
222 \reimp
223*/
224void QRadioButton::mouseMoveEvent(QMouseEvent *e)
225{
226 Q_D(QRadioButton);
227 if (testAttribute(attribute: Qt::WA_Hover)) {
228 bool hit = false;
229 if (underMouse())
230 hit = hitButton(pos: e->pos());
231
232 if (hit != d->hovering) {
233 update();
234 d->hovering = hit;
235 }
236 }
237
238 QAbstractButton::mouseMoveEvent(e);
239}
240
241/*!\reimp
242 */
243void QRadioButton::paintEvent(QPaintEvent *)
244{
245 QStylePainter p(this);
246 QStyleOptionButton opt;
247 initStyleOption(option: &opt);
248 p.drawControl(ce: QStyle::CE_RadioButton, opt);
249}
250
251/*! \reimp */
252bool QRadioButton::event(QEvent *e)
253{
254 Q_D(QRadioButton);
255 if (e->type() == QEvent::StyleChange
256#ifdef Q_OS_MAC
257 || e->type() == QEvent::MacSizeChange
258#endif
259 )
260 d->setLayoutItemMargins(element: QStyle::SE_RadioButtonLayoutItem);
261 return QAbstractButton::event(e);
262}
263
264
265QT_END_NAMESPACE
266
267#include "moc_qradiobutton.cpp"
268

source code of qtbase/src/widgets/widgets/qradiobutton.cpp