QSkinny 0.8.0
C++/Qt UI toolkit
Loading...
Searching...
No Matches
QskPushButton.cpp
1/******************************************************************************
2 * QSkinny - Copyright (C) The authors
3 * SPDX-License-Identifier: BSD-3-Clause
4 *****************************************************************************/
5
6#include "QskPushButton.h"
7#include "QskAnimationHint.h"
8#include "QskAspect.h"
9#include "QskBoxShapeMetrics.h"
10#include "QskGraphic.h"
11#include "QskGraphicProvider.h"
12#include "QskSkinManager.h"
13#include "QskSkin.h"
14#include "QskSkinlet.h"
15#include "QskTextOptions.h"
16#include "QskEvent.h"
17
18QSK_SUBCONTROL( QskPushButton, Panel )
19QSK_SUBCONTROL( QskPushButton, Splash )
20QSK_SUBCONTROL( QskPushButton, Text )
21QSK_SUBCONTROL( QskPushButton, Icon )
22
23class QskPushButton::PrivateData
24{
25 public:
26 PrivateData( const QString& txt )
27 : text( txt )
28 , isCheckable( false )
29 , isIconSourceDirty( false )
30 , emphasis( NoEmphasis )
31 {
32 }
33
34 void ensureIcon( const QskPushButton* button )
35 {
36 if ( isIconSourceDirty )
37 {
38 if ( !iconSource.isEmpty() )
39 icon = button->loadIcon( iconSource );
40
41 isIconSourceDirty = false;
42 }
43 }
44
45 QString text;
46
47 QUrl iconSource;
48 QskGraphic icon;
49
50 bool isCheckable : 1;
51 bool isIconSourceDirty : 1;
52 int emphasis : 4;
53};
54
55QskPushButton::QskPushButton( QQuickItem* parent )
56 : QskPushButton( QString(), parent )
57{
58}
59
60QskPushButton::QskPushButton( const QString& text, QQuickItem* parent )
61 : Inherited( parent )
62 , m_data( new PrivateData( text ) )
63{
64 initSizePolicy( QskSizePolicy::Minimum, QskSizePolicy::Fixed );
65}
66
67QskPushButton::~QskPushButton()
68{
69}
70
71void QskPushButton::setCheckable( bool on )
72{
73 if ( on != m_data->isCheckable )
74 {
75 m_data->isCheckable = on;
76 Q_EMIT checkableChanged( on );
77 }
78}
79
80bool QskPushButton::isCheckable() const
81{
82 return m_data->isCheckable;
83}
84
85void QskPushButton::setEmphasis( Emphasis emphasis )
86{
87 if ( emphasis != m_data->emphasis )
88 {
89 m_data->emphasis = emphasis;
90
92 update();
93
94 Q_EMIT emphasisChanged( emphasis );
95 }
96}
97
98QskPushButton::Emphasis QskPushButton::emphasis() const
99{
100 return static_cast< Emphasis >( m_data->emphasis );
101}
102
103void QskPushButton::setShape( const QskBoxShapeMetrics& shape )
104{
105 if ( setBoxShapeHint( Panel, shape ) )
106 Q_EMIT shapeChanged();
107}
108
109void QskPushButton::resetShape()
110{
111 if ( resetBoxShapeHint( Panel ) )
112 Q_EMIT shapeChanged();
113}
114
115QskBoxShapeMetrics QskPushButton::shape() const
116{
117 return boxShapeHint( Panel );
118}
119
120void QskPushButton::setText( const QString& text )
121{
122 if ( text != m_data->text )
123 {
124 m_data->text = text;
125
127 update();
128
129 Q_EMIT textChanged();
130 }
131}
132
133QString QskPushButton::text() const
134{
135 return m_data->text;
136}
137
138void QskPushButton::setTextOptions( const QskTextOptions& textOptions )
139{
140 if ( setTextOptionsHint( Text, textOptions ) )
141 Q_EMIT textOptionsChanged();
142}
143
144QskTextOptions QskPushButton::textOptions() const
145{
146 return textOptionsHint( Text );
147}
148
149void QskPushButton::resetTextOptions()
150{
151 if ( resetTextOptionsHint( Text ) )
152 Q_EMIT textOptionsChanged();
153}
154
155QFont QskPushButton::font() const
156{
157 return effectiveFont( Text );
158}
159
160void QskPushButton::resetIconStrutSize()
161{
162 if ( resetStrutSizeHint( Icon ) )
163 Q_EMIT iconStrutSizeChanged();
164}
165
166void QskPushButton::setIconStrutSize( const QSizeF& size )
167{
168 auto newSize = size;
169 if ( newSize.width() < 0.0 )
170 newSize.setWidth( -1.0 );
171
172 if ( newSize.height() < 0.0 )
173 newSize.setHeight( -1.0 );
174
175 if ( setStrutSizeHint( Icon, newSize ) )
176 Q_EMIT iconStrutSizeChanged();
177}
178
179QSizeF QskPushButton::iconStrutSize() const
180{
181 return strutSizeHint( Icon );
182}
183
184void QskPushButton::setIconSource( const QUrl& url )
185{
186 if ( m_data->iconSource == url )
187 return;
188
189 m_data->iconSource = url;
190 m_data->icon.reset();
191
192 m_data->isIconSourceDirty = true;
193
195 polish();
196 update();
197
198 Q_EMIT iconSourceChanged();
199}
200
201void QskPushButton::setIconSource( const QString& source )
202{
203 setIconSource( QUrl( source ) );
204}
205
206QUrl QskPushButton::iconSource() const
207{
208 return m_data->iconSource;
209}
210
211void QskPushButton::setIcon( const QskGraphic& icon )
212{
213 if ( icon != m_data->icon )
214 {
215 m_data->icon = icon;
216
217 if ( !m_data->iconSource.isEmpty() )
218 {
219 m_data->iconSource = QString();
220 m_data->isIconSourceDirty = false;
221
222 Q_EMIT iconSourceChanged();
223 }
224
225 Q_EMIT iconChanged();
226
228 polish();
229 update();
230 }
231}
232
233QskGraphic QskPushButton::icon() const
234{
235 m_data->ensureIcon( this );
236 return m_data->icon;
237}
238
239bool QskPushButton::hasIcon() const
240{
241 return !( icon().isEmpty() && iconSource().isEmpty() );
242}
243
244void QskPushButton::updateResources()
245{
246 m_data->ensureIcon( this );
247}
248
250{
251 switch( m_data->emphasis )
252 {
253 case VeryLowEmphasis:
254 return QskAspect::Tiny;
255
256 case LowEmphasis:
257 return QskAspect::Small;
258
259 case HighEmphasis:
260 return QskAspect::Large;
261
262 case VeryHighEmphasis:
263 return QskAspect::Huge;
264
265 default:
267 }
268}
269
270QRectF QskPushButton::layoutRectForSize( const QSizeF& size ) const
271{
272 return subControlContentsRect( size, Panel );
273}
274
275void QskPushButton::changeEvent( QEvent* event )
276{
277 switch ( event->type() )
278 {
279 case QEvent::StyleChange:
280 {
281 if ( !m_data->iconSource.isEmpty() &&
282 qskSkinManager->skin()->hasGraphicProvider() )
283 {
284 // we might need to reload from a different skin
285 m_data->isIconSourceDirty = true;
286 }
287 break;
288 }
289 case QEvent::LocaleChange:
290 {
291 if ( !m_data->text.isEmpty() )
292 {
293 // maybe QLocale::textDirection() has changed
294 update();
295 }
296
297 break;
298 }
299 default:
300 break;
301 }
302
303 Inherited::changeEvent( event );
304}
305
306void QskPushButton::mousePressEvent( QMouseEvent* event )
307{
308 Inherited::mousePressEvent( event );
309
310 using A = QskAspect;
311
312 const auto hint = animationHint( Splash | A::Color );
313
314 if( hint.isValid() )
315 {
316 setPositionHint( Splash, qskMousePosition( event ).x() );
317 startTransition( Splash | A::Metric | A::Size, hint, 0.0, 1.0 );
318 }
319}
320
321QskGraphic QskPushButton::loadIcon( const QUrl& url ) const
322{
323 return Qsk::loadGraphic( url );
324}
325
326#include "moc_QskPushButton.cpp"
Lookup key for a QskSkinHintTable.
Definition QskAspect.h:15
Variation
Some sort of variation.
Definition QskAspect.h:82
@ NoVariation
Definition QskAspect.h:83
QRectF subControlContentsRect(QskAspect::Subcontrol) const
A paint device for scalable graphics.
Definition QskGraphic.h:28
void resetImplicitSize()
Definition QskItem.cpp:721
virtual void changeEvent(QEvent *)
Definition QskItem.cpp:859
QskAspect::Variation effectiveVariation() const override
QRectF layoutRectForSize(const QSizeF &) const override
void changeEvent(QEvent *) override
bool setStrutSizeHint(QskAspect, const QSizeF &)
Sets a metric hint.
QFont effectiveFont(QskAspect) const
QSizeF strutSizeHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a strut size hint.
QskBoxShapeMetrics boxShapeHint(QskAspect, QskSkinHintStatus *=nullptr) const
Retrieves a shape hint.
QskAnimationHint animationHint(QskAspect, QskSkinHintStatus *=nullptr) const
bool setBoxShapeHint(QskAspect, const QskBoxShapeMetrics &)
Sets a shape hint.
bool resetStrutSizeHint(QskAspect)
Removes a strut size hint from the local table.
bool resetBoxShapeHint(QskAspect)
Removes a shape hint from the local table.