-
Notifications
You must be signed in to change notification settings - Fork 105
/
pie_menu.h
172 lines (135 loc) · 4.72 KB
/
pie_menu.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
* Copyright 2012, 2013 Thomas Schöps
* Copyright 2014 Thomas Schöps, Kai Pastor
*
* This file is part of OpenOrienteering.
*
* OpenOrienteering is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenOrienteering is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenOrienteering. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENORIENTEERING_PIE_MENU_H
#define OPENORIENTEERING_PIE_MENU_H
#include <cmath>
#include <QtGlobal>
#include <QHash>
#include <QObject>
#include <QPoint>
#include <QPolygon>
#include <QWidget>
class QAction;
class QActionEvent;
class QHideEvent;
class QMouseEvent;
class QPaintEvent;
namespace OpenOrienteering {
/**
* Displays a pie menu.
*
* This class has an API and behavior similar to QMenu,
* but is neither a subclass nor a full replacement.
*/
class PieMenu : public QWidget
{
Q_OBJECT
public:
/** Stores the geometry of a particular item in the PieMenu. */
struct ItemGeometry
{
/** The area covered by the item. */
QPolygon area;
/** The position of the center of the item. */
QPoint icon_pos;
};
/** Constructs a pie menu with default settings. */
PieMenu(QWidget* parent = nullptr);
/** Returns the minimum number of actions in the menu. */
int minimumActionCount() const;
/** Sets the minimum number of actions in the menu (must be at least three). */
void setMinimumActionCount(int count);
/** Returns the current number of visible actions. */
int visibleActionCount() const;
/** Removes all actions from the menu.
* Other than QMenu::clear(), this will not immediately delete any action,
* even if owned by this object. (Actions owned by this object will be
* deleted when this objected is deleted.)
* @see QMenu::clear() */
void clear();
/** Returns true if there are no visible actions in the menu,
* false otherwise.
* @see QMenu::isEmpty */
bool isEmpty() const;
/** Returns the icon size (single dimension). */
int iconSize() const;
/** Sets the icon size (single dimension).
* @param icon_size the new size (at least 1) */
void setIconSize(int icon_size);
/** Returns the action at pos.
* Returns nullptr if there is no action at this place. */
QAction* actionAt(const QPoint& pos) const;
/** Returns the geometry of the given action.
* The action must be enabled and visible.
* Otherwise the geometry will be empty.
* @see QMenu::actionGeometry */
ItemGeometry actionGeometry(QAction* action) const;
/** Returns the currently highlighted action.
* Returns nullptr if no action is highlighted.
* @see QMenu::activeAction */
QAction* activeAction() const;
/** Sets the currently highlighted action.
* The action must be enabled and visible.
* Otherwise there will be no highlighted action.
* @see QMenu::setActiveAction */
void setActiveAction(QAction* action);
/** Shows the menu at the given absolute position.
* @see QMenu::popup */
void popup(const QPoint& pos);
signals:
/** This signal is emitted just before the menu is shown.
* @see QMenu::aboutToShow */
void aboutToShow();
/** This signal is emitted just before the menu is hidden.
* @see QMenu::aboutToHide */
void aboutToHide();
/** This signal is emitted when a menu item is highlighted.
* @see QMenu::hovered */
void hovered(QAction* action);
/** This signal is emitted when a menu item's action is triggered.
* @see QMenu::triggered */
void triggered(QAction* action);
protected:
void actionEvent(QActionEvent* event) override;
void hideEvent(QHideEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override;
void mousePressEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override;
void paintEvent(QPaintEvent* event) override;
void updateCachedState();
QPoint getPoint(double radius, double angle) const;
int minimum_action_count;
int icon_size;
QAction* active_action;
bool actions_changed;
bool clicked;
int total_radius;
QPolygon outer_border;
QPolygon inner_border;
QHash< QAction*, ItemGeometry > geometries;
};
// ### PieMenu inline code ###
inline
QPoint PieMenu::getPoint(double radius, double angle) const
{
return QPoint(total_radius + qRound(radius * -sin(angle)), total_radius + qRound(radius * -cos(angle)));
}
} // namespace OpenOrienteering
#endif