| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 | 
							- /*=========================================================================
 
-   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 <QApplication>
 
- #include <QCleanlooksStyle>
 
- #include <QDebug>
 
- #include <QDesktopWidget>
 
- #include <QLayout>
 
- #include <QMouseEvent>
 
- #include <QMenu>
 
- #include <QPainter>
 
- #include <QPointer>
 
- #include <QPushButton>
 
- #include <QStyle>
 
- #include <QStyleOptionButton>
 
- #include <QStylePainter>
 
- #include <QToolBar>
 
- // CTK includes
 
- #include "ctkCheckablePushButton.h"
 
- //-----------------------------------------------------------------------------
 
- class ctkCheckablePushButtonPrivate
 
- {
 
-   Q_DECLARE_PUBLIC(ctkCheckablePushButton);
 
- protected:
 
-   ctkCheckablePushButton* const q_ptr;
 
- public:
 
-   ctkCheckablePushButtonPrivate(ctkCheckablePushButton& object);
 
-   void init();
 
-   QRect checkboxRect() const;
 
-   QSize buttonSizeHint()const;
 
-   // Tuning of the button look&feel
 
-   Qt::Alignment TextAlignment;
 
-   Qt::Alignment IndicatorAlignment;
 
- };
 
- //-----------------------------------------------------------------------------
 
- ctkCheckablePushButtonPrivate::ctkCheckablePushButtonPrivate(ctkCheckablePushButton& object)
 
-   :q_ptr(&object)
 
- {
 
-   this->TextAlignment = Qt::AlignLeft | Qt::AlignVCenter;
 
-   this->IndicatorAlignment = Qt::AlignLeft | Qt::AlignVCenter;
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkCheckablePushButtonPrivate::init()
 
- {
 
- }
 
- //-----------------------------------------------------------------------------
 
- QRect ctkCheckablePushButtonPrivate::checkboxRect()const
 
- {
 
-   Q_Q(const ctkCheckablePushButton);
 
-   QRect rect;
 
-   QStyleOptionButton opt;
 
-   q->initStyleOption(&opt);
 
-   QSize indicatorSize = QSize(q->style()->pixelMetric(QStyle::PM_IndicatorWidth, &opt, q),
 
-                               q->style()->pixelMetric(QStyle::PM_IndicatorHeight, &opt, q));
 
-   int buttonHeight = opt.rect.height();
 
-   uint tf = this->TextAlignment;
 
-   if (q->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, q))
 
-     {
 
-     tf |= Qt::TextShowMnemonic;
 
-     }
 
-   else
 
-     {
 
-     tf |= Qt::TextHideMnemonic;
 
-     }
 
-   int textWidth = opt.fontMetrics.boundingRect(opt.rect, tf, opt.text).width();
 
-   int indicatorSpacing = q->style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &opt, q);
 
-   int buttonMargin = q->style()->pixelMetric(QStyle::PM_ButtonMargin, &opt, q);
 
-   if (this->IndicatorAlignment & Qt::AlignLeft)
 
-     {
 
-     rect = QRect((buttonHeight - indicatorSize.width()) / 2,
 
-                  (buttonHeight - indicatorSize.height()) / 2,
 
-                  indicatorSize.width(), indicatorSize.height());
 
-     }
 
-   else if (this->IndicatorAlignment & Qt::AlignHCenter)
 
-     {
 
-     int w = indicatorSize.width();
 
-     if (!opt.text.isEmpty() && (this->TextAlignment & Qt::AlignHCenter))
 
-       {
 
-       w += textWidth + indicatorSpacing;
 
-       }
 
-     rect = QRect(opt.rect.x()+ opt.rect.width() /2 - w / 2,
 
-                  (buttonHeight - indicatorSize.height()) / 2,
 
-                  indicatorSize.width(), indicatorSize.height());
 
-     if (this->TextAlignment & Qt::AlignLeft &&
 
-         rect.left() < opt.rect.x() + buttonMargin + textWidth)
 
-       {
 
-       rect.moveLeft(opt.rect.x() + buttonMargin + textWidth);
 
-       }
 
-     else if (this->TextAlignment & Qt::AlignRight &&
 
-              rect.right() > opt.rect.right() - buttonMargin - textWidth)
 
-       {
 
-       rect.moveRight(opt.rect.right() - buttonMargin - textWidth);
 
-       }
 
-     }
 
-   else if (this->IndicatorAlignment & Qt::AlignRight)
 
-     {
 
-     rect = QRect(opt.rect.width() - (buttonHeight - indicatorSize.width()) / 2
 
-                                   - indicatorSize.width(),
 
-                  (buttonHeight - indicatorSize.height()) / 2,
 
-                  indicatorSize.width(), indicatorSize.height());
 
-     }
 
-   return rect;
 
- }
 
- //-----------------------------------------------------------------------------
 
- QSize ctkCheckablePushButtonPrivate::buttonSizeHint()const
 
- {
 
-   Q_Q(const ctkCheckablePushButton);
 
-   int w = 0, h = 0;
 
-   QStyleOptionButton opt;
 
-   opt.initFrom(q);
 
-   
 
-   // indicator
 
-   QSize indicatorSize = QSize(q->style()->pixelMetric(QStyle::PM_IndicatorWidth, &opt, q),
 
-                               q->style()->pixelMetric(QStyle::PM_IndicatorHeight, &opt, q));
 
-   int indicatorSpacing = q->style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &opt, q);
 
-   int ih = indicatorSize.height();
 
-   int iw = indicatorSize.width() + indicatorSpacing;
 
-   w += iw;
 
-   h = qMax(h, ih);
 
-   
 
-   // text 
 
-   QString string(q->text());
 
-   bool empty = string.isEmpty();
 
-   if (empty)
 
-     {
 
-     string = QString::fromLatin1("XXXX");
 
-     }
 
-   QFontMetrics fm = q->fontMetrics();
 
-   QSize sz = fm.size(Qt::TextShowMnemonic, string);
 
-   if(!empty || !w)
 
-     {
 
-     w += sz.width();
 
-     }
 
-   h = qMax(h, sz.height());
 
-   //opt.rect.setSize(QSize(w, h)); // PM_MenuButtonIndicator depends on the height
 
-   QSize buttonSize = (q->style()->sizeFromContents(QStyle::CT_PushButton, &opt, QSize(w, h), q).
 
-                       expandedTo(QApplication::globalStrut()));
 
-   return buttonSize;
 
- }
 
- //-----------------------------------------------------------------------------
 
- ctkCheckablePushButton::ctkCheckablePushButton(QWidget* _parent)
 
-   :QPushButton(_parent)
 
-   , d_ptr(new ctkCheckablePushButtonPrivate(*this))
 
- {
 
-   Q_D(ctkCheckablePushButton);
 
-   d->init();
 
- }
 
- //-----------------------------------------------------------------------------
 
- ctkCheckablePushButton::ctkCheckablePushButton(const QString& title, QWidget* _parent)
 
-   :QPushButton(title, _parent)
 
-   , d_ptr(new ctkCheckablePushButtonPrivate(*this))
 
- {
 
- }
 
- //-----------------------------------------------------------------------------
 
- ctkCheckablePushButton::~ctkCheckablePushButton()
 
- {
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkCheckablePushButton::setButtonTextAlignment(Qt::Alignment textAlignment)
 
- {
 
-   Q_D(ctkCheckablePushButton);
 
-   d->TextAlignment = textAlignment;
 
-   this->update();
 
- }
 
- //-----------------------------------------------------------------------------
 
- Qt::Alignment ctkCheckablePushButton::buttonTextAlignment()const
 
- {
 
-   Q_D(const ctkCheckablePushButton);
 
-   return d->TextAlignment;
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkCheckablePushButton::setIndicatorAlignment(Qt::Alignment indicatorAlignment)
 
- {
 
-   Q_D(ctkCheckablePushButton);
 
-   d->IndicatorAlignment = indicatorAlignment;
 
-   this->update();
 
- }
 
- //-----------------------------------------------------------------------------
 
- Qt::Alignment ctkCheckablePushButton::indicatorAlignment()const
 
- {
 
-   Q_D(const ctkCheckablePushButton);
 
-   return d->IndicatorAlignment;
 
- }
 
- //-----------------------------------------------------------------------------
 
- QSize ctkCheckablePushButton::minimumSizeHint()const
 
- {
 
-   Q_D(const ctkCheckablePushButton);
 
-   return d->buttonSizeHint();
 
- }
 
- //-----------------------------------------------------------------------------
 
- QSize ctkCheckablePushButton::sizeHint()const
 
- {
 
-   return this->minimumSizeHint();
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkCheckablePushButton::paintEvent(QPaintEvent * _event)
 
- {
 
-   Q_UNUSED(_event);
 
-   Q_D(ctkCheckablePushButton);
 
-   QPainter p(this);
 
-   // Draw Button
 
-   QStyleOptionButton opt;
 
-   this->initStyleOption(&opt);
 
-   // Checkbox size
 
-   QSize indicatorSize = QSize(style()->pixelMetric(QStyle::PM_IndicatorWidth, &opt, this),
 
-                               style()->pixelMetric(QStyle::PM_IndicatorHeight, &opt, this));
 
-   // Replace the icon size by the checkbox size
 
-   opt.iconSize = indicatorSize;
 
-   // Draw the panel of the button (no text, no icon)
 
-   style()->drawControl(QStyle::CE_PushButtonBevel, &opt, &p, this);
 
-   // TBD is PE_PanelButtonCommand better ?
 
-   //style()->drawPrimitive(QStyle::PE_PanelButtonCommand, &opt, &p, this);
 
-   //int buttonHeight = opt.rect.height();
 
-   uint tf = d->TextAlignment;
 
-   if (this->style()->styleHint(QStyle::SH_UnderlineShortcut, &opt, this))
 
-     {
 
-     tf |= Qt::TextShowMnemonic;
 
-     }
 
-   else
 
-     {
 
-     tf |= Qt::TextHideMnemonic;
 
-     }
 
-   int textWidth = opt.fontMetrics.boundingRect(opt.rect, tf, opt.text).width();
 
-   // Spacing betweent the text and the checkbox
 
-   int indicatorSpacing = this->style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing, &opt, this);
 
-   int buttonMargin = this->style()->pixelMetric(QStyle::PM_ButtonMargin, &opt, this);
 
-   // Draw Indicator
 
-   QStyleOption indicatorOpt;
 
-   indicatorOpt.init(this);
 
-   if (this->isCheckable())
 
-     {
 
-     indicatorOpt.state |= QStyle::State_On;
 
-     }
 
-   else
 
-     {
 
-     indicatorOpt.state |= QStyle::State_Off;
 
-     }
 
-   indicatorOpt.rect = d->checkboxRect();
 
-   this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &indicatorOpt, &p, 0);
 
-   // Draw Text
 
-   if (d->TextAlignment & Qt::AlignLeft)
 
-     {
 
-     if (d->IndicatorAlignment & Qt::AlignLeft)
 
-       {
 
-       opt.rect.setLeft(indicatorOpt.rect.right() + indicatorSpacing);
 
-       }
 
-     else
 
-       {
 
-       opt.rect.setLeft(opt.rect.x() + buttonMargin);
 
-       }
 
-     }
 
-   else if (d->TextAlignment & Qt::AlignHCenter)
 
-     {
 
-     if (d->IndicatorAlignment & Qt::AlignHCenter)
 
-       {
 
-       opt.rect.setLeft(indicatorOpt.rect.right() + indicatorSpacing);
 
-       }
 
-     else
 
-       {
 
-       opt.rect.setLeft(opt.rect.x() + opt.rect.width() / 2 - textWidth / 2);
 
-       if (d->IndicatorAlignment & Qt::AlignLeft)
 
-         {
 
-         opt.rect.setLeft( qMax(indicatorOpt.rect.right() + indicatorSpacing, opt.rect.left()) );
 
-         }
 
-       }
 
-     }
 
-   else if (d->TextAlignment & Qt::AlignRight)
 
-     {
 
-     if (d->IndicatorAlignment & Qt::AlignRight)
 
-       {
 
-       opt.rect.setLeft(indicatorOpt.rect.left() - indicatorSpacing - textWidth);
 
-       }
 
-     else
 
-       {
 
-       opt.rect.setLeft(opt.rect.right() - buttonMargin - textWidth);
 
-       }
 
-     }
 
-   // all the computations have been made infering the text would be left oriented
 
-   tf &= ~Qt::AlignHCenter & ~Qt::AlignRight;
 
-   tf |= Qt::AlignLeft;
 
-   this->style()->drawItemText(&p, opt.rect, tf, opt.palette, (opt.state & QStyle::State_Enabled),
 
-                         opt.text, QPalette::ButtonText);
 
- }
 
- //-----------------------------------------------------------------------------
 
- bool ctkCheckablePushButton::hitButton(const QPoint & _pos)const
 
- {
 
-   Q_D(const ctkCheckablePushButton);
 
-   return !d->checkboxRect().contains(_pos) 
 
-     && this->QPushButton::hitButton(_pos);
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkCheckablePushButton::initStyleOption(QStyleOptionButton* option)const
 
- {
 
-   this->QPushButton::initStyleOption(option);
 
-   option->iconSize = QSize(this->style()->pixelMetric(QStyle::PM_IndicatorWidth, option, this),
 
-                            this->style()->pixelMetric(QStyle::PM_IndicatorHeight, option, this));
 
- }
 
- //-----------------------------------------------------------------------------
 
- void ctkCheckablePushButton::mousePressEvent(QMouseEvent *e)
 
- {
 
-   Q_D(ctkCheckablePushButton);
 
-   this->QPushButton::mousePressEvent(e);
 
-   if (e->isAccepted())
 
-     {
 
-     return;
 
-     }
 
-   if (d->checkboxRect().contains(e->pos()))
 
-     {
 
-     //check the checkbox
 
-     this->setCheckable(!this->isCheckable());
 
-     this->update();
 
-     e->accept();
 
-     }
 
- }
 
 
  |