implement toggle action for icon menu

This commit is contained in:
laserpants 2016-04-27 02:14:39 +03:00
parent bb2f00bab1
commit 8a0daa0c8f
2 changed files with 98 additions and 10 deletions

View File

@ -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()));
}

View File

@ -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