]> git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/meshtex/GenericPluginUI.h
Merge branch 'master' into master-merge
[xonotic/netradiant.git] / contrib / meshtex / GenericPluginUI.h
1 /**
2  * @file GenericPluginUI.h
3  * Declares the GenericPluginUI class.
4  * @ingroup generic-ui
5  */
6
7 /*
8  * Copyright 2012 Joel Baxter
9  *
10  * This file is part of MeshTex.
11  *
12  * MeshTex is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * MeshTex is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with MeshTex.  If not, see <http://www.gnu.org/licenses/>.
24  */
25
26 #if !defined(INCLUDED_GENERICPLUGINUI_H)
27 #define INCLUDED_GENERICPLUGINUI_H
28
29 #include <vector>
30 #include <gdk/gdk.h>
31 #include <glib.h>
32
33 #include "GenericMainMenu.h"
34 #include "GenericDialog.h"
35
36 #include "qerplugin.h"
37 #include "generic/referencecounted.h"
38
39 /**
40  * Framework for a manager of a command menu and dialog windows. It is
41  * responsible for:
42  * - holding a reference on those objects for lifecycle management
43  * - providing lookup facilities for those objects
44  * - mapping GTK+ event/signal callbacks into method invocations on
45  * the dialog objects
46  * - providing automatic handling of widgets that should be active or
47  * inactive based on the active state of other widgets
48  * - providing utility functions for generating message popups
49  *
50  * A subclass should handle the creation and registration of the UI objects.
51  *
52  * @ingroup generic-ui
53  */
54 class GenericPluginUI
55 {
56 protected: // protected methods
57
58    /// @name Lifecycle
59    //@{
60    GenericPluginUI();
61    virtual ~GenericPluginUI();
62    //@}
63
64 private: // private methods
65
66    /// @name Unimplemented to prevent copy/assignment
67    //@{
68    GenericPluginUI(const GenericPluginUI&);
69    const GenericPluginUI& operator=(const GenericPluginUI&);
70    //@}
71
72 public: // public types
73
74    /**
75     * Type for GTK+ event callbacks. The callback takes a GtkWidget* argument
76     * (widget generating the event), a GdkEvent* argument (the event), and a
77     * gpointer argument (the callback ID); it returns gint (success as TRUE or
78     * FALSE).
79     */
80    typedef Callback3<GtkWidget *, GdkEvent *, gpointer, gint> DialogEventCallback;
81
82    /**
83     * Type for GTK+ signal callbacks. The callback takes a GtkWidget* argument
84     * (widget generating the signal) and a gpointer argument (the callback data);
85     * it has no return value.
86     */
87    typedef Callback2<GtkWidget *, gpointer, void> DialogSignalCallback;
88
89    /**
90     * An instance of this class can be used as a
91     * GenericPluginUI::DialogEventCallback, in situations where the callback is
92     * a method to be invoked on a target object. When invoking this constructor,
93     * the target object is the constructor argument, and the target object class
94     * and method are template parameters. The target object's method must have
95     * an appropriate signature for DialogEventCallback: one GtkWidget* argument,
96     * one GdkEvent* argument, one gpointer argument, gint return.
97     */
98    template<typename ObjectClass, gint (ObjectClass::*member)(GtkWidget *, GdkEvent*, gpointer)>
99    class DialogEventCallbackMethod : public BindFirstOpaque3<Member3<ObjectClass, GtkWidget *, GdkEvent*, gpointer, gint, member> >
100    {
101    public:
102       /**
103        * Constructor.
104        *
105        * @param object The object on which to invoke the callback method.
106        */
107       DialogEventCallbackMethod(ObjectClass& object) :
108          BindFirstOpaque3<Member3<ObjectClass, GtkWidget *, GdkEvent *, gpointer, gint, member> >(object) {}
109    };
110
111    /**
112     * An instance of this class can be used as a
113     * GenericPluginUI::DialogSignalCallback, in situations where the callback is
114     * a method to be invoked on a target object. When invoking this constructor,
115     * the target object is the constructor argument, and the target object class
116     * and method are template parameters. The target object's method must have
117     * an appropriate signature for DialogSignalCallback: one GtkWidget* argument,
118     * one gpointer argument, void return.
119     */
120    template<typename ObjectClass, void (ObjectClass::*member)(GtkWidget *, gpointer)>
121    class DialogSignalCallbackMethod : public BindFirstOpaque2<Member2<ObjectClass, GtkWidget *, gpointer, void, member> >
122    {
123    public:
124       /**
125        * Constructor.
126        *
127        * @param object The object on which to invoke the callback method.
128        */
129       DialogSignalCallbackMethod(ObjectClass& object) :
130          BindFirstOpaque2<Member2<ObjectClass, GtkWidget *, gpointer, void, member> >(object) {}
131    };
132
133 public: // public methods
134
135    /// @name Setup
136    //@{
137    void RegisterMainMenu(SmartPointer<GenericMainMenu>& mainMenu);
138    void RegisterDialog(SmartPointer<GenericDialog>& dialog);
139    void SetWindow(GtkWidget *window);
140    //@}
141    /// @name Lookup
142    //@{
143    GenericMainMenu *MainMenu();
144    GenericDialog *Dialog(const std::string& key);
145    //@}
146    /// @name Event/signal dispatch
147    //@{
148    static gint DialogEventCallbackDispatch(GtkWidget *widget,
149                                            GdkEvent* event,
150                                            gpointer data);
151    static void DialogSignalCallbackDispatch(GtkWidget *widget,
152                                             gpointer data);
153    gpointer RegisterDialogEventCallback(GtkWidget *widget,
154                                         const gchar *name,
155                                         const DialogEventCallback& callback);
156    gpointer RegisterDialogSignalCallback(GtkWidget *widget,
157                                          const gchar *name,
158                                          const DialogSignalCallback& callback);
159    //@}
160    /// @name Widget dependence
161    //@{
162    void RegisterWidgetDependence(GtkWidget *controller,
163                                  GtkWidget *controllee);
164    void RegisterWidgetAntiDependence(GtkWidget *controller,
165                                      GtkWidget *controllee);
166    void WidgetControlCallback(GtkWidget *widget,
167                               gpointer callbackID);
168    //@}
169    /// @name Message popups
170    //@{
171    static void ErrorReportDialog(const char *title,
172                                  const char *message);
173    static void WarningReportDialog(const char *title,
174                                    const char *message);
175    static void InfoReportDialog(const char *title,
176                                 const char *message);
177    //@}
178
179 private: // private types
180
181    /**
182     * Type for a map between string and reference-counted dialog window.
183     */
184    typedef std::map<std::string, SmartPointer<GenericDialog> > DialogMap;
185
186    /**
187     * Type for a map between gpointer (for callback ID) and event callback.
188     */
189    typedef std::map<gpointer, DialogEventCallback> DialogEventCallbackMap;
190
191    /**
192     * Type for a map between gpointer (for callback ID) and signal callback.
193     */
194    typedef std::map<gpointer, DialogSignalCallback> DialogSignalCallbackMap;
195
196    /**
197     * Type for a map between a widget and a vector of widgets.
198     */
199    typedef std::map<GtkWidget *, std::vector<GtkWidget *> > WidgetDependenceMap;
200
201 private: // private member vars
202
203    /**
204     * The parent window.
205     */
206    GtkWidget *_window;
207
208    /**
209     * Pointer to a reference-counted handle on the main menu object.
210     */
211    SmartPointer<GenericMainMenu> *_mainMenu;
212
213    /**
214     * Next ID to use when registering an event or signal callback. Starts at 1;
215     * 0 is reserved to mean invalid.
216     */
217    unsigned _callbackID;
218
219    /**
220     * Callback to implement widget-active dependences.
221     */
222    const DialogSignalCallbackMethod<GenericPluginUI, &GenericPluginUI::WidgetControlCallback>
223       _widgetControlCallback;
224
225    /**
226     * Associations between keys and dialog windows.
227     */
228    DialogMap _dialogMap;
229
230    /**
231     * Associations between callback IDs and event callbacks.
232     */
233    DialogEventCallbackMap _dialogEventCallbackMap;
234
235    /**
236     * Associations between callback IDs and signal callbacks.
237     */
238    DialogSignalCallbackMap _dialogSignalCallbackMap;
239
240    /**
241     * Associations between controller and controllee widgets for all dependences
242     * and anti-dependences.
243     */
244    WidgetDependenceMap _widgetControlMap;
245
246    /**
247     * Associations between controller and controllee widgets for dependences
248     * only.
249     */
250    WidgetDependenceMap _widgetControlledByMap;
251
252    /**
253     * Associations between controller and controllee widgets for anti-
254     * dependences only.
255     */
256    WidgetDependenceMap _widgetAntiControlledByMap;
257 };
258
259
260 /**
261  * Get the singleton instance of the UI manager.
262  *
263  * @internal
264  * This function is not implemented in the GenericPluginUI.cpp file. It must
265  * be implemented somewhere, because it is invoked from various places even
266  * within the generic UI code. The implementation of this function should
267  * return a reference to the singleton instance of a GenericPluginUI subclass.
268  * @endinternal
269  *
270  * @return Reference to a singleton that implements GenericPluginUI.
271  *
272  * @relates GenericPluginUI
273  */
274 GenericPluginUI& UIInstance();
275
276 #endif // #if !defined(INCLUDED_GENERICPLUGINUI_H)