implement toggle action for icon menu
This commit is contained in:
parent
bb2f00bab1
commit
8a0daa0c8f
|
@ -1,5 +1,8 @@
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QPainter>
|
||||||
#include "iconmenu.h"
|
#include "iconmenu.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
|
@ -7,6 +10,7 @@ MenuOverlay::MenuOverlay(QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
{
|
{
|
||||||
setAttribute(Qt::WA_NoSystemBackground);
|
setAttribute(Qt::WA_NoSystemBackground);
|
||||||
|
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuOverlay::~MenuOverlay()
|
MenuOverlay::~MenuOverlay()
|
||||||
|
@ -15,11 +19,27 @@ MenuOverlay::~MenuOverlay()
|
||||||
|
|
||||||
IconMenu::IconMenu(const QIcon &icon, QWidget *parent)
|
IconMenu::IconMenu(const QIcon &icon, QWidget *parent)
|
||||||
: IconButton(icon, parent),
|
: IconButton(icon, parent),
|
||||||
_menuOverlay(new MenuOverlay(parent)),
|
_menuOverlay(new MenuOverlay),
|
||||||
_menu(new Menu(_menuOverlay)),
|
_menu(new Menu(_menuOverlay)),
|
||||||
_menuGeometryWidget(0)
|
_animation(new QPropertyAnimation(this)),
|
||||||
|
_menuVisible(false),
|
||||||
|
_progress(0)
|
||||||
{
|
{
|
||||||
setCheckable(true);
|
setCheckable(true);
|
||||||
|
setOverlayParent(parent);
|
||||||
|
|
||||||
|
_animation->setPropertyName("progress");
|
||||||
|
_animation->setTargetObject(this);
|
||||||
|
_animation->setDuration(350);
|
||||||
|
_animation->setStartValue(1);
|
||||||
|
_animation->setEndValue(0);
|
||||||
|
|
||||||
|
_menu->hide();
|
||||||
|
|
||||||
|
_menuOverlay->installEventFilter(this);
|
||||||
|
|
||||||
|
connect(this, SIGNAL(clicked(bool)), this, SLOT(toggleMenu()));
|
||||||
|
connect(_animation, SIGNAL(finished()), this, SLOT(animationFinished()));
|
||||||
|
|
||||||
_menu->addMenuItem("Maps");
|
_menu->addMenuItem("Maps");
|
||||||
_menu->addMenuItem("Books");
|
_menu->addMenuItem("Books");
|
||||||
|
@ -31,17 +51,65 @@ IconMenu::~IconMenu()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IconMenu::setProgress(qreal progress)
|
||||||
|
{
|
||||||
|
if (_progress == progress)
|
||||||
|
return;
|
||||||
|
_progress = progress;
|
||||||
|
|
||||||
|
emit progressChanged(progress);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
void IconMenu::setOverlayParent(QWidget *parent)
|
void IconMenu::setOverlayParent(QWidget *parent)
|
||||||
{
|
{
|
||||||
_menuOverlay->setParent(parent);
|
_menuOverlay->setParent(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IconMenu::toggleMenu()
|
||||||
|
{
|
||||||
|
_animation->setDirection(_menuVisible
|
||||||
|
? QAbstractAnimation::Forward
|
||||||
|
: QAbstractAnimation::Backward);
|
||||||
|
_animation->start();
|
||||||
|
|
||||||
|
_menuVisible = !_menuVisible;
|
||||||
|
|
||||||
|
if (_menuVisible) {
|
||||||
|
_menu->show();
|
||||||
|
_menuOverlay->setAttribute(Qt::WA_TransparentForMouseEvents, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconMenu::animationFinished()
|
||||||
|
{
|
||||||
|
if (!_menuVisible) {
|
||||||
|
_menu->hide();
|
||||||
|
_menuOverlay->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IconMenu::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if (QEvent::MouseButtonRelease == event->type() && _menuOverlay == obj)
|
||||||
|
toggleMenu();
|
||||||
|
return IconButton::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
bool IconMenu::event(QEvent *event)
|
bool IconMenu::event(QEvent *event)
|
||||||
{
|
{
|
||||||
if (QEvent::ParentChange == event->type()) {
|
const QEvent::Type &type = event->type();
|
||||||
|
if (QEvent::ParentChange == type) {
|
||||||
setOverlayParent(parentWidget());
|
setOverlayParent(parentWidget());
|
||||||
QSize hint = _menu->layout()->sizeHint();
|
updateOverlayGeometry();
|
||||||
_menuOverlay->setGeometry(0, 0, hint.width(), hint.height());
|
} else if (QEvent::Move == type || QEvent::Resize == type) {
|
||||||
|
_menuPos = parentWidget()->mapToParent(pos());
|
||||||
|
updateOverlayGeometry();
|
||||||
}
|
}
|
||||||
return IconButton::event(event);
|
return IconButton::event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IconMenu::updateOverlayGeometry()
|
||||||
|
{
|
||||||
|
_menu->setGeometry(QRect(_menuPos, _menu->layout()->sizeHint()));
|
||||||
|
}
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
#define ICONMENU_H
|
#define ICONMENU_H
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QPoint>
|
||||||
#include "iconbutton.h"
|
#include "iconbutton.h"
|
||||||
|
|
||||||
class Menu;
|
|
||||||
|
|
||||||
class MenuOverlay : public QWidget
|
class MenuOverlay : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -15,23 +14,44 @@ public:
|
||||||
~MenuOverlay();
|
~MenuOverlay();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QPropertyAnimation;
|
||||||
|
class Menu;
|
||||||
|
|
||||||
class IconMenu : public IconButton
|
class IconMenu : public IconButton
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(qreal progress WRITE setProgress READ progress NOTIFY progressChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit IconMenu(const QIcon &icon, QWidget *parent = 0);
|
explicit IconMenu(const QIcon &icon, QWidget *parent = 0);
|
||||||
~IconMenu();
|
~IconMenu();
|
||||||
|
|
||||||
|
void setProgress(qreal progress);
|
||||||
|
inline qreal progress() const { return _progress; }
|
||||||
|
|
||||||
void setOverlayParent(QWidget *parent);
|
void setOverlayParent(QWidget *parent);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void toggleMenu();
|
||||||
|
void animationFinished();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void progressChanged(qreal);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
|
||||||
bool event(QEvent *event) Q_DECL_OVERRIDE;
|
bool event(QEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void updateOverlayGeometry();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MenuOverlay *const _menuOverlay;
|
MenuOverlay *const _menuOverlay;
|
||||||
Menu *const _menu;
|
Menu *const _menu;
|
||||||
QWidget *_menuGeometryWidget;
|
QPropertyAnimation *const _animation;
|
||||||
|
QPoint _menuPos;
|
||||||
|
bool _menuVisible;
|
||||||
|
qreal _progress;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ICONMENU_H
|
#endif // ICONMENU_H
|
||||||
|
|
Loading…
Reference in New Issue