]> git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/meshtex/GenericDialog.cpp
* added MeshTex plugin src to project (can't compile)
[xonotic/netradiant.git] / contrib / meshtex / GenericDialog.cpp
1 /**
2  * @file GenericDialog.cpp
3  * Implements the GenericDialog 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 #include <gtk/gtk.h>
27
28 #include "GenericDialog.h"
29 #include "GenericPluginUI.h"
30
31
32 /**
33  * Constructor. Create the GTK+ widget for the dialog window (not visible
34  * yet). Initialize callback IDs to zero (invalid). Note that as this is a
35  * protected method, GenericDialog objects cannot be created directly; only
36  * subclasses of GenericDialog can be created.
37  *
38  * @param key Unique key to identify this dialog widget.
39  */
40 GenericDialog::GenericDialog(const std::string& key) :
41    _dialog(gtk_window_new(GTK_WINDOW_TOPLEVEL)),
42    _window(NULL),
43    _key(key),
44    _okCallbackID(0),
45    _applyCallbackID(0),
46    _cancelCallbackID(0)
47 {
48    // XXX Should we go ahead invoke CreateWindowCloseCallback here (and make it
49    // private) rather than leaving that to the subclass constructors? Depends on
50    // whether it's plausible that a dialog would ever NOT want the usual
51    // handling for the close event.
52 }
53
54 /**
55  * Virtual destructor. Destroy the GTK+ dialog widget (and therefore its
56  * contained widgets) if necessary.
57  */
58 GenericDialog::~GenericDialog()
59 {
60    if (_dialog != NULL)
61    {
62       gtk_widget_destroy(_dialog);
63    }
64 }
65
66 /**
67  * Get the unique key that identifies this dialog widget.
68  *
69  * @return The key.
70  */
71 const std::string&
72 GenericDialog::GetKey() const
73 {
74    return _key;
75 }
76
77 /**
78  * Mark this window widget as a modal dialog for a parent window.
79  *
80  * @param window The parent window.
81  */
82 void
83 GenericDialog::SetWindow(GtkWidget *window)
84 {
85    // Remember the parent window.
86    _window = window;
87    // Mark this widget as a modal dialog for it.
88    if (_dialog != NULL)
89    {
90       gtk_window_set_transient_for(GTK_WINDOW(_dialog), GTK_WINDOW(_window));
91    }
92 }
93
94 /**
95  * Raise this dialog window to the top of the window stack.
96  */
97 void
98 GenericDialog::Raise()
99 {
100    // Don't bother if not visible.
101    if (GTK_WIDGET_VISIBLE(_dialog))
102    {
103       gdk_window_raise(_dialog->window);
104    }
105 }
106
107 /**
108  * Make this dialog window visible and foreground.
109  *
110  * @param triggerCommand The command token that summoned the dialog.
111  */
112 void
113 GenericDialog::Show(const std::string& triggerCommand)
114 {
115    // Remember the command token that summoned the dialog; subclasses can make
116    // use of this information.
117    _triggerCommand = triggerCommand;
118    // Show the window if it is currently hidden.
119    if (!GTK_WIDGET_VISIBLE(_dialog))
120    {
121       gtk_widget_show(_dialog);
122    }
123    // Raise the window to the top of the stack.
124    Raise();
125 }
126
127 /**
128  * Hide this dialog window.
129  */
130 void
131 GenericDialog::Hide()
132 {
133    // Bail out if the window is already invisible.
134    if (!GTK_WIDGET_VISIBLE(_dialog))
135    {
136       return;
137    }
138    // Hide the window.
139    gtk_widget_hide(_dialog);
140    // If there's a parent window, raise it to the top of the stack.
141    if (_window == NULL)
142    {
143       return;
144    }
145    gdk_window_raise(_window->window);
146 }
147
148 /**
149  * Default handler for Apply logic. This method should be overriden by
150  * subclass implementations that need to execute some logic when OK or Apply
151  * is clicked. The return value should be the success of that logic. A
152  * successful OK will cause the window to be hidden.
153  *
154  * @return true if the apply logic executed; always the case in this skeleton
155  *         implementation.
156  */
157 bool
158 GenericDialog::Apply()
159 {
160    // Default logic does nothing.
161    return true;
162 }
163
164 /**
165  * Callback for window-close event.
166  *
167  * @param widget     This dialog window widget.
168  * @param event      The event that instigated the callback.
169  * @param callbackID Unique numerical ID for the callback.
170  *
171  * @return TRUE as defined by glib.
172  */
173 gint
174 GenericDialog::CloseEventCallback(GtkWidget *widget,
175                                   GdkEvent* event,
176                                   gpointer callbackID)
177 {
178    // All we need to do is hide the window.
179    Hide();
180    return TRUE;
181 }
182
183 /**
184  * Callback for clicking on OK/Apply/Cancel button.
185  *
186  * @param widget     This dialog window widget.
187  * @param callbackID Unique numerical ID for the callback.
188  */
189 void
190 GenericDialog::FinalizeCallback(GtkWidget *widget,
191                                 gpointer callbackID)
192 {
193    // Assume success until we have to do something.
194    bool success = true;
195    // If this is not a Cancel callback, run the Apply logic.
196    if (callbackID != _cancelCallbackID)
197    {
198       success = Apply();
199    }
200    // Hide the window if this is a cancel or a successful OK callback.
201    if (success && callbackID != _applyCallbackID)
202    {
203       Hide();
204    }
205 }
206
207 /**
208  * Register the callback for the close-window event.
209  */
210 void
211 GenericDialog::CreateWindowCloseCallback()
212 {
213    // The close-window event will trigger the CloseEventCallback method.
214    const GenericPluginUI::DialogEventCallbackMethod
215       <GenericDialog, &GenericDialog::CloseEventCallback> closeCallback(*this);
216    UIInstance().RegisterDialogEventCallback(_dialog, "delete_event", closeCallback);
217 }
218
219 /**
220  * Register the callback for the OK button.
221  *
222  * @param button The OK button widget.
223  */
224 void
225 GenericDialog::CreateOkButtonCallback(GtkWidget *button)
226 {
227    // Clicking the OK button will trigger the FinalizeCallback method. Since
228    // FinalizeCallback can be used for multiple buttons, we'll save the specific
229    // callback ID associated with the OK button.
230    const GenericPluginUI::DialogSignalCallbackMethod
231       <GenericDialog, &GenericDialog::FinalizeCallback> finalizeCallback(*this);
232    _okCallbackID =
233       UIInstance().RegisterDialogSignalCallback(button, "clicked", finalizeCallback);
234 }
235
236 /**
237  * Register the callback for the Apply button.
238  *
239  * @param button The Apply button widget.
240  */
241 void
242 GenericDialog::CreateApplyButtonCallback(GtkWidget *button)
243 {
244    // Clicking the Apply button will trigger the FinalizeCallback method. Since
245    // FinalizeCallback can be used for multiple buttons, we'll save the specific
246    // callback ID associated with the Apply button.
247    const GenericPluginUI::DialogSignalCallbackMethod
248       <GenericDialog, &GenericDialog::FinalizeCallback> finalizeCallback(*this);
249    _applyCallbackID =
250       UIInstance().RegisterDialogSignalCallback(button, "clicked", finalizeCallback);
251 }
252
253 /**
254  * Register the callback for the Cancel button.
255  *
256  * @param button The Cancel button widget.
257  */
258 void
259 GenericDialog::CreateCancelButtonCallback(GtkWidget *button)
260 {
261    // Clicking the Cancel button will trigger the FinalizeCallback method. Since
262    // FinalizeCallback can be used for multiple buttons, we'll save the specific
263    // callback ID associated with the Cancel button.
264    const GenericPluginUI::DialogSignalCallbackMethod
265       <GenericDialog, &GenericDialog::FinalizeCallback> finalizeCallback(*this);
266    _cancelCallbackID =
267       UIInstance().RegisterDialogSignalCallback(button, "clicked", finalizeCallback);
268 }