1
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
3
* Copyright (C) 1997 Josef Wilgen
4
* Copyright (C) 2002 Uwe Rathmann
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
*****************************************************************************/
14
#include "qwt_polygon.h"
15
#include "qwt_arrow_button.h"
17
static const int MaxNum = 3;
18
static const int Margin = 2;
19
static const int Spacing = 1;
21
class QwtArrowButton::PrivateData
25
Qt::ArrowType arrowType;
29
#if QT_VERSION >= 0x040000
30
#include <qstyleoption.h>
31
static QStyleOptionButton styleOpt(const QwtArrowButton* btn)
33
QStyleOptionButton option;
35
option.features = QStyleOptionButton::None;
37
option.features |= QStyleOptionButton::Flat;
39
option.features |= QStyleOptionButton::HasMenu;
40
if (btn->autoDefault() || btn->isDefault())
41
option.features |= QStyleOptionButton::AutoDefaultButton;
43
option.features |= QStyleOptionButton::DefaultButton;
45
option.state |= QStyle::State_Sunken;
46
if (!btn->isFlat() && !btn->isDown())
47
option.state |= QStyle::State_Raised;
54
\param num Number of arrows
55
\param arrowType see Qt::ArowType in the Qt docs.
56
\param parent Parent widget
58
QwtArrowButton::QwtArrowButton(int num,
59
Qt::ArrowType arrowType, QWidget *parent):
62
d_data = new PrivateData;
63
d_data->num = qwtLim(num, 1, MaxNum);
64
d_data->arrowType = arrowType;
67
setAutoDefault(false);
69
switch(d_data->arrowType)
73
setSizePolicy(QSizePolicy::Expanding,
77
setSizePolicy(QSizePolicy::Fixed,
78
QSizePolicy::Expanding);
83
QwtArrowButton::~QwtArrowButton()
90
\brief The direction of the arrows
92
Qt::ArrowType QwtArrowButton::arrowType() const
94
return d_data->arrowType;
98
\brief The number of arrows
100
int QwtArrowButton::num() const
106
\return the bounding rect for the label
108
QRect QwtArrowButton::labelRect() const
110
const int m = Margin;
113
r.setRect(r.x() + m, r.y() + m,
114
r.width() - 2 * m, r.height() - 2 * m);
119
#if QT_VERSION < 0x040000
120
ph = style().pixelMetric(
121
QStyle::PM_ButtonShiftHorizontal, this);
122
pv = style().pixelMetric(
123
QStyle::PM_ButtonShiftVertical, this);
126
QStyleOptionButton option = styleOpt(this);
127
ph = style()->pixelMetric(
128
QStyle::PM_ButtonShiftHorizontal, &option, this);
129
pv = style()->pixelMetric(
130
QStyle::PM_ButtonShiftVertical, &option, this);
138
#if QT_VERSION >= 0x040000
141
\param event Paint event
143
void QwtArrowButton::paintEvent(QPaintEvent *event)
145
QPushButton::paintEvent(event);
146
QPainter painter(this);
147
drawButtonLabel(&painter);
152
\brief Draw the button label
154
\param painter Painter
155
\sa The Qt Manual on QPushButton
157
void QwtArrowButton::drawButtonLabel(QPainter *painter)
159
const bool isVertical = d_data->arrowType == Qt::UpArrow ||
160
d_data->arrowType == Qt::DownArrow;
162
const QRect r = labelRect();
163
QSize boundingSize = labelRect().size();
165
boundingSize.transpose();
168
(boundingSize.width() - (MaxNum - 1) * Spacing) / MaxNum;
170
QSize arrow = arrowSize(Qt::RightArrow,
171
QSize(w, boundingSize.height()));
176
QRect contentsSize; // aligned rect where to paint all arrows
177
if ( d_data->arrowType == Qt::LeftArrow || d_data->arrowType == Qt::RightArrow )
179
contentsSize.setWidth(d_data->num * arrow.width()
180
+ (d_data->num - 1) * Spacing);
181
contentsSize.setHeight(arrow.height());
185
contentsSize.setWidth(arrow.width());
186
contentsSize.setHeight(d_data->num * arrow.height()
187
+ (d_data->num - 1) * Spacing);
190
QRect arrowRect(contentsSize);
191
arrowRect.moveCenter(r.center());
192
arrowRect.setSize(arrow);
195
for (int i = 0; i < d_data->num; i++)
197
drawArrow(painter, arrowRect, d_data->arrowType);
203
dy = arrow.height() + Spacing;
205
dx = arrow.width() + Spacing;
207
#if QT_VERSION >= 0x040000
208
arrowRect.translate(dx, dy);
210
arrowRect.moveBy(dx, dy);
217
#if QT_VERSION >= 0x040000
218
QStyleOptionFocusRect option;
220
option.backgroundColor = palette().color(QPalette::Background);
222
style()->drawPrimitive(QStyle::PE_FrameFocusRect,
223
&option, painter, this);
225
const QRect focusRect =
226
style().subRect(QStyle::SR_PushButtonFocusRect, this);
227
style().drawPrimitive(QStyle::PE_FocusRect, painter,
228
focusRect, colorGroup());
234
Draw an arrow int a bounding rect
236
\param painter Painter
237
\param r Rectangle where to paint the arrow
238
\param arrowType Arrow type
240
void QwtArrowButton::drawArrow(QPainter *painter,
241
const QRect &r, Qt::ArrowType arrowType) const
248
pa.setPoint(0, r.bottomLeft());
249
pa.setPoint(1, r.bottomRight());
250
pa.setPoint(2, r.center().x(), r.top());
253
pa.setPoint(0, r.topLeft());
254
pa.setPoint(1, r.topRight());
255
pa.setPoint(2, r.center().x(), r.bottom());
258
pa.setPoint(0, r.topLeft());
259
pa.setPoint(1, r.bottomLeft());
260
pa.setPoint(2, r.right(), r.center().y());
263
pa.setPoint(0, r.topRight());
264
pa.setPoint(1, r.bottomRight());
265
pa.setPoint(2, r.left(), r.center().y());
272
#if QT_VERSION < 0x040000
273
painter->setPen(colorGroup().buttonText());
274
painter->setBrush(colorGroup().brush(QColorGroup::ButtonText));
276
painter->setPen(palette().color(QPalette::ButtonText));
277
painter->setBrush(palette().brush(QPalette::ButtonText));
279
painter->drawPolygon(pa);
286
QSize QwtArrowButton::sizeHint() const
288
return minimumSizeHint();
292
\brief Return a minimum size hint
294
QSize QwtArrowButton::minimumSizeHint() const
296
const QSize asz = arrowSize(Qt::RightArrow, QSize());
299
2 * Margin + (MaxNum - 1) * Spacing + MaxNum * asz.width(),
300
2 * Margin + asz.height()
303
if ( d_data->arrowType == Qt::UpArrow || d_data->arrowType == Qt::DownArrow )
306
#if QT_VERSION >= 0x040000
307
QStyleOption styleOption;
308
styleOption.init(this);
310
const QSize hsz = style()->sizeFromContents(QStyle::CT_PushButton,
311
&styleOption, sz, this);
312
#if QT_VERSION < 0x040300
313
if ( hsz.width() != 80 ) // avoid a bug in the Cleanlooks style
318
sz = style().sizeFromContents(QStyle::CT_PushButton, this, sz);
325
Calculate the size for a arrow that fits into a rect of a given size
327
\param arrowType Arrow type
328
\param boundingSize Bounding size
329
\return Size of the arrow
331
QSize QwtArrowButton::arrowSize(Qt::ArrowType arrowType,
332
const QSize &boundingSize) const
334
QSize bs = boundingSize;
335
if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
338
const int MinLen = 2;
339
const QSize sz = bs.expandedTo(
340
QSize(MinLen, 2 * MinLen - 1)); // minimum
345
if ( h > sz.height() )
352
if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
359
\brief autoRepeat for the space keys
361
void QwtArrowButton::keyPressEvent(QKeyEvent *e)
363
if ( e->isAutoRepeat() && e->key() == Qt::Key_Space )
366
QPushButton::keyPressEvent(e);