00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qapplication.h>
00013 #include <qpainter.h>
00014 #include <qpicture.h>
00015 #include <qbitmap.h>
00016 #include <qstyle.h>
00017 #include "qwt_legend.h"
00018 #include "qwt_painter.h"
00019 #include "qwt_dyngrid_layout.h"
00020
00021 static const int IdentifierWidth = 8;
00029 QwtLegendButton::QwtLegendButton(
00030 const QwtSymbol &symbol, const QPen &pen, const QString &text,
00031 QWidget *parent, const char *name):
00032 QPushButton(text, parent, name),
00033 d_identifierMode(QwtLegendButton::ShowLine
00034 | QwtLegendButton::ShowText),
00035 d_symbol(symbol),
00036 d_curvePen(pen)
00037 {
00038 setFlat(TRUE);
00039 updateIconset();
00040 }
00041
00046 QwtLegendButton::QwtLegendButton(QWidget *parent, const char *name):
00047 QPushButton(parent, name),
00048 d_identifierMode(QwtLegendButton::ShowLine
00049 | QwtLegendButton::ShowText),
00050 d_curvePen(Qt::NoPen)
00051 {
00052 setFlat(TRUE);
00053 updateIconset();
00054 }
00055
00063 void QwtLegendButton::setIdentifierMode(int mode)
00064 {
00065 if ( mode != d_identifierMode )
00066 {
00067 d_identifierMode = mode;
00068 updateIconset();
00069 }
00070 }
00071
00078 void QwtLegendButton::setSymbol(const QwtSymbol &symbol)
00079 {
00080 if ( symbol != d_symbol )
00081 {
00082 d_symbol = symbol;
00083 updateIconset();
00084 }
00085 }
00086
00093 void QwtLegendButton::setCurvePen(const QPen &pen)
00094 {
00095 if ( pen != d_curvePen )
00096 {
00097 d_curvePen = pen;
00098 updateIconset();
00099 }
00100 }
00101
00105 void QwtLegendButton::updateIconset()
00106 {
00107 const QFontMetrics fm(font());
00108
00109 QPixmap pm(IdentifierWidth, fm.height());
00110 pm.fill(this, 0, 0);
00111
00112 QPainter p(&pm);
00113 drawIdentifier(&p, QRect(0, 0, pm.width(), pm.height()) );
00114 p.end();
00115
00116 pm.setMask(pm.createHeuristicMask());
00117
00118 setIconSet(QIconSet(pm));
00119 }
00120
00126 void QwtLegendButton::drawIdentifier(
00127 QPainter *painter, const QRect &rect) const
00128 {
00129 if ( rect.isEmpty() )
00130 return;
00131
00132 if ( (d_identifierMode & ShowLine ) && (d_curvePen.style() != Qt::NoPen) )
00133 {
00134 QRect scaledRect = QwtPainter::scale(rect, painter);
00135
00136 painter->save();
00137 painter->setPen(d_curvePen);
00138 painter->drawLine(scaledRect.left(), scaledRect.center().y(),
00139 scaledRect.right(), scaledRect.center().y());
00140 painter->restore();
00141 }
00142
00143 if ( (d_identifierMode & ShowSymbol)
00144 && (d_symbol.style() != QwtSymbol::None) )
00145 {
00146 QRect symbolRect;
00147 symbolRect.setSize(d_symbol.size().boundedTo(rect.size()));
00148 symbolRect.moveCenter(rect.center());
00149
00150 painter->save();
00151 d_symbol.draw(painter, symbolRect);
00152 painter->restore();
00153 }
00154 }
00155
00164 void QwtLegendButton::drawContents(QPainter *painter,
00165 const QRect &rect) const
00166 {
00167 const QFontMetrics fm(font());
00168
00169 QPixmap pm(IdentifierWidth, fm.height());
00170
00171 QRect identifierRect(rect.x() + 2, rect.y(),
00172 IdentifierWidth, fm.height());
00173 identifierRect.moveCenter(QPoint(identifierRect.center().x(),
00174 rect.center().y()));
00175
00176 drawIdentifier(painter, identifierRect);
00177
00178 QRect textRect = rect;
00179 textRect.setX(identifierRect.right() + 4);
00180 QwtPainter::drawText(painter, textRect,
00181 AlignLeft | AlignVCenter, text());
00182 }
00183
00184 class PaintFilter: public QPicture
00185 {
00186
00187
00188
00189 public:
00190 PaintFilter():
00191 d_textStart(0)
00192 {
00193 }
00194
00195 virtual bool cmd(int c, QPainter *p, QPDevCmdParam *param)
00196 {
00197 switch(c)
00198 {
00199 case PdcDrawPixmap:
00200 {
00201
00202 #if QT_VERSION < 300
00203 d_textStart = param[0].point->x()
00204 + param[1].pixmap->width();
00205 #else
00206 d_textStart = param[0].rect->right();
00207 #endif
00208 d_textStart += 4;
00209 break;
00210 }
00211 case PdcDrawTextFormatted:
00212 case PdcDrawText2Formatted:
00213 {
00214 if ( d_textStart > 0 )
00215 {
00216
00217
00218
00219 QRect r = *(param[0].rect);
00220 r.moveBy(d_textStart - r.x(), 0);
00221
00222 QPDevCmdParam changed[3];
00223 changed[0].rect = &r;
00224 changed[1].ival = param[1].ival;
00225 changed[1].ival &= ~Qt::AlignHCenter;
00226 changed[1].ival |= Qt::AlignLeft;
00227
00228 changed[2].str = param[2].str;
00229
00230 return QPicture::cmd(c, p, changed);
00231 }
00232 break;
00233 }
00234 }
00235 return QPicture::cmd(c, p, param);
00236 }
00237 private:
00238 int d_textStart;
00239 };
00240
00249 void QwtLegendButton::drawButtonLabel(QPainter *painter)
00250 {
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 PaintFilter filter;
00263
00264 bool disabled = (bool)testWState(WState_Disabled);
00265 clearWState(WState_Disabled);
00266
00267 QPainter picPainter(&filter);
00268 QPushButton::drawButtonLabel(&picPainter);
00269 picPainter.end();
00270
00271 if ( disabled )
00272 setWState(WState_Disabled);
00273
00274 filter.play(painter);
00275 }
00276
00281 QSize QwtLegendButton::sizeHint() const
00282 {
00283 return minimumSizeHint();
00284 }
00285
00290 QSize QwtLegendButton::minimumSizeHint() const
00291 {
00292 const QFontMetrics fm(font());
00293
00294 int h = QPushButton::sizeHint().height();
00295
00296 int w = iconSet()->pixmap(
00297 QIconSet::Small, QIconSet::Normal).width();
00298 w += 4;
00299 w += fm.size(ShowPrefix, text()).width();
00300
00301 #if QT_VERSION < 300
00302 w += 2 * (style().buttonMargin() - 1);
00303 if ( isDefault() || autoDefault() )
00304 w += 2 * style().buttonDefaultIndicatorWidth();
00305 #else
00306 w = style().sizeFromContents(QStyle::CT_PushButton,
00307 this, QSize(w, fm.height() + 2)).width();
00308 #endif
00309
00310 return QSize(w, h).expandedTo(QApplication::globalStrut());
00311 }
00312
00317 QwtLegend::QwtLegend(QWidget *parent, const char *name):
00318 QScrollView(parent, name),
00319 d_displayPolicy(QwtLegend::Auto),
00320 d_identifierMode(QwtLegendButton::ShowLine
00321 | QwtLegendButton::ShowSymbol
00322 | QwtLegendButton::ShowText)
00323 {
00324 setFrameStyle(NoFrame);
00325 setResizePolicy(Manual);
00326
00327 viewport()->setBackgroundMode(QWidget::NoBackground);
00328
00329 d_contentsWidget = new QWidget(viewport());
00330 d_contentsWidget->installEventFilter(this);
00331
00332 QwtDynGridLayout *layout = new QwtDynGridLayout(d_contentsWidget);
00333 layout->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
00334 layout->setAutoAdd(TRUE);
00335
00336 addChild(d_contentsWidget);
00337 }
00338
00343 void QwtLegend::setDisplayPolicy(int policy, int mode)
00344 {
00345 d_displayPolicy = policy;
00346 if (-1 != mode)
00347 d_identifierMode = mode;
00348 }
00349
00357 void QwtLegend::insertItem(QWidget *item, long key)
00358 {
00359 if ( item == NULL || key < 0 )
00360 return;
00361
00362 if ( item->parent() != d_contentsWidget )
00363 item->reparent(d_contentsWidget, QPoint(0, 0));
00364
00365 item->show();
00366
00367 if ( d_items.count() > d_items.size() - 5 )
00368 d_items.resize(d_items.count() + 5);
00369
00370 d_items.insert(key, item);
00371
00372 layoutContents();
00373
00374 QWidget *w = 0;
00375
00376 if ( d_contentsWidget->layout() )
00377 {
00378
00379
00380 QLayoutIterator layoutIterator =
00381 d_contentsWidget->layout()->iterator();
00382
00383 for ( QLayoutItem *item = layoutIterator.current();
00384 item != 0; item = ++layoutIterator)
00385 {
00386 if ( w && item->widget() )
00387 QWidget::setTabOrder(w, item->widget());
00388
00389 w = item->widget();
00390 }
00391 }
00392 }
00393
00399 long QwtLegend::key(const QWidget *item) const
00400 {
00401 QIntDictIterator<QWidget> it(d_items);
00402 for ( const QWidget *w = it.toFirst(); w != 0; w = ++it)
00403 {
00404 if ( w == item )
00405 return it.currentKey();
00406 }
00407 return -1;
00408 }
00409
00411 void QwtLegend::clear()
00412 {
00413
00414
00415
00416
00417 QValueList<QWidget *> clearList;
00418
00419 QIntDictIterator<QWidget> it(d_items);
00420 for ( QWidget *item = it.toFirst(); item != 0; item = ++it)
00421 clearList += item;
00422
00423 for ( uint i = 0; i < clearList.count(); i++ )
00424 delete clearList[i];
00425
00426 #if QT_VERSION < 232
00427
00428
00429
00430
00431
00432 d_items.clear();
00433 #endif
00434 }
00435
00437 QIntDictIterator<QWidget> QwtLegend::itemIterator() const
00438 {
00439 return QIntDictIterator<QWidget>(d_items);
00440 }
00441
00443 QSize QwtLegend::sizeHint() const
00444 {
00445 QSize hint = d_contentsWidget->sizeHint();
00446 hint += QSize(2 * frameWidth(), 2 * frameWidth());
00447
00448 return hint;
00449 }
00450
00454 int QwtLegend::heightForWidth(int w) const
00455 {
00456 w -= 2 * frameWidth();
00457
00458 int h = d_contentsWidget->heightForWidth(w);
00459 if ( h <= 0 )
00460 {
00461 QLayout *l = d_contentsWidget->layout();
00462 if ( l && l->hasHeightForWidth() )
00463 {
00464 h = l->heightForWidth(w);
00465 h += 2 * frameWidth();
00466 }
00467 }
00468
00469 return h;
00470 }
00471
00475 void QwtLegend::layoutContents()
00476 {
00477 const QSize visibleSize = viewport()->size();
00478
00479 const QLayout *l = d_contentsWidget->layout();
00480 if ( l && l->inherits("QwtDynGridLayout") )
00481 {
00482 const QwtDynGridLayout *tl = (const QwtDynGridLayout *)l;
00483
00484 const int minW = int(tl->maxItemWidth()) + 2 * tl->margin();
00485
00486 int w = QMAX(visibleSize.width(), minW);
00487 int h = QMAX(tl->heightForWidth(w), visibleSize.height());
00488
00489 const int vpWidth = viewportSize(w, h).width();
00490
00491 if ( w > vpWidth )
00492 {
00493 w = QMAX(vpWidth, minW);
00494 h = QMAX(tl->heightForWidth(w), visibleSize.height());
00495 }
00496
00497 d_contentsWidget->resize(w, h);
00498 resizeContents(w, h);
00499 }
00500 }
00501
00502
00503
00504
00505
00506
00507 bool QwtLegend::eventFilter(QObject *o, QEvent *e)
00508 {
00509 if ( o == d_contentsWidget )
00510 {
00511 switch(e->type())
00512 {
00513 case QEvent::ChildRemoved:
00514 {
00515 const QChildEvent *ce = (const QChildEvent *)e;
00516 if ( ce->child()->isWidgetType() )
00517 (void)takeItem(key((QWidget *)ce->child()));
00518 break;
00519 }
00520 case QEvent::LayoutHint:
00521 {
00522 layoutContents();
00523 break;
00524 }
00525 default:
00526 break;
00527 }
00528 }
00529
00530 return QScrollView::eventFilter(o, e);
00531 }
00532
00533
00534
00535
00536
00537 void QwtLegend::viewportResizeEvent(QResizeEvent *e)
00538 {
00539 QScrollView::viewportResizeEvent(e);
00540
00541
00542
00543
00544
00545 QApplication::postEvent(d_contentsWidget, new QEvent(QEvent::LayoutHint));
00546 }