ctkCrosshairLabel.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.commontk.org/LICENSE
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // Qt includes
  15. #include <QColor>
  16. #include <QDebug>
  17. #include <QEvent>
  18. #include <QPainter>
  19. #include <QSize>
  20. // CTK includes
  21. #include "ctkCrosshairLabel.h"
  22. #include "ctkLogger.h"
  23. // STD includes
  24. #include <math.h>
  25. //--------------------------------------------------------------------------
  26. static ctkLogger logger("org.commontk.visualization.vtk.widgets.ctkCrosshairLabel");
  27. //--------------------------------------------------------------------------
  28. //-----------------------------------------------------------------------------
  29. class ctkCrosshairLabelPrivate
  30. {
  31. Q_DECLARE_PUBLIC(ctkCrosshairLabel);
  32. protected:
  33. ctkCrosshairLabel* const q_ptr;
  34. public:
  35. ctkCrosshairLabelPrivate(ctkCrosshairLabel& object);
  36. void init();
  37. void drawCrosshair();
  38. void drawSimpleCrosshair(QPainter& painter);
  39. void drawBullsEyeCrosshair(QPainter& painter);
  40. bool ShowCrosshair;
  41. QPen CrosshairPen;
  42. ctkCrosshairLabel::CrosshairTypes CrosshairType;
  43. int BullsEyeWidth;
  44. static const double BULLS_EYE_BLANK_FRACTION = 0.1;
  45. };
  46. // --------------------------------------------------------------------------
  47. // ctkCrosshairLabelPrivate methods
  48. // --------------------------------------------------------------------------
  49. ctkCrosshairLabelPrivate::ctkCrosshairLabelPrivate(ctkCrosshairLabel& object)
  50. :q_ptr(&object)
  51. {
  52. this->ShowCrosshair = true;
  53. this->CrosshairType = ctkCrosshairLabel::SimpleCrosshair;
  54. this->BullsEyeWidth = 15;
  55. }
  56. //---------------------------------------------------------------------------
  57. void ctkCrosshairLabelPrivate::init()
  58. {
  59. Q_Q(ctkCrosshairLabel);
  60. q->setAutoFillBackground(true);
  61. q->setAlignment(Qt::AlignCenter);
  62. this->CrosshairPen.setColor(q->palette().color(QPalette::Highlight));
  63. this->CrosshairPen.setWidth(0);
  64. this->CrosshairPen.setJoinStyle(Qt::MiterJoin);
  65. }
  66. //---------------------------------------------------------------------------
  67. void ctkCrosshairLabelPrivate::drawCrosshair()
  68. {
  69. // Abort if we are not to draw the crosshair
  70. if (!this->ShowCrosshair)
  71. {
  72. return;
  73. }
  74. // Setup the painter object to paint on the label
  75. Q_Q(ctkCrosshairLabel);
  76. QPainter painter(q);
  77. painter.setPen(this->CrosshairPen);
  78. // Draw crosshair (based on current parameters) onto the label
  79. switch (this->CrosshairType)
  80. {
  81. case ctkCrosshairLabel::SimpleCrosshair:
  82. this->drawSimpleCrosshair(painter);
  83. break;
  84. case ctkCrosshairLabel::BullsEyeCrosshair:
  85. this->drawBullsEyeCrosshair(painter);
  86. break;
  87. default:
  88. qDebug() << "Unsupported crosshair type" << this->CrosshairType;
  89. break;
  90. }
  91. }
  92. //---------------------------------------------------------------------------
  93. void ctkCrosshairLabelPrivate::drawSimpleCrosshair(QPainter& painter)
  94. {
  95. Q_Q(ctkCrosshairLabel);
  96. QSize size = q->size();
  97. double halfWidth = (size.width()-1.0) / 2.0;
  98. double halfHeight = (size.height()-1.0) / 2.0;
  99. painter.drawLine(QPointF(0, halfHeight), QPointF(size.width(), halfHeight));
  100. painter.drawLine(QPointF(halfWidth, 0), QPointF(halfWidth, size.height()));
  101. }
  102. // --------------------------------------------------------------------------
  103. void ctkCrosshairLabelPrivate::drawBullsEyeCrosshair(QPainter& painter)
  104. {
  105. Q_Q(ctkCrosshairLabel);
  106. QSize size = q->size();
  107. // Draw rectangle
  108. double bullsEye = this->BullsEyeWidth;
  109. double lineWidth = painter.pen().width();
  110. lineWidth = std::max(lineWidth, 1.0);
  111. double halfLineWidth = (lineWidth-1.0) / 2.0;
  112. double x = (size.width()-bullsEye) / 2.0;
  113. double y = (size.height()-bullsEye) / 2.0;
  114. double rectWidth = bullsEye;
  115. if (bullsEye != 1)
  116. {
  117. rectWidth = rectWidth - lineWidth;
  118. }
  119. rectWidth = std::max(rectWidth, 0.0);
  120. painter.drawRect(
  121. QRectF(x+halfLineWidth, y+halfLineWidth, rectWidth, rectWidth));
  122. // Draw the lines
  123. double halfWidth = (size.width()-1.0) / 2.0;
  124. double halfHeight = (size.height()-1.0) / 2.0;
  125. double blank = round(std::min(halfWidth, halfHeight)
  126. * this->BULLS_EYE_BLANK_FRACTION);
  127. painter.drawLine(QPointF(0, halfHeight), QPointF(x-blank-1.0, halfHeight));
  128. painter.drawLine(QPointF(x+bullsEye+blank, halfHeight),
  129. QPointF(size.width(), halfHeight));
  130. painter.drawLine(QPointF(halfWidth, 0), QPointF(halfWidth, y-blank-1.0));
  131. painter.drawLine(QPointF(halfWidth, y+bullsEye+blank),
  132. QPointF(halfWidth, size.height()));
  133. }
  134. //---------------------------------------------------------------------------
  135. // ctkCrosshairLabel methods
  136. // --------------------------------------------------------------------------
  137. ctkCrosshairLabel::ctkCrosshairLabel(QWidget* parent)
  138. : Superclass(parent)
  139. , d_ptr(new ctkCrosshairLabelPrivate(*this))
  140. {
  141. Q_D(ctkCrosshairLabel);
  142. d->init();
  143. }
  144. // --------------------------------------------------------------------------
  145. ctkCrosshairLabel::~ctkCrosshairLabel()
  146. {
  147. }
  148. // --------------------------------------------------------------------------
  149. CTK_GET_CPP(ctkCrosshairLabel, bool, showCrosshair, ShowCrosshair);
  150. // --------------------------------------------------------------------------
  151. void ctkCrosshairLabel::setShowCrosshair(bool newShow)
  152. {
  153. Q_D(ctkCrosshairLabel);
  154. if (newShow == d->ShowCrosshair)
  155. {
  156. return;
  157. }
  158. d->ShowCrosshair = newShow;
  159. this->update();
  160. }
  161. // --------------------------------------------------------------------------
  162. CTK_GET_CPP(ctkCrosshairLabel, QPen, crosshairPen, CrosshairPen);
  163. // --------------------------------------------------------------------------
  164. void ctkCrosshairLabel::setCrosshairPen(const QPen& newPen)
  165. {
  166. Q_D(ctkCrosshairLabel);
  167. if (newPen == d->CrosshairPen)
  168. {
  169. return;
  170. }
  171. d->CrosshairPen = newPen;
  172. this->update();
  173. }
  174. // --------------------------------------------------------------------------
  175. QColor ctkCrosshairLabel::crosshairColor() const
  176. {
  177. Q_D(const ctkCrosshairLabel);
  178. return d->CrosshairPen.color();
  179. }
  180. // --------------------------------------------------------------------------
  181. void ctkCrosshairLabel::setCrosshairColor(const QColor& newColor)
  182. {
  183. Q_D(ctkCrosshairLabel);
  184. if (d->CrosshairPen.color() == newColor)
  185. {
  186. return;
  187. }
  188. d->CrosshairPen.setColor(newColor);
  189. this->update();
  190. }
  191. // --------------------------------------------------------------------------
  192. int ctkCrosshairLabel::lineWidth() const
  193. {
  194. Q_D(const ctkCrosshairLabel);
  195. return d->CrosshairPen.width();
  196. }
  197. // --------------------------------------------------------------------------
  198. void ctkCrosshairLabel::setLineWidth(int newWidth)
  199. {
  200. Q_D(ctkCrosshairLabel);
  201. if (d->CrosshairPen.width() == newWidth || newWidth < 0)
  202. {
  203. return;
  204. }
  205. d->CrosshairPen.setWidth(newWidth);
  206. this->update();
  207. }
  208. // --------------------------------------------------------------------------
  209. CTK_GET_CPP(ctkCrosshairLabel, ctkCrosshairLabel::CrosshairTypes,
  210. crosshairType, CrosshairType);
  211. // --------------------------------------------------------------------------
  212. void ctkCrosshairLabel::setCrosshairType(const CrosshairTypes& newType)
  213. {
  214. Q_D(ctkCrosshairLabel);
  215. if (newType == d->CrosshairType)
  216. {
  217. return;
  218. }
  219. d->CrosshairType = newType;
  220. this->update();
  221. }
  222. // --------------------------------------------------------------------------
  223. QColor ctkCrosshairLabel::marginColor() const
  224. {
  225. return this->palette().color(QPalette::Window);
  226. }
  227. // --------------------------------------------------------------------------
  228. void ctkCrosshairLabel::setMarginColor(const QColor& newColor)
  229. {
  230. if (!newColor.isValid())
  231. {
  232. return;
  233. }
  234. QPalette palette(this->palette());
  235. QColor solidColor(newColor.rgb());
  236. if (solidColor != palette.color(QPalette::Window))
  237. {
  238. // Ignore alpha channel
  239. palette.setColor(QPalette::Window, solidColor);
  240. this->setPalette(palette);
  241. this->update();
  242. }
  243. }
  244. // --------------------------------------------------------------------------
  245. CTK_GET_CPP(ctkCrosshairLabel, int, bullsEyeWidth, BullsEyeWidth);
  246. // --------------------------------------------------------------------------
  247. void ctkCrosshairLabel::setBullsEyeWidth(int newWidth)
  248. {
  249. Q_D(ctkCrosshairLabel);
  250. if (newWidth == d->BullsEyeWidth || newWidth < 0)
  251. {
  252. return;
  253. }
  254. d->BullsEyeWidth = newWidth;
  255. this->update();
  256. }
  257. // --------------------------------------------------------------------------
  258. void ctkCrosshairLabel::paintEvent(QPaintEvent * event)
  259. {
  260. Superclass::paintEvent(event);
  261. Q_D(ctkCrosshairLabel);
  262. d->drawCrosshair();
  263. }
  264. // --------------------------------------------------------------------------
  265. QSize ctkCrosshairLabel::minimumSizeHint()const
  266. {
  267. // Pretty arbitrary size (matches ctkVTKAbstractView)
  268. return QSize(50, 50);
  269. }
  270. // --------------------------------------------------------------------------
  271. QSize ctkCrosshairLabel::sizeHint()const
  272. {
  273. // Pretty arbitrary size (matches ctkVTKAbstractView)
  274. return QSize(300, 300);
  275. }
  276. //----------------------------------------------------------------------------
  277. bool ctkCrosshairLabel::hasHeightForWidth()const
  278. {
  279. return true;
  280. }
  281. //----------------------------------------------------------------------------
  282. int ctkCrosshairLabel::heightForWidth(int width)const
  283. {
  284. // Tends to be square
  285. return width;
  286. }