1 #pragma once
2
3 #include <list>
4 #include <map>
5 #include <string>
6
7 #include "iselection.h"
8
9 #include "generic/constant.h"
10 #include "generic/callbackfwd.h"
11
12 // GTK forward declaration
13 typedef struct _GtkObject GtkObject;
14 typedef struct _GtkWindow GtkWindow;
15 typedef struct _GtkWidget GtkWidget;
16 typedef struct _GdkEventButton GdkEventButton;
17 typedef struct _GdkEventKey GdkEventKey;
18
19 /* greebo: Below are the actual events that are "read" by the views/observers to
20 * interpret the mouseclicks. */
21
22 namespace ui {
23
24 // The possible modes when in "component manipulation mode"
25 enum XYViewEvent {
26 xyNothing, // unrecognised event
27 xyMoveView, // drag the view around
28 xySelect, // selection / clip
29 xyZoom, // drag-zoom operator
30 xyCameraMove, // the button used to drag the camera around
31 xyCameraAngle, // the button used to change camera angle
32 xyNewBrushDrag // used to create new brushes
33 };
34
35 // These are the buttons for the camera view
36 enum CamViewEvent {
37 camNothing, // nothing special, event can be passed to the windowobservers
38 camEnableFreeLookMode, // used to enable the free look mode in the camera view
39 camDisableFreeLookMode // used to disable the free look mode in the camera view
40 };
41
42 // If the click is passed to the windowobservers, these are the possibilites
43 enum ObserverEvent {
44 obsNothing, // any uninterpreted/unsupported combination
45 obsManipulate, // manipulate an object by drag or click
46 obsSelect, // selection toggle
47 obsToggle, // selection toggle
48 obsToggleFace, // selection toggle (face)
49 obsReplace, // replace/cycle selection through possible candidates
50 obsReplaceFace, // replace/cycle selection through possible face candidates
51 obsCopyTexture, // copy texture from object
52 obsPasteTexture, // paste texture to object (projected)
53 obsPasteTextureToBrush, // paste texture to all brush faces of the selected brush
54 obsJumpToObject // focuses the cam & xyviews to the clicked object
55 };
56 } // namespace ui
57
58
59 class IEvent
60 {
61 public:
~IEvent()62 virtual ~IEvent() {}
63
64 // Handles the incoming keyUp / keyDown calls
65 virtual void keyUp() = 0;
66 virtual void keyDown() = 0;
67
68 // Returns true if this event could be toggled (returns false if the event is not a Toggle).
69 virtual bool setToggled(const bool toggled) = 0;
70
71 /** greebo: Returns true if the event is a Toggle (or a subtype of a Toggle)
72 */
73 virtual bool isToggle() const = 0;
74
75 // Enables/disables this event
76 virtual void setEnabled(const bool enabled) = 0;
77
78 // Connect a GtkWidget to this event (the event must support the according widget).
79 virtual void connectWidget(GtkWidget* widget) = 0;
80
81 // Exports the current state to the widgets
82 virtual void updateWidgets() = 0;
83 };
84
85 /* greebo: The mouse event manager provides methods to interpret mouse clicks.
86 */
87 class IMouseEvents {
88 public:
~IMouseEvents()89 virtual ~IMouseEvents() {}
90
91 // Return the ObserverEvent type for a given GdkEventButton
92 virtual ui::CamViewEvent getCameraViewEvent(GdkEventButton* event) = 0;
93
94 // Return the ObserverEvent type for a given GdkEventButton
95 virtual ui::ObserverEvent getObserverEvent(GdkEventButton* event) = 0;
96 virtual ui::ObserverEvent getObserverEvent(const unsigned int& state) = 0;
97
98 // Return the current XYView event for a GdkEventMotion state or an GdkEventButton
99 virtual ui::XYViewEvent getXYViewEvent(GdkEventButton* event) = 0;
100 virtual ui::XYViewEvent getXYViewEvent(const unsigned int& state) = 0;
101
102 virtual bool stateMatchesXYViewEvent(const ui::XYViewEvent& xyViewEvent, GdkEventButton* event) = 0;
103 virtual bool stateMatchesXYViewEvent(const ui::XYViewEvent& xyViewEvent, const unsigned int& state) = 0;
104
105 virtual bool stateMatchesObserverEvent(const ui::ObserverEvent& observerEvent, GdkEventButton* event) = 0;
106
107 virtual bool stateMatchesCameraViewEvent(const ui::CamViewEvent& camViewEvent, GdkEventButton* event) = 0;
108
109 virtual std::string printXYViewEvent(const ui::XYViewEvent& xyViewEvent) = 0;
110 virtual std::string printObserverEvent(const ui::ObserverEvent& observerEvent) = 0;
111
112 virtual float getCameraStrafeSpeed() = 0;
113 virtual float getCameraForwardStrafeFactor() = 0;
114 virtual bool strafeActive(unsigned int& state) = 0;
115 virtual bool strafeForwardActive(unsigned int& state) = 0;
116 };
117
118 class IAccelerator
119 {
120 public:
~IAccelerator()121 virtual ~IAccelerator() {}
122
123 // Get/set the GDK key value
124 virtual void setKey(const unsigned int& key) = 0;
125 virtual unsigned int getKey() const = 0;
126
127 // Get/Set the modifier flags
128 virtual void setModifiers(const unsigned int& modifiers) = 0;
129 virtual unsigned int getModifiers() const = 0;
130
131 // Connect this IEvent to this accelerator
132 virtual void connectEvent(IEvent* event) = 0;
133 };
134
135 // Event visitor class
136 class IEventVisitor {
137 public:
~IEventVisitor()138 virtual ~IEventVisitor() {}
139
140 virtual void visit(const std::string& eventName, const IEvent* event) = 0;
141 };
142
143 class IEventManager
144 {
145 public:
146 INTEGER_CONSTANT(Version, 1);
147 STRING_CONSTANT(Name, "EventManager");
148
~IEventManager()149 virtual ~IEventManager() {}
150
151 /* Create an accelerator using the given arguments and add it to the list
152 *
153 * @key: The symbolic name of the key, e.g. "A", "Esc"
154 * @modifierStr: A string containing the modifiers, e.g. "Shift+Control" or "Shift"
155 *
156 * @returns: the pointer to the newly created accelerator object */
157 virtual IAccelerator* addAccelerator(const std::string& key, const std::string& modifierStr) = 0;
158 // The same as above, but with GDK event values as argument (event->keyval, event->state)
159 virtual IAccelerator* addAccelerator(GdkEventKey* event) = 0;
160 virtual IAccelerator* findAccelerator(const IEvent* event) = 0;
161
162 /* greebo: This is to avoid cyclic dependencies, because the eventmanager depends
163 * on the selectionsystem, the selectionsystem on the gridmodule, the gridmodule on
164 * the eventmanager, and there we have our cycle. Call this before any mouse events
165 * have to be interpreted!
166 */
167 virtual void connectSelectionSystem(SelectionSystem* selectionSystem) = 0;
168
169 /* greebo: Returns the mouse event "manager" providing a separate interface for
170 * handling mouse events. I moved this into a separate interface to keep
171 * the IEventManager interface cleaner.
172 */
173 virtual IMouseEvents& MouseEvents() = 0;
174
175 // Creates a new command that calls the given callback when invoked
176 virtual IEvent* addCommand(const std::string& name, const Callback& callback) = 0;
177
178 // Creates a new keyevent that calls the given callback when invoked
179 virtual IEvent* addKeyEvent(const std::string& name, const Callback& keyUpCallback, const Callback& keyDownCallback) = 0;
180
181 // Creates a new toggle event that calls the given callback when toggled
182 virtual IEvent* addToggle(const std::string& name, const Callback& onToggled) = 0;
183 virtual void setToggled(const std::string& name, const bool toggled) = 0;
184
185 virtual IEvent* addWidgetToggle(const std::string& name) = 0;
186 virtual IEvent* addRegistryToggle(const std::string& name, const std::string& registryKey) = 0;
187
188 // Returns the pointer to the command specified by the <given> commandName
189 virtual IEvent* findEvent(const std::string& name) = 0;
190 virtual IEvent* findEvent(GdkEventKey* event) = 0;
191
192 // Retrieves the event name for the given IEvent
193 virtual std::string getEventName(IEvent* event) = 0;
194
195 // Connects the given accelerator to the given command (identified by the string)
196 virtual void connectAccelerator(IAccelerator* accelerator, const std::string& command) = 0;
197 // Disconnects the given command from any accelerators
198 virtual void disconnectAccelerator(const std::string& command) = 0;
199
200 // Connects/disconnects the keyboard handlers of the keyeventmanager to the specified window, so that key events are catched
201 virtual void connect(GtkObject* object) = 0;
202 virtual void disconnect(GtkObject* object) = 0;
203
204 // Connects/Disconnects a Dialog Window to the eventmanager. Dialog windows get the chance
205 // to process an incoming keypress event, BEFORE the global shortcuts are searched and launched.
206 virtual void connectDialogWindow(GtkWindow* window) = 0;
207 virtual void disconnectDialogWindow(GtkWindow* window) = 0;
208
209 // Tells the key event manager about the main window so that the accelgroup can be connected correctly
210 virtual void connectAccelGroup(GtkWindow* window) = 0;
211
212 // Loads the shortcut->command associations from the XMLRegistry
213 virtual void loadAccelerators() = 0;
214
215 // Enables/Disables the specified command
216 virtual void enableEvent(const std::string& eventName) = 0;
217 virtual void disableEvent(const std::string& eventName) = 0;
218
219 // Removes the given event and disconnects all accelerators from it
220 virtual void removeEvent(const std::string& eventName) = 0;
221
222 // Visit each event with the given class
223 virtual void foreachEvent(IEventVisitor* eventVisitor) = 0;
224
225 /* greebo: Retrieves a string representation of the modifiers set in <modifierFlags>
226 * (This is used internally by Modifers class)
227 *
228 * @forMenu:
229 * <true> yields a string of type: Ctrl-Shift
230 * <false> results in a string of type: CTRL+SHIFT
231 */
232 virtual std::string getModifierStr(const unsigned int& modifierFlags, bool forMenu = false) = 0;
233
234 /* greebo: Retrieves the string representation of the given GDK <event>
235 */
236 virtual std::string getGDKEventStr(GdkEventKey* event) = 0;
237
238 virtual std::string getAcceleratorStr(const IEvent* event, bool forMenu) = 0;
239
240 /** greebo: Returns the current keyboard eventkey state
241 */
242 virtual unsigned int getModifierState() = 0;
243 };
244
245 // Module definitions
246
247 #include "modulesystem.h"
248
249 template<typename Type>
250 class GlobalModule;
251 typedef GlobalModule<IEventManager> GlobalEventManagerModule;
252
253 template<typename Type>
254 class GlobalModuleRef;
255 typedef GlobalModuleRef<IEventManager> GlobalEventManagerModuleRef;
256
257 // This is the accessor for the event manager
GlobalEventManager()258 inline IEventManager& GlobalEventManager() {
259 return GlobalEventManagerModule::getTable();
260 }
261