qwt_legend_item.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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_legend_item.h"
  10. #include "qwt_math.h"
  11. #include "qwt_painter.h"
  12. #include "qwt_symbol.h"
  13. #include <qpainter.h>
  14. #include <qdrawutil.h>
  15. #include <qstyle.h>
  16. #include <qpen.h>
  17. #include <qevent.h>
  18. #include <qstyleoption.h>
  19. static const int ButtonFrame = 2;
  20. static const int Margin = 2;
  21. static QSize buttonShift( const QwtLegendItem *w )
  22. {
  23. QStyleOption option;
  24. option.init( w );
  25. const int ph = w->style()->pixelMetric(
  26. QStyle::PM_ButtonShiftHorizontal, &option, w );
  27. const int pv = w->style()->pixelMetric(
  28. QStyle::PM_ButtonShiftVertical, &option, w );
  29. return QSize( ph, pv );
  30. }
  31. class QwtLegendItem::PrivateData
  32. {
  33. public:
  34. PrivateData():
  35. itemMode( QwtLegend::ReadOnlyItem ),
  36. isDown( false ),
  37. identifierSize( 8, 8 ),
  38. spacing( Margin )
  39. {
  40. }
  41. QwtLegend::LegendItemMode itemMode;
  42. bool isDown;
  43. QSize identifierSize;
  44. QPixmap identifier;
  45. int spacing;
  46. };
  47. /*!
  48. \param parent Parent widget
  49. */
  50. QwtLegendItem::QwtLegendItem( QWidget *parent ):
  51. QwtTextLabel( parent )
  52. {
  53. d_data = new PrivateData;
  54. setMargin( Margin );
  55. setIndent( Margin + d_data->identifierSize.width() + 2 * d_data->spacing );
  56. }
  57. //! Destructor
  58. QwtLegendItem::~QwtLegendItem()
  59. {
  60. delete d_data;
  61. d_data = NULL;
  62. }
  63. /*!
  64. Set the text to the legend item
  65. \param text Text label
  66. \sa QwtTextLabel::text()
  67. */
  68. void QwtLegendItem::setText( const QwtText &text )
  69. {
  70. const int flags = Qt::AlignLeft | Qt::AlignVCenter
  71. | Qt::TextExpandTabs | Qt::TextWordWrap;
  72. QwtText txt = text;
  73. txt.setRenderFlags( flags );
  74. QwtTextLabel::setText( txt );
  75. }
  76. /*!
  77. Set the item mode
  78. The default is QwtLegend::ReadOnlyItem
  79. \param mode Item mode
  80. \sa itemMode()
  81. */
  82. void QwtLegendItem::setItemMode( QwtLegend::LegendItemMode mode )
  83. {
  84. if ( mode != d_data->itemMode )
  85. {
  86. d_data->itemMode = mode;
  87. d_data->isDown = false;
  88. setFocusPolicy( mode != QwtLegend::ReadOnlyItem ? Qt::TabFocus : Qt::NoFocus );
  89. setMargin( ButtonFrame + Margin );
  90. updateGeometry();
  91. }
  92. }
  93. /*!
  94. Return the item mode
  95. \sa setItemMode()
  96. */
  97. QwtLegend::LegendItemMode QwtLegendItem::itemMode() const
  98. {
  99. return d_data->itemMode;
  100. }
  101. /*!
  102. Assign the identifier
  103. The identifier needs to be created according to the identifierWidth()
  104. \param identifier Pixmap representing a plot item
  105. \sa identifier(), identifierWidth()
  106. */
  107. void QwtLegendItem::setIdentifier( const QPixmap &identifier )
  108. {
  109. d_data->identifier = identifier;
  110. update();
  111. }
  112. /*!
  113. \return pixmap representing a plot item
  114. \sa setIdentifier()
  115. */
  116. QPixmap QwtLegendItem::identifier() const
  117. {
  118. return d_data->identifier;
  119. }
  120. /*!
  121. Set the size for the identifier
  122. Default is 8x8 pixels
  123. \param size New size
  124. \sa identifierSize()
  125. */
  126. void QwtLegendItem::setIdentifierSize( const QSize &size )
  127. {
  128. QSize sz = size.expandedTo( QSize( 0, 0 ) );
  129. if ( sz != d_data->identifierSize )
  130. {
  131. d_data->identifierSize = sz;
  132. setIndent( margin() + d_data->identifierSize.width()
  133. + 2 * d_data->spacing );
  134. updateGeometry();
  135. }
  136. }
  137. /*!
  138. Return the width of the identifier
  139. \sa setIdentifierSize()
  140. */
  141. QSize QwtLegendItem::identifierSize() const
  142. {
  143. return d_data->identifierSize;
  144. }
  145. /*!
  146. Change the spacing
  147. \param spacing Spacing
  148. \sa spacing(), identifierWidth(), QwtTextLabel::margin()
  149. */
  150. void QwtLegendItem::setSpacing( int spacing )
  151. {
  152. spacing = qMax( spacing, 0 );
  153. if ( spacing != d_data->spacing )
  154. {
  155. d_data->spacing = spacing;
  156. setIndent( margin() + d_data->identifierSize.width()
  157. + 2 * d_data->spacing );
  158. }
  159. }
  160. /*!
  161. Return the spacing
  162. \sa setSpacing(), identifierWidth(), QwtTextLabel::margin()
  163. */
  164. int QwtLegendItem::spacing() const
  165. {
  166. return d_data->spacing;
  167. }
  168. /*!
  169. Check/Uncheck a the item
  170. \param on check/uncheck
  171. \sa setItemMode()
  172. */
  173. void QwtLegendItem::setChecked( bool on )
  174. {
  175. if ( d_data->itemMode == QwtLegend::CheckableItem )
  176. {
  177. const bool isBlocked = signalsBlocked();
  178. blockSignals( true );
  179. setDown( on );
  180. blockSignals( isBlocked );
  181. }
  182. }
  183. //! Return true, if the item is checked
  184. bool QwtLegendItem::isChecked() const
  185. {
  186. return d_data->itemMode == QwtLegend::CheckableItem && isDown();
  187. }
  188. //! Set the item being down
  189. void QwtLegendItem::setDown( bool down )
  190. {
  191. if ( down == d_data->isDown )
  192. return;
  193. d_data->isDown = down;
  194. update();
  195. if ( d_data->itemMode == QwtLegend::ClickableItem )
  196. {
  197. if ( d_data->isDown )
  198. Q_EMIT pressed();
  199. else
  200. {
  201. Q_EMIT released();
  202. Q_EMIT clicked();
  203. }
  204. }
  205. if ( d_data->itemMode == QwtLegend::CheckableItem )
  206. Q_EMIT checked( d_data->isDown );
  207. }
  208. //! Return true, if the item is down
  209. bool QwtLegendItem::isDown() const
  210. {
  211. return d_data->isDown;
  212. }
  213. //! Return a size hint
  214. QSize QwtLegendItem::sizeHint() const
  215. {
  216. QSize sz = QwtTextLabel::sizeHint();
  217. sz.setHeight( qMax( sz.height(), d_data->identifier.height() + 4 ) );
  218. if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
  219. sz += buttonShift( this );
  220. return sz;
  221. }
  222. //! Paint event
  223. void QwtLegendItem::paintEvent( QPaintEvent *e )
  224. {
  225. const QRect cr = contentsRect();
  226. QPainter painter( this );
  227. painter.setClipRegion( e->region() );
  228. if ( d_data->isDown )
  229. {
  230. qDrawWinButton( &painter, 0, 0, width(), height(),
  231. palette(), true );
  232. }
  233. painter.save();
  234. if ( d_data->isDown )
  235. {
  236. const QSize shiftSize = buttonShift( this );
  237. painter.translate( shiftSize.width(), shiftSize.height() );
  238. }
  239. painter.setClipRect( cr );
  240. drawContents( &painter );
  241. if ( !d_data->identifier.isNull() )
  242. {
  243. QRect identRect = cr;
  244. identRect.setX( identRect.x() + margin() );
  245. if ( d_data->itemMode != QwtLegend::ReadOnlyItem )
  246. identRect.setX( identRect.x() + ButtonFrame );
  247. identRect.setSize( d_data->identifier.size() );
  248. identRect.moveCenter( QPoint( identRect.center().x(), cr.center().y() ) );
  249. painter.drawPixmap( identRect, d_data->identifier );
  250. }
  251. painter.restore();
  252. }
  253. //! Handle mouse press events
  254. void QwtLegendItem::mousePressEvent( QMouseEvent *e )
  255. {
  256. if ( e->button() == Qt::LeftButton )
  257. {
  258. switch ( d_data->itemMode )
  259. {
  260. case QwtLegend::ClickableItem:
  261. {
  262. setDown( true );
  263. return;
  264. }
  265. case QwtLegend::CheckableItem:
  266. {
  267. setDown( !isDown() );
  268. return;
  269. }
  270. default:;
  271. }
  272. }
  273. QwtTextLabel::mousePressEvent( e );
  274. }
  275. //! Handle mouse release events
  276. void QwtLegendItem::mouseReleaseEvent( QMouseEvent *e )
  277. {
  278. if ( e->button() == Qt::LeftButton )
  279. {
  280. switch ( d_data->itemMode )
  281. {
  282. case QwtLegend::ClickableItem:
  283. {
  284. setDown( false );
  285. return;
  286. }
  287. case QwtLegend::CheckableItem:
  288. {
  289. return; // do nothing, but accept
  290. }
  291. default:;
  292. }
  293. }
  294. QwtTextLabel::mouseReleaseEvent( e );
  295. }
  296. //! Handle key press events
  297. void QwtLegendItem::keyPressEvent( QKeyEvent *e )
  298. {
  299. if ( e->key() == Qt::Key_Space )
  300. {
  301. switch ( d_data->itemMode )
  302. {
  303. case QwtLegend::ClickableItem:
  304. {
  305. if ( !e->isAutoRepeat() )
  306. setDown( true );
  307. return;
  308. }
  309. case QwtLegend::CheckableItem:
  310. {
  311. if ( !e->isAutoRepeat() )
  312. setDown( !isDown() );
  313. return;
  314. }
  315. default:;
  316. }
  317. }
  318. QwtTextLabel::keyPressEvent( e );
  319. }
  320. //! Handle key release events
  321. void QwtLegendItem::keyReleaseEvent( QKeyEvent *e )
  322. {
  323. if ( e->key() == Qt::Key_Space )
  324. {
  325. switch ( d_data->itemMode )
  326. {
  327. case QwtLegend::ClickableItem:
  328. {
  329. if ( !e->isAutoRepeat() )
  330. setDown( false );
  331. return;
  332. }
  333. case QwtLegend::CheckableItem:
  334. {
  335. return; // do nothing, but accept
  336. }
  337. default:;
  338. }
  339. }
  340. QwtTextLabel::keyReleaseEvent( e );
  341. }