123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- /*=========================================================================
- Library: CTK
- Copyright (c) Kitware Inc.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0.txt
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- =========================================================================*/
- // Qt includes
- #include <QColor>
- #include <QDebug>
- #include <QEvent>
- #include <QPainter>
- #include <QSize>
- // CTK includes
- #include "ctkCrosshairLabel.h"
- #include "ctkLogger.h"
- // STD includes
- #include <math.h>
- //--------------------------------------------------------------------------
- static ctkLogger logger("org.commontk.visualization.vtk.widgets.ctkCrosshairLabel");
- //--------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- class ctkCrosshairLabelPrivate
- {
- Q_DECLARE_PUBLIC(ctkCrosshairLabel)
- protected:
- ctkCrosshairLabel* const q_ptr;
- public:
- ctkCrosshairLabelPrivate(ctkCrosshairLabel& object);
- void init();
- void drawCrosshair();
- void drawSimpleCrosshair(QPainter& painter);
- void drawBullsEyeCrosshair(QPainter& painter);
- static int round(double f)
- { return static_cast<int>( f + ( f >= 0 ? 0.5 : -0.5 ) ); }
- bool ShowCrosshair;
- QPen CrosshairPen;
- ctkCrosshairLabel::CrosshairTypes CrosshairType;
- int BullsEyeWidth;
- static const double BULLS_EYE_BLANK_FRACTION;
- };
- const double ctkCrosshairLabelPrivate::BULLS_EYE_BLANK_FRACTION = 0.1;
- // --------------------------------------------------------------------------
- // ctkCrosshairLabelPrivate methods
- // --------------------------------------------------------------------------
- ctkCrosshairLabelPrivate::ctkCrosshairLabelPrivate(ctkCrosshairLabel& object)
- :q_ptr(&object)
- {
- this->ShowCrosshair = true;
- this->CrosshairType = ctkCrosshairLabel::SimpleCrosshair;
- this->BullsEyeWidth = 15;
- }
- //---------------------------------------------------------------------------
- void ctkCrosshairLabelPrivate::init()
- {
- Q_Q(ctkCrosshairLabel);
- q->setAutoFillBackground(true);
- q->setAlignment(Qt::AlignCenter);
- this->CrosshairPen.setColor(q->palette().color(QPalette::Highlight));
- this->CrosshairPen.setWidth(0);
- this->CrosshairPen.setJoinStyle(Qt::MiterJoin);
- }
- //---------------------------------------------------------------------------
- void ctkCrosshairLabelPrivate::drawCrosshair()
- {
- // Abort if we are not to draw the crosshair
- if (!this->ShowCrosshair)
- {
- return;
- }
- // Setup the painter object to paint on the label
- Q_Q(ctkCrosshairLabel);
- QPainter painter(q);
- painter.setPen(this->CrosshairPen);
- // Draw crosshair (based on current parameters) onto the label
- switch (this->CrosshairType)
- {
- case ctkCrosshairLabel::SimpleCrosshair:
- this->drawSimpleCrosshair(painter);
- break;
- case ctkCrosshairLabel::BullsEyeCrosshair:
- this->drawBullsEyeCrosshair(painter);
- break;
- default:
- qCritical() << "Unsupported crosshair type" << static_cast<int>(this->CrosshairType);
- break;
- }
- }
- //---------------------------------------------------------------------------
- void ctkCrosshairLabelPrivate::drawSimpleCrosshair(QPainter& painter)
- {
- Q_Q(ctkCrosshairLabel);
- QSize size = q->size();
- double halfWidth = (size.width()-1.0) / 2.0;
- double halfHeight = (size.height()-1.0) / 2.0;
- painter.drawLine(QPointF(0, halfHeight), QPointF(size.width(), halfHeight));
- painter.drawLine(QPointF(halfWidth, 0), QPointF(halfWidth, size.height()));
- }
- // --------------------------------------------------------------------------
- void ctkCrosshairLabelPrivate::drawBullsEyeCrosshair(QPainter& painter)
- {
- Q_Q(ctkCrosshairLabel);
- QSize size = q->size();
- // Draw rectangle
- double bullsEye = this->BullsEyeWidth;
- double lineWidth = painter.pen().width();
- lineWidth = std::max(lineWidth, 1.0);
- double halfLineWidth = (lineWidth-1.0) / 2.0;
- double x = (size.width()-bullsEye) / 2.0;
- double y = (size.height()-bullsEye) / 2.0;
- double rectWidth = bullsEye;
- if (bullsEye != 1)
- {
- rectWidth = rectWidth - lineWidth;
- }
- rectWidth = std::max(rectWidth, 0.0);
- painter.drawRect(
- QRectF(x+halfLineWidth, y+halfLineWidth, rectWidth, rectWidth));
- // Draw the lines
- double halfWidth = (size.width()-1.0) / 2.0;
- double halfHeight = (size.height()-1.0) / 2.0;
- double blank = ctkCrosshairLabelPrivate::round(
- std::min(halfWidth, halfHeight) * this->BULLS_EYE_BLANK_FRACTION);
- painter.drawLine(QPointF(0, halfHeight), QPointF(x-blank-1.0, halfHeight));
- painter.drawLine(QPointF(x+bullsEye+blank, halfHeight),
- QPointF(size.width(), halfHeight));
- painter.drawLine(QPointF(halfWidth, 0), QPointF(halfWidth, y-blank-1.0));
- painter.drawLine(QPointF(halfWidth, y+bullsEye+blank),
- QPointF(halfWidth, size.height()));
- }
- //---------------------------------------------------------------------------
- // ctkCrosshairLabel methods
- // --------------------------------------------------------------------------
- ctkCrosshairLabel::ctkCrosshairLabel(QWidget* parent)
- : Superclass(parent)
- , d_ptr(new ctkCrosshairLabelPrivate(*this))
- {
- Q_D(ctkCrosshairLabel);
- d->init();
- }
- // --------------------------------------------------------------------------
- ctkCrosshairLabel::~ctkCrosshairLabel()
- {
- }
- // --------------------------------------------------------------------------
- CTK_GET_CPP(ctkCrosshairLabel, bool, showCrosshair, ShowCrosshair)
- // --------------------------------------------------------------------------
- void ctkCrosshairLabel::setShowCrosshair(bool newShow)
- {
- Q_D(ctkCrosshairLabel);
- if (newShow == d->ShowCrosshair)
- {
- return;
- }
- d->ShowCrosshair = newShow;
- this->update();
- }
- // --------------------------------------------------------------------------
- CTK_GET_CPP(ctkCrosshairLabel, QPen, crosshairPen, CrosshairPen)
- // --------------------------------------------------------------------------
- void ctkCrosshairLabel::setCrosshairPen(const QPen& newPen)
- {
- Q_D(ctkCrosshairLabel);
- if (newPen == d->CrosshairPen)
- {
- return;
- }
- d->CrosshairPen = newPen;
- this->update();
- }
- // --------------------------------------------------------------------------
- QColor ctkCrosshairLabel::crosshairColor() const
- {
- Q_D(const ctkCrosshairLabel);
- return d->CrosshairPen.color();
- }
- // --------------------------------------------------------------------------
- void ctkCrosshairLabel::setCrosshairColor(const QColor& newColor)
- {
- Q_D(ctkCrosshairLabel);
- if (d->CrosshairPen.color() == newColor)
- {
- return;
- }
- d->CrosshairPen.setColor(newColor);
- this->update();
- }
- // --------------------------------------------------------------------------
- int ctkCrosshairLabel::lineWidth() const
- {
- Q_D(const ctkCrosshairLabel);
- return d->CrosshairPen.width();
- }
- // --------------------------------------------------------------------------
- void ctkCrosshairLabel::setLineWidth(int newWidth)
- {
- Q_D(ctkCrosshairLabel);
- if (d->CrosshairPen.width() == newWidth || newWidth < 0)
- {
- return;
- }
- d->CrosshairPen.setWidth(newWidth);
- this->update();
- }
- // --------------------------------------------------------------------------
- CTK_GET_CPP(ctkCrosshairLabel, ctkCrosshairLabel::CrosshairTypes,
- crosshairType, CrosshairType)
- // --------------------------------------------------------------------------
- void ctkCrosshairLabel::setCrosshairType(const CrosshairTypes& newType)
- {
- Q_D(ctkCrosshairLabel);
- if (newType == d->CrosshairType)
- {
- return;
- }
- d->CrosshairType = newType;
- this->update();
- }
- // --------------------------------------------------------------------------
- QColor ctkCrosshairLabel::marginColor() const
- {
- return this->palette().color(QPalette::Window);
- }
- // --------------------------------------------------------------------------
- void ctkCrosshairLabel::setMarginColor(const QColor& newColor)
- {
- if (!newColor.isValid())
- {
- return;
- }
- QPalette palette(this->palette());
- QColor solidColor(newColor.rgb());
- if (solidColor != palette.color(QPalette::Window))
- {
- // Ignore alpha channel
- palette.setColor(QPalette::Window, solidColor);
- this->setPalette(palette);
- this->update();
- }
- }
- // --------------------------------------------------------------------------
- CTK_GET_CPP(ctkCrosshairLabel, int, bullsEyeWidth, BullsEyeWidth)
- // --------------------------------------------------------------------------
- void ctkCrosshairLabel::setBullsEyeWidth(int newWidth)
- {
- Q_D(ctkCrosshairLabel);
- if (newWidth == d->BullsEyeWidth || newWidth < 0)
- {
- return;
- }
- d->BullsEyeWidth = newWidth;
- this->update();
- }
- // --------------------------------------------------------------------------
- void ctkCrosshairLabel::paintEvent(QPaintEvent * event)
- {
- Superclass::paintEvent(event);
- Q_D(ctkCrosshairLabel);
- d->drawCrosshair();
- }
- // --------------------------------------------------------------------------
- QSize ctkCrosshairLabel::minimumSizeHint()const
- {
- // Pretty arbitrary size (matches ctkVTKAbstractView)
- return QSize(50, 50);
- }
- // --------------------------------------------------------------------------
- QSize ctkCrosshairLabel::sizeHint()const
- {
- // Pretty arbitrary size (matches ctkVTKAbstractView)
- return QSize(300, 300);
- }
- //----------------------------------------------------------------------------
- bool ctkCrosshairLabel::hasHeightForWidth()const
- {
- return true;
- }
- //----------------------------------------------------------------------------
- int ctkCrosshairLabel::heightForWidth(int width)const
- {
- // Tends to be square
- return width;
- }
|