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 <QLayout>
#include <QPropertyAnimation>
#include <QDebug>
#include <QPainter>
#include "iconmenu.h"
#include "menu.h"
@ -7,6 +10,7 @@ MenuOverlay::MenuOverlay(QWidget *parent)
: QWidget(parent)
{
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_TransparentForMouseEvents);
}
MenuOverlay::~MenuOverlay()
@ -15,11 +19,27 @@ MenuOverlay::~MenuOverlay()
IconMenu::IconMenu(const QIcon &icon, QWidget *parent)
: IconButton(icon, parent),
_menuOverlay(new MenuOverlay(parent)),
_menuOverlay(new MenuOverlay),
_menu(new Menu(_menuOverlay)),
_menuGeometryWidget(0)
_animation(new QPropertyAnimation(this)),
_menuVisible(false),
_progress(0)
{
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("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)
{
_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)
{
if (QEvent::ParentChange == event->type()) {
const QEvent::Type &type = event->type();
if (QEvent::ParentChange == type) {
setOverlayParent(parentWidget());
QSize hint = _menu->layout()->sizeHint();
_menuOverlay->setGeometry(0, 0, hint.width(), hint.height());
updateOverlayGeometry();
} else if (QEvent::Move == type || QEvent::Resize == type) {
_menuPos = parentWidget()->mapToParent(pos());
updateOverlayGeometry();
}
return IconButton::event(event);
}
void IconMenu::updateOverlayGeometry()
{
_menu->setGeometry(QRect(_menuPos, _menu->layout()->sizeHint()));
}

View File

@ -2,10 +2,9 @@
#define ICONMENU_H
#include <QWidget>
#include <QPoint>
#include "iconbutton.h"
class Menu;
class MenuOverlay : public QWidget
{
Q_OBJECT
@ -15,23 +14,44 @@ public:
~MenuOverlay();
};
class QPropertyAnimation;
class Menu;
class IconMenu : public IconButton
{
Q_OBJECT
Q_PROPERTY(qreal progress WRITE setProgress READ progress NOTIFY progressChanged)
public:
explicit IconMenu(const QIcon &icon, QWidget *parent = 0);
~IconMenu();
void setProgress(qreal progress);
inline qreal progress() const { return _progress; }
void setOverlayParent(QWidget *parent);
protected slots:
void toggleMenu();
void animationFinished();
signals:
void progressChanged(qreal);
protected:
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
bool event(QEvent *event) Q_DECL_OVERRIDE;
void updateOverlayGeometry();
private:
MenuOverlay *const _menuOverlay;
Menu *const _menu;
QWidget *_menuGeometryWidget;
MenuOverlay *const _menuOverlay;
Menu *const _menu;
QPropertyAnimation *const _animation;
QPoint _menuPos;
bool _menuVisible;
qreal _progress;
};
#endif // ICONMENU_H