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