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