-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGenericPluginUI.h
276 lines (241 loc) · 9.06 KB
/
GenericPluginUI.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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/**
* @file GenericPluginUI.h
* Declares the GenericPluginUI class.
* @ingroup generic-ui
*/
/*
* Copyright 2012 Joel Baxter
*
* This file is part of MeshTex.
*
* MeshTex 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 2 of the License, or
* (at your option) any later version.
*
* MeshTex 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 MeshTex. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(INCLUDED_GENERICPLUGINUI_H)
#define INCLUDED_GENERICPLUGINUI_H
#include <vector>
#include <gdk/gdk.h>
#include <glib.h>
#include "GenericMainMenu.h"
#include "GenericDialog.h"
#include "qerplugin.h"
#include "generic/referencecounted.h"
/**
* Framework for a manager of a command menu and dialog windows. It is
* responsible for:
* - holding a reference on those objects for lifecycle management
* - providing lookup facilities for those objects
* - mapping GTK+ event/signal callbacks into method invocations on
* the dialog objects
* - providing automatic handling of widgets that should be active or
* inactive based on the active state of other widgets
* - providing utility functions for generating message popups
*
* A subclass should handle the creation and registration of the UI objects.
*
* @ingroup generic-ui
*/
class GenericPluginUI
{
protected: // protected methods
/// @name Lifecycle
//@{
GenericPluginUI();
virtual ~GenericPluginUI();
//@}
private: // private methods
/// @name Unimplemented to prevent copy/assignment
//@{
GenericPluginUI(const GenericPluginUI&);
const GenericPluginUI& operator=(const GenericPluginUI&);
//@}
public: // public types
/**
* Type for GTK+ event callbacks. The callback takes a GtkWidget* argument
* (widget generating the event), a GdkEvent* argument (the event), and a
* gpointer argument (the callback ID); it returns gint (success as TRUE or
* FALSE).
*/
typedef Callback3<GtkWidget *, GdkEvent *, gpointer, gint> DialogEventCallback;
/**
* Type for GTK+ signal callbacks. The callback takes a GtkWidget* argument
* (widget generating the signal) and a gpointer argument (the callback data);
* it has no return value.
*/
typedef Callback2<GtkWidget *, gpointer, void> DialogSignalCallback;
/**
* An instance of this class can be used as a
* GenericPluginUI::DialogEventCallback, in situations where the callback is
* a method to be invoked on a target object. When invoking this constructor,
* the target object is the constructor argument, and the target object class
* and method are template parameters. The target object's method must have
* an appropriate signature for DialogEventCallback: one GtkWidget* argument,
* one GdkEvent* argument, one gpointer argument, gint return.
*/
template<typename ObjectClass, gint (ObjectClass::*member)(GtkWidget *, GdkEvent*, gpointer)>
class DialogEventCallbackMethod : public BindFirstOpaque3<Member3<ObjectClass, GtkWidget *, GdkEvent*, gpointer, gint, member> >
{
public:
/**
* Constructor.
*
* @param object The object on which to invoke the callback method.
*/
DialogEventCallbackMethod(ObjectClass& object) :
BindFirstOpaque3<Member3<ObjectClass, GtkWidget *, GdkEvent *, gpointer, gint, member> >(object) {}
};
/**
* An instance of this class can be used as a
* GenericPluginUI::DialogSignalCallback, in situations where the callback is
* a method to be invoked on a target object. When invoking this constructor,
* the target object is the constructor argument, and the target object class
* and method are template parameters. The target object's method must have
* an appropriate signature for DialogSignalCallback: one GtkWidget* argument,
* one gpointer argument, void return.
*/
template<typename ObjectClass, void (ObjectClass::*member)(GtkWidget *, gpointer)>
class DialogSignalCallbackMethod : public BindFirstOpaque2<Member2<ObjectClass, GtkWidget *, gpointer, void, member> >
{
public:
/**
* Constructor.
*
* @param object The object on which to invoke the callback method.
*/
DialogSignalCallbackMethod(ObjectClass& object) :
BindFirstOpaque2<Member2<ObjectClass, GtkWidget *, gpointer, void, member> >(object) {}
};
public: // public methods
/// @name Setup
//@{
void RegisterMainMenu(SmartPointer<GenericMainMenu>& mainMenu);
void RegisterDialog(SmartPointer<GenericDialog>& dialog);
void SetWindow(GtkWidget *window);
//@}
/// @name Lookup
//@{
GenericMainMenu *MainMenu();
GenericDialog *Dialog(const std::string& key);
//@}
/// @name Event/signal dispatch
//@{
static gint DialogEventCallbackDispatch(GtkWidget *widget,
GdkEvent* event,
gpointer data);
static void DialogSignalCallbackDispatch(GtkWidget *widget,
gpointer data);
gpointer RegisterDialogEventCallback(GtkWidget *widget,
const gchar *name,
const DialogEventCallback& callback);
gpointer RegisterDialogSignalCallback(GtkWidget *widget,
const gchar *name,
const DialogSignalCallback& callback);
//@}
/// @name Widget dependence
//@{
void RegisterWidgetDependence(GtkWidget *controller,
GtkWidget *controllee);
void RegisterWidgetAntiDependence(GtkWidget *controller,
GtkWidget *controllee);
void WidgetControlCallback(GtkWidget *widget,
gpointer callbackID);
//@}
/// @name Message popups
//@{
static void ErrorReportDialog(const char *title,
const char *message);
static void WarningReportDialog(const char *title,
const char *message);
static void InfoReportDialog(const char *title,
const char *message);
//@}
private: // private types
/**
* Type for a map between string and reference-counted dialog window.
*/
typedef std::map<std::string, SmartPointer<GenericDialog> > DialogMap;
/**
* Type for a map between gpointer (for callback ID) and event callback.
*/
typedef std::map<gpointer, DialogEventCallback> DialogEventCallbackMap;
/**
* Type for a map between gpointer (for callback ID) and signal callback.
*/
typedef std::map<gpointer, DialogSignalCallback> DialogSignalCallbackMap;
/**
* Type for a map between a widget and a vector of widgets.
*/
typedef std::map<GtkWidget *, std::vector<GtkWidget *> > WidgetDependenceMap;
private: // private member vars
/**
* The parent window.
*/
GtkWidget *_window;
/**
* Pointer to a reference-counted handle on the main menu object.
*/
SmartPointer<GenericMainMenu> *_mainMenu;
/**
* Next ID to use when registering an event or signal callback. Starts at 1;
* 0 is reserved to mean invalid.
*/
unsigned _callbackID;
/**
* Callback to implement widget-active dependences.
*/
const DialogSignalCallbackMethod<GenericPluginUI, &GenericPluginUI::WidgetControlCallback>
_widgetControlCallback;
/**
* Associations between keys and dialog windows.
*/
DialogMap _dialogMap;
/**
* Associations between callback IDs and event callbacks.
*/
DialogEventCallbackMap _dialogEventCallbackMap;
/**
* Associations between callback IDs and signal callbacks.
*/
DialogSignalCallbackMap _dialogSignalCallbackMap;
/**
* Associations between controller and controllee widgets for all dependences
* and anti-dependences.
*/
WidgetDependenceMap _widgetControlMap;
/**
* Associations between controller and controllee widgets for dependences
* only.
*/
WidgetDependenceMap _widgetControlledByMap;
/**
* Associations between controller and controllee widgets for anti-
* dependences only.
*/
WidgetDependenceMap _widgetAntiControlledByMap;
};
/**
* Get the singleton instance of the UI manager.
*
* @internal
* This function is not implemented in the GenericPluginUI.cpp file. It must
* be implemented somewhere, because it is invoked from various places even
* within the generic UI code. The implementation of this function should
* return a reference to the singleton instance of a GenericPluginUI subclass.
* @endinternal
*
* @return Reference to a singleton that implements GenericPluginUI.
*
* @relates GenericPluginUI
*/
GenericPluginUI& UIInstance();
#endif // #if !defined(INCLUDED_GENERICPLUGINUI_H)