00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qscrollbar.h>
00013 #include "qwt_text.h"
00014 #include "qwt_text_label.h"
00015 #include "qwt_plot_canvas.h"
00016 #include "qwt_scale_widget.h"
00017 #include "qwt_legend.h"
00018 #include "qwt_plot_layout.h"
00019
00020 class QwtPlotLayout::LayoutData
00021 {
00022 public:
00023 void init(const QwtPlot *, const QRect &rect);
00024
00025 struct t_legendData
00026 {
00027 int frameWidth;
00028 int vScrollBarWidth;
00029 int hScrollBarHeight;
00030 QSize hint;
00031 } legend;
00032
00033 struct t_titleData
00034 {
00035 QwtText text;
00036 int frameWidth;
00037 } title;
00038
00039 struct t_scaleData
00040 {
00041 bool isEnabled;
00042 const QwtScaleWidget *scaleWidget;
00043 QFont scaleFont;
00044 int start;
00045 int end;
00046 int baseLineOffset;
00047 int tickOffset;
00048 int dimWithoutTitle;
00049 } scale[QwtPlot::axisCnt];
00050
00051 struct t_canvasData
00052 {
00053 int frameWidth;
00054 } canvas;
00055 };
00056
00057
00058
00059
00060
00061 void QwtPlotLayout::LayoutData::init(const QwtPlot *plot, const QRect &rect)
00062 {
00063
00064
00065 if ( plot->plotLayout()->legendPosition() != QwtPlot::ExternalLegend
00066 && 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 title.text = QwtText();
00091
00092 if (plot->titleLabel() )
00093 {
00094 const QwtTextLabel *label = plot->titleLabel();
00095 title.text = label->text();
00096 if ( !(title.text.testPaintAttribute(QwtText::PaintUsingTextFont)) )
00097 title.text.setFont(label->font());
00098
00099 title.frameWidth = plot->titleLabel()->frameWidth();
00100 }
00101
00102
00103
00104 for (int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00105 {
00106 if ( plot->axisEnabled(axis) )
00107 {
00108 const QwtScaleWidget *scaleWidget = plot->axisWidget(axis);
00109
00110 scale[axis].isEnabled = true;
00111
00112 scale[axis].scaleWidget = scaleWidget;
00113
00114 scale[axis].scaleFont = scaleWidget->font();
00115
00116 scale[axis].start = scaleWidget->startBorderDist();
00117 scale[axis].end = scaleWidget->endBorderDist();
00118
00119 scale[axis].baseLineOffset = scaleWidget->margin();
00120 scale[axis].tickOffset = scaleWidget->margin();
00121 if ( scaleWidget->scaleDraw()->hasComponent(
00122 QwtAbstractScaleDraw::Ticks) )
00123 {
00124 scale[axis].tickOffset +=
00125 (int)scaleWidget->scaleDraw()->majTickLength();
00126 }
00127
00128 scale[axis].dimWithoutTitle = scaleWidget->dimForLength(
00129 QWIDGETSIZE_MAX, scale[axis].scaleFont);
00130
00131 if ( !scaleWidget->title().isEmpty() )
00132 {
00133 scale[axis].dimWithoutTitle -=
00134 scaleWidget->titleHeightForWidth(QWIDGETSIZE_MAX);
00135 }
00136 }
00137 else
00138 {
00139 scale[axis].isEnabled = false;
00140 scale[axis].start = 0;
00141 scale[axis].end = 0;
00142 scale[axis].baseLineOffset = 0;
00143 scale[axis].tickOffset = 0;
00144 scale[axis].dimWithoutTitle = 0;
00145 }
00146 }
00147
00148
00149
00150 canvas.frameWidth = plot->canvas()->frameWidth();
00151 }
00152
00153 class QwtPlotLayout::PrivateData
00154 {
00155 public:
00156 PrivateData():
00157 margin(0),
00158 spacing(5),
00159 alignCanvasToScales(false)
00160 {
00161 }
00162
00163 QRect titleRect;
00164 QRect legendRect;
00165 QRect scaleRect[QwtPlot::axisCnt];
00166 QRect canvasRect;
00167
00168 QwtPlotLayout::LayoutData layoutData;
00169
00170 QwtPlot::LegendPosition legendPos;
00171 double legendRatio;
00172 unsigned int margin;
00173 unsigned int spacing;
00174 unsigned int canvasMargin[QwtPlot::axisCnt];
00175 bool alignCanvasToScales;
00176 };
00177
00182 QwtPlotLayout::QwtPlotLayout()
00183 {
00184 d_data = new PrivateData;
00185
00186 setLegendPosition(QwtPlot::BottomLegend);
00187 setCanvasMargin(4);
00188
00189 invalidate();
00190 }
00191
00193 QwtPlotLayout::~QwtPlotLayout()
00194 {
00195 delete d_data;
00196 }
00197
00206 void QwtPlotLayout::setMargin(int margin)
00207 {
00208 if ( margin < 0 )
00209 margin = 0;
00210 d_data->margin = margin;
00211 }
00212
00217 int QwtPlotLayout::margin() const
00218 {
00219 return d_data->margin;
00220 }
00221
00235 void QwtPlotLayout::setCanvasMargin(int margin, int axis)
00236 {
00237 if ( margin < -1 )
00238 margin = -1;
00239
00240 if ( axis == -1 )
00241 {
00242 for (axis = 0; axis < QwtPlot::axisCnt; axis++)
00243 d_data->canvasMargin[axis] = margin;
00244 }
00245 else if ( axis >= 0 && axis < QwtPlot::axisCnt )
00246 d_data->canvasMargin[axis] = margin;
00247 }
00248
00253 int QwtPlotLayout::canvasMargin(int axis) const
00254 {
00255 if ( axis < 0 || axis >= QwtPlot::axisCnt )
00256 return 0;
00257
00258 return d_data->canvasMargin[axis];
00259 }
00260
00273 void QwtPlotLayout::setAlignCanvasToScales(bool alignCanvasToScales)
00274 {
00275 d_data->alignCanvasToScales = alignCanvasToScales;
00276 }
00277
00287 bool QwtPlotLayout::alignCanvasToScales() const
00288 {
00289 return d_data->alignCanvasToScales;
00290 }
00291
00299 void QwtPlotLayout::setSpacing(int spacing)
00300 {
00301 d_data->spacing = qwtMax(0, spacing);
00302 }
00303
00308 int QwtPlotLayout::spacing() const
00309 {
00310 return d_data->spacing;
00311 }
00312
00326 void QwtPlotLayout::setLegendPosition(QwtPlot::LegendPosition pos, double ratio)
00327 {
00328 if ( ratio > 1.0 )
00329 ratio = 1.0;
00330
00331 switch(pos)
00332 {
00333 case QwtPlot::TopLegend:
00334 case QwtPlot::BottomLegend:
00335 if ( ratio <= 0.0 )
00336 ratio = 0.33;
00337 d_data->legendRatio = ratio;
00338 d_data->legendPos = pos;
00339 break;
00340 case QwtPlot::LeftLegend:
00341 case QwtPlot::RightLegend:
00342 if ( ratio <= 0.0 )
00343 ratio = 0.5;
00344 d_data->legendRatio = ratio;
00345 d_data->legendPos = pos;
00346 break;
00347 case QwtPlot::ExternalLegend:
00348 d_data->legendRatio = ratio;
00349 d_data->legendPos = pos;
00350 default:
00351 break;
00352 }
00353 }
00354
00363 void QwtPlotLayout::setLegendPosition(QwtPlot::LegendPosition pos)
00364 {
00365 setLegendPosition(pos, 0.0);
00366 }
00367
00373 QwtPlot::LegendPosition QwtPlotLayout::legendPosition() const
00374 {
00375 return d_data->legendPos;
00376 }
00377
00387 void QwtPlotLayout::setLegendRatio(double ratio)
00388 {
00389 setLegendPosition(legendPosition(), ratio);
00390 }
00391
00396 double QwtPlotLayout::legendRatio() const
00397 {
00398 return d_data->legendRatio;
00399 }
00400
00406 const QRect &QwtPlotLayout::titleRect() const
00407 {
00408 return d_data->titleRect;
00409 }
00410
00416 const QRect &QwtPlotLayout::legendRect() const
00417 {
00418 return d_data->legendRect;
00419 }
00420
00427 const QRect &QwtPlotLayout::scaleRect(int axis) const
00428 {
00429 if ( axis < 0 || axis >= QwtPlot::axisCnt )
00430 {
00431 static QRect dummyRect;
00432 return dummyRect;
00433 }
00434 return d_data->scaleRect[axis];
00435 }
00436
00442 const QRect &QwtPlotLayout::canvasRect() const
00443 {
00444 return d_data->canvasRect;
00445 }
00446
00451 void QwtPlotLayout::invalidate()
00452 {
00453 d_data->titleRect = d_data->legendRect = d_data->canvasRect = QRect();
00454 for (int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00455 d_data->scaleRect[axis] = QRect();
00456 }
00457
00463 QSize QwtPlotLayout::minimumSizeHint(const QwtPlot *plot) const
00464 {
00465 class ScaleData
00466 {
00467 public:
00468 ScaleData()
00469 {
00470 w = h = minLeft = minRight = tickOffset = 0;
00471 }
00472
00473 int w;
00474 int h;
00475 int minLeft;
00476 int minRight;
00477 int tickOffset;
00478 } scaleData[QwtPlot::axisCnt];
00479
00480 int canvasBorder[QwtPlot::axisCnt];
00481
00482 int axis;
00483 for ( axis = 0; axis < QwtPlot::axisCnt; axis++ )
00484 {
00485 if ( plot->axisEnabled(axis) )
00486 {
00487 const QwtScaleWidget *scl = plot->axisWidget(axis);
00488 ScaleData &sd = scaleData[axis];
00489
00490 const QSize hint = scl->minimumSizeHint();
00491 sd.w = hint.width();
00492 sd.h = hint.height();
00493 scl->getBorderDistHint(sd.minLeft, sd.minRight);
00494 sd.tickOffset = scl->margin();
00495 if ( scl->scaleDraw()->hasComponent(QwtAbstractScaleDraw::Ticks) )
00496 sd.tickOffset += scl->scaleDraw()->majTickLength();
00497 }
00498
00499 canvasBorder[axis] = plot->canvas()->frameWidth() +
00500 d_data->canvasMargin[axis] + 1;
00501
00502 }
00503
00504
00505 for ( axis = 0; axis < QwtPlot::axisCnt; axis++ )
00506 {
00507 ScaleData &sd = scaleData[axis];
00508 if ( sd.w && (axis == QwtPlot::xBottom || axis == QwtPlot::xTop) )
00509 {
00510 if ( (sd.minLeft > canvasBorder[QwtPlot::yLeft])
00511 && scaleData[QwtPlot::yLeft].w )
00512 {
00513 int shiftLeft = sd.minLeft - canvasBorder[QwtPlot::yLeft];
00514 if ( shiftLeft > scaleData[QwtPlot::yLeft].w )
00515 shiftLeft = scaleData[QwtPlot::yLeft].w;
00516
00517 sd.w -= shiftLeft;
00518 }
00519 if ( (sd.minRight > canvasBorder[QwtPlot::yRight])
00520 && scaleData[QwtPlot::yRight].w )
00521 {
00522 int shiftRight = sd.minRight - canvasBorder[QwtPlot::yRight];
00523 if ( shiftRight > scaleData[QwtPlot::yRight].w )
00524 shiftRight = scaleData[QwtPlot::yRight].w;
00525
00526 sd.w -= shiftRight;
00527 }
00528 }
00529
00530 if ( sd.h && (axis == QwtPlot::yLeft || axis == QwtPlot::yRight) )
00531 {
00532 if ( (sd.minLeft > canvasBorder[QwtPlot::xBottom]) &&
00533 scaleData[QwtPlot::xBottom].h )
00534 {
00535 int shiftBottom = sd.minLeft - canvasBorder[QwtPlot::xBottom];
00536 if ( shiftBottom > scaleData[QwtPlot::xBottom].tickOffset )
00537 shiftBottom = scaleData[QwtPlot::xBottom].tickOffset;
00538
00539 sd.h -= shiftBottom;
00540 }
00541 if ( (sd.minLeft > canvasBorder[QwtPlot::xTop]) &&
00542 scaleData[QwtPlot::xTop].h )
00543 {
00544 int shiftTop = sd.minRight - canvasBorder[QwtPlot::xTop];
00545 if ( shiftTop > scaleData[QwtPlot::xTop].tickOffset )
00546 shiftTop = scaleData[QwtPlot::xTop].tickOffset;
00547
00548 sd.h -= shiftTop;
00549 }
00550 }
00551 }
00552
00553 const QwtPlotCanvas *canvas = plot->canvas();
00554 const QSize minCanvasSize = canvas->minimumSize();
00555
00556 int w = scaleData[QwtPlot::yLeft].w + scaleData[QwtPlot::yRight].w;
00557 int cw = qwtMax(scaleData[QwtPlot::xBottom].w, scaleData[QwtPlot::xTop].w)
00558 + 2 * (canvas->frameWidth() + 1);
00559 w += qwtMax(cw, minCanvasSize.width());
00560
00561 int h = scaleData[QwtPlot::xBottom].h + scaleData[QwtPlot::xTop].h;
00562 int ch = qwtMax(scaleData[QwtPlot::yLeft].h, scaleData[QwtPlot::yRight].h)
00563 + 2 * (canvas->frameWidth() + 1);
00564 h += qwtMax(ch, minCanvasSize.height());
00565
00566 const QwtTextLabel *title = plot->titleLabel();
00567 if (title && !title->text().isEmpty())
00568 {
00569
00570
00571 const bool centerOnCanvas = !(plot->axisEnabled(QwtPlot::yLeft)
00572 && plot->axisEnabled(QwtPlot::yRight));
00573
00574 int titleW = w;
00575 if ( centerOnCanvas )
00576 {
00577 titleW -= scaleData[QwtPlot::yLeft].w
00578 + scaleData[QwtPlot::yRight].w;
00579 }
00580
00581 int titleH = title->heightForWidth(titleW);
00582 if ( titleH > titleW )
00583 {
00584 w = titleW = titleH;
00585 if ( centerOnCanvas )
00586 {
00587 w += scaleData[QwtPlot::yLeft].w
00588 + scaleData[QwtPlot::yRight].w;
00589 }
00590
00591 titleH = title->heightForWidth(titleW);
00592 }
00593 h += titleH + d_data->spacing;
00594 }
00595
00596
00597
00598 const QwtLegend *legend = plot->legend();
00599 if ( d_data->legendPos != QwtPlot::ExternalLegend
00600 && legend && !legend->isEmpty() )
00601 {
00602 if ( d_data->legendPos == QwtPlot::LeftLegend
00603 || d_data->legendPos == QwtPlot::RightLegend )
00604 {
00605 int legendW = legend->sizeHint().width();
00606 int legendH = legend->heightForWidth(legendW);
00607
00608 if ( legend->frameWidth() > 0 )
00609 w += d_data->spacing;
00610
00611 if ( legendH > h )
00612 legendW += legend->verticalScrollBar()->sizeHint().height();
00613
00614 if ( d_data->legendRatio < 1.0 )
00615 legendW = qwtMin(legendW, int(w / (1.0 - d_data->legendRatio)));
00616
00617 w += legendW;
00618 }
00619 else
00620 {
00621 int legendW = qwtMin(legend->sizeHint().width(), w);
00622 int legendH = legend->heightForWidth(legendW);
00623
00624 if ( legend->frameWidth() > 0 )
00625 h += d_data->spacing;
00626
00627 if ( d_data->legendRatio < 1.0 )
00628 legendH = qwtMin(legendH, int(h / (1.0 - d_data->legendRatio)));
00629
00630 h += legendH;
00631 }
00632 }
00633
00634 w += 2 * d_data->margin;
00635 h += 2 * d_data->margin;
00636
00637 return QSize( w, h );
00638 }
00639
00647 QRect QwtPlotLayout::layoutLegend(int options,
00648 const QRect &rect) const
00649 {
00650 const QSize hint(d_data->layoutData.legend.hint);
00651
00652 int dim;
00653 if ( d_data->legendPos == QwtPlot::LeftLegend
00654 || d_data->legendPos == QwtPlot::RightLegend )
00655 {
00656
00657
00658
00659 dim = qwtMin(hint.width(), int(rect.width() * d_data->legendRatio));
00660
00661 if ( !(options & IgnoreScrollbars) )
00662 {
00663 if ( hint.height() > rect.height() )
00664 {
00665
00666
00667
00668 dim += d_data->layoutData.legend.vScrollBarWidth;
00669 }
00670 }
00671 }
00672 else
00673 {
00674 dim = qwtMin(hint.height(), int(rect.height() * d_data->legendRatio));
00675 dim = qwtMax(dim, d_data->layoutData.legend.hScrollBarHeight);
00676 }
00677
00678 QRect legendRect = rect;
00679 switch(d_data->legendPos)
00680 {
00681 case QwtPlot::LeftLegend:
00682 legendRect.setWidth(dim);
00683 break;
00684 case QwtPlot::RightLegend:
00685 legendRect.setX(rect.right() - dim + 1);
00686 legendRect.setWidth(dim);
00687 break;
00688 case QwtPlot::TopLegend:
00689 legendRect.setHeight(dim);
00690 break;
00691 case QwtPlot::BottomLegend:
00692 legendRect.setY(rect.bottom() - dim + 1);
00693 legendRect.setHeight(dim);
00694 break;
00695 case QwtPlot::ExternalLegend:
00696 break;
00697 }
00698
00699 return legendRect;
00700 }
00701
00708 QRect QwtPlotLayout::alignLegend(const QRect &canvasRect,
00709 const QRect &legendRect) const
00710 {
00711 QRect alignedRect = legendRect;
00712
00713 if ( d_data->legendPos == QwtPlot::BottomLegend
00714 || d_data->legendPos == QwtPlot::TopLegend )
00715 {
00716 if ( d_data->layoutData.legend.hint.width() < canvasRect.width() )
00717 {
00718 alignedRect.setX(canvasRect.x());
00719 alignedRect.setWidth(canvasRect.width());
00720 }
00721 }
00722 else
00723 {
00724 if ( d_data->layoutData.legend.hint.height() < canvasRect.height() )
00725 {
00726 alignedRect.setY(canvasRect.y());
00727 alignedRect.setHeight(canvasRect.height());
00728 }
00729 }
00730
00731 return alignedRect;
00732 }
00733
00743 void QwtPlotLayout::expandLineBreaks(int options, const QRect &rect,
00744 int &dimTitle, int dimAxis[QwtPlot::axisCnt]) const
00745 {
00746 dimTitle = 0;
00747 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00748 dimAxis[axis] = 0;
00749
00750 int backboneOffset[QwtPlot::axisCnt];
00751 for (int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00752 {
00753 backboneOffset[axis] = 0;
00754 if ( !d_data->alignCanvasToScales )
00755 backboneOffset[axis] += d_data->canvasMargin[axis];
00756 if ( !(options & IgnoreFrames) )
00757 backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
00758 }
00759
00760 bool done = false;
00761 while (!done)
00762 {
00763 done = true;
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773 if ( !d_data->layoutData.title.text.isEmpty() )
00774 {
00775 int w = rect.width();
00776
00777 if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled
00778 != d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
00779 {
00780
00781 w -= dimAxis[QwtPlot::yLeft] + dimAxis[QwtPlot::yRight];
00782 }
00783
00784 int d = d_data->layoutData.title.text.heightForWidth(w);
00785 if ( !(options & IgnoreFrames) )
00786 d += 2 * d_data->layoutData.title.frameWidth;
00787
00788 if ( d > dimTitle )
00789 {
00790 dimTitle = d;
00791 done = false;
00792 }
00793 }
00794
00795 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00796 {
00797 const struct LayoutData::t_scaleData &scaleData =
00798 d_data->layoutData.scale[axis];
00799
00800 if (scaleData.isEnabled)
00801 {
00802 int length;
00803 if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
00804 {
00805 length = rect.width() - dimAxis[QwtPlot::yLeft]
00806 - dimAxis[QwtPlot::yRight];
00807 length -= scaleData.start + scaleData.end;
00808
00809 if ( dimAxis[QwtPlot::yRight] > 0 )
00810 length -= 1;
00811
00812 length += qwtMin(dimAxis[QwtPlot::yLeft],
00813 scaleData.start - backboneOffset[QwtPlot::yLeft]);
00814 length += qwtMin(dimAxis[QwtPlot::yRight],
00815 scaleData.end - backboneOffset[QwtPlot::yRight]);
00816 }
00817 else
00818 {
00819 length = rect.height() - dimAxis[QwtPlot::xTop]
00820 - dimAxis[QwtPlot::xBottom];
00821 length -= scaleData.start + scaleData.end;
00822 length -= 1;
00823
00824 if ( dimAxis[QwtPlot::xBottom] <= 0 )
00825 length -= 1;
00826 if ( dimAxis[QwtPlot::xTop] <= 0 )
00827 length -= 1;
00828
00829 if ( dimAxis[QwtPlot::xBottom] > 0 )
00830 {
00831 length += qwtMin(
00832 d_data->layoutData.scale[QwtPlot::xBottom].tickOffset,
00833 scaleData.start - backboneOffset[QwtPlot::xBottom]);
00834 }
00835 if ( dimAxis[QwtPlot::xTop] > 0 )
00836 {
00837 length += qwtMin(
00838 d_data->layoutData.scale[QwtPlot::xTop].tickOffset,
00839 scaleData.end - backboneOffset[QwtPlot::xTop]);
00840 }
00841
00842 if ( dimTitle > 0 )
00843 length -= dimTitle + d_data->spacing;
00844 }
00845
00846 int d = scaleData.dimWithoutTitle;
00847 if ( !scaleData.scaleWidget->title().isEmpty() )
00848 {
00849 d += scaleData.scaleWidget->titleHeightForWidth(length);
00850 }
00851
00852
00853 if ( d > dimAxis[axis] )
00854 {
00855 dimAxis[axis] = d;
00856 done = false;
00857 }
00858 }
00859 }
00860 }
00861 }
00862
00868 void QwtPlotLayout::alignScales(int options,
00869 QRect &canvasRect, QRect scaleRect[QwtPlot::axisCnt]) const
00870 {
00871 int axis;
00872
00873 int backboneOffset[QwtPlot::axisCnt];
00874 for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
00875 {
00876 backboneOffset[axis] = 0;
00877 if ( !d_data->alignCanvasToScales )
00878 backboneOffset[axis] += d_data->canvasMargin[axis];
00879 if ( !(options & IgnoreFrames) )
00880 backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
00881 }
00882
00883 for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
00884 {
00885 if ( !scaleRect[axis].isValid() )
00886 continue;
00887
00888 const int startDist = d_data->layoutData.scale[axis].start;
00889 const int endDist = d_data->layoutData.scale[axis].end;
00890
00891 QRect &axisRect = scaleRect[axis];
00892
00893 if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
00894 {
00895 const int leftOffset =
00896 backboneOffset[QwtPlot::yLeft] - startDist;
00897
00898 if ( scaleRect[QwtPlot::yLeft].isValid() )
00899 {
00900 int minLeft = scaleRect[QwtPlot::yLeft].left();
00901 int left = axisRect.left() + leftOffset;
00902 axisRect.setLeft(qwtMax(left, minLeft));
00903 }
00904 else
00905 {
00906 if ( d_data->alignCanvasToScales && leftOffset < 0 )
00907 {
00908 canvasRect.setLeft(qwtMax(canvasRect.left(),
00909 axisRect.left() - leftOffset));
00910 }
00911 else
00912 {
00913 if ( leftOffset > 0 )
00914 axisRect.setLeft(axisRect.left() + leftOffset);
00915 }
00916 }
00917
00918 const int rightOffset =
00919 backboneOffset[QwtPlot::yRight] - endDist + 1;
00920
00921 if ( scaleRect[QwtPlot::yRight].isValid() )
00922 {
00923 int maxRight = scaleRect[QwtPlot::yRight].right();
00924 int right = axisRect.right() - rightOffset;
00925 axisRect.setRight(qwtMin(right, maxRight));
00926 }
00927 else
00928 {
00929 if ( d_data->alignCanvasToScales && rightOffset < 0 )
00930 {
00931 canvasRect.setRight( qwtMin(canvasRect.right(),
00932 axisRect.right() + rightOffset) );
00933 }
00934 else
00935 {
00936 if ( rightOffset > 0 )
00937 axisRect.setRight(axisRect.right() - rightOffset);
00938 }
00939 }
00940 }
00941 else
00942 {
00943 const int bottomOffset =
00944 backboneOffset[QwtPlot::xBottom] - endDist + 1;
00945
00946 if ( scaleRect[QwtPlot::xBottom].isValid() )
00947 {
00948 int maxBottom = scaleRect[QwtPlot::xBottom].top() +
00949 d_data->layoutData.scale[QwtPlot::xBottom].tickOffset;
00950
00951 int bottom = axisRect.bottom() - bottomOffset;
00952 axisRect.setBottom(qwtMin(bottom, maxBottom));
00953 }
00954 else
00955 {
00956 if ( d_data->alignCanvasToScales && bottomOffset < 0 )
00957 {
00958 canvasRect.setBottom(qwtMin(canvasRect.bottom(),
00959 axisRect.bottom() + bottomOffset));
00960 }
00961 else
00962 {
00963 if ( bottomOffset > 0 )
00964 axisRect.setBottom(axisRect.bottom() - bottomOffset);
00965 }
00966 }
00967
00968 const int topOffset = backboneOffset[QwtPlot::xTop] - startDist;
00969
00970 if ( scaleRect[QwtPlot::xTop].isValid() )
00971 {
00972 int minTop = scaleRect[QwtPlot::xTop].bottom() -
00973 d_data->layoutData.scale[QwtPlot::xTop].tickOffset;
00974
00975 int top = axisRect.top() + topOffset;
00976 axisRect.setTop(qwtMax(top, minTop));
00977 }
00978 else
00979 {
00980 if ( d_data->alignCanvasToScales && topOffset < 0 )
00981 {
00982 canvasRect.setTop(qwtMax(canvasRect.top(),
00983 axisRect.top() - topOffset));
00984 }
00985 else
00986 {
00987 if ( topOffset > 0 )
00988 axisRect.setTop(axisRect.top() + topOffset);
00989 }
00990 }
00991 }
00992 }
00993
00994 if ( d_data->alignCanvasToScales )
00995 {
00996
00997
00998
00999
01000
01001 int fw = 0;
01002 if ( !(options & IgnoreFrames) )
01003 fw = d_data->layoutData.canvas.frameWidth;
01004
01005 if ( scaleRect[QwtPlot::xBottom].isValid() &&
01006 scaleRect[QwtPlot::xTop].isValid() )
01007 {
01008 for ( int axis = QwtPlot::xBottom; axis <= QwtPlot::xTop; axis++ )
01009 {
01010 scaleRect[axis].setLeft(canvasRect.left() + fw
01011 - d_data->layoutData.scale[axis].start);
01012 scaleRect[axis].setRight(canvasRect.right() - fw - 1
01013 + d_data->layoutData.scale[axis].end);
01014 }
01015 }
01016
01017 if ( scaleRect[QwtPlot::yLeft].isValid() &&
01018 scaleRect[QwtPlot::yRight].isValid() )
01019 {
01020 for ( int axis = QwtPlot::yLeft; axis <= QwtPlot::yRight; axis++ )
01021 {
01022 scaleRect[axis].setTop(canvasRect.top() + fw
01023 - d_data->layoutData.scale[axis].start);
01024 scaleRect[axis].setBottom(canvasRect.bottom() - fw - 1
01025 + d_data->layoutData.scale[axis].end);
01026 }
01027 }
01028 }
01029 }
01030
01041 void QwtPlotLayout::activate(const QwtPlot *plot,
01042 const QRect &plotRect, int options)
01043 {
01044 invalidate();
01045
01046 QRect rect(plotRect);
01047
01048 if ( !(options & IgnoreMargin) )
01049 {
01050
01051
01052 rect.setRect(
01053 rect.x() + d_data->margin,
01054 rect.y() + d_data->margin,
01055 rect.width() - 2 * d_data->margin,
01056 rect.height() - 2 * d_data->margin
01057 );
01058 }
01059
01060
01061
01062
01063 d_data->layoutData.init(plot, rect);
01064
01065 if (!(options & IgnoreLegend)
01066 && d_data->legendPos != QwtPlot::ExternalLegend
01067 && plot->legend() && !plot->legend()->isEmpty() )
01068 {
01069 d_data->legendRect = layoutLegend(options, rect);
01070
01071
01072
01073 const QRegion region(rect);
01074 rect = region.subtract(d_data->legendRect).boundingRect();
01075
01076 if ( d_data->layoutData.legend.frameWidth &&
01077 !(options & IgnoreFrames ) )
01078 {
01079
01080
01081
01082
01083 switch(d_data->legendPos)
01084 {
01085 case QwtPlot::LeftLegend:
01086 rect.setLeft(rect.left() + d_data->spacing);
01087 break;
01088 case QwtPlot::RightLegend:
01089 rect.setRight(rect.right() - d_data->spacing);
01090 break;
01091 case QwtPlot::TopLegend:
01092 rect.setTop(rect.top() + d_data->spacing);
01093 break;
01094 case QwtPlot::BottomLegend:
01095 rect.setBottom(rect.bottom() - d_data->spacing);
01096 break;
01097 case QwtPlot::ExternalLegend:
01098 break;
01099 }
01100 }
01101 }
01102
01103 #ifdef __GNUC__
01104 #endif
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127 int dimTitle, dimAxes[QwtPlot::axisCnt];
01128 expandLineBreaks(options, rect, dimTitle, dimAxes);
01129
01130 if (dimTitle > 0 )
01131 {
01132 d_data->titleRect = QRect(rect.x(), rect.y(),
01133 rect.width(), dimTitle);
01134
01135 if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled !=
01136 d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
01137 {
01138
01139
01140
01141 d_data->titleRect.setX(rect.x() + dimAxes[QwtPlot::yLeft]);
01142 d_data->titleRect.setWidth(rect.width()
01143 - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight]);
01144 }
01145
01146
01147 rect.setTop(rect.top() + dimTitle + d_data->spacing);
01148 }
01149
01150 d_data->canvasRect.setRect(
01151 rect.x() + dimAxes[QwtPlot::yLeft],
01152 rect.y() + dimAxes[QwtPlot::xTop],
01153 rect.width() - dimAxes[QwtPlot::yRight] - dimAxes[QwtPlot::yLeft],
01154 rect.height() - dimAxes[QwtPlot::xBottom] - dimAxes[QwtPlot::xTop]);
01155
01156 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
01157 {
01158
01159
01160 if ( dimAxes[axis] )
01161 {
01162 int dim = dimAxes[axis];
01163 QRect &scaleRect = d_data->scaleRect[axis];
01164
01165 scaleRect = d_data->canvasRect;
01166 switch(axis)
01167 {
01168 case QwtPlot::yLeft:
01169 scaleRect.setX(d_data->canvasRect.left() - dim);
01170 scaleRect.setWidth(dim);
01171 break;
01172 case QwtPlot::yRight:
01173 scaleRect.setX(d_data->canvasRect.right() + 1);
01174 scaleRect.setWidth(dim);
01175 break;
01176 case QwtPlot::xBottom:
01177 scaleRect.setY(d_data->canvasRect.bottom() + 1);
01178 scaleRect.setHeight(dim);
01179 break;
01180 case QwtPlot::xTop:
01181 scaleRect.setY(d_data->canvasRect.top() - dim);
01182 scaleRect.setHeight(dim);
01183 break;
01184 }
01185 #if QT_VERSION < 0x040000
01186 scaleRect = scaleRect.normalize();
01187 #else
01188 scaleRect = scaleRect.normalized();
01189 #endif
01190 }
01191 }
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213 alignScales(options, d_data->canvasRect, d_data->scaleRect);
01214
01215 if (!d_data->legendRect.isEmpty() )
01216 {
01217
01218
01219
01220 d_data->legendRect = alignLegend(d_data->canvasRect, d_data->legendRect);
01221 }
01222 }