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
00648 QRect QwtPlotLayout::layoutLegend(int options,
00649 const QRect &rect) const
00650 {
00651 const QSize hint(d_data->layoutData.legend.hint);
00652
00653 int dim;
00654 if ( d_data->legendPos == QwtPlot::LeftLegend
00655 || d_data->legendPos == QwtPlot::RightLegend )
00656 {
00657
00658
00659
00660 dim = qwtMin(hint.width(), int(rect.width() * d_data->legendRatio));
00661
00662 if ( !(options & IgnoreScrollbars) )
00663 {
00664 if ( hint.height() > rect.height() )
00665 {
00666
00667
00668
00669 dim += d_data->layoutData.legend.vScrollBarWidth;
00670 }
00671 }
00672 }
00673 else
00674 {
00675 dim = qwtMin(hint.height(), int(rect.height() * d_data->legendRatio));
00676 dim = qwtMax(dim, d_data->layoutData.legend.hScrollBarHeight);
00677 }
00678
00679 QRect legendRect = rect;
00680 switch(d_data->legendPos)
00681 {
00682 case QwtPlot::LeftLegend:
00683 legendRect.setWidth(dim);
00684 break;
00685 case QwtPlot::RightLegend:
00686 legendRect.setX(rect.right() - dim + 1);
00687 legendRect.setWidth(dim);
00688 break;
00689 case QwtPlot::TopLegend:
00690 legendRect.setHeight(dim);
00691 break;
00692 case QwtPlot::BottomLegend:
00693 legendRect.setY(rect.bottom() - dim + 1);
00694 legendRect.setHeight(dim);
00695 break;
00696 case QwtPlot::ExternalLegend:
00697 break;
00698 }
00699
00700 return legendRect;
00701 }
00702
00709 QRect QwtPlotLayout::alignLegend(const QRect &canvasRect,
00710 const QRect &legendRect) const
00711 {
00712 QRect alignedRect = legendRect;
00713
00714 if ( d_data->legendPos == QwtPlot::BottomLegend
00715 || d_data->legendPos == QwtPlot::TopLegend )
00716 {
00717 if ( d_data->layoutData.legend.hint.width() < canvasRect.width() )
00718 {
00719 alignedRect.setX(canvasRect.x());
00720 alignedRect.setWidth(canvasRect.width());
00721 }
00722 }
00723 else
00724 {
00725 if ( d_data->layoutData.legend.hint.height() < canvasRect.height() )
00726 {
00727 alignedRect.setY(canvasRect.y());
00728 alignedRect.setHeight(canvasRect.height());
00729 }
00730 }
00731
00732 return alignedRect;
00733 }
00734
00746 void QwtPlotLayout::expandLineBreaks(int options, const QRect &rect,
00747 int &dimTitle, int dimAxis[QwtPlot::axisCnt]) const
00748 {
00749 dimTitle = 0;
00750 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00751 dimAxis[axis] = 0;
00752
00753 int backboneOffset[QwtPlot::axisCnt];
00754 for (int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00755 {
00756 backboneOffset[axis] = 0;
00757 if ( !d_data->alignCanvasToScales )
00758 backboneOffset[axis] += d_data->canvasMargin[axis];
00759 if ( !(options & IgnoreFrames) )
00760 backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
00761 }
00762
00763 bool done = false;
00764 while (!done)
00765 {
00766 done = true;
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 if ( !d_data->layoutData.title.text.isEmpty() )
00777 {
00778 int w = rect.width();
00779
00780 if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled
00781 != d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
00782 {
00783
00784 w -= dimAxis[QwtPlot::yLeft] + dimAxis[QwtPlot::yRight];
00785 }
00786
00787 int d = d_data->layoutData.title.text.heightForWidth(w);
00788 if ( !(options & IgnoreFrames) )
00789 d += 2 * d_data->layoutData.title.frameWidth;
00790
00791 if ( d > dimTitle )
00792 {
00793 dimTitle = d;
00794 done = false;
00795 }
00796 }
00797
00798 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
00799 {
00800 const struct LayoutData::t_scaleData &scaleData =
00801 d_data->layoutData.scale[axis];
00802
00803 if (scaleData.isEnabled)
00804 {
00805 int length;
00806 if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
00807 {
00808 length = rect.width() - dimAxis[QwtPlot::yLeft]
00809 - dimAxis[QwtPlot::yRight];
00810 length -= scaleData.start + scaleData.end;
00811
00812 if ( dimAxis[QwtPlot::yRight] > 0 )
00813 length -= 1;
00814
00815 length += qwtMin(dimAxis[QwtPlot::yLeft],
00816 scaleData.start - backboneOffset[QwtPlot::yLeft]);
00817 length += qwtMin(dimAxis[QwtPlot::yRight],
00818 scaleData.end - backboneOffset[QwtPlot::yRight]);
00819 }
00820 else
00821 {
00822 length = rect.height() - dimAxis[QwtPlot::xTop]
00823 - dimAxis[QwtPlot::xBottom];
00824 length -= scaleData.start + scaleData.end;
00825 length -= 1;
00826
00827 if ( dimAxis[QwtPlot::xBottom] <= 0 )
00828 length -= 1;
00829 if ( dimAxis[QwtPlot::xTop] <= 0 )
00830 length -= 1;
00831
00832 if ( dimAxis[QwtPlot::xBottom] > 0 )
00833 {
00834 length += qwtMin(
00835 d_data->layoutData.scale[QwtPlot::xBottom].tickOffset,
00836 scaleData.start - backboneOffset[QwtPlot::xBottom]);
00837 }
00838 if ( dimAxis[QwtPlot::xTop] > 0 )
00839 {
00840 length += qwtMin(
00841 d_data->layoutData.scale[QwtPlot::xTop].tickOffset,
00842 scaleData.end - backboneOffset[QwtPlot::xTop]);
00843 }
00844
00845 if ( dimTitle > 0 )
00846 length -= dimTitle + d_data->spacing;
00847 }
00848
00849 int d = scaleData.dimWithoutTitle;
00850 if ( !scaleData.scaleWidget->title().isEmpty() )
00851 {
00852 d += scaleData.scaleWidget->titleHeightForWidth(length);
00853 }
00854
00855
00856 if ( d > dimAxis[axis] )
00857 {
00858 dimAxis[axis] = d;
00859 done = false;
00860 }
00861 }
00862 }
00863 }
00864 }
00865
00873 void QwtPlotLayout::alignScales(int options,
00874 QRect &canvasRect, QRect scaleRect[QwtPlot::axisCnt]) const
00875 {
00876 int axis;
00877
00878 int backboneOffset[QwtPlot::axisCnt];
00879 for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
00880 {
00881 backboneOffset[axis] = 0;
00882 if ( !d_data->alignCanvasToScales )
00883 backboneOffset[axis] += d_data->canvasMargin[axis];
00884 if ( !(options & IgnoreFrames) )
00885 backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
00886 }
00887
00888 for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
00889 {
00890 if ( !scaleRect[axis].isValid() )
00891 continue;
00892
00893 const int startDist = d_data->layoutData.scale[axis].start;
00894 const int endDist = d_data->layoutData.scale[axis].end;
00895
00896 QRect &axisRect = scaleRect[axis];
00897
00898 if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
00899 {
00900 const int leftOffset =
00901 backboneOffset[QwtPlot::yLeft] - startDist;
00902
00903 if ( scaleRect[QwtPlot::yLeft].isValid() )
00904 {
00905 int minLeft = scaleRect[QwtPlot::yLeft].left();
00906 int left = axisRect.left() + leftOffset;
00907 axisRect.setLeft(qwtMax(left, minLeft));
00908 }
00909 else
00910 {
00911 if ( d_data->alignCanvasToScales && leftOffset < 0 )
00912 {
00913 canvasRect.setLeft(qwtMax(canvasRect.left(),
00914 axisRect.left() - leftOffset));
00915 }
00916 else
00917 {
00918 if ( leftOffset > 0 )
00919 axisRect.setLeft(axisRect.left() + leftOffset);
00920 }
00921 }
00922
00923 const int rightOffset =
00924 backboneOffset[QwtPlot::yRight] - endDist + 1;
00925
00926 if ( scaleRect[QwtPlot::yRight].isValid() )
00927 {
00928 int maxRight = scaleRect[QwtPlot::yRight].right();
00929 int right = axisRect.right() - rightOffset;
00930 axisRect.setRight(qwtMin(right, maxRight));
00931 }
00932 else
00933 {
00934 if ( d_data->alignCanvasToScales && rightOffset < 0 )
00935 {
00936 canvasRect.setRight( qwtMin(canvasRect.right(),
00937 axisRect.right() + rightOffset) );
00938 }
00939 else
00940 {
00941 if ( rightOffset > 0 )
00942 axisRect.setRight(axisRect.right() - rightOffset);
00943 }
00944 }
00945 }
00946 else
00947 {
00948 const int bottomOffset =
00949 backboneOffset[QwtPlot::xBottom] - endDist + 1;
00950
00951 if ( scaleRect[QwtPlot::xBottom].isValid() )
00952 {
00953 int maxBottom = scaleRect[QwtPlot::xBottom].top() +
00954 d_data->layoutData.scale[QwtPlot::xBottom].tickOffset;
00955
00956 int bottom = axisRect.bottom() - bottomOffset;
00957 axisRect.setBottom(qwtMin(bottom, maxBottom));
00958 }
00959 else
00960 {
00961 if ( d_data->alignCanvasToScales && bottomOffset < 0 )
00962 {
00963 canvasRect.setBottom(qwtMin(canvasRect.bottom(),
00964 axisRect.bottom() + bottomOffset));
00965 }
00966 else
00967 {
00968 if ( bottomOffset > 0 )
00969 axisRect.setBottom(axisRect.bottom() - bottomOffset);
00970 }
00971 }
00972
00973 const int topOffset = backboneOffset[QwtPlot::xTop] - startDist;
00974
00975 if ( scaleRect[QwtPlot::xTop].isValid() )
00976 {
00977 int minTop = scaleRect[QwtPlot::xTop].bottom() -
00978 d_data->layoutData.scale[QwtPlot::xTop].tickOffset;
00979
00980 int top = axisRect.top() + topOffset;
00981 axisRect.setTop(qwtMax(top, minTop));
00982 }
00983 else
00984 {
00985 if ( d_data->alignCanvasToScales && topOffset < 0 )
00986 {
00987 canvasRect.setTop(qwtMax(canvasRect.top(),
00988 axisRect.top() - topOffset));
00989 }
00990 else
00991 {
00992 if ( topOffset > 0 )
00993 axisRect.setTop(axisRect.top() + topOffset);
00994 }
00995 }
00996 }
00997 }
00998
00999 if ( d_data->alignCanvasToScales )
01000 {
01001
01002
01003
01004
01005
01006 int fw = 0;
01007 if ( !(options & IgnoreFrames) )
01008 fw = d_data->layoutData.canvas.frameWidth;
01009
01010 if ( scaleRect[QwtPlot::xBottom].isValid() &&
01011 scaleRect[QwtPlot::xTop].isValid() )
01012 {
01013 for ( int axis = QwtPlot::xBottom; axis <= QwtPlot::xTop; axis++ )
01014 {
01015 scaleRect[axis].setLeft(canvasRect.left() + fw
01016 - d_data->layoutData.scale[axis].start);
01017 scaleRect[axis].setRight(canvasRect.right() - fw - 1
01018 + d_data->layoutData.scale[axis].end);
01019 }
01020 }
01021
01022 if ( scaleRect[QwtPlot::yLeft].isValid() &&
01023 scaleRect[QwtPlot::yRight].isValid() )
01024 {
01025 for ( int axis = QwtPlot::yLeft; axis <= QwtPlot::yRight; axis++ )
01026 {
01027 scaleRect[axis].setTop(canvasRect.top() + fw
01028 - d_data->layoutData.scale[axis].start);
01029 scaleRect[axis].setBottom(canvasRect.bottom() - fw - 1
01030 + d_data->layoutData.scale[axis].end);
01031 }
01032 }
01033 }
01034 }
01035
01046 void QwtPlotLayout::activate(const QwtPlot *plot,
01047 const QRect &plotRect, int options)
01048 {
01049 invalidate();
01050
01051 QRect rect(plotRect);
01052
01053 if ( !(options & IgnoreMargin) )
01054 {
01055
01056
01057 rect.setRect(
01058 rect.x() + d_data->margin,
01059 rect.y() + d_data->margin,
01060 rect.width() - 2 * d_data->margin,
01061 rect.height() - 2 * d_data->margin
01062 );
01063 }
01064
01065
01066
01067
01068 d_data->layoutData.init(plot, rect);
01069
01070 if (!(options & IgnoreLegend)
01071 && d_data->legendPos != QwtPlot::ExternalLegend
01072 && plot->legend() && !plot->legend()->isEmpty() )
01073 {
01074 d_data->legendRect = layoutLegend(options, rect);
01075
01076
01077
01078 const QRegion region(rect);
01079 rect = region.subtract(d_data->legendRect).boundingRect();
01080
01081 if ( d_data->layoutData.legend.frameWidth &&
01082 !(options & IgnoreFrames ) )
01083 {
01084
01085
01086
01087
01088 switch(d_data->legendPos)
01089 {
01090 case QwtPlot::LeftLegend:
01091 rect.setLeft(rect.left() + d_data->spacing);
01092 break;
01093 case QwtPlot::RightLegend:
01094 rect.setRight(rect.right() - d_data->spacing);
01095 break;
01096 case QwtPlot::TopLegend:
01097 rect.setTop(rect.top() + d_data->spacing);
01098 break;
01099 case QwtPlot::BottomLegend:
01100 rect.setBottom(rect.bottom() - d_data->spacing);
01101 break;
01102 case QwtPlot::ExternalLegend:
01103 break;
01104 }
01105 }
01106 }
01107
01108 #ifdef __GNUC__
01109 #endif
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132 int dimTitle, dimAxes[QwtPlot::axisCnt];
01133 expandLineBreaks(options, rect, dimTitle, dimAxes);
01134
01135 if (dimTitle > 0 )
01136 {
01137 d_data->titleRect = QRect(rect.x(), rect.y(),
01138 rect.width(), dimTitle);
01139
01140 if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled !=
01141 d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
01142 {
01143
01144
01145
01146 d_data->titleRect.setX(rect.x() + dimAxes[QwtPlot::yLeft]);
01147 d_data->titleRect.setWidth(rect.width()
01148 - dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight]);
01149 }
01150
01151
01152 rect.setTop(rect.top() + dimTitle + d_data->spacing);
01153 }
01154
01155 d_data->canvasRect.setRect(
01156 rect.x() + dimAxes[QwtPlot::yLeft],
01157 rect.y() + dimAxes[QwtPlot::xTop],
01158 rect.width() - dimAxes[QwtPlot::yRight] - dimAxes[QwtPlot::yLeft],
01159 rect.height() - dimAxes[QwtPlot::xBottom] - dimAxes[QwtPlot::xTop]);
01160
01161 for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
01162 {
01163
01164
01165 if ( dimAxes[axis] )
01166 {
01167 int dim = dimAxes[axis];
01168 QRect &scaleRect = d_data->scaleRect[axis];
01169
01170 scaleRect = d_data->canvasRect;
01171 switch(axis)
01172 {
01173 case QwtPlot::yLeft:
01174 scaleRect.setX(d_data->canvasRect.left() - dim);
01175 scaleRect.setWidth(dim);
01176 break;
01177 case QwtPlot::yRight:
01178 scaleRect.setX(d_data->canvasRect.right() + 1);
01179 scaleRect.setWidth(dim);
01180 break;
01181 case QwtPlot::xBottom:
01182 scaleRect.setY(d_data->canvasRect.bottom() + 1);
01183 scaleRect.setHeight(dim);
01184 break;
01185 case QwtPlot::xTop:
01186 scaleRect.setY(d_data->canvasRect.top() - dim);
01187 scaleRect.setHeight(dim);
01188 break;
01189 }
01190 #if QT_VERSION < 0x040000
01191 scaleRect = scaleRect.normalize();
01192 #else
01193 scaleRect = scaleRect.normalized();
01194 #endif
01195 }
01196 }
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218 alignScales(options, d_data->canvasRect, d_data->scaleRect);
01219
01220 if (!d_data->legendRect.isEmpty() )
01221 {
01222
01223
01224
01225 d_data->legendRect = alignLegend(d_data->canvasRect, d_data->legendRect);
01226 }
01227 }