qwt_scale_draw.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
  2. * Qwt Widget Library
  3. * Copyright (C) 1997 Josef Wilgen
  4. * Copyright (C) 2002 Uwe Rathmann
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the Qwt License, Version 1.0
  8. *****************************************************************************/
  9. #include "qwt_scale_draw.h"
  10. #include "qwt_scale_div.h"
  11. #include "qwt_scale_map.h"
  12. #include "qwt_math.h"
  13. #include "qwt_painter.h"
  14. #include <qpen.h>
  15. #include <qpainter.h>
  16. #include <qmath.h>
  17. class QwtScaleDraw::PrivateData
  18. {
  19. public:
  20. PrivateData():
  21. len( 0 ),
  22. alignment( QwtScaleDraw::BottomScale ),
  23. labelAlignment( 0 ),
  24. labelRotation( 0.0 )
  25. {
  26. }
  27. QPointF pos;
  28. double len;
  29. Alignment alignment;
  30. Qt::Alignment labelAlignment;
  31. double labelRotation;
  32. };
  33. /*!
  34. \brief Constructor
  35. The range of the scale is initialized to [0, 100],
  36. The position is at (0, 0) with a length of 100.
  37. The orientation is QwtAbstractScaleDraw::Bottom.
  38. */
  39. QwtScaleDraw::QwtScaleDraw()
  40. {
  41. d_data = new QwtScaleDraw::PrivateData;
  42. setLength( 100 );
  43. }
  44. //! Destructor
  45. QwtScaleDraw::~QwtScaleDraw()
  46. {
  47. delete d_data;
  48. }
  49. /*!
  50. Return alignment of the scale
  51. \sa setAlignment()
  52. */
  53. QwtScaleDraw::Alignment QwtScaleDraw::alignment() const
  54. {
  55. return d_data->alignment;
  56. }
  57. /*!
  58. Set the alignment of the scale
  59. The default alignment is QwtScaleDraw::BottomScale
  60. \sa alignment()
  61. */
  62. void QwtScaleDraw::setAlignment( Alignment align )
  63. {
  64. d_data->alignment = align;
  65. }
  66. /*!
  67. Return the orientation
  68. TopScale, BottomScale are horizontal (Qt::Horizontal) scales,
  69. LeftScale, RightScale are vertical (Qt::Vertical) scales.
  70. \sa alignment()
  71. */
  72. Qt::Orientation QwtScaleDraw::orientation() const
  73. {
  74. switch ( d_data->alignment )
  75. {
  76. case TopScale:
  77. case BottomScale:
  78. return Qt::Horizontal;
  79. case LeftScale:
  80. case RightScale:
  81. default:
  82. return Qt::Vertical;
  83. }
  84. }
  85. /*!
  86. \brief Determine the minimum border distance
  87. This member function returns the minimum space
  88. needed to draw the mark labels at the scale's endpoints.
  89. \param font Font
  90. \param start Start border distance
  91. \param end End border distance
  92. */
  93. void QwtScaleDraw::getBorderDistHint( const QFont &font,
  94. int &start, int &end ) const
  95. {
  96. start = 0;
  97. end = 0;
  98. if ( !hasComponent( QwtAbstractScaleDraw::Labels ) )
  99. return;
  100. const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
  101. if ( ticks.count() == 0 )
  102. return;
  103. // Find the ticks, that are mapped to the borders.
  104. // minTick is the tick, that is mapped to the top/left-most position
  105. // in widget coordinates.
  106. double minTick = ticks[0];
  107. double minPos = map().transform( minTick );
  108. double maxTick = minTick;
  109. double maxPos = minPos;
  110. for ( uint i = 1; i < ( uint )ticks.count(); i++ )
  111. {
  112. const double tickPos = map().transform( ticks[i] );
  113. if ( tickPos < minPos )
  114. {
  115. minTick = ticks[i];
  116. minPos = tickPos;
  117. }
  118. if ( tickPos > map().transform( maxTick ) )
  119. {
  120. maxTick = ticks[i];
  121. maxPos = tickPos;
  122. }
  123. }
  124. double e = 0.0;
  125. double s = 0.0;
  126. if ( orientation() == Qt::Vertical )
  127. {
  128. s = -labelRect( font, minTick ).top();
  129. s -= qAbs( minPos - qRound( map().p2() ) );
  130. e = labelRect( font, maxTick ).bottom();
  131. e -= qAbs( maxPos - map().p1() );
  132. }
  133. else
  134. {
  135. s = -labelRect( font, minTick ).left();
  136. s -= qAbs( minPos - map().p1() );
  137. e = labelRect( font, maxTick ).right();
  138. e -= qAbs( maxPos - map().p2() );
  139. }
  140. if ( s < 0.0 )
  141. s = 0.0;
  142. if ( e < 0.0 )
  143. e = 0.0;
  144. start = qCeil( s );
  145. end = qCeil( e );
  146. }
  147. /*!
  148. Determine the minimum distance between two labels, that is necessary
  149. that the texts don't overlap.
  150. \param font Font
  151. \return The maximum width of a label
  152. \sa getBorderDistHint()
  153. */
  154. int QwtScaleDraw::minLabelDist( const QFont &font ) const
  155. {
  156. if ( !hasComponent( QwtAbstractScaleDraw::Labels ) )
  157. return 0;
  158. const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
  159. if ( ticks.count() == 0 )
  160. return 0;
  161. const QFontMetrics fm( font );
  162. const bool vertical = ( orientation() == Qt::Vertical );
  163. QRectF bRect1;
  164. QRectF bRect2 = labelRect( font, ticks[0] );
  165. if ( vertical )
  166. {
  167. bRect2.setRect( -bRect2.bottom(), 0, bRect2.height(), bRect2.width() );
  168. }
  169. int maxDist = 0;
  170. for ( uint i = 1; i < ( uint )ticks.count(); i++ )
  171. {
  172. bRect1 = bRect2;
  173. bRect2 = labelRect( font, ticks[i] );
  174. if ( vertical )
  175. {
  176. bRect2.setRect( -bRect2.bottom(), 0,
  177. bRect2.height(), bRect2.width() );
  178. }
  179. int dist = fm.leading(); // space between the labels
  180. if ( bRect1.right() > 0 )
  181. dist += bRect1.right();
  182. if ( bRect2.left() < 0 )
  183. dist += -bRect2.left();
  184. if ( dist > maxDist )
  185. maxDist = dist;
  186. }
  187. double angle = labelRotation() / 180.0 * M_PI;
  188. if ( vertical )
  189. angle += M_PI / 2;
  190. if ( qSin( angle ) == 0.0 )
  191. return maxDist;
  192. const int fmHeight = fm.ascent() - 2;
  193. // The distance we need until there is
  194. // the height of the label font. This height is needed
  195. // for the neighbour labal.
  196. int labelDist = ( int )( fmHeight / qSin( angle ) * qCos( angle ) );
  197. if ( labelDist < 0 )
  198. labelDist = -labelDist;
  199. // The cast above floored labelDist. We want to ceil.
  200. labelDist++;
  201. // For text orientations close to the scale orientation
  202. if ( labelDist > maxDist )
  203. labelDist = maxDist;
  204. // For text orientations close to the opposite of the
  205. // scale orientation
  206. if ( labelDist < fmHeight )
  207. labelDist = fmHeight;
  208. return labelDist;
  209. }
  210. /*!
  211. Calculate the width/height that is needed for a
  212. vertical/horizontal scale.
  213. The extent is calculated from the pen width of the backbone,
  214. the major tick length, the spacing and the maximum width/height
  215. of the labels.
  216. \param font Font used for painting the labels
  217. \sa minLength()
  218. */
  219. double QwtScaleDraw::extent( const QFont &font ) const
  220. {
  221. double d = 0;
  222. if ( hasComponent( QwtAbstractScaleDraw::Labels ) )
  223. {
  224. if ( orientation() == Qt::Vertical )
  225. d = maxLabelWidth( font );
  226. else
  227. d = maxLabelHeight( font );
  228. if ( d > 0 )
  229. d += spacing();
  230. }
  231. if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
  232. {
  233. d += majTickLength();
  234. }
  235. if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
  236. {
  237. const double pw = qMax( 1, penWidth() ); // penwidth can be zero
  238. d += pw;
  239. }
  240. d = qMax( d, minimumExtent() );
  241. return d;
  242. }
  243. /*!
  244. Calculate the minimum length that is needed to draw the scale
  245. \param font Font used for painting the labels
  246. \sa extent()
  247. */
  248. int QwtScaleDraw::minLength( const QFont &font ) const
  249. {
  250. int startDist, endDist;
  251. getBorderDistHint( font, startDist, endDist );
  252. const QwtScaleDiv &sd = scaleDiv();
  253. const uint minorCount =
  254. sd.ticks( QwtScaleDiv::MinorTick ).count() +
  255. sd.ticks( QwtScaleDiv::MediumTick ).count();
  256. const uint majorCount =
  257. sd.ticks( QwtScaleDiv::MajorTick ).count();
  258. int lengthForLabels = 0;
  259. if ( hasComponent( QwtAbstractScaleDraw::Labels ) )
  260. {
  261. if ( majorCount >= 2 )
  262. lengthForLabels = minLabelDist( font ) * ( majorCount - 1 );
  263. }
  264. int lengthForTicks = 0;
  265. if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
  266. {
  267. const double pw = qMax( 1, penWidth() ); // penwidth can be zero
  268. lengthForTicks = qCeil( ( majorCount + minorCount ) * ( pw + 1.0 ) );
  269. }
  270. return startDist + endDist + qMax( lengthForLabels, lengthForTicks );
  271. }
  272. /*!
  273. Find the position, where to paint a label
  274. The position has a distance of majTickLength() + spacing() + 1
  275. from the backbone. The direction depends on the alignment()
  276. \param value Value
  277. */
  278. QPointF QwtScaleDraw::labelPosition( double value ) const
  279. {
  280. const double tval = map().transform( value );
  281. double dist = spacing();
  282. if ( hasComponent( QwtAbstractScaleDraw::Backbone ) )
  283. dist += qMax( 1, penWidth() );
  284. if ( hasComponent( QwtAbstractScaleDraw::Ticks ) )
  285. dist += majTickLength();
  286. double px = 0;
  287. double py = 0;
  288. switch ( alignment() )
  289. {
  290. case RightScale:
  291. {
  292. px = d_data->pos.x() + dist;
  293. py = tval;
  294. break;
  295. }
  296. case LeftScale:
  297. {
  298. px = d_data->pos.x() - dist;
  299. py = tval;
  300. break;
  301. }
  302. case BottomScale:
  303. {
  304. px = tval;
  305. py = d_data->pos.y() + dist;
  306. break;
  307. }
  308. case TopScale:
  309. {
  310. px = tval;
  311. py = d_data->pos.y() - dist;
  312. break;
  313. }
  314. }
  315. return QPointF( px, py );
  316. }
  317. /*!
  318. Draw a tick
  319. \param painter Painter
  320. \param value Value of the tick
  321. \param len Lenght of the tick
  322. \sa drawBackbone(), drawLabel()
  323. */
  324. void QwtScaleDraw::drawTick( QPainter *painter, double value, double len ) const
  325. {
  326. if ( len <= 0 )
  327. return;
  328. const bool roundingAlignment = QwtPainter::roundingAlignment( painter );
  329. QwtScaleMap scaleMap = map();
  330. QPointF pos = d_data->pos;
  331. double tval = scaleMap.transform( value );
  332. if ( roundingAlignment )
  333. tval = qRound( tval );
  334. const int pw = penWidth();
  335. int a = 0;
  336. if ( pw > 1 && roundingAlignment )
  337. a = 1;
  338. switch ( alignment() )
  339. {
  340. case LeftScale:
  341. {
  342. double x1 = pos.x() + a;
  343. double x2 = pos.x() + a - pw - len;
  344. if ( roundingAlignment )
  345. {
  346. x1 = qRound( x1 );
  347. x2 = qRound( x2 );
  348. }
  349. QwtPainter::drawLine( painter, x1, tval, x2, tval );
  350. break;
  351. }
  352. case RightScale:
  353. {
  354. double x1 = pos.x();
  355. double x2 = pos.x() + pw + len;
  356. if ( roundingAlignment )
  357. {
  358. x1 = qRound( x1 );
  359. x2 = qRound( x2 );
  360. }
  361. QwtPainter::drawLine( painter, x1, tval, x2, tval );
  362. break;
  363. }
  364. case BottomScale:
  365. {
  366. double y1 = pos.y();
  367. double y2 = pos.y() + pw + len;
  368. if ( roundingAlignment )
  369. {
  370. y1 = qRound( y1 );
  371. y2 = qRound( y2 );
  372. }
  373. QwtPainter::drawLine( painter, tval, y1, tval, y2 );
  374. break;
  375. }
  376. case TopScale:
  377. {
  378. double y1 = pos.y() + a;
  379. double y2 = pos.y() - pw - len + a;
  380. if ( roundingAlignment )
  381. {
  382. y1 = qRound( y1 );
  383. y2 = qRound( y2 );
  384. }
  385. QwtPainter::drawLine( painter, tval, y1, tval, y2 );
  386. break;
  387. }
  388. }
  389. }
  390. /*!
  391. Draws the baseline of the scale
  392. \param painter Painter
  393. \sa drawTick(), drawLabel()
  394. */
  395. void QwtScaleDraw::drawBackbone( QPainter *painter ) const
  396. {
  397. const bool doAlign = QwtPainter::roundingAlignment( painter );
  398. const QPointF &pos = d_data->pos;
  399. const double len = d_data->len;
  400. const int pw = qMax( penWidth(), 1 );
  401. // pos indicates a border not the center of the backbone line
  402. // so we need to shift its position depending on the pen width
  403. // and the alignment of the scale
  404. double off;
  405. if ( doAlign )
  406. {
  407. if ( alignment() == LeftScale || alignment() == TopScale )
  408. off = ( pw - 1 ) / 2;
  409. else
  410. off = pw / 2;
  411. }
  412. else
  413. {
  414. off = 0.5 * penWidth();
  415. }
  416. switch ( alignment() )
  417. {
  418. case LeftScale:
  419. {
  420. double x = pos.x() - off;
  421. if ( doAlign )
  422. x = qRound( x );
  423. QwtPainter::drawLine( painter, x, pos.y(), x, pos.y() + len );
  424. break;
  425. }
  426. case RightScale:
  427. {
  428. double x = pos.x() + off;
  429. if ( doAlign )
  430. x = qRound( x );
  431. QwtPainter::drawLine( painter, x, pos.y(), x, pos.y() + len );
  432. break;
  433. }
  434. case TopScale:
  435. {
  436. double y = pos.y() - off;
  437. if ( doAlign )
  438. y = qRound( y );
  439. QwtPainter::drawLine( painter, pos.x(), y, pos.x() + len, y );
  440. break;
  441. }
  442. case BottomScale:
  443. {
  444. double y = pos.y() + off;
  445. if ( doAlign )
  446. y = qRound( y );
  447. QwtPainter::drawLine( painter, pos.x(), y, pos.x() + len, y );
  448. break;
  449. }
  450. }
  451. }
  452. /*!
  453. \brief Move the position of the scale
  454. The meaning of the parameter pos depends on the alignment:
  455. <dl>
  456. <dt>QwtScaleDraw::LeftScale
  457. <dd>The origin is the topmost point of the
  458. backbone. The backbone is a vertical line.
  459. Scale marks and labels are drawn
  460. at the left of the backbone.
  461. <dt>QwtScaleDraw::RightScale
  462. <dd>The origin is the topmost point of the
  463. backbone. The backbone is a vertical line.
  464. Scale marks and labels are drawn
  465. at the right of the backbone.
  466. <dt>QwtScaleDraw::TopScale
  467. <dd>The origin is the leftmost point of the
  468. backbone. The backbone is a horizontal line.
  469. Scale marks and labels are drawn
  470. above the backbone.
  471. <dt>QwtScaleDraw::BottomScale
  472. <dd>The origin is the leftmost point of the
  473. backbone. The backbone is a horizontal line
  474. Scale marks and labels are drawn
  475. below the backbone.
  476. </dl>
  477. \param pos Origin of the scale
  478. \sa pos(), setLength()
  479. */
  480. void QwtScaleDraw::move( const QPointF &pos )
  481. {
  482. d_data->pos = pos;
  483. updateMap();
  484. }
  485. /*!
  486. \return Origin of the scale
  487. \sa move(), length()
  488. */
  489. QPointF QwtScaleDraw::pos() const
  490. {
  491. return d_data->pos;
  492. }
  493. /*!
  494. Set the length of the backbone.
  495. The length doesn't include the space needed for
  496. overlapping labels.
  497. \sa move(), minLabelDist()
  498. */
  499. void QwtScaleDraw::setLength( double length )
  500. {
  501. if ( length >= 0 && length < 10 )
  502. length = 10;
  503. if ( length < 0 && length > -10 )
  504. length = -10;
  505. d_data->len = length;
  506. updateMap();
  507. }
  508. /*!
  509. \return the length of the backbone
  510. \sa setLength(), pos()
  511. */
  512. double QwtScaleDraw::length() const
  513. {
  514. return d_data->len;
  515. }
  516. /*!
  517. Draws the label for a major scale tick
  518. \param painter Painter
  519. \param value Value
  520. \sa drawTick(), drawBackbone(), boundingLabelRect()
  521. */
  522. void QwtScaleDraw::drawLabel( QPainter *painter, double value ) const
  523. {
  524. QwtText lbl = tickLabel( painter->font(), value );
  525. if ( lbl.isEmpty() )
  526. return;
  527. QPointF pos = labelPosition( value );
  528. QSizeF labelSize = lbl.textSize( painter->font() );
  529. const QTransform transform = labelTransformation( pos, labelSize );
  530. painter->save();
  531. painter->setWorldTransform( transform, true );
  532. lbl.draw ( painter, QRect( QPoint( 0, 0 ), labelSize.toSize() ) );
  533. painter->restore();
  534. }
  535. /*!
  536. Find the bounding rect for the label. The coordinates of
  537. the rect are absolute coordinates ( calculated from pos() ).
  538. in direction of the tick.
  539. \param font Font used for painting
  540. \param value Value
  541. \sa labelRect()
  542. */
  543. QRect QwtScaleDraw::boundingLabelRect( const QFont &font, double value ) const
  544. {
  545. QwtText lbl = tickLabel( font, value );
  546. if ( lbl.isEmpty() )
  547. return QRect();
  548. const QPointF pos = labelPosition( value );
  549. QSizeF labelSize = lbl.textSize( font );
  550. const QTransform transform = labelTransformation( pos, labelSize );
  551. return transform.mapRect( QRect( QPoint( 0, 0 ), labelSize.toSize() ) );
  552. }
  553. /*!
  554. Calculate the transformation that is needed to paint a label
  555. depending on its alignment and rotation.
  556. \param pos Position where to paint the label
  557. \param size Size of the label
  558. \sa setLabelAlignment(), setLabelRotation()
  559. */
  560. QTransform QwtScaleDraw::labelTransformation(
  561. const QPointF &pos, const QSizeF &size ) const
  562. {
  563. QTransform transform;
  564. transform.translate( pos.x(), pos.y() );
  565. transform.rotate( labelRotation() );
  566. int flags = labelAlignment();
  567. if ( flags == 0 )
  568. {
  569. switch ( alignment() )
  570. {
  571. case RightScale:
  572. {
  573. if ( flags == 0 )
  574. flags = Qt::AlignRight | Qt::AlignVCenter;
  575. break;
  576. }
  577. case LeftScale:
  578. {
  579. if ( flags == 0 )
  580. flags = Qt::AlignLeft | Qt::AlignVCenter;
  581. break;
  582. }
  583. case BottomScale:
  584. {
  585. if ( flags == 0 )
  586. flags = Qt::AlignHCenter | Qt::AlignBottom;
  587. break;
  588. }
  589. case TopScale:
  590. {
  591. if ( flags == 0 )
  592. flags = Qt::AlignHCenter | Qt::AlignTop;
  593. break;
  594. }
  595. }
  596. }
  597. double x, y;
  598. if ( flags & Qt::AlignLeft )
  599. x = -size.width();
  600. else if ( flags & Qt::AlignRight )
  601. x = 0.0;
  602. else // Qt::AlignHCenter
  603. x = -( 0.5 * size.width() );
  604. if ( flags & Qt::AlignTop )
  605. y = -size.height();
  606. else if ( flags & Qt::AlignBottom )
  607. y = 0;
  608. else // Qt::AlignVCenter
  609. y = -( 0.5 * size.height() );
  610. transform.translate( x, y );
  611. return transform;
  612. }
  613. /*!
  614. Find the bounding rect for the label. The coordinates of
  615. the rect are relative to spacing + ticklength from the backbone
  616. in direction of the tick.
  617. \param font Font used for painting
  618. \param value Value
  619. */
  620. QRectF QwtScaleDraw::labelRect( const QFont &font, double value ) const
  621. {
  622. QwtText lbl = tickLabel( font, value );
  623. if ( lbl.isEmpty() )
  624. return QRectF( 0.0, 0.0, 0.0, 0.0 );
  625. const QPointF pos = labelPosition( value );
  626. const QSizeF labelSize = lbl.textSize( font );
  627. const QTransform transform = labelTransformation( pos, labelSize );
  628. QRectF br = transform.mapRect( QRectF( QPointF( 0, 0 ), labelSize ) );
  629. br.translate( -pos.x(), -pos.y() );
  630. return br;
  631. }
  632. /*!
  633. Calculate the size that is needed to draw a label
  634. \param font Label font
  635. \param value Value
  636. */
  637. QSizeF QwtScaleDraw::labelSize( const QFont &font, double value ) const
  638. {
  639. return labelRect( font, value ).size();
  640. }
  641. /*!
  642. Rotate all labels.
  643. When changing the rotation, it might be necessary to
  644. adjust the label flags too. Finding a useful combination is
  645. often the result of try and error.
  646. \param rotation Angle in degrees. When changing the label rotation,
  647. the label flags often needs to be adjusted too.
  648. \sa setLabelAlignment(), labelRotation(), labelAlignment().
  649. */
  650. void QwtScaleDraw::setLabelRotation( double rotation )
  651. {
  652. d_data->labelRotation = rotation;
  653. }
  654. /*!
  655. \return the label rotation
  656. \sa setLabelRotation(), labelAlignment()
  657. */
  658. double QwtScaleDraw::labelRotation() const
  659. {
  660. return d_data->labelRotation;
  661. }
  662. /*!
  663. \brief Change the label flags
  664. Labels are aligned to the point ticklength + spacing away from the backbone.
  665. The alignment is relative to the orientation of the label text.
  666. In case of an flags of 0 the label will be aligned
  667. depending on the orientation of the scale:
  668. QwtScaleDraw::TopScale: Qt::AlignHCenter | Qt::AlignTop\n
  669. QwtScaleDraw::BottomScale: Qt::AlignHCenter | Qt::AlignBottom\n
  670. QwtScaleDraw::LeftScale: Qt::AlignLeft | Qt::AlignVCenter\n
  671. QwtScaleDraw::RightScale: Qt::AlignRight | Qt::AlignVCenter\n
  672. Changing the alignment is often necessary for rotated labels.
  673. \param alignment Or'd Qt::AlignmentFlags <see qnamespace.h>
  674. \sa setLabelRotation(), labelRotation(), labelAlignment()
  675. \warning The various alignments might be confusing.
  676. The alignment of the label is not the alignment
  677. of the scale and is not the alignment of the flags
  678. (QwtText::flags()) returned from QwtAbstractScaleDraw::label().
  679. */
  680. void QwtScaleDraw::setLabelAlignment( Qt::Alignment alignment )
  681. {
  682. d_data->labelAlignment = alignment;
  683. }
  684. /*!
  685. \return the label flags
  686. \sa setLabelAlignment(), labelRotation()
  687. */
  688. Qt::Alignment QwtScaleDraw::labelAlignment() const
  689. {
  690. return d_data->labelAlignment;
  691. }
  692. /*!
  693. \param font Font
  694. \return the maximum width of a label
  695. */
  696. int QwtScaleDraw::maxLabelWidth( const QFont &font ) const
  697. {
  698. int maxWidth = 0;
  699. const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
  700. for ( uint i = 0; i < ( uint )ticks.count(); i++ )
  701. {
  702. const double v = ticks[i];
  703. if ( scaleDiv().contains( v ) )
  704. {
  705. const int w = labelSize( font, ticks[i] ).width();
  706. if ( w > maxWidth )
  707. maxWidth = w;
  708. }
  709. }
  710. return maxWidth;
  711. }
  712. /*!
  713. \param font Font
  714. \return the maximum height of a label
  715. */
  716. int QwtScaleDraw::maxLabelHeight( const QFont &font ) const
  717. {
  718. int maxHeight = 0;
  719. const QList<double> &ticks = scaleDiv().ticks( QwtScaleDiv::MajorTick );
  720. for ( uint i = 0; i < ( uint )ticks.count(); i++ )
  721. {
  722. const double v = ticks[i];
  723. if ( scaleDiv().contains( v ) )
  724. {
  725. const int h = labelSize( font, ticks[i] ).height();
  726. if ( h > maxHeight )
  727. maxHeight = h;
  728. }
  729. }
  730. return maxHeight;
  731. }
  732. void QwtScaleDraw::updateMap()
  733. {
  734. const QPointF pos = d_data->pos;
  735. double len = d_data->len;
  736. QwtScaleMap &sm = scaleMap();
  737. if ( orientation() == Qt::Vertical )
  738. sm.setPaintInterval( pos.y() + len, pos.y() );
  739. else
  740. sm.setPaintInterval( pos.x(), pos.x() + len );
  741. }