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 i = 0; i < QwtPlot::axisCnt; i++ )
00748 dimAxis[i] = 0;
00749
00750 bool done = false;
00751 while (!done)
00752 {
00753 done = true;
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 if ( !d_data->layoutData.title.text.isEmpty() )
00764 {
00765 int w = rect.width();
00766
00767 if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled
00768 != d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
00769 {
00770
00771 w -= dimAxis[QwtPlot::yLeft] + dimAxis[QwtPlot::yRight];
00772 }
00773
00774 int d = d_data->layoutData.title.text.heightForWidth(w);
00775 if ( !(options & IgnoreFrames) )
00776 d += 2 * d_data->layoutData.title.frameWidth;
00777
00778 if ( d > dimTitle )
00779 {
00780 dimTitle = d;
00781 done = false;
00782 }
00783 }
00784
00785 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00786 {
00787 int backboneOffset = d_data->canvasMargin[axis];
00788 if ( !(options & IgnoreFrames) )
00789 backboneOffset += d_data->layoutData.canvas.frameWidth;
00790
00791 const struct LayoutData::t_scaleData &scaleData =
00792 d_data->layoutData.scale[axis];
00793
00794 if (scaleData.isEnabled)
00795 {
00796 int length;
00797 if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
00798 {
00799 length = rect.width() - dimAxis[QwtPlot::yLeft]
00800 - dimAxis[QwtPlot::yRight];
00801 length += qwtMin(dimAxis[QwtPlot::yLeft],
00802 scaleData.start - backboneOffset);
00803 length += qwtMin(dimAxis[QwtPlot::yRight],
00804 scaleData.end - backboneOffset);
00805 }
00806 else
00807 {
00808 length = rect.height() - dimAxis[QwtPlot::xTop]
00809 - dimAxis[QwtPlot::xBottom];
00810
00811 if ( dimAxis[QwtPlot::xBottom] > 0 )
00812 {
00813 length += qwtMin(
00814 d_data->layoutData.scale[QwtPlot::xBottom].tickOffset,
00815 scaleData.start - backboneOffset);
00816 }
00817 if ( dimAxis[QwtPlot::xTop] > 0 )
00818 {
00819 length += qwtMin(
00820 d_data->layoutData.scale[QwtPlot::xTop].tickOffset,
00821 scaleData.end - backboneOffset);
00822 }
00823
00824 if ( dimTitle > 0 )
00825 length -= dimTitle + d_data->spacing;
00826 }
00827
00828 int d = scaleData.dimWithoutTitle;
00829 if ( !scaleData.scaleWidget->title().isEmpty() )
00830 {
00831 d += scaleData.scaleWidget->titleHeightForWidth(length);
00832 }
00833
00834 if ( d > dimAxis[axis] )
00835 {
00836 dimAxis[axis] = d;
00837 done = false;
00838 }
00839 }
00840 }
00841 }
00842 }
00843
00849 void QwtPlotLayout::alignScales(int options,
00850 QRect &canvasRect, QRect scaleRect[QwtPlot::axisCnt]) const
00851 {
00852 int axis;
00853
00854 int backboneOffset[QwtPlot::axisCnt];
00855 for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
00856 {
00857 backboneOffset[axis] = 0;
00858 if ( !d_data->alignCanvasToScales )
00859 backboneOffset[axis] += d_data->canvasMargin[axis];
00860 if ( !(options & IgnoreFrames) )
00861 backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
00862 }
00863
00864 for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
00865 {
00866 if ( !scaleRect[axis].isValid() )
00867 continue;
00868
00869 const int startDist = d_data->layoutData.scale[axis].start;
00870 const int endDist = d_data->layoutData.scale[axis].end;
00871
00872 QRect &axisRect = scaleRect[axis];
00873
00874 if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
00875 {
00876 const int leftOffset =
00877 backboneOffset[QwtPlot::yLeft] - startDist;
00878
00879 if ( scaleRect[QwtPlot::yLeft].isValid() )
00880 {
00881 int minLeft = scaleRect[QwtPlot::yLeft].left();
00882 int left = axisRect.left() + leftOffset;
00883 axisRect.setLeft(qwtMax(left, minLeft));
00884 }
00885 else
00886 {
00887 if ( d_data->alignCanvasToScales && leftOffset < 0 )
00888 {
00889 canvasRect.setLeft(qwtMax(canvasRect.left(),
00890 axisRect.left() - leftOffset));
00891 }
00892 else
00893 {
00894 if ( leftOffset > 0 )
00895 axisRect.setLeft(axisRect.left() + leftOffset);
00896 }
00897 }
00898
00899 const int rightOffset =
00900 backboneOffset[QwtPlot::yRight] - endDist + 1;
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 && rightOffset < 0 )
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] - endDist + 1;
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 && bottomOffset < 0 )
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] - startDist;
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 && topOffset < 0 )
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 if ( d_data->alignCanvasToScales )
00976 {
00977
00978
00979
00980
00981
00982 int fw = 0;
00983 if ( !(options & IgnoreFrames) )
00984 fw = d_data->layoutData.canvas.frameWidth;
00985
00986 if ( scaleRect[QwtPlot::xBottom].isValid() &&
00987 scaleRect[QwtPlot::xTop].isValid() )
00988 {
00989 for ( int axis = QwtPlot::xBottom; axis <= QwtPlot::xTop; axis++ )
00990 {
00991 scaleRect[axis].setLeft(canvasRect.left() + fw
00992 - d_data->layoutData.scale[axis].start);
00993 scaleRect[axis].setRight(canvasRect.right() - fw - 1
00994 + d_data->layoutData.scale[axis].end);
00995 }
00996 }
00997
00998 if ( scaleRect[QwtPlot::yLeft].isValid() &&
00999 scaleRect[QwtPlot::yRight].isValid() )
01000 {
01001 for ( int axis = QwtPlot::yLeft; axis <= QwtPlot::yRight; axis++ )
01002 {
01003 scaleRect[axis].setTop(canvasRect.top() + fw
01004 - d_data->layoutData.scale[axis].start);
01005 scaleRect[axis].setBottom(canvasRect.bottom() - fw - 1
01006 + d_data->layoutData.scale[axis].end);
01007 }
01008 }
01009 }
01010 }
01011
01022 void QwtPlotLayout::activate(const QwtPlot *plot,
01023 const QRect &plotRect, int options)
01024 {
01025 invalidate();
01026
01027 QRect rect(plotRect);
01028
01029 if ( !(options & IgnoreMargin) )
01030 {
01031
01032
01033 rect.setRect(
01034 rect.x() + d_data->margin,
01035 rect.y() + d_data->margin,
01036 rect.width() - 2 * d_data->margin,
01037 rect.height() - 2 * d_data->margin
01038 );
01039 }
01040
01041
01042
01043
01044 d_data->layoutData.init(plot, rect);
01045
01046 if (!(options & IgnoreLegend)
01047 && d_data->legendPos != QwtPlot::ExternalLegend
01048 && plot->legend() && !plot->legend()->isEmpty() )
01049 {
01050 d_data->legendRect = layoutLegend(options, rect);
01051
01052
01053
01054 const QRegion region(rect);
01055 rect = region.subtract(d_data->legendRect).boundingRect();
01056
01057 if ( d_data->layoutData.legend.frameWidth &&
01058 !(options & IgnoreFrames ) )
01059 {
01060
01061
01062
01063
01064 switch(d_data->legendPos)
01065 {
01066 case QwtPlot::LeftLegend:
01067 rect.setLeft(rect.left() + d_data->spacing);
01068 break;
01069 case QwtPlot::RightLegend:
01070 rect.setRight(rect.right() - d_data->spacing);
01071 break;
01072 case QwtPlot::TopLegend:
01073 rect.setTop(rect.top() + d_data->spacing);
01074 break;
01075 case QwtPlot::BottomLegend:
01076 rect.setBottom(rect.bottom() - d_data->spacing);
01077 break;
01078 case QwtPlot::ExternalLegend:
01079 break;
01080 }
01081 }
01082 }
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 int dimTitle, dimAxes[QwtPlot::axisCnt];
01108 expandLineBreaks(options, rect, dimTitle, dimAxes);
01109
01110 if (dimTitle > 0 )
01111 {
01112 d_data->titleRect = QRect(rect.x(), rect.y(),
01113 rect.width(), dimTitle);
01114
01115 if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled !=
01116 d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
01117 {
01118
01119
01120
01121 d_data->titleRect.setX(rect.x() + dimAxes[QwtPlot::yLeft]);
01122 d_data->titleRect.setWidth(rect.width()
01123 - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight]);
01124 }
01125
01126
01127 rect.setTop(rect.top() + dimTitle + d_data->spacing);
01128 }
01129
01130 d_data->canvasRect.setRect(
01131 rect.x() + dimAxes[QwtPlot::yLeft],
01132 rect.y() + dimAxes[QwtPlot::xTop],
01133 rect.width() - dimAxes[QwtPlot::yRight] - dimAxes[QwtPlot::yLeft],
01134 rect.height() - dimAxes[QwtPlot::xBottom] - dimAxes[QwtPlot::xTop]);
01135
01136 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
01137 {
01138
01139
01140 if ( dimAxes[axis] )
01141 {
01142 int dim = dimAxes[axis];
01143 QRect &scaleRect = d_data->scaleRect[axis];
01144
01145 scaleRect = d_data->canvasRect;
01146 switch(axis)
01147 {
01148 case QwtPlot::yLeft:
01149 scaleRect.setX(d_data->canvasRect.left() - dim);
01150 scaleRect.setWidth(dim);
01151 break;
01152 case QwtPlot::yRight:
01153 scaleRect.setX(d_data->canvasRect.right() + 1);
01154 scaleRect.setWidth(dim);
01155 break;
01156 case QwtPlot::xBottom:
01157 scaleRect.setY(d_data->canvasRect.bottom() + 1);
01158 scaleRect.setHeight(dim);
01159 break;
01160 case QwtPlot::xTop:
01161 scaleRect.setY(d_data->canvasRect.top() - dim);
01162 scaleRect.setHeight(dim);
01163 break;
01164 }
01165 #if QT_VERSION < 0x040000
01166 scaleRect = scaleRect.normalize();
01167 #else
01168 scaleRect = scaleRect.normalized();
01169 #endif
01170 }
01171 }
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193 alignScales(options, d_data->canvasRect, d_data->scaleRect);
01194
01195 if (!d_data->legendRect.isEmpty() )
01196 {
01197
01198
01199
01200 d_data->legendRect = alignLegend(d_data->canvasRect, d_data->legendRect);
01201 }
01202 }