00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qlabel.h>
00013 #include <qscrollbar.h>
00014 #include "qwt_rect.h"
00015 #include "qwt_text.h"
00016 #include "qwt_plot_canvas.h"
00017 #include "qwt_scale_widget.h"
00018 #include "qwt_legend.h"
00019 #include "qwt_plot_layout.h"
00020
00021 class QwtPlotLayout::LayoutData
00022 {
00023 public:
00024 LayoutData()
00025 {
00026 title.text = NULL;
00027 }
00028
00029 ~LayoutData()
00030 {
00031 delete title.text;
00032 }
00033
00034 void init(const QwtPlot *, const QRect &rect);
00035
00036 struct t_legendData
00037 {
00038 int frameWidth;
00039 int vScrollBarWidth;
00040 int hScrollBarHeight;
00041 QSize hint;
00042 } legend;
00043
00044 struct t_titleData
00045 {
00046 const QwtText *text;
00047 int frameWidth;
00048 } title;
00049
00050 struct t_scaleData
00051 {
00052 bool isEnabled;
00053 const QwtScaleWidget *scaleWidget;
00054 QFont scaleFont;
00055 int start;
00056 int end;
00057 int baseLineOffset;
00058 int tickOffset;
00059 int dimWithoutTitle;
00060 } scale[QwtPlot::axisCnt];
00061
00062 struct t_canvasData
00063 {
00064 int frameWidth;
00065 } canvas;
00066 };
00067
00068
00069
00070
00071
00072 void QwtPlotLayout::LayoutData::init(const QwtPlot *plot, const QRect &rect)
00073 {
00074
00075
00076 if ( plot->legend() )
00077 {
00078 legend.frameWidth = plot->legend()->frameWidth();
00079 legend.vScrollBarWidth =
00080 plot->legend()->verticalScrollBar()->sizeHint().width();
00081 legend.hScrollBarHeight =
00082 plot->legend()->horizontalScrollBar()->sizeHint().height();
00083
00084 const QSize hint = plot->legend()->sizeHint();
00085
00086 int w = qwtMin(hint.width(), rect.width());
00087 int h = plot->legend()->heightForWidth(w);
00088 if ( h == 0 )
00089 h = hint.height();
00090
00091 if ( h > rect.height() )
00092 w += legend.vScrollBarWidth;
00093
00094 legend.hint = QSize(w, h);
00095 }
00096
00097
00098
00099 title.frameWidth = 0;
00100 delete title.text;
00101 title.text = NULL;
00102
00103 if (plot->titleLabel() && !plot->titleLabel()->text().isEmpty())
00104 {
00105 const QLabel *label = plot->titleLabel();
00106 int alignment = label->alignment();
00107 #if QT_VERSION >= 0x040000
00108 if ( label->wordWrap() )
00109 alignment |= Qt::TextWordWrap;
00110 #endif
00111 title.text = QwtText::makeText(label->text(), label->textFormat(),
00112 alignment, label->font());
00113 title.frameWidth = plot->titleLabel()->frameWidth();
00114 }
00115
00116
00117
00118 for (int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00119 {
00120 if ( plot->axisEnabled(axis) )
00121 {
00122 const QwtScaleWidget *scaleWidget = plot->axisWidget(axis);
00123
00124 scale[axis].isEnabled = true;
00125
00126 scale[axis].scaleWidget = scaleWidget;
00127
00128 scale[axis].scaleFont = scaleWidget->font();
00129
00130 scale[axis].start = scaleWidget->startBorderDist();
00131 scale[axis].end = scaleWidget->endBorderDist();
00132
00133 scale[axis].baseLineOffset = scaleWidget->baseLineDist();
00134 scale[axis].tickOffset = scaleWidget->baseLineDist() +
00135 (int)scaleWidget->scaleDraw()->majTickLength();
00136
00137 scale[axis].dimWithoutTitle = scaleWidget->dimForLength(
00138 QWIDGETSIZE_MAX, scale[axis].scaleFont);
00139
00140 if ( !scaleWidget->title().isEmpty() )
00141 {
00142 scale[axis].dimWithoutTitle -=
00143 scaleWidget->titleHeightForWidth(QWIDGETSIZE_MAX);
00144 }
00145 }
00146 else
00147 {
00148 scale[axis].isEnabled = false;
00149 scale[axis].start = 0;
00150 scale[axis].end = 0;
00151 scale[axis].baseLineOffset = 0;
00152 scale[axis].tickOffset = 0;
00153 scale[axis].dimWithoutTitle = 0;
00154 }
00155 }
00156
00157
00158
00159 canvas.frameWidth = plot->canvas()->frameWidth();
00160 }
00161
00162 class QwtPlotLayout::PrivateData
00163 {
00164 public:
00165 PrivateData():
00166 margin(0),
00167 spacing(5),
00168 alignCanvasToScales(false)
00169 {
00170 }
00171
00172 QRect titleRect;
00173 QRect legendRect;
00174 QRect scaleRect[QwtPlot::axisCnt];
00175 QRect canvasRect;
00176
00177 QwtPlotLayout::LayoutData layoutData;
00178
00179 QwtPlot::LegendPosition legendPos;
00180 double legendRatio;
00181 unsigned int margin;
00182 unsigned int spacing;
00183 unsigned int canvasMargin[QwtPlot::axisCnt];
00184 bool alignCanvasToScales;
00185 };
00186
00191 QwtPlotLayout::QwtPlotLayout()
00192 {
00193 d_data = new PrivateData;
00194
00195 setLegendPosition(QwtPlot::BottomLegend);
00196 setCanvasMargin(4);
00197
00198 invalidate();
00199 }
00200
00202 QwtPlotLayout::~QwtPlotLayout()
00203 {
00204 delete d_data;
00205 }
00206
00216 void QwtPlotLayout::setMargin(int margin)
00217 {
00218 if ( margin < 0 )
00219 margin = 0;
00220 d_data->margin = margin;
00221 }
00222
00229 int QwtPlotLayout::margin() const
00230 {
00231 return d_data->margin;
00232 }
00233
00247 void QwtPlotLayout::setCanvasMargin(int margin, int axis)
00248 {
00249 if ( margin < -1 )
00250 margin = -1;
00251
00252 if ( axis == -1 )
00253 {
00254 for (axis = 0; axis < QwtPlot::axisCnt; axis++)
00255 d_data->canvasMargin[axis] = margin;
00256 }
00257 else if ( axis >= 0 || axis < QwtPlot::axisCnt )
00258 d_data->canvasMargin[axis] = margin;
00259 }
00260
00266 int QwtPlotLayout::canvasMargin(int axis) const
00267 {
00268 if ( axis < 0 || axis >= QwtPlot::axisCnt )
00269 return 0;
00270
00271 return d_data->canvasMargin[axis];
00272 }
00273
00274
00288 void QwtPlotLayout::setAlignCanvasToScales(bool alignCanvasToScales)
00289 {
00290 d_data->alignCanvasToScales = alignCanvasToScales;
00291 }
00292
00303 bool QwtPlotLayout::alignCanvasToScales() const
00304 {
00305 return d_data->alignCanvasToScales;
00306 }
00307
00316 void QwtPlotLayout::setSpacing(int spacing)
00317 {
00318 d_data->spacing = qwtMax(0, spacing);
00319 }
00320
00325 int QwtPlotLayout::spacing() const
00326 {
00327 return d_data->spacing;
00328 }
00329
00344 void QwtPlotLayout::setLegendPosition(QwtPlot::LegendPosition pos, double ratio)
00345 {
00346 if ( ratio > 1.0 )
00347 ratio = 1.0;
00348
00349 switch(pos)
00350 {
00351 case QwtPlot::TopLegend:
00352 case QwtPlot::BottomLegend:
00353 if ( ratio <= 0.0 )
00354 ratio = 0.33;
00355 d_data->legendRatio = ratio;
00356 d_data->legendPos = pos;
00357 break;
00358 case QwtPlot::LeftLegend:
00359 case QwtPlot::RightLegend:
00360 if ( ratio <= 0.0 )
00361 ratio = 0.5;
00362 d_data->legendRatio = ratio;
00363 d_data->legendPos = pos;
00364 break;
00365 default:
00366 break;
00367 }
00368 }
00369
00378 void QwtPlotLayout::setLegendPosition(QwtPlot::LegendPosition pos)
00379 {
00380 setLegendPosition(pos, 0.0);
00381 }
00382
00389 QwtPlot::LegendPosition QwtPlotLayout::legendPosition() const
00390 {
00391 return d_data->legendPos;
00392 }
00393
00405 void QwtPlotLayout::setLegendRatio(double ratio)
00406 {
00407 setLegendPosition(legendPosition(), ratio);
00408 }
00409
00415 double QwtPlotLayout::legendRatio() const
00416 {
00417 return d_data->legendRatio;
00418 }
00419
00425 const QRect &QwtPlotLayout::titleRect() const
00426 {
00427 return d_data->titleRect;
00428 }
00429
00435 const QRect &QwtPlotLayout::legendRect() const
00436 {
00437 return d_data->legendRect;
00438 }
00439
00446 const QRect &QwtPlotLayout::scaleRect(int axis) const
00447 {
00448 if ( axis < 0 || axis >= QwtPlot::axisCnt )
00449 {
00450 static QRect dummyRect;
00451 return dummyRect;
00452 }
00453 return d_data->scaleRect[axis];
00454 }
00455
00461 const QRect &QwtPlotLayout::canvasRect() const
00462 {
00463 return d_data->canvasRect;
00464 }
00465
00470 void QwtPlotLayout::invalidate()
00471 {
00472 d_data->titleRect = d_data->legendRect = d_data->canvasRect = QRect();
00473 for (int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00474 d_data->scaleRect[axis] = QRect();
00475 }
00476
00482 QSize QwtPlotLayout::minimumSizeHint(const QwtPlot *plot) const
00483 {
00484 class ScaleData
00485 {
00486 public:
00487 ScaleData()
00488 {
00489 w = h = minLeft = minRight = tickOffset = 0;
00490 }
00491
00492 int w;
00493 int h;
00494 int minLeft;
00495 int minRight;
00496 int tickOffset;
00497 } scaleData[QwtPlot::axisCnt];
00498
00499 int canvasBorder[QwtPlot::axisCnt];
00500
00501 int axis;
00502 for ( axis = 0; axis < QwtPlot::axisCnt; axis++ )
00503 {
00504 if ( plot->axisEnabled(axis) )
00505 {
00506 const QwtScaleWidget *scl = plot->axisWidget(axis);
00507 ScaleData &sd = scaleData[axis];
00508
00509 const QSize hint = scl->minimumSizeHint();
00510 sd.w = hint.width();
00511 sd.h = hint.height();
00512 scl->minBorderDist(sd.minLeft, sd.minRight);
00513 sd.tickOffset = scl->baseLineDist() +
00514 scl->scaleDraw()->majTickLength();
00515 }
00516
00517 canvasBorder[axis] = plot->canvas()->frameWidth() +
00518 d_data->canvasMargin[axis] + 1;
00519
00520 }
00521
00522
00523 for ( axis = 0; axis < QwtPlot::axisCnt; axis++ )
00524 {
00525 ScaleData &sd = scaleData[axis];
00526 if ( sd.w && (axis == QwtPlot::xBottom || axis == QwtPlot::xTop) )
00527 {
00528 if ( (sd.minLeft > canvasBorder[QwtPlot::yLeft])
00529 && scaleData[QwtPlot::yLeft].w )
00530 {
00531 int shiftLeft = sd.minLeft - canvasBorder[QwtPlot::yLeft];
00532 if ( shiftLeft > scaleData[QwtPlot::yLeft].w )
00533 shiftLeft = scaleData[QwtPlot::yLeft].w;
00534
00535 sd.w -= shiftLeft;
00536 }
00537 if ( (sd.minRight > canvasBorder[QwtPlot::yRight])
00538 && scaleData[QwtPlot::yRight].w )
00539 {
00540 int shiftRight = sd.minRight - canvasBorder[QwtPlot::yRight];
00541 if ( shiftRight > scaleData[QwtPlot::yRight].w )
00542 shiftRight = scaleData[QwtPlot::yRight].w;
00543
00544 sd.w -= shiftRight;
00545 }
00546 }
00547
00548 if ( sd.h && (axis == QwtPlot::yLeft || axis == QwtPlot::yRight) )
00549 {
00550 if ( (sd.minLeft > canvasBorder[QwtPlot::xBottom]) &&
00551 scaleData[QwtPlot::xBottom].h )
00552 {
00553 int shiftBottom = sd.minLeft - canvasBorder[QwtPlot::xBottom];
00554 if ( shiftBottom > scaleData[QwtPlot::xBottom].tickOffset )
00555 shiftBottom = scaleData[QwtPlot::xBottom].tickOffset;
00556
00557 sd.h -= shiftBottom;
00558 }
00559 if ( (sd.minLeft > canvasBorder[QwtPlot::xTop]) &&
00560 scaleData[QwtPlot::xTop].h )
00561 {
00562 int shiftTop = sd.minRight - canvasBorder[QwtPlot::xTop];
00563 if ( shiftTop > scaleData[QwtPlot::xTop].tickOffset )
00564 shiftTop = scaleData[QwtPlot::xTop].tickOffset;
00565
00566 sd.h -= shiftTop;
00567 }
00568 }
00569 }
00570
00571 const QwtPlotCanvas *canvas = plot->canvas();
00572
00573 int w = scaleData[QwtPlot::yLeft].w + scaleData[QwtPlot::yRight].w
00574 + qwtMax(scaleData[QwtPlot::xBottom].w, scaleData[QwtPlot::xTop].w)
00575 + 2 * (canvas->frameWidth() + 1);
00576 int h = scaleData[QwtPlot::xBottom].h + scaleData[QwtPlot::xTop].h
00577 + qwtMax(scaleData[QwtPlot::yLeft].h, scaleData[QwtPlot::yRight].h)
00578 + 2 * (canvas->frameWidth() + 1);
00579
00580 const QLabel *title = plot->titleLabel();
00581 if (title && !title->text().isEmpty())
00582 {
00583
00584
00585 const bool centerOnCanvas = !(plot->axisEnabled(QwtPlot::yLeft)
00586 && plot->axisEnabled(QwtPlot::yRight));
00587
00588 int titleW = w;
00589 if ( centerOnCanvas )
00590 {
00591 titleW -= scaleData[QwtPlot::yLeft].w
00592 + scaleData[QwtPlot::yRight].w;
00593 }
00594
00595 int titleH = title->heightForWidth(titleW);
00596 if ( titleH > titleW )
00597 {
00598 w = titleW = titleH;
00599 if ( centerOnCanvas )
00600 {
00601 w += scaleData[QwtPlot::yLeft].w
00602 + scaleData[QwtPlot::yRight].w;
00603 }
00604
00605 titleH = title->heightForWidth(titleW);
00606 }
00607 h += titleH + d_data->spacing;
00608 }
00609
00610
00611
00612 const QwtLegend *legend = plot->legend();
00613 if ( legend && !legend->isEmpty() )
00614 {
00615 if ( d_data->legendPos == QwtPlot::LeftLegend
00616 || d_data->legendPos == QwtPlot::RightLegend )
00617 {
00618 int legendW = legend->sizeHint().width();
00619 int legendH = legend->heightForWidth(legendW);
00620
00621 if ( legend->frameWidth() > 0 )
00622 w += d_data->spacing;
00623
00624 if ( legendH > h )
00625 legendW += legend->verticalScrollBar()->sizeHint().height();
00626
00627 if ( d_data->legendRatio < 1.0 )
00628 legendW = qwtMin(legendW, int(w / (1.0 - d_data->legendRatio)));
00629
00630 w += legendW;
00631 }
00632 else
00633 {
00634 int legendW = qwtMin(legend->sizeHint().width(), w);
00635 int legendH = legend->heightForWidth(legendW);
00636
00637 if ( legend->frameWidth() > 0 )
00638 h += d_data->spacing;
00639
00640 if ( d_data->legendRatio < 1.0 )
00641 legendH = qwtMin(legendH, int(h / (1.0 - d_data->legendRatio)));
00642
00643 h += legendH;
00644 }
00645 }
00646
00647 w += 2 * d_data->margin;
00648 h += 2 * d_data->margin;
00649
00650 return QSize( w, h );
00651 }
00652
00660 QRect QwtPlotLayout::layoutLegend(int options,
00661 const QRect &rect) const
00662 {
00663 const QSize hint(d_data->layoutData.legend.hint);
00664
00665 int dim;
00666 if ( d_data->legendPos == QwtPlot::LeftLegend
00667 || d_data->legendPos == QwtPlot::RightLegend )
00668 {
00669
00670
00671
00672 dim = qwtMin(hint.width(), int(rect.width() * d_data->legendRatio));
00673
00674 if ( !(options & IgnoreScrollbars) )
00675 {
00676 if ( hint.height() > rect.height() )
00677 {
00678
00679
00680
00681 dim += d_data->layoutData.legend.vScrollBarWidth;
00682 }
00683 }
00684 }
00685 else
00686 {
00687 dim = qwtMin(hint.height(), int(rect.height() * d_data->legendRatio));
00688 dim = qwtMax(dim, d_data->layoutData.legend.hScrollBarHeight);
00689 }
00690
00691 QRect legendRect = rect;
00692 switch(d_data->legendPos)
00693 {
00694 case QwtPlot::LeftLegend:
00695 legendRect.setWidth(dim);
00696 break;
00697 case QwtPlot::RightLegend:
00698 legendRect.setX(rect.right() - dim + 1);
00699 legendRect.setWidth(dim);
00700 break;
00701 case QwtPlot::TopLegend:
00702 legendRect.setHeight(dim);
00703 break;
00704 case QwtPlot::BottomLegend:
00705 legendRect.setY(rect.bottom() - dim + 1);
00706 legendRect.setHeight(dim);
00707 break;
00708 }
00709
00710 return legendRect;
00711 }
00712
00719 QRect QwtPlotLayout::alignLegend(const QRect &canvasRect,
00720 const QRect &legendRect) const
00721 {
00722 QRect alignedRect = legendRect;
00723
00724 if ( d_data->legendPos == QwtPlot::BottomLegend
00725 || d_data->legendPos == QwtPlot::TopLegend )
00726 {
00727 if ( d_data->layoutData.legend.hint.width() < canvasRect.width() )
00728 {
00729 alignedRect.setX(canvasRect.x());
00730 alignedRect.setWidth(canvasRect.width());
00731 }
00732 }
00733 else
00734 {
00735 if ( d_data->layoutData.legend.hint.height() < canvasRect.height() )
00736 {
00737 alignedRect.setY(canvasRect.y());
00738 alignedRect.setHeight(canvasRect.height());
00739 }
00740 }
00741
00742 return alignedRect;
00743 }
00744
00754 void QwtPlotLayout::expandLineBreaks(int options, const QRect &rect,
00755 int &dimTitle, int dimAxis[QwtPlot::axisCnt]) const
00756 {
00757 dimTitle = 0;
00758 for ( int i = 0; i < QwtPlot::axisCnt; i++ )
00759 dimAxis[i] = 0;
00760
00761 bool done = false;
00762 while (!done)
00763 {
00764 done = true;
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 if ( d_data->layoutData.title.text)
00775 {
00776 int w = rect.width();
00777
00778 if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled
00779 != d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
00780 {
00781
00782 w -= dimAxis[QwtPlot::yLeft] + dimAxis[QwtPlot::yRight];
00783 }
00784
00785 int d = d_data->layoutData.title.text->heightForWidth(w);
00786 if ( !(options & IgnoreFrames) )
00787 d += 2 * d_data->layoutData.title.frameWidth;
00788
00789 if ( d > dimTitle )
00790 {
00791 dimTitle = d;
00792 done = false;
00793 }
00794 }
00795
00796 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00797 {
00798 int backboneOffset = d_data->canvasMargin[axis];
00799 if ( !(options & IgnoreFrames) )
00800 backboneOffset += d_data->layoutData.canvas.frameWidth;
00801
00802 const struct LayoutData::t_scaleData &scaleData =
00803 d_data->layoutData.scale[axis];
00804
00805 if (scaleData.isEnabled)
00806 {
00807 int length;
00808 if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
00809 {
00810 length = rect.width() - dimAxis[QwtPlot::yLeft]
00811 - dimAxis[QwtPlot::yRight];
00812 length += qwtMin(dimAxis[QwtPlot::yLeft],
00813 scaleData.start - backboneOffset);
00814 length += qwtMin(dimAxis[QwtPlot::yRight],
00815 scaleData.end - backboneOffset);
00816 }
00817 else
00818 {
00819 length = rect.height() - dimAxis[QwtPlot::xTop]
00820 - dimAxis[QwtPlot::xBottom];
00821
00822 if ( dimAxis[QwtPlot::xBottom] > 0 )
00823 {
00824 length += qwtMin(
00825 d_data->layoutData.scale[QwtPlot::xBottom].tickOffset,
00826 scaleData.start - backboneOffset);
00827 }
00828 if ( dimAxis[QwtPlot::xTop] > 0 )
00829 {
00830 length += qwtMin(
00831 d_data->layoutData.scale[QwtPlot::xTop].tickOffset,
00832 scaleData.end - backboneOffset);
00833 }
00834
00835 if ( dimTitle > 0 )
00836 length -= dimTitle + d_data->spacing;
00837 }
00838
00839 int d = scaleData.dimWithoutTitle;
00840 if ( !scaleData.scaleWidget->title().isEmpty() )
00841 {
00842 d += scaleData.scaleWidget->titleHeightForWidth(length);
00843 }
00844
00845 if ( options & AlignScales )
00846 d -= scaleData.baseLineOffset;
00847
00848 if ( d > dimAxis[axis] )
00849 {
00850 dimAxis[axis] = d;
00851 done = false;
00852 }
00853 }
00854 }
00855 }
00856 }
00857
00863 void QwtPlotLayout::alignScales(int options,
00864 QRect &canvasRect, QRect scaleRect[QwtPlot::axisCnt]) const
00865 {
00866 int axis;
00867
00868 int backboneOffset[QwtPlot::axisCnt];
00869 for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
00870 {
00871 backboneOffset[axis] = 0;
00872 if ( !d_data->alignCanvasToScales )
00873 backboneOffset[axis] += d_data->canvasMargin[axis];
00874 if ( !(options & IgnoreFrames) )
00875 backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
00876 }
00877
00878 for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
00879 {
00880 if ( !scaleRect[axis].isValid() )
00881 continue;
00882
00883 const int startDist = d_data->layoutData.scale[axis].start;
00884 const int endDist = d_data->layoutData.scale[axis].end;
00885
00886 QRect &axisRect = scaleRect[axis];
00887
00888 if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
00889 {
00890 const int leftOffset = backboneOffset[QwtPlot::yLeft] - startDist;
00891
00892 if ( scaleRect[QwtPlot::yLeft].isValid() )
00893 {
00894 int minLeft = scaleRect[QwtPlot::yLeft].left();
00895 int left = axisRect.left() + leftOffset;
00896 axisRect.setLeft(qwtMax(left, minLeft));
00897 }
00898 else
00899 {
00900 if ( d_data->alignCanvasToScales )
00901 {
00902 canvasRect.setLeft(qwtMax(canvasRect.left(),
00903 axisRect.left() - leftOffset));
00904 }
00905 else
00906 {
00907 if ( leftOffset > 0 )
00908 axisRect.setLeft(axisRect.left() + leftOffset);
00909 }
00910 }
00911
00912 const int rightOffset = backboneOffset[QwtPlot::yRight] - endDist;
00913
00914 if ( scaleRect[QwtPlot::yRight].isValid() )
00915 {
00916 int maxRight = scaleRect[QwtPlot::yRight].right();
00917 int right = axisRect.right() - rightOffset;
00918 axisRect.setRight(qwtMin(right, maxRight));
00919 }
00920 else
00921 {
00922 if ( d_data->alignCanvasToScales )
00923 {
00924 canvasRect.setRight( qwtMin(canvasRect.right(),
00925 axisRect.right() + rightOffset) );
00926 }
00927 else
00928 {
00929 if ( rightOffset > 0 )
00930 axisRect.setRight(axisRect.right() - rightOffset);
00931 }
00932 }
00933 }
00934 else
00935 {
00936 const int bottomOffset =
00937 backboneOffset[QwtPlot::xBottom] - startDist;
00938
00939 if ( scaleRect[QwtPlot::xBottom].isValid() )
00940 {
00941 int maxBottom = scaleRect[QwtPlot::xBottom].top() +
00942 d_data->layoutData.scale[QwtPlot::xBottom].tickOffset;
00943
00944 int bottom = axisRect.bottom() - bottomOffset;
00945 axisRect.setBottom(qwtMin(bottom, maxBottom));
00946 }
00947 else
00948 {
00949 if ( d_data->alignCanvasToScales )
00950 {
00951 canvasRect.setBottom(qwtMin(canvasRect.bottom(),
00952 axisRect.bottom() + bottomOffset));
00953 }
00954 else
00955 {
00956 if ( bottomOffset > 0 )
00957 axisRect.setBottom(axisRect.bottom() - bottomOffset);
00958 }
00959 }
00960
00961 const int topOffset = backboneOffset[QwtPlot::xTop] - endDist;
00962
00963 if ( scaleRect[QwtPlot::xTop].isValid() )
00964 {
00965 int minTop = scaleRect[QwtPlot::xTop].bottom() -
00966 d_data->layoutData.scale[QwtPlot::xTop].tickOffset;
00967
00968 int top = axisRect.top() + topOffset;
00969 axisRect.setTop(qwtMax(top, minTop));
00970 }
00971 else
00972 {
00973 if ( d_data->alignCanvasToScales )
00974 {
00975 canvasRect.setTop(qwtMax(canvasRect.top(),
00976 axisRect.top() + - topOffset));
00977 }
00978 else
00979 {
00980 if ( topOffset > 0 )
00981 axisRect.setTop(axisRect.top() + topOffset);
00982 }
00983 }
00984 }
00985 }
00986 }
00987
01000 void QwtPlotLayout::activate(const QwtPlot *plot,
01001 const QRect &plotRect, int options)
01002 {
01003 invalidate();
01004
01005 QRect rect(plotRect);
01006
01007 if ( !(options & IgnoreMargin) )
01008 {
01009
01010
01011 rect.setRect(
01012 rect.x() + d_data->margin,
01013 rect.y() + d_data->margin,
01014 rect.width() - 2 * d_data->margin,
01015 rect.height() - 2 * d_data->margin
01016 );
01017 }
01018
01019
01020
01021
01022 d_data->layoutData.init(plot, rect);
01023
01024 if (!(options & IgnoreLegend)
01025 && plot->legend() && !plot->legend()->isEmpty() )
01026 {
01027 d_data->legendRect = layoutLegend(options, rect);
01028
01029
01030
01031 const QRegion region(rect);
01032 rect = region.subtract(d_data->legendRect).boundingRect();
01033
01034 if ( d_data->layoutData.legend.frameWidth &&
01035 !(options & IgnoreFrames ) )
01036 {
01037
01038
01039
01040
01041 switch(d_data->legendPos)
01042 {
01043 case QwtPlot::LeftLegend:
01044 rect.setLeft(rect.left() + d_data->spacing);
01045 break;
01046 case QwtPlot::RightLegend:
01047 rect.setRight(rect.right() - d_data->spacing);
01048 break;
01049 case QwtPlot::TopLegend:
01050 rect.setTop(rect.top() + d_data->spacing);
01051 break;
01052 case QwtPlot::BottomLegend:
01053 rect.setBottom(rect.bottom() - d_data->spacing);
01054 break;
01055 }
01056 }
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082 int dimTitle, dimAxes[QwtPlot::axisCnt];
01083 expandLineBreaks(options, rect, dimTitle, dimAxes);
01084
01085 if (dimTitle > 0 )
01086 {
01087 d_data->titleRect = QRect(rect.x(), rect.y(),
01088 rect.width(), dimTitle);
01089
01090 if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled !=
01091 d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
01092 {
01093
01094
01095
01096 d_data->titleRect.setX(rect.x() + dimAxes[QwtPlot::yLeft]);
01097 d_data->titleRect.setWidth(rect.width()
01098 - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight]);
01099 }
01100
01101
01102 rect.setTop(rect.top() + dimTitle + d_data->spacing);
01103 }
01104
01105 d_data->canvasRect.setRect(
01106 rect.x() + dimAxes[QwtPlot::yLeft],
01107 rect.y() + dimAxes[QwtPlot::xTop],
01108 rect.width() - dimAxes[QwtPlot::yRight] - dimAxes[QwtPlot::yLeft],
01109 rect.height() - dimAxes[QwtPlot::xBottom] - dimAxes[QwtPlot::xTop]);
01110
01111 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
01112 {
01113
01114
01115 if ( dimAxes[axis] )
01116 {
01117 int dim = dimAxes[axis];
01118 QRect &scaleRect = d_data->scaleRect[axis];
01119
01120 scaleRect = d_data->canvasRect;
01121 switch(axis)
01122 {
01123 case QwtPlot::yLeft:
01124 scaleRect.setX(d_data->canvasRect.left() - dim);
01125 scaleRect.setWidth(dim);
01126 break;
01127 case QwtPlot::yRight:
01128 scaleRect.setX(d_data->canvasRect.right() + 1);
01129 scaleRect.setWidth(dim);
01130 break;
01131 case QwtPlot::xBottom:
01132 scaleRect.setY(d_data->canvasRect.bottom() + 1);
01133 scaleRect.setHeight(dim);
01134 break;
01135 case QwtPlot::xTop:
01136 scaleRect.setY(d_data->canvasRect.top() - dim);
01137 scaleRect.setHeight(dim);
01138 break;
01139 }
01140 #if QT_VERSION < 0x040000
01141 scaleRect = scaleRect.normalize();
01142 #else
01143 scaleRect = scaleRect.normalized();
01144 #endif
01145 }
01146 }
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168 alignScales(options, d_data->canvasRect, d_data->scaleRect);
01169
01170 if (!d_data->legendRect.isEmpty() )
01171 {
01172
01173
01174
01175 d_data->legendRect = alignLegend(d_data->canvasRect, d_data->legendRect);
01176 }
01177 }