forked from vnotex/vnote
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvcaptain.h
More file actions
189 lines (140 loc) · 4.7 KB
/
vcaptain.h
File metadata and controls
189 lines (140 loc) · 4.7 KB
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#ifndef VCAPTAIN_H
#define VCAPTAIN_H
#include <functional>
#include <QWidget>
#include <QVector>
#include <QHash>
class QKeyEvent;
class VNavigationMode;
class QShortcut;
// bool func(void *p_target, void *p_data);
// Return true if the target needs to restore focus by the Captain.
typedef std::function<bool(void *, void *)> CaptainFunc;
// Will be passed to CaptainFunc as the data.
struct CaptainData
{
CaptainData(QWidget *p_focusWidgetBeforeCaptain)
: m_focusWidgetBeforeCaptain(p_focusWidgetBeforeCaptain)
{
}
QWidget *m_focusWidgetBeforeCaptain;
};
class VCaptain : public QWidget
{
Q_OBJECT
public:
explicit VCaptain(QWidget *p_parent);
// Register a target for Navigation mode.
void registerNavigationTarget(VNavigationMode *p_target);
// Register a target for Captain mode.
bool registerCaptainTarget(const QString &p_name,
const QString &p_key,
void *p_target,
CaptainFunc p_func);
void setCaptainModeEnabled(bool p_enabled);
void exitCaptainMode();
signals:
// Emit when mode changed.
void captainModeChanged(bool p_captainMode);
protected:
void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
private slots:
// Exit Navigation mode if focus lost.
void handleFocusChanged(QWidget *p_old, QWidget *p_new);
private:
// A widget target for Navigation mode.
struct NaviModeTarget {
NaviModeTarget()
: m_target(nullptr), m_available(false)
{
}
NaviModeTarget(VNavigationMode *p_target, bool p_available)
: m_target(p_target), m_available(p_available)
{
}
VNavigationMode *m_target;
bool m_available;
};
// Modes.
enum class CaptainMode {
Normal = 0,
Pending,
Navigation
};
struct CaptainModeTarget {
CaptainModeTarget()
: m_target(nullptr), m_function(nullptr)
{
}
CaptainModeTarget(const QString &p_name,
const QString &p_key,
void *p_target,
CaptainFunc p_func)
: m_name(p_name),
m_key(p_key),
m_target(p_target),
m_function(p_func)
{
}
QString toString() const
{
return QString("Captain mode target %1 key[%2]").arg(m_name).arg(m_key);
}
// Name to display.
QString m_name;
// Key sequence to trigger this target.
// This is the sub-sequence after leader key.
QString m_key;
// Target.
void *m_target;
// Function to call when this target is trigger.
CaptainFunc m_function;
};
// Restore the focus to m_widgetBeforeCaptain.
void restoreFocus();
// Return true if finish handling the event; otherwise, let the base widget
// to handle it.
bool handleKeyPress(int p_key, Qt::KeyboardModifiers p_modifiers);
// Handle key press event in Navigation mode.
bool handleKeyPressNavigationMode(int p_key,
Qt::KeyboardModifiers p_modifiers);
// Handle key press event in Captain mode.
bool handleKeyPressCaptainMode(int p_key,
Qt::KeyboardModifiers p_modifiers);
// Get next major key to use for Navigation mode.
QChar getNextMajorKey();
// Trigger navigation mode to ask all targets show themselves.
void triggerNavigationMode();
// Exit navigation mode to ask all targets hide themselves.
void exitNavigationMode();
// Called to trigger the action of a Captain target which has
// registered @p_key.
void triggerCaptainTarget(const QString &p_key);
void setMode(CaptainMode p_mode);
bool checkMode(CaptainMode p_mode) const;
void trigger();
void triggerCaptainMode();
static bool navigationModeByCaptain(void *p_target, void *p_data);
// Used to indicate current mode.
CaptainMode m_mode;
// The widget which has the focus before entering Captain mode.
QWidget *m_widgetBeforeCaptain;
// Targets for Navigation mode.
QVector<NaviModeTarget> m_naviTargets;
QChar m_nextMajorKey;
// Targets for Captain mode.
// Key(lower) -> CaptainModeTarget.
QHash<QString, CaptainModeTarget> m_captainTargets;
// Ignore focus change during handling Captain and Navigation target actions.
bool m_ignoreFocusChange;
QShortcut *m_captainModeShortcut;
};
inline void VCaptain::setMode(CaptainMode p_mode)
{
m_mode = p_mode;
}
inline bool VCaptain::checkMode(CaptainMode p_mode) const
{
return m_mode == p_mode;
}
#endif // VCAPTAIN_H