~l3on/ubuntu/oneiric/qwt/fix-921430

« back to all changes in this revision

Viewing changes to qwt-5.0.1/src/qwt_arrow_button.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2007-10-05 15:20:41 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20071005152041-qmybqh4fj9jejyo2
Tags: 5.0.2-2
* Handle nostrip build option. (Closes: #437877)
* Build libqwt5-doc package in binary-indep target. (Closes: #443110)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
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 <qpainter.h>
11
 
#include <qstyle.h>
12
 
#include <qevent.h>
13
 
#include "qwt_math.h"
14
 
#include "qwt_polygon.h"
15
 
#include "qwt_arrow_button.h"
16
 
 
17
 
static const int MaxNum = 3;
18
 
static const int Margin = 2;
19
 
static const int Spacing = 1;
20
 
 
21
 
class QwtArrowButton::PrivateData
22
 
{
23
 
public:
24
 
    int num;
25
 
    Qt::ArrowType arrowType;
26
 
};
27
 
 
28
 
 
29
 
#if QT_VERSION >= 0x040000
30
 
#include <qstyleoption.h>
31
 
static QStyleOptionButton styleOpt(const QwtArrowButton* btn)
32
 
{
33
 
    QStyleOptionButton option;
34
 
    option.init(btn);
35
 
    option.features = QStyleOptionButton::None;
36
 
    if (btn->isFlat())
37
 
        option.features |= QStyleOptionButton::Flat;
38
 
    if (btn->menu())
39
 
        option.features |= QStyleOptionButton::HasMenu;
40
 
    if (btn->autoDefault() || btn->isDefault())
41
 
        option.features |= QStyleOptionButton::AutoDefaultButton;
42
 
    if (btn->isDefault())
43
 
        option.features |= QStyleOptionButton::DefaultButton;
44
 
    if (btn->isDown())
45
 
        option.state |= QStyle::State_Sunken;
46
 
    if (!btn->isFlat() && !btn->isDown())
47
 
        option.state |= QStyle::State_Raised;
48
 
 
49
 
    return option;
50
 
}
51
 
#endif
52
 
 
53
 
/*!
54
 
  \param num Number of arrows
55
 
  \param arrowType see Qt::ArowType in the Qt docs.
56
 
  \param parent Parent widget
57
 
*/
58
 
QwtArrowButton::QwtArrowButton(int num, 
59
 
        Qt::ArrowType arrowType, QWidget *parent): 
60
 
    QPushButton(parent)
61
 
{
62
 
    d_data = new PrivateData;
63
 
    d_data->num = qwtLim(num, 1, MaxNum);
64
 
    d_data->arrowType = arrowType;
65
 
 
66
 
    setAutoRepeat(true);
67
 
    setAutoDefault(false);
68
 
 
69
 
    switch(d_data->arrowType)
70
 
    {
71
 
        case Qt::LeftArrow:
72
 
        case Qt::RightArrow:
73
 
            setSizePolicy(QSizePolicy::Expanding, 
74
 
                QSizePolicy::Fixed);
75
 
            break;
76
 
        default:
77
 
            setSizePolicy(QSizePolicy::Fixed, 
78
 
                QSizePolicy::Expanding);
79
 
    }
80
 
}
81
 
 
82
 
//! Destructor
83
 
QwtArrowButton::~QwtArrowButton()
84
 
{
85
 
    delete d_data;
86
 
    d_data = NULL;
87
 
}
88
 
 
89
 
/*!
90
 
  \brief The direction of the arrows
91
 
*/
92
 
Qt::ArrowType QwtArrowButton::arrowType() const 
93
 
94
 
    return d_data->arrowType; 
95
 
}
96
 
 
97
 
/*!
98
 
  \brief The number of arrows
99
 
*/
100
 
int QwtArrowButton::num() const 
101
 
102
 
    return d_data->num; 
103
 
}
104
 
 
105
 
/*!
106
 
  \return the bounding rect for the label
107
 
*/
108
 
QRect QwtArrowButton::labelRect() const
109
 
{
110
 
    const int m = Margin;
111
 
 
112
 
    QRect r = rect();
113
 
    r.setRect(r.x() + m, r.y() + m, 
114
 
        r.width() - 2 * m, r.height() - 2 * m);
115
 
 
116
 
    if ( isDown() )
117
 
    {
118
 
        int ph, pv;
119
 
#if QT_VERSION < 0x040000
120
 
        ph = style().pixelMetric(
121
 
            QStyle::PM_ButtonShiftHorizontal, this);
122
 
        pv = style().pixelMetric(
123
 
            QStyle::PM_ButtonShiftVertical, this);
124
 
        r.moveBy(ph, pv);
125
 
#else
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);
131
 
        r.translate(ph, pv);
132
 
#endif
133
 
    }
134
 
 
135
 
    return r;
136
 
}
137
 
 
138
 
#if QT_VERSION >= 0x040000
139
 
/*!
140
 
   Paint event handler
141
 
   \param event Paint event
142
 
*/
143
 
void QwtArrowButton::paintEvent(QPaintEvent *event)
144
 
{
145
 
    QPushButton::paintEvent(event);
146
 
    QPainter painter(this);
147
 
    drawButtonLabel(&painter);
148
 
}
149
 
#endif
150
 
 
151
 
/*!
152
 
  \brief Draw the button label
153
 
 
154
 
  \param painter Painter
155
 
  \sa The Qt Manual on QPushButton
156
 
*/
157
 
void QwtArrowButton::drawButtonLabel(QPainter *painter)
158
 
{
159
 
    const bool isVertical = d_data->arrowType == Qt::UpArrow ||
160
 
        d_data->arrowType == Qt::DownArrow;
161
 
 
162
 
    const QRect r = labelRect();
163
 
    QSize boundingSize = labelRect().size();
164
 
    if ( isVertical )
165
 
        boundingSize.transpose();
166
 
        
167
 
    const int w = 
168
 
        (boundingSize.width() - (MaxNum - 1) * Spacing) / MaxNum;
169
 
 
170
 
    QSize arrow = arrowSize(Qt::RightArrow, 
171
 
        QSize(w, boundingSize.height()));
172
 
 
173
 
    if ( isVertical )
174
 
        arrow.transpose();
175
 
 
176
 
    QRect contentsSize; // aligned rect where to paint all arrows
177
 
    if ( d_data->arrowType == Qt::LeftArrow || d_data->arrowType == Qt::RightArrow )
178
 
    {
179
 
        contentsSize.setWidth(d_data->num * arrow.width() 
180
 
            + (d_data->num - 1) * Spacing);
181
 
        contentsSize.setHeight(arrow.height());
182
 
    }
183
 
    else
184
 
    {
185
 
        contentsSize.setWidth(arrow.width());
186
 
        contentsSize.setHeight(d_data->num * arrow.height() 
187
 
            + (d_data->num - 1) * Spacing);
188
 
    }
189
 
 
190
 
    QRect arrowRect(contentsSize);
191
 
    arrowRect.moveCenter(r.center());
192
 
    arrowRect.setSize(arrow);
193
 
 
194
 
    painter->save();
195
 
    for (int i = 0; i < d_data->num; i++)
196
 
    {
197
 
        drawArrow(painter, arrowRect, d_data->arrowType);
198
 
 
199
 
        int dx = 0;
200
 
        int dy = 0;
201
 
 
202
 
        if ( isVertical )
203
 
            dy = arrow.height() + Spacing;
204
 
        else
205
 
            dx = arrow.width() + Spacing;
206
 
 
207
 
#if QT_VERSION >= 0x040000
208
 
        arrowRect.translate(dx, dy);
209
 
#else
210
 
        arrowRect.moveBy(dx, dy);
211
 
#endif
212
 
    }
213
 
    painter->restore();
214
 
 
215
 
    if ( hasFocus() )
216
 
    {
217
 
#if QT_VERSION >= 0x040000
218
 
        QStyleOptionFocusRect option;
219
 
        option.init(this);
220
 
        option.backgroundColor = palette().color(QPalette::Background);
221
 
 
222
 
        style()->drawPrimitive(QStyle::PE_FrameFocusRect, 
223
 
            &option, painter, this);
224
 
#else
225
 
        const QRect focusRect =  
226
 
            style().subRect(QStyle::SR_PushButtonFocusRect, this);
227
 
        style().drawPrimitive(QStyle::PE_FocusRect, painter,
228
 
            focusRect, colorGroup());
229
 
#endif
230
 
    }
231
 
}
232
 
 
233
 
/*!
234
 
    Draw an arrow int a bounding rect
235
 
 
236
 
    \param painter Painter
237
 
    \param r Rectangle where to paint the arrow
238
 
    \param arrowType Arrow type
239
 
*/
240
 
void QwtArrowButton::drawArrow(QPainter *painter, 
241
 
    const QRect &r, Qt::ArrowType arrowType) const 
242
 
{
243
 
    QwtPolygon pa(3);
244
 
 
245
 
    switch(arrowType)
246
 
    {
247
 
        case Qt::UpArrow:
248
 
            pa.setPoint(0, r.bottomLeft());
249
 
            pa.setPoint(1, r.bottomRight());
250
 
            pa.setPoint(2, r.center().x(), r.top());
251
 
            break;
252
 
        case Qt::DownArrow:
253
 
            pa.setPoint(0, r.topLeft());
254
 
            pa.setPoint(1, r.topRight());
255
 
            pa.setPoint(2, r.center().x(), r.bottom());
256
 
            break;
257
 
        case Qt::RightArrow:
258
 
            pa.setPoint(0, r.topLeft());
259
 
            pa.setPoint(1, r.bottomLeft());
260
 
            pa.setPoint(2, r.right(), r.center().y());
261
 
            break;
262
 
        case Qt::LeftArrow:
263
 
            pa.setPoint(0, r.topRight());
264
 
            pa.setPoint(1, r.bottomRight());
265
 
            pa.setPoint(2, r.left(), r.center().y());
266
 
            break;
267
 
        default:
268
 
            break;
269
 
    }
270
 
 
271
 
    painter->save();
272
 
#if QT_VERSION < 0x040000
273
 
    painter->setPen(colorGroup().buttonText());
274
 
    painter->setBrush(colorGroup().brush(QColorGroup::ButtonText));
275
 
#else
276
 
    painter->setPen(palette().color(QPalette::ButtonText));
277
 
    painter->setBrush(palette().brush(QPalette::ButtonText));
278
 
#endif
279
 
    painter->drawPolygon(pa);
280
 
    painter->restore();
281
 
}
282
 
 
283
 
/*!
284
 
  \return a size hint
285
 
*/
286
 
QSize QwtArrowButton::sizeHint() const
287
 
{
288
 
    return minimumSizeHint();
289
 
}
290
 
 
291
 
/*!
292
 
  \brief Return a minimum size hint
293
 
*/
294
 
QSize QwtArrowButton::minimumSizeHint() const
295
 
{
296
 
    const QSize asz = arrowSize(Qt::RightArrow, QSize()); 
297
 
 
298
 
    QSize sz(
299
 
        2 * Margin + (MaxNum - 1) * Spacing + MaxNum * asz.width(),
300
 
        2 * Margin + asz.height()
301
 
    );
302
 
 
303
 
    if ( d_data->arrowType == Qt::UpArrow || d_data->arrowType == Qt::DownArrow )
304
 
        sz.transpose();
305
 
 
306
 
#if QT_VERSION >= 0x040000
307
 
    QStyleOption styleOption;
308
 
    styleOption.init(this);
309
 
 
310
 
    sz = style()->sizeFromContents(QStyle::CT_PushButton, 
311
 
        &styleOption, sz, this);
312
 
#else
313
 
    sz = style().sizeFromContents(QStyle::CT_PushButton, this, sz);
314
 
#endif
315
 
 
316
 
    return sz;
317
 
}
318
 
 
319
 
/*!
320
 
   Calculate the size for a arrow that fits into a rect of a given size
321
 
 
322
 
   \param arrowType Arrow type
323
 
   \param boundingSize Bounding size
324
 
   \return Size of the arrow
325
 
*/
326
 
QSize QwtArrowButton::arrowSize(Qt::ArrowType arrowType,
327
 
    const QSize &boundingSize) const
328
 
{
329
 
    QSize bs = boundingSize;
330
 
    if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
331
 
        bs.transpose();
332
 
        
333
 
    const int MinLen = 2;
334
 
    const QSize sz = bs.expandedTo(
335
 
        QSize(MinLen, 2 * MinLen - 1)); // minimum
336
 
 
337
 
    int w = sz.width();
338
 
    int h = 2 * w - 1;
339
 
 
340
 
    if ( h > sz.height() )
341
 
    {
342
 
        h = sz.height();
343
 
        w = (h + 1) / 2;
344
 
    }
345
 
 
346
 
    QSize arrSize(w, h);
347
 
    if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
348
 
        arrSize.transpose();
349
 
 
350
 
    return arrSize;
351
 
}
352
 
 
353
 
/*!
354
 
  \brief autoRepeat for the space keys
355
 
*/
356
 
void QwtArrowButton::keyPressEvent(QKeyEvent *e)
357
 
{
358
 
    if ( e->isAutoRepeat() && e->key() == Qt::Key_Space )
359
 
        emit clicked();
360
 
 
361
 
    QPushButton::keyPressEvent(e);
362
 
}