Qwt User's Guide 6.2.0

qwt_arrow_button.cpp
1 /******************************************************************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10 #include "qwt_arrow_button.h"
11 #include "qwt.h"
12
13 #include <qpainter.h>
14 #include <qstyle.h>
15 #include <qstyleoption.h>
16 #include <qevent.h>
17
18 static const int MaxNum = 3;
19 static const int Margin = 2;
20 static const int Spacing = 1;
21
22 class QwtArrowButton::PrivateData
23 {
24 public:
25 int num;
26 Qt::ArrowType arrowType;
27 };
28
29 static QStyleOptionButton styleOpt( const QwtArrowButton* btn )
30 {
31 QStyleOptionButton option;
32 option.initFrom( btn );
33 option.features = QStyleOptionButton::None;
34 if ( btn->isFlat() )
35 option.features |= QStyleOptionButton::Flat;
36 if ( btn->menu() )
37 option.features |= QStyleOptionButton::HasMenu;
38 if ( btn->autoDefault() || btn->isDefault() )
39 option.features |= QStyleOptionButton::AutoDefaultButton;
40 if ( btn->isDefault() )
41 option.features |= QStyleOptionButton::DefaultButton;
42 if ( btn->isDown() )
43 option.state |= QStyle::State_Sunken;
44 if ( !btn->isFlat() && !btn->isDown() )
45 option.state |= QStyle::State_Raised;
46
47 return option;
48 }
49
55 QwtArrowButton::QwtArrowButton( int num, Qt::ArrowType arrowType, QWidget* parent )
56 : QPushButton( parent )
57 {
58 m_data = new PrivateData;
59 m_data->num = qBound( 1, num, MaxNum );
60 m_data->arrowType = arrowType;
61
62 setAutoRepeat( true );
63 setAutoDefault( false );
64
65 switch ( m_data->arrowType )
66 {
67 case Qt::LeftArrow:
68 case Qt::RightArrow:
69 setSizePolicy( QSizePolicy::Expanding,
70 QSizePolicy::Fixed );
71 break;
72 default:
73 setSizePolicy( QSizePolicy::Fixed,
74 QSizePolicy::Expanding );
75 }
76 }
77
79 QwtArrowButton::~QwtArrowButton()
80 {
81 delete m_data;
82 m_data = NULL;
83 }
84
88 Qt::ArrowType QwtArrowButton::arrowType() const
89 {
90 return m_data->arrowType;
91 }
92
96 int QwtArrowButton::num() const
97 {
98 return m_data->num;
99 }
100
104 QRect QwtArrowButton::labelRect() const
105 {
106 const int m = Margin;
107
108 QRect r = rect();
109 r.setRect( r.x() + m, r.y() + m,
110 r.width() - 2 * m, r.height() - 2 * m );
111
112 if ( isDown() )
113 {
114 QStyleOptionButton option = styleOpt( this );
115 const int ph = style()->pixelMetric(
116 QStyle::PM_ButtonShiftHorizontal, &option, this );
117 const int pv = style()->pixelMetric(
118 QStyle::PM_ButtonShiftVertical, &option, this );
119
120 r.translate( ph, pv );
121 }
122
123 return r;
124 }
125
130 void QwtArrowButton::paintEvent( QPaintEvent* event )
131 {
132 QPushButton::paintEvent( event );
133 QPainter painter( this );
134 drawButtonLabel( &painter );
135 }
136
143 void QwtArrowButton::drawButtonLabel( QPainter* painter )
144 {
145 const bool isVertical = m_data->arrowType == Qt::UpArrow ||
146 m_data->arrowType == Qt::DownArrow;
147
148 const QRect r = labelRect();
149 QSize boundingSize = labelRect().size();
150 if ( isVertical )
151 boundingSize.transpose();
152
153 const int w =
154 ( boundingSize.width() - ( MaxNum - 1 ) * Spacing ) / MaxNum;
155
156 QSize arrow = arrowSize( Qt::RightArrow,
157 QSize( w, boundingSize.height() ) );
158
159 if ( isVertical )
160 arrow.transpose();
161
162 QRect contentsSize; // aligned rect where to paint all arrows
163 if ( m_data->arrowType == Qt::LeftArrow || m_data->arrowType == Qt::RightArrow )
164 {
165 contentsSize.setWidth( m_data->num * arrow.width()
166 + ( m_data->num - 1 ) * Spacing );
167 contentsSize.setHeight( arrow.height() );
168 }
169 else
170 {
171 contentsSize.setWidth( arrow.width() );
172 contentsSize.setHeight( m_data->num * arrow.height()
173 + ( m_data->num - 1 ) * Spacing );
174 }
175
176 QRect arrowRect( contentsSize );
177 arrowRect.moveCenter( r.center() );
178 arrowRect.setSize( arrow );
179
180 painter->save();
181 for ( int i = 0; i < m_data->num; i++ )
182 {
183 drawArrow( painter, arrowRect, m_data->arrowType );
184
185 int dx = 0;
186 int dy = 0;
187
188 if ( isVertical )
189 dy = arrow.height() + Spacing;
190 else
191 dx = arrow.width() + Spacing;
192
193 arrowRect.translate( dx, dy );
194 }
195 painter->restore();
196
197 if ( hasFocus() )
198 {
199 QStyleOptionFocusRect option;
200 option.initFrom( this );
201 option.backgroundColor = palette().color( QPalette::Window );
202
203 style()->drawPrimitive( QStyle::PE_FrameFocusRect,
204 &option, painter, this );
205 }
206 }
207
215 void QwtArrowButton::drawArrow( QPainter* painter,
216 const QRect& r, Qt::ArrowType arrowType ) const
217 {
218 QPolygon pa( 3 );
219
220 switch ( arrowType )
221 {
222 case Qt::UpArrow:
223 pa.setPoint( 0, r.bottomLeft() );
224 pa.setPoint( 1, r.bottomRight() );
225 pa.setPoint( 2, r.center().x(), r.top() );
226 break;
227 case Qt::DownArrow:
228 pa.setPoint( 0, r.topLeft() );
229 pa.setPoint( 1, r.topRight() );
230 pa.setPoint( 2, r.center().x(), r.bottom() );
231 break;
232 case Qt::RightArrow:
233 pa.setPoint( 0, r.topLeft() );
234 pa.setPoint( 1, r.bottomLeft() );
235 pa.setPoint( 2, r.right(), r.center().y() );
236 break;
237 case Qt::LeftArrow:
238 pa.setPoint( 0, r.topRight() );
239 pa.setPoint( 1, r.bottomRight() );
240 pa.setPoint( 2, r.left(), r.center().y() );
241 break;
242 default:
243 break;
244 }
245
246 painter->save();
247
248 painter->setRenderHint( QPainter::Antialiasing, true );
249 painter->setPen( Qt::NoPen );
250 painter->setBrush( palette().brush( QPalette::ButtonText ) );
251 painter->drawPolygon( pa );
252
253 painter->restore();
254 }
255
259 QSize QwtArrowButton::sizeHint() const
260 {
261 const QSize hint = minimumSizeHint();
262 return qwtExpandedToGlobalStrut( hint );
263 }
264
268 QSize QwtArrowButton::minimumSizeHint() const
269 {
270 const QSize asz = arrowSize( Qt::RightArrow, QSize() );
271
272 QSize sz(
273 2 * Margin + ( MaxNum - 1 ) * Spacing + MaxNum * asz.width(),
274 2 * Margin + asz.height()
275 );
276
277 if ( m_data->arrowType == Qt::UpArrow || m_data->arrowType == Qt::DownArrow )
278 sz.transpose();
279
280 QStyleOption styleOption;
281 styleOption.initFrom( this );
282
283 sz = style()->sizeFromContents( QStyle::CT_PushButton,
284 &styleOption, sz, this );
285
286 return sz;
287 }
288
296 QSize QwtArrowButton::arrowSize( Qt::ArrowType arrowType,
297 const QSize& boundingSize ) const
298 {
299 QSize bs = boundingSize;
300 if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
301 bs.transpose();
302
303 const int MinLen = 2;
304 const QSize sz = bs.expandedTo(
305 QSize( MinLen, 2 * MinLen - 1 ) ); // minimum
306
307 int w = sz.width();
308 int h = 2 * w - 1;
309
310 if ( h > sz.height() )
311 {
312 h = sz.height();
313 w = ( h + 1 ) / 2;
314 }
315
316 QSize arrSize( w, h );
317 if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
318 arrSize.transpose();
319
320 return arrSize;
321 }
322
326 void QwtArrowButton::keyPressEvent( QKeyEvent* event )
327 {
328 if ( event->isAutoRepeat() && event->key() == Qt::Key_Space )
329 Q_EMIT clicked();
330
331 QPushButton::keyPressEvent( event );
332 }
QwtArrowButton
Arrow Button.
Definition: qwt_arrow_button.h:24
QwtArrowButton::arrowSize
virtual QSize arrowSize(Qt::ArrowType, const QSize &boundingSize) const
Definition: qwt_arrow_button.cpp:296
QwtArrowButton::keyPressEvent
virtual void keyPressEvent(QKeyEvent *) override
autoRepeat for the space keys
Definition: qwt_arrow_button.cpp:326
QwtArrowButton::~QwtArrowButton
virtual ~QwtArrowButton()
Destructor.
Definition: qwt_arrow_button.cpp:79
QwtArrowButton::drawArrow
virtual void drawArrow(QPainter *, const QRect &, Qt::ArrowType) const
Definition: qwt_arrow_button.cpp:215
QwtArrowButton::labelRect
virtual QRect labelRect() const
Definition: qwt_arrow_button.cpp:104
QwtArrowButton::paintEvent
virtual void paintEvent(QPaintEvent *) override
Definition: qwt_arrow_button.cpp:130
QwtArrowButton::num
int num() const
The number of arrows.
Definition: qwt_arrow_button.cpp:96
QwtArrowButton::arrowType
Qt::ArrowType arrowType() const
The direction of the arrows.
Definition: qwt_arrow_button.cpp:88
QwtArrowButton::QwtArrowButton
QwtArrowButton(int num, Qt::ArrowType, QWidget *parent=NULL)
Definition: qwt_arrow_button.cpp:55
QwtArrowButton::minimumSizeHint
virtual QSize minimumSizeHint() const override
Return a minimum size hint.
Definition: qwt_arrow_button.cpp:268
QwtArrowButton::sizeHint
virtual QSize sizeHint() const override
Definition: qwt_arrow_button.cpp:259
QwtArrowButton::drawButtonLabel
virtual void drawButtonLabel(QPainter *)
Draw the button label.
Definition: qwt_arrow_button.cpp:143