]> git.lyx.org Git - features.git/commitdiff
* Get rid the of the QWidgetAction subclass and use homebrew tearoff widget:
authorEdwin Leuven <e.leuven@gmail.com>
Thu, 21 Jun 2007 09:51:50 +0000 (09:51 +0000)
committerEdwin Leuven <e.leuven@gmail.com>
Thu, 21 Jun 2007 09:51:50 +0000 (09:51 +0000)
  this is a qt 4.1 solution and behaves on all platforms

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@18842 a592a061-630c-0410-9148-cb99ea01b6c8

src/frontends/qt4/IconPalette.cpp
src/frontends/qt4/IconPalette.h
src/frontends/qt4/QLToolbar.cpp

index 40a34ffa49a5ee41a05f2886781bf32f8d217b9c..43d0b14bbb07f17311c1acd6bff2157cd788bab0 100644 (file)
 #include <QStyle>
 #include <QStyleOptionFrame>
 #include <QMouseEvent>
+#include <QVBoxLayout>
 
 namespace lyx {
 namespace frontend {
 
-#if QT_VERSION >= 0x040200
-
-
-class MathButton : public QToolButton
-{
-public:
-       MathButton(QWidget * parent = 0) {}
-       void mouseReleaseEvent(QMouseEvent *event); 
-       void mousePressEvent(QMouseEvent *event); 
-};
-
-
-void MathButton::mouseReleaseEvent(QMouseEvent *event)
-{
-       QToolButton::mouseReleaseEvent(event);
-       event->ignore();
-}
-
-
-void MathButton::mousePressEvent(QMouseEvent *event)
+TearOff::TearOff(QWidget * parent) 
+       : QWidget(parent)
 {
-       QToolButton::mousePressEvent(event);
-       event->ignore();
+       highlighted_ = false;
+       // + 2 because the default is a bit tight, see also:
+       // http://trolltech.com/developer/task-tracker/index_html?id=167954&method=entry
+       setMinimumHeight(style()->pixelMetric(QStyle::PM_MenuTearoffHeight) + 2);
+       setToolTip(qt_("Click to detach"));
+       // trigger tooltip (children of popups do not receive mousemove events)
+       setMouseTracking(true);
 }
 
 
-IconPalette::IconPalette(QWidget * parent)
-       : QWidgetAction(parent), size_(QSize(22, 22))
+void TearOff::mouseReleaseEvent(QMouseEvent * event)
 {
+       // signal
+       tearOff();
 }
 
 
-void IconPalette::addButton(QAction * action)
-{
-       actions_.push_back(action);
-}
-
-
-QWidget * IconPalette::createWidget(QWidget * parent)
+void TearOff::enterEvent(QEvent * event)
 {
-       QWidget * widget = new QWidget(parent);
-       QGridLayout * layout = new QGridLayout(widget);
-       layout->setSpacing(0);
-
-       for (int i = 0; i < actions_.size(); ++i) {
-               MathButton * tb = new MathButton(widget);
-               tb->setAutoRaise(true);
-               tb->setDefaultAction(actions_.at(i));
-               tb->setIconSize(size_);
-               connect(this, SIGNAL(iconSizeChanged(const QSize &)),
-                       tb, SLOT(setIconSize(const QSize &)));
-       
-               int const row = i/qMin(6, i + 1) + 1;
-               int const col = qMax(1, i + 1 - (row - 1) * 6);
-               layout->addWidget(tb, row, col);
-       }
-
-       return widget;
+       highlighted_ = true;
+       update();
+       event->ignore();
 }
 
 
-void IconPalette::setIconSize(const QSize & size)
+void TearOff::leaveEvent(QEvent * event)
 {
-       size_ = size;
-       // signal
-       iconSizeChanged(size);
+       highlighted_ = false;
+       update();
+       event->ignore();
 }
 
 
-void IconPalette::updateParent()
+void TearOff::paintEvent(QPaintEvent * event)
 {
-       bool enable = false;
-       for (int i = 0; i < actions_.size(); ++i)
-               if (actions_.at(i)->isEnabled()) {
-                       enable = true;
-                       break;
-               }
-       // signal
-       enabled(enable);
+       QPainter p(this);
+       const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this);
+       QStyleOptionMenuItem menuOpt;
+       menuOpt.initFrom(this);
+       menuOpt.palette = palette();
+       menuOpt.state = QStyle::State_None;
+       menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
+       menuOpt.menuRect = rect();
+       menuOpt.maxIconWidth = 0;
+       menuOpt.tabWidth = 0;
+       menuOpt.menuItemType = QStyleOptionMenuItem::TearOff;
+       menuOpt.rect.setRect(fw, fw, width() - (fw * 2),
+               style()->pixelMetric(QStyle::PM_MenuTearoffHeight, 0, this));
+       p.setClipRect(menuOpt.rect);
+       menuOpt.state = QStyle::State_None;
+       if (highlighted_)
+               menuOpt.state |= QStyle::State_Selected;
+       style()->drawControl(QStyle::CE_MenuTearoff, &menuOpt, &p, this);
 }
 
-#else  // QT_VERSION >= 0x040200
 
 IconPalette::IconPalette(QWidget * parent)
-       : QWidget(parent, Qt::Popup)
+       : QWidget(parent, Qt::Popup), tornoff_(false)
 {
-       layout_ = new QGridLayout(this);
+       QVBoxLayout * v = new QVBoxLayout(this);
+       v->setMargin(0);
+       v->setSpacing(0);
+       layout_ = new QGridLayout;
        layout_->setSpacing(0);
-       layout_->setMargin(3);
+       const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this);
+       layout_->setMargin(fw);
+       tearoffwidget_ = new TearOff(this);
+       connect(tearoffwidget_, SIGNAL(tearOff()), this, SLOT(tearOff()));
+       v->addWidget(tearoffwidget_);
+       v->addLayout(layout_);
 }
 
 
@@ -127,6 +112,9 @@ void IconPalette::addButton(QAction * action)
        QToolButton * tb = new QToolButton;
        tb->setAutoRaise(true);
        tb->setDefaultAction(action);
+       // trigger tooltip (children of popups do not receive mousemove events)
+       tb->setMouseTracking(true);
+
        connect(tb, SIGNAL(triggered(QAction *)),
                this, SLOT(clicked(QAction *)));
        QToolBar * toolbar = qobject_cast<QToolBar *>(parentWidget()->parentWidget());
@@ -141,15 +129,31 @@ void IconPalette::addButton(QAction * action)
 }
 
 
+void IconPalette::tearOff()
+{
+       blockSignals(true);
+       hide();
+       setWindowFlags(Qt::Tool);
+       tornoff_ = true;
+       tearoffwidget_->setVisible(!tornoff_);
+       show();
+       blockSignals(false);
+}
+
+
 void IconPalette::clicked(QAction * action)
 {
        triggered(action);
-       setVisible(false);
+       if (!tornoff_)
+               setVisible(false);
 }
 
 
 void IconPalette::showEvent(QShowEvent * event)
 {
+       resize(sizeHint());
+       setMaximumSize(sizeHint());
+
        int hoffset = - parentWidget()->pos().x();
        int voffset = - parentWidget()->pos().y();
        int const parwidth = parentWidget()->geometry().width();
@@ -183,15 +187,21 @@ void IconPalette::showEvent(QShowEvent * event)
                        voffset += parheight;
        }
 
-       move(gpos.x() + hoffset, gpos.y() + voffset);
-       QWidget::showEvent(event);
+       QRect r = rect();
+       r.moveTo(gpos.x() + hoffset, gpos.y() + voffset);
+       setGeometry(r); 
 }
 
 
 void IconPalette::hideEvent(QHideEvent * event )
 {
-       visible(false);
        QWidget::hideEvent(event);
+       visible(false);
+       if (tornoff_) {
+               setWindowFlags(Qt::Popup);
+               tornoff_ = false;
+               tearoffwidget_->setVisible(!tornoff_);
+       }
 }
 
 
@@ -211,17 +221,15 @@ void IconPalette::updateParent()
 void IconPalette::paintEvent(QPaintEvent * event)
 {
        // draw border
-       QPainter p(this);
-       QRegion emptyArea = QRegion(rect());
        const int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, this);
-       if (fw) {
+       if (fw && !tornoff_) {
+               QPainter p(this);
                QRegion borderReg;
                borderReg += QRect(0, 0, fw, height()); //left
-               borderReg += QRect(width()-fw, 0, fw, height()); //right
+               borderReg += QRect(width() - fw, 0, fw, height()); //right
                borderReg += QRect(0, 0, width(), fw); //top
-               borderReg += QRect(0, height()-fw, width(), fw); //bottom
+               borderReg += QRect(0, height() - fw, width(), fw); //bottom
                p.setClipRegion(borderReg);
-               emptyArea -= borderReg;
                QStyleOptionFrame frame;
                frame.rect = rect();
                frame.palette = palette();
@@ -230,11 +238,7 @@ void IconPalette::paintEvent(QPaintEvent * event)
                frame.midLineWidth = 0;
                style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, &p, this);
        }
-       p.end();
-       // draw the rest (buttons)
-       QWidget::paintEvent(event);
 }
-#endif // QT_VERSION >= 0x040200
 
 
 ButtonMenu::ButtonMenu(const QString & title, QWidget * parent)
index ed1fb2ae492b5adba6a6c4de410c98d830c449b3..3b72e500828d24ccedbce6e689a57bf742e39796 100644 (file)
 #include <QLayout>
 #include "Action.h"
 
-// FIXME: this can go when we move to Qt 4.3
-#define QT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
-
-#if QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)
-#include <QWidgetAction>
-#endif
 
 namespace lyx {
 namespace frontend {
 
 /**
- * For holding an arbitrary set of icons.
- */
-#if QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)
-
-class IconPalette : public QWidgetAction {
+  * tear-off widget
+  */
+class TearOff : public QWidget {
        Q_OBJECT
 public:
-       IconPalette(QWidget * parent);
-       void addButton(QAction *);
-       QWidget * createWidget(QWidget * parent);
-public Q_SLOTS:
-       void updateParent();
-       void setIconSize(const QSize &);
+       TearOff(QWidget * parent);
+       void enterEvent(QEvent *);
+       void leaveEvent(QEvent *);
+       void mouseReleaseEvent (QMouseEvent *);
 Q_SIGNALS:
-       void enabled(bool);
-       void iconSizeChanged(const QSize &);
+       void tearOff();
+protected:
+       void paintEvent(QPaintEvent *);
 private:
-       QList<QAction *> actions_;
-       QSize size_;
+       bool highlighted_;
 };
 
-#else
 
+/**
+ * For holding an arbitrary set of icons.
+ */
 class IconPalette : public QWidget {
        Q_OBJECT
 public:
@@ -70,14 +62,16 @@ protected:
        void paintEvent(QPaintEvent * event);
 
 private Q_SLOTS:
+       void tearOff();
        virtual void clicked(QAction *);
 
 private:
        QGridLayout * layout_;
        QList<QAction *> actions_;
+       bool tornoff_;
+       TearOff * tearoffwidget_; 
 };
 
-#endif // QT_VERSION >= QT_VERSION_CHECK(4, 2, 0)
 
 /**
  * Popup menu for a toolbutton.
index ac3ed551b30828eb5bc869d5f8275c4a8072e122..1340920abe58e45f63777e2bbb057023794bae74 100644 (file)
@@ -211,16 +211,7 @@ void QLToolbar::add(ToolbarItem const & item)
                tb->setText(qt_(to_ascii(item.label_)));
                connect(this, SIGNAL(iconSizeChanged(const QSize &)),
                        tb, SLOT(setIconSize(const QSize &)));
-
-#if QT_VERSION >= 0x040200
-               IconPalette * panel = new IconPalette(&owner_);
-               connect(panel, SIGNAL(enabled(bool)),
-                       tb, SLOT(setEnabled(bool)));
-               connect(this, SIGNAL(iconSizeChanged(const QSize &)),
-                       panel, SLOT(setIconSize(const QSize &)));
-#else
                IconPalette * panel = new IconPalette(tb);
-#endif
                connect(this, SIGNAL(updated()), panel, SLOT(updateParent()));
                ToolbarInfo const & tbinfo = toolbarbackend.getToolbar(item.name_);
                ToolbarInfo::item_iterator it = tbinfo.items.begin();
@@ -238,20 +229,9 @@ void QLToolbar::add(ToolbarItem const & item)
                                if (it == tbinfo.items.begin())
                                        tb->setIcon(QPixmap(getIcon(it->func_).c_str()));
                        }
-
-#if QT_VERSION >= 0x040200
-               QMenu * m = new QMenu(tb);
-               m->addAction(panel);
-               m->setTearOffEnabled(true);
-               m->setWindowTitle(qt_(to_ascii(item.label_)));
-               tb->setPopupMode(QToolButton::InstantPopup);
-               tb->setMenu(m);
-#else
                tb->setCheckable(true);
                connect(tb, SIGNAL(clicked(bool)), panel, SLOT(setVisible(bool)));
                connect(panel, SIGNAL(visible(bool)), tb, SLOT(setChecked(bool)));
-#endif // QT_VERSION >= 0x040200
-
                addWidget(tb);
                break;
                }