Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

qwt_arrow_button.cpp

00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  * 
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 #include <qpainter.h>
00011 #include <qstyle.h>
00012 #include <qevent.h>
00013 #include "qwt_math.h"
00014 #include "qwt_arrow_button.h"
00015 
00016 #if QT_VERSION < 0x040000
00017 #include <qpointarray.h>
00018 #define QwtPointArray QPointArray
00019 #else
00020 #include <qpolygon.h>
00021 #define QwtPointArray QPolygon
00022 #endif
00023 
00024 static const int MaxNum = 3;
00025 static const int Margin = 2;
00026 static const int Spacing = 1;
00027 
00028 class QwtArrowButton::PrivateData
00029 {
00030 public:
00031     int num;
00032     Qt::ArrowType arrowType;
00033 };
00034 
00035 
00036 #if QT_VERSION >= 0x040000
00037 #include <qstyleoption.h>
00038 static QStyleOptionButton styleOpt(const QwtArrowButton* btn)
00039 {
00040     QStyleOptionButton option;
00041     option.init(btn);
00042     option.features = QStyleOptionButton::None;
00043     if (btn->isFlat())
00044         option.features |= QStyleOptionButton::Flat;
00045     if (btn->menu())
00046         option.features |= QStyleOptionButton::HasMenu;
00047     if (btn->autoDefault() || btn->isDefault())
00048         option.features |= QStyleOptionButton::AutoDefaultButton;
00049     if (btn->isDefault())
00050         option.features |= QStyleOptionButton::DefaultButton;
00051     if (btn->isDown())
00052         option.state |= QStyle::State_Sunken;
00053     if (!btn->isFlat() && !btn->isDown())
00054         option.state |= QStyle::State_Raised;
00055 
00056     return option;
00057 }
00058 #endif
00059 
00065 QwtArrowButton::QwtArrowButton(int num, 
00066         Qt::ArrowType arrowType, QWidget *parent): 
00067     QPushButton(parent)
00068 {
00069     d_data = new PrivateData;
00070     d_data->num = qwtLim(num, 1, MaxNum);
00071     d_data->arrowType = arrowType;
00072 
00073     setAutoRepeat(true);
00074     setAutoDefault(false);
00075 
00076     switch(d_data->arrowType)
00077     {
00078         case Qt::LeftArrow:
00079         case Qt::RightArrow:
00080             setSizePolicy(QSizePolicy::Expanding, 
00081                 QSizePolicy::Fixed);
00082             break;
00083         default:
00084             setSizePolicy(QSizePolicy::Fixed, 
00085                 QSizePolicy::Expanding);
00086     }
00087 }
00088 
00089 QwtArrowButton::~QwtArrowButton()
00090 {
00091     delete d_data;
00092     d_data = NULL;
00093 }
00094 
00098 Qt::ArrowType QwtArrowButton::arrowType() const 
00099 { 
00100     return d_data->arrowType; 
00101 }
00102 
00106 int QwtArrowButton::num() const 
00107 { 
00108     return d_data->num; 
00109 }
00110 
00114 QRect QwtArrowButton::labelRect() const
00115 {
00116     const int m = Margin;
00117 
00118     QRect r = rect();
00119     r.setRect(r.x() + m, r.y() + m, 
00120         r.width() - 2 * m, r.height() - 2 * m);
00121 
00122     if ( isDown() )
00123     {
00124         int ph, pv;
00125 #if QT_VERSION < 0x040000
00126         ph = style().pixelMetric(
00127             QStyle::PM_ButtonShiftHorizontal, this);
00128         pv = style().pixelMetric(
00129             QStyle::PM_ButtonShiftVertical, this);
00130         r.moveBy(ph, pv);
00131 #else
00132         QStyleOptionButton option = styleOpt(this);
00133         ph = style()->pixelMetric(
00134             QStyle::PM_ButtonShiftHorizontal, &option, this);
00135         pv = style()->pixelMetric(
00136             QStyle::PM_ButtonShiftVertical, &option, this);
00137         r.translate(ph, pv);
00138 #endif
00139     }
00140 
00141     return r;
00142 }
00143 
00144 #if QT_VERSION >= 0x040000
00145 void QwtArrowButton::paintEvent(QPaintEvent *event)
00146 {
00147     QPushButton::paintEvent(event);
00148     QPainter painter(this);
00149     drawButtonLabel(&painter);
00150 }
00151 #endif
00152 
00157 void QwtArrowButton::drawButtonLabel(QPainter *p)
00158 {
00159     const bool isVertical = d_data->arrowType == Qt::UpArrow ||
00160         d_data->arrowType == Qt::DownArrow;
00161 
00162     const QRect r = labelRect();
00163     QSize boundingSize = labelRect().size();
00164     if ( isVertical )
00165         boundingSize.transpose();
00166         
00167     const int w = 
00168         (boundingSize.width() - (MaxNum - 1) * Spacing) / MaxNum;
00169 
00170     QSize arrow = arrowSize(Qt::RightArrow, 
00171         QSize(w, boundingSize.height()));
00172 
00173     if ( isVertical )
00174         arrow.transpose();
00175 
00176     QRect contentsSize; // aligned rect where to paint all arrows
00177     if ( d_data->arrowType == Qt::LeftArrow || d_data->arrowType == Qt::RightArrow )
00178     {
00179         contentsSize.setWidth(d_data->num * arrow.width() 
00180             + (d_data->num - 1) * Spacing);
00181         contentsSize.setHeight(arrow.height());
00182     }
00183     else
00184     {
00185         contentsSize.setWidth(arrow.width());
00186         contentsSize.setHeight(d_data->num * arrow.height() 
00187             + (d_data->num - 1) * Spacing);
00188     }
00189 
00190     QRect arrowRect(contentsSize);
00191     arrowRect.moveCenter(r.center());
00192     arrowRect.setSize(arrow);
00193 
00194     p->save();
00195     for (int i = 0; i < d_data->num; i++)
00196     {
00197         drawArrow(p, arrowRect, d_data->arrowType);
00198 
00199         int dx = 0;
00200         int dy = 0;
00201 
00202         if ( isVertical )
00203             dy = arrow.height() + Spacing;
00204         else
00205             dx = arrow.width() + Spacing;
00206 
00207 #if QT_VERSION >= 0x040000
00208         arrowRect.translate(dx, dy);
00209 #else
00210         arrowRect.moveBy(dx, dy);
00211 #endif
00212     }
00213     p->restore();
00214 
00215     if ( hasFocus() )
00216     {
00217 #if QT_VERSION >= 0x040000
00218         QStyleOptionFocusRect option;
00219         option.init(this);
00220         option.backgroundColor = palette().color(QPalette::Background);
00221 
00222         style()->drawPrimitive(QStyle::PE_FrameFocusRect, 
00223             &option, p, this);
00224 #else
00225         const QRect focusRect =  
00226             style().subRect(QStyle::SR_PushButtonFocusRect, this);
00227         style().drawPrimitive(QStyle::PE_FocusRect, p,
00228             focusRect, colorGroup());
00229 #endif
00230     }
00231 }
00232 
00240 void QwtArrowButton::drawArrow(QPainter *p, 
00241     const QRect &r, Qt::ArrowType arrowType) const 
00242 {
00243     QwtPointArray pa(3);
00244 
00245     switch(arrowType)
00246     {
00247         case Qt::UpArrow:
00248             pa.setPoint(0, r.bottomLeft());
00249             pa.setPoint(1, r.bottomRight());
00250             pa.setPoint(2, r.center().x(), r.top());
00251             break;
00252         case Qt::DownArrow:
00253             pa.setPoint(0, r.topLeft());
00254             pa.setPoint(1, r.topRight());
00255             pa.setPoint(2, r.center().x(), r.bottom());
00256             break;
00257         case Qt::RightArrow:
00258             pa.setPoint(0, r.topLeft());
00259             pa.setPoint(1, r.bottomLeft());
00260             pa.setPoint(2, r.right(), r.center().y());
00261             break;
00262         case Qt::LeftArrow:
00263             pa.setPoint(0, r.topRight());
00264             pa.setPoint(1, r.bottomRight());
00265             pa.setPoint(2, r.left(), r.center().y());
00266             break;
00267         default:
00268             break;
00269     }
00270 
00271     p->save();
00272 #if QT_VERSION < 0x040000
00273     p->setPen(colorGroup().buttonText());
00274     p->setBrush(colorGroup().brush(QColorGroup::ButtonText));
00275 #else
00276     p->setPen(palette().color(QPalette::ButtonText));
00277     p->setBrush(palette().brush(QPalette::ButtonText));
00278 #endif
00279     p->drawPolygon(pa);
00280     p->restore();
00281 }
00282 
00286 QSize QwtArrowButton::sizeHint() const
00287 {
00288     return minimumSizeHint();
00289 }
00290 
00294 QSize QwtArrowButton::minimumSizeHint() const
00295 {
00296     const QSize asz = arrowSize(Qt::RightArrow, QSize()); 
00297 
00298     QSize sz(
00299         2 * Margin + (MaxNum - 1) * Spacing + MaxNum * asz.width(),
00300         2 * Margin + asz.height()
00301     );
00302 
00303     if ( d_data->arrowType == Qt::UpArrow || d_data->arrowType == Qt::DownArrow )
00304         sz.transpose();
00305 
00306 #if QT_VERSION >= 0x040000
00307     QStyleOption styleOption;
00308     styleOption.init(this);
00309 
00310     sz = style()->sizeFromContents(QStyle::CT_PushButton, 
00311         &styleOption, sz, this);
00312 #else
00313     sz = style().sizeFromContents(QStyle::CT_PushButton, this, sz);
00314 #endif
00315 
00316     return sz;
00317 }
00318 
00326 QSize QwtArrowButton::arrowSize(Qt::ArrowType arrowType,
00327     const QSize &boundingSize) const
00328 {
00329     QSize bs = boundingSize;
00330     if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
00331         bs.transpose();
00332         
00333     const int MinLen = 2;
00334     const QSize sz = bs.expandedTo(
00335         QSize(MinLen, 2 * MinLen - 1)); // minimum
00336 
00337     int w = sz.width();
00338     int h = 2 * w - 1;
00339 
00340     if ( h > sz.height() )
00341     {
00342         h = sz.height();
00343         w = (h + 1) / 2;
00344     }
00345 
00346     QSize arrSize(w, h);
00347     if ( arrowType == Qt::UpArrow || arrowType == Qt::DownArrow )
00348         arrSize.transpose();
00349 
00350     return arrSize;
00351 }
00352 
00356 void QwtArrowButton::keyPressEvent(QKeyEvent *e)
00357 {
00358     if ( e->isAutoRepeat() && e->key() == Qt::Key_Space )
00359         emit clicked();
00360 
00361     QPushButton::keyPressEvent(e);
00362 }

Generated on Mon Jan 30 22:16:25 2006 for Qwt User's Guide by  doxygen 1.4.4