parent
f6e4788bd1
commit
f370877bda
6 changed files with 194 additions and 51 deletions
@ -0,0 +1,101 @@ |
||||
#include "buttonwithmenu.h" |
||||
|
||||
ButtonWithMenu::ButtonWithMenu(QWidget* parent) : |
||||
QToolButton(parent) |
||||
, m_menu(new QMenu(this)) |
||||
, m_currentItem(0) |
||||
{ |
||||
setPopupMode(QToolButton::InstantPopup); |
||||
setCursor(Qt::ArrowCursor); |
||||
setFocusPolicy(Qt::ClickFocus); |
||||
setMenu(m_menu); |
||||
} |
||||
|
||||
void ButtonWithMenu::setCurrentItem() |
||||
{ |
||||
if (QAction* action = qobject_cast<QAction*>(sender())) { |
||||
setActiveItem(action->data().value<Item>()); |
||||
} |
||||
} |
||||
|
||||
void ButtonWithMenu::addItem(const Item &item) |
||||
{ |
||||
m_items.append(item); |
||||
|
||||
if (!m_currentItem) |
||||
setActiveItem(item); |
||||
|
||||
QVariant variant; |
||||
variant.setValue<Item>(item); |
||||
m_menu->addAction(item.icon, item.text, this, SLOT(setCurrentItem()))->setData(variant); |
||||
|
||||
emit itemAdded(item); |
||||
} |
||||
|
||||
void ButtonWithMenu::addItems(const QList<Item> &items) |
||||
{ |
||||
foreach (const Item &item, items) { |
||||
addItem(item); |
||||
} |
||||
} |
||||
|
||||
void ButtonWithMenu::removeItem(const Item &item) |
||||
{ |
||||
int index = m_items.indexOf(item); |
||||
if (index < 0) |
||||
return; |
||||
|
||||
m_items.removeOne(item); |
||||
|
||||
if (*m_currentItem == item) |
||||
setActiveItem(m_items.takeFirst()); |
||||
|
||||
generateMenu(); |
||||
} |
||||
|
||||
void ButtonWithMenu::setActiveItem(const Item &item) |
||||
{ |
||||
int index = m_items.indexOf(item); |
||||
if (index < 0) |
||||
return; |
||||
|
||||
m_currentItem = const_cast<Item*>(&m_items.at(index)); |
||||
|
||||
setIcon(m_currentItem->icon); |
||||
setToolTip(m_currentItem->text); |
||||
|
||||
emit activeItemChanged(*m_currentItem); |
||||
} |
||||
|
||||
void ButtonWithMenu::wheelEvent(QWheelEvent *event) |
||||
{ |
||||
int currItemIndex = m_items.indexOf(*m_currentItem); |
||||
int itemsCount = m_items.count(); |
||||
|
||||
int numDegrees = event->delta() / 8; |
||||
int numSteps = numDegrees / 15; |
||||
if (numSteps == 1) { |
||||
if (currItemIndex != 0) |
||||
setActiveItem(m_items.at(currItemIndex - 1)); |
||||
} else { |
||||
if (currItemIndex < itemsCount - 1) |
||||
setActiveItem(m_items.at(currItemIndex + 1)); |
||||
} |
||||
event->accept(); |
||||
} |
||||
|
||||
ButtonWithMenu::Item* ButtonWithMenu::activeItem() |
||||
{ |
||||
return m_currentItem; |
||||
} |
||||
|
||||
void ButtonWithMenu::generateMenu() |
||||
{ |
||||
m_menu->clear(); |
||||
addItems(m_items); |
||||
} |
||||
|
||||
ButtonWithMenu::~ButtonWithMenu() |
||||
{ |
||||
delete m_menu; |
||||
} |
||||
@ -0,0 +1,62 @@ |
||||
#ifndef BUTTONWITHMENU_H |
||||
#define BUTTONWITHMENU_H |
||||
|
||||
#include <QToolButton> |
||||
#include <QAction> |
||||
#include <QMenu> |
||||
#include <QWheelEvent> |
||||
|
||||
class ButtonWithMenu : public QToolButton |
||||
{ |
||||
Q_OBJECT |
||||
public: |
||||
struct Item { |
||||
QString text; |
||||
QIcon icon; |
||||
QVariant userData; |
||||
|
||||
Item(const QString &a = QString(), const QIcon &b = QIcon()) |
||||
{ |
||||
text = a; |
||||
icon = b; |
||||
} |
||||
|
||||
bool operator==(const Item &a) |
||||
{ |
||||
return (a.text == text) && (a.icon.pixmap(16,16).toImage() == icon.pixmap(16,16).toImage()); |
||||
} |
||||
}; |
||||
|
||||
explicit ButtonWithMenu(QWidget* parent = 0); |
||||
~ButtonWithMenu(); |
||||
|
||||
void addItem(const Item &item); |
||||
void addItems(const QList<Item> &items); |
||||
void removeItem(const Item &item); |
||||
void setActiveItem(const Item &item); |
||||
|
||||
Item* activeItem(); |
||||
|
||||
signals: |
||||
void activeItemChanged(const ButtonWithMenu::Item &item); |
||||
void itemAdded(const ButtonWithMenu::Item &item); |
||||
void itemRemoved(const ButtonWithMenu::Item &item); |
||||
|
||||
public slots: |
||||
|
||||
private slots: |
||||
void setCurrentItem(); |
||||
|
||||
private: |
||||
void wheelEvent(QWheelEvent *event); |
||||
void generateMenu(); |
||||
|
||||
QMenu* m_menu; |
||||
QList<Item> m_items; |
||||
Item* m_currentItem; |
||||
|
||||
}; |
||||
|
||||
Q_DECLARE_METATYPE(ButtonWithMenu::Item) |
||||
|
||||
#endif // BUTTONWITHMENU_H
|
||||
Loading…
Reference in new issue