qwt_arrow_button.cpp
Go to the documentation of this file.
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 
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 );
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 
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 
97 {
98  return m_data->num;
99 }
100 
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 
260 {
261  const QSize hint = minimumSizeHint();
262  return qwtExpandedToGlobalStrut( hint );
263 }
264 
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::drawButtonLabel
virtual void drawButtonLabel(QPainter *)
Draw the button label.
Definition: qwt_arrow_button.cpp:143
QwtArrowButton::minimumSizeHint
virtual QSize minimumSizeHint() const QWT_OVERRIDE
Return a minimum size hint.
Definition: qwt_arrow_button.cpp:268
Margin
static const int Margin
Definition: qwt_arrow_button.cpp:19
qwtExpandedToGlobalStrut
QSize qwtExpandedToGlobalStrut(const QSize &size)
Definition: qwt.cpp:21
QwtArrowButton::m_data
PrivateData * m_data
Definition: qwt_arrow_button.h:54
QwtArrowButton::PrivateData::num
int num
Definition: qwt_arrow_button.cpp:25
QwtArrowButton::arrowSize
virtual QSize arrowSize(Qt::ArrowType, const QSize &boundingSize) const
Definition: qwt_arrow_button.cpp:296
qwt_arrow_button.h
QwtArrowButton::drawArrow
virtual void drawArrow(QPainter *, const QRect &, Qt::ArrowType) const
Definition: qwt_arrow_button.cpp:215
QwtArrowButton::QwtArrowButton
QwtArrowButton(int num, Qt::ArrowType, QWidget *parent=NULL)
Definition: qwt_arrow_button.cpp:55
QwtArrowButton::~QwtArrowButton
virtual ~QwtArrowButton()
Destructor.
Definition: qwt_arrow_button.cpp:79
QwtArrowButton::labelRect
virtual QRect labelRect() const
Definition: qwt_arrow_button.cpp:104
QwtArrowButton::paintEvent
virtual void paintEvent(QPaintEvent *) QWT_OVERRIDE
Definition: qwt_arrow_button.cpp:130
qwt.h
Spacing
static const int Spacing
Definition: qwt_arrow_button.cpp:20
QwtArrowButton::sizeHint
virtual QSize sizeHint() const QWT_OVERRIDE
Definition: qwt_arrow_button.cpp:259
QwtArrowButton::PrivateData::arrowType
Qt::ArrowType arrowType
Definition: qwt_arrow_button.cpp:26
QwtArrowButton::arrowType
Qt::ArrowType arrowType() const
The direction of the arrows.
Definition: qwt_arrow_button.cpp:88
QwtArrowButton::keyPressEvent
virtual void keyPressEvent(QKeyEvent *) QWT_OVERRIDE
autoRepeat for the space keys
Definition: qwt_arrow_button.cpp:326
QwtArrowButton::num
int num() const
The number of arrows.
Definition: qwt_arrow_button.cpp:96
QwtArrowButton
Arrow Button.
Definition: qwt_arrow_button.h:23
styleOpt
static QStyleOptionButton styleOpt(const QwtArrowButton *btn)
Definition: qwt_arrow_button.cpp:29
MaxNum
static const int MaxNum
Definition: qwt_arrow_button.cpp:18
QwtArrowButton::PrivateData
Definition: qwt_arrow_button.cpp:22


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Aug 11 2024 02:24:24