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;