Bennett Helm wrote: > What I meant is that when the panel pops up, there's no clear indication > from its appearance that tearing it off can work, and so people won't > likely try clicking there and discover the tear-off feature. Is there > some other way to make this function more apparent?
i've added a tooltip but for the moment tooltips don't show in the panels i don't know why: when we tear off the panel (ie set windowflags to Qt:Tool) they *do* show so i am afraid that for the moment this is just the way it is (unless someone else comes up with the solution)... > But then it should not be resizable. the attached patch does that ... in summary: - allow panels to tear off using only qt 4.1 functionality - reported to work on windows, linux and mac seeking 2 ok's
Index: src/frontends/qt4/IconPalette.cpp =================================================================== --- src/frontends/qt4/IconPalette.cpp (revision 18822) +++ src/frontends/qt4/IconPalette.cpp (working copy) @@ -25,99 +25,80 @@ #include <QStyle> #include <QStyleOptionFrame> #include <QMouseEvent> +#include <QVBoxLayout> namespace lyx { namespace frontend { -#if QT_VERSION >= 0x040200 - - -class MathButton : public QToolButton +TearOff::TearOff(QWidget * parent) + : QWidget(parent) { -public: - MathButton(QWidget * parent = 0) {} - void mouseReleaseEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent *event); -}; + highlighted_ = false; + setMinimumHeight(8); + setToolTip(qt_("Click to tear off")); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); +} -void MathButton::mouseReleaseEvent(QMouseEvent *event) +void TearOff::mouseReleaseEvent(QMouseEvent * event) { - QToolButton::mouseReleaseEvent(event); - event->ignore(); + // signal + tearOff(); } -void MathButton::mousePressEvent(QMouseEvent *event) +void TearOff::enterEvent(QEvent * event) { - QToolButton::mousePressEvent(event); + highlighted_ = true; + update(); event->ignore(); } -IconPalette::IconPalette(QWidget * parent) - : QWidgetAction(parent), size_(QSize(22, 22)) +void TearOff::leaveEvent(QEvent * event) { + highlighted_ = false; + update(); + event->ignore(); } -void IconPalette::addButton(QAction * action) +void TearOff::paintEvent(QPaintEvent * event) { - actions_.push_back(action); + 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); } -QWidget * IconPalette::createWidget(QWidget * parent) -{ - 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; -} - - -void IconPalette::setIconSize(const QSize & size) -{ - size_ = size; - // signal - iconSizeChanged(size); -} - - -void IconPalette::updateParent() -{ - bool enable = false; - for (int i = 0; i < actions_.size(); ++i) - if (actions_.at(i)->isEnabled()) { - enable = true; - break; - } - // signal - enabled(enable); -} - -#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); + layout_->setMargin(2); + tearoffwidget_ = new TearOff(this); + connect(tearoffwidget_, SIGNAL(tearOff()), this, SLOT(tearOff())); + v->addWidget(tearoffwidget_); + v->addLayout(layout_); } @@ -141,15 +122,30 @@ } +void IconPalette::tearOff() +{ + blockSignals(true); + 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,14 +179,20 @@ 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); + if (tornoff_) { + setWindowFlags(Qt::Window | Qt::Popup); + tornoff_ = false; + tearoffwidget_->setVisible(!tornoff_); + } QWidget::hideEvent(event); } @@ -211,17 +213,15 @@ 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 +230,7 @@ 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: src/frontends/qt4/IconPalette.h =================================================================== --- src/frontends/qt4/IconPalette.h (revision 18822) +++ src/frontends/qt4/IconPalette.h (working copy) @@ -17,40 +17,32 @@ #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 @@ 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: src/frontends/qt4/QLToolbar.cpp =================================================================== --- src/frontends/qt4/QLToolbar.cpp (revision 18822) +++ src/frontends/qt4/QLToolbar.cpp (working copy) @@ -212,15 +212,8 @@ 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(); @@ -239,18 +232,10 @@ 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;