Add Icon Menu

This commit is contained in:
johanneshilden 2017-09-29 21:12:46 +03:00
parent dfecc15468
commit 8515cc2c8f
6 changed files with 452 additions and 0 deletions

View File

@ -0,0 +1,169 @@
#include "xx/qtmaterialiconmenu.h"
#include "xx/qtmaterialiconmenu_p.h"
#include <QEvent>
#include <QTimer>
#include "xxlib/qtmaterialoverlaywidget.h"
#include "xx/qtmaterialcollapsiblemenu.h"
/*!
* \class QtMaterialIconMenuPrivate
* \internal
*/
QtMaterialIconMenuPrivate::QtMaterialIconMenuPrivate(QtMaterialIconMenu *q)
: QtMaterialIconButtonPrivate(q)
{
}
QtMaterialIconMenuPrivate::~QtMaterialIconMenuPrivate()
{
}
void QtMaterialIconMenuPrivate::init()
{
Q_Q(QtMaterialIconMenu);
menuOverlay = new QtMaterialOverlayWidget(q);
menu = new QtMaterialCollapsibleMenu;
autoCollapse = true;
menuOverlay->setParent(q->parentWidget());
menuOverlay->setAttribute(Qt::WA_TransparentForMouseEvents);
menuOverlay->installEventFilter(q);
menu->setParent(menuOverlay);
menu->setMaximumHeight(300);
menu->setMinimumWidth(200);
QObject::connect(menu, SIGNAL(aboutToCollapse()), q, SLOT(makeTransparent()));
QObject::connect(menu, SIGNAL(wasExpanded()), q, SLOT(makeOpaque()));
QObject::connect(menu, SIGNAL(aboutToExpand()), menuOverlay, SLOT(raise()));
QObject::connect(menu, SIGNAL(itemClicked(int)), q, SIGNAL(itemSelected(int)));
QObject::connect(menu, SIGNAL(itemClicked(int)), q, SLOT(collapseDelayed()));
}
/*!
* \class QtMaterialIconMenu
*/
QtMaterialIconMenu::QtMaterialIconMenu(const QIcon &icon, QWidget *parent)
: QtMaterialIconButton(*new QtMaterialIconMenuPrivate(this), parent)
{
d_func()->init();
setIcon(icon);
}
QtMaterialIconMenu::~QtMaterialIconMenu()
{
}
void QtMaterialIconMenu::addMenuItem(const QString &text)
{
Q_D(QtMaterialIconMenu);
d->menu->addMenuItem(text);
}
void QtMaterialIconMenu::addMenuItem(QtMaterialMenuItem *item)
{
Q_D(QtMaterialIconMenu);
d->menu->addMenuItem(item);
}
QtMaterialMenuItem *QtMaterialIconMenu::itemAt(int index) const
{
Q_D(const QtMaterialIconMenu);
return d->menu->menuItemAt(index);
}
void QtMaterialIconMenu::setAutoCollapse(bool value)
{
Q_D(QtMaterialIconMenu);
d->autoCollapse = value;
}
bool QtMaterialIconMenu::autoCollapse() const
{
Q_D(const QtMaterialIconMenu);
return d->autoCollapse;
}
void QtMaterialIconMenu::makeTransparent()
{
Q_D(QtMaterialIconMenu);
d->menuOverlay->setAttribute(Qt::WA_TransparentForMouseEvents, true);
}
void QtMaterialIconMenu::makeOpaque()
{
Q_D(QtMaterialIconMenu);
d->menuOverlay->setAttribute(Qt::WA_TransparentForMouseEvents, false);
}
void QtMaterialIconMenu::collapseDelayed()
{
Q_D(QtMaterialIconMenu);
if (d->autoCollapse) {
QTimer::singleShot(110, d->menu, SLOT(collapse()));
}
}
/*!
* \reimp
*/
bool QtMaterialIconMenu::event(QEvent *event)
{
Q_D(QtMaterialIconMenu);
switch (event->type())
{
case QEvent::Move:
case QEvent::Resize:
{
const QSize sh = d->menu->sizeHint();
QPoint p = pos();
p += QPoint(width()/2, height()/2);
d->menu->setGeometry(p.x(), p.y(), sh.width(), sh.height());
break;
}
case QEvent::MouseButtonRelease:
{
if (isEnabled()) {
d->menu->expand();
}
break;
}
case QEvent::ParentChange:
{
QWidget *widget;
if ((widget = parentWidget())) {
d->menuOverlay->setParent(widget);
}
break;
}
default:
break;
}
return QtMaterialIconButton::event(event);
}
/*!
* \reimp
*/
bool QtMaterialIconMenu::eventFilter(QObject *obj, QEvent *event)
{
Q_D(QtMaterialIconMenu);
if (QEvent::MouseButtonPress == event->type()) {
d->menu->collapse();
}
return QtMaterialIconButton::eventFilter(obj, event);
}

View File

@ -0,0 +1,42 @@
#ifndef QTMATERIALICONMENU_H
#define QTMATERIALICONMENU_H
#include "xx/qtmaterialiconbutton.h"
class QtMaterialIconMenuPrivate;
class QtMaterialMenuItem;
class QtMaterialIconMenu : public QtMaterialIconButton
{
Q_OBJECT
public:
explicit QtMaterialIconMenu(const QIcon &icon, QWidget *parent = 0);
~QtMaterialIconMenu();
void addMenuItem(const QString &text);
void addMenuItem(QtMaterialMenuItem *item);
QtMaterialMenuItem *itemAt(int index) const;
void setAutoCollapse(bool value);
bool autoCollapse() const;
signals:
void itemSelected(int index);
protected slots:
void makeTransparent();
void makeOpaque();
void collapseDelayed();
protected:
bool event(QEvent *event) Q_DECL_OVERRIDE;
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
private:
Q_DISABLE_COPY(QtMaterialIconMenu)
Q_DECLARE_PRIVATE(QtMaterialIconMenu)
};
#endif // QTMATERIALICONMENU_H

View File

@ -0,0 +1,26 @@
#ifndef QTMATERIALICONMENU_P_H
#define QTMATERIALICONMENU_P_H
#include "xx/qtmaterialiconbutton_p.h"
class QtMaterialIconMenu;
class QtMaterialOverlayWidget;
class QtMaterialCollapsibleMenu;
class QtMaterialIconMenuPrivate : public QtMaterialIconButtonPrivate
{
Q_DISABLE_COPY(QtMaterialIconMenuPrivate)
Q_DECLARE_PUBLIC(QtMaterialIconMenu)
public:
QtMaterialIconMenuPrivate(QtMaterialIconMenu *q);
~QtMaterialIconMenuPrivate();
void init();
QtMaterialOverlayWidget *menuOverlay;
QtMaterialCollapsibleMenu *menu;
bool autoCollapse;
};
#endif // QTMATERIALICONMENU_P_H

View File

@ -0,0 +1,87 @@
#include "yy/iconmenusettingseditor.h"
#include <QVBoxLayout>
#include <QDebug>
#include <QColorDialog>
#include "xx/qtmaterialiconmenu.h"
#include "xx/qtmaterialmenuitem.h"
IconMenuSettingsEditor::IconMenuSettingsEditor(QWidget *parent)
: QWidget(parent),
ui(new Ui::IconMenuSettingsForm),
m_iconMenu(new QtMaterialIconMenu(QIcon("../qt-material-widgets/ic_star_black_24px.svg")))
{
QVBoxLayout *layout = new QVBoxLayout;
setLayout(layout);
QWidget *widget = new QWidget;
layout->addWidget(widget);
QWidget *canvas = new QWidget;
canvas->setStyleSheet("QWidget { background: white; }");
layout->addWidget(canvas);
ui->setupUi(widget);
layout->setContentsMargins(20, 20, 20, 20);
layout = new QVBoxLayout;
canvas->setLayout(layout);
layout->addWidget(m_iconMenu);
layout->setAlignment(m_iconMenu, Qt::AlignCenter);
{
m_iconMenu->addMenuItem("C");
m_iconMenu->addMenuItem("C++");
m_iconMenu->addMenuItem("PHP");
m_iconMenu->addMenuItem("Haskell");
m_iconMenu->addMenuItem("JavaScript");
m_iconMenu->addMenuItem("ECMAScript");
m_iconMenu->addMenuItem("OCaml");
m_iconMenu->addMenuItem("Python");
m_iconMenu->addMenuItem("F#");
m_iconMenu->addMenuItem("Clojure");
m_iconMenu->addMenuItem("Java");
m_iconMenu->itemAt(2)->setDisabled(true);
}
setupForm();
connect(ui->disabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget()));
connect(ui->autoCollapseCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget()));
connect(ui->colorToolButton, SIGNAL(clicked(bool)), this, SLOT(selectColor()));
connect(ui->disabledColorToolButton, SIGNAL(clicked(bool)), this, SLOT(selectColor()));
}
IconMenuSettingsEditor::~IconMenuSettingsEditor()
{
delete ui;
}
void IconMenuSettingsEditor::setupForm()
{
ui->disabledCheckBox->setChecked(!m_iconMenu->isEnabled());
ui->autoCollapseCheckBox->setChecked(m_iconMenu->autoCollapse());
}
void IconMenuSettingsEditor::updateWidget()
{
m_iconMenu->setDisabled(ui->disabledCheckBox->isChecked());
m_iconMenu->setAutoCollapse(ui->autoCollapseCheckBox->isChecked());
}
void IconMenuSettingsEditor::selectColor()
{
QColorDialog dialog;
if (dialog.exec()) {
QColor color = dialog.selectedColor();
QString senderName = sender()->objectName();
if ("colorToolButton" == senderName) {
m_iconMenu->setColor(color);
ui->colorLineEdit->setText(color.name(QColor::HexRgb));
} else if ("disabledColorToolButton" == senderName) {
m_iconMenu->setDisabledColor(color);
ui->disabledColorLineEdit->setText(color.name(QColor::HexRgb));
}
}
setupForm();
}

View File

@ -0,0 +1,27 @@
#ifndef ICONMENUSETTINGSEDITOR_H
#define ICONMENUSETTINGSEDITOR_H
#include <QWidget>
#include "ui_iconmenusettingsform.h"
class QtMaterialIconMenu;
class IconMenuSettingsEditor : public QWidget
{
Q_OBJECT
public:
explicit IconMenuSettingsEditor(QWidget *parent = 0);
~IconMenuSettingsEditor();
protected slots:
void setupForm();
void updateWidget();
void selectColor();
private:
Ui::IconMenuSettingsForm *const ui;
QtMaterialIconMenu *const m_iconMenu;
};
#endif // ICONMENUSETTINGSEDITOR_H

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>IconMenuSettingsForm</class>
<widget class="QWidget" name="IconMenuSettingsForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>160</width>
<height>104</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="disabledLabel">
<property name="text">
<string>Disabled</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="disabledCheckBox"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="colorLabel">
<property name="text">
<string>Color</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="autoCollapseLabel">
<property name="text">
<string>Auto collapse</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="autoCollapseCheckBox"/>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLineEdit" name="colorLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="colorToolButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="disabledColorLabel">
<property name="text">
<string>Disabled color</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLineEdit" name="disabledColorLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="disabledColorToolButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>