* fixed a lot of compiler warnings (mostly const char * stuff and use of uninitialize...
[xonotic/netradiant.git] / plugins / surface_ufoai / surfaceflagsdialog_ufoai.cpp
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #include <gtk/gtk.h>
23 #include <glib/gi18n.h>
24 #include <gdk/gdkkeysyms.h>
25
26 #include "surfdlg_plugin.h"
27
28 #include "surfaceflagsdialog_ufoai.h"
29
30 GtkWidget *notebook1;
31
32 // 32 bit is the max
33 #define MAX_BUTTONS 32
34
35 GtkWidget *surface_buttons[MAX_BUTTONS];
36 GtkWidget *content_buttons[MAX_BUTTONS];
37
38 GtkWidget *value_entry;
39 gboolean setup_buttons = TRUE;
40
41 int working_surface_flags;
42 int surface_mask;
43 int working_content_flags;
44 int content_mask;
45 int working_value;
46
47 inline void set_inconsistent(GtkWidget *toggle_button)
48 {
49         gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON (toggle_button), TRUE);
50 }
51
52 inline void clear_inconsistent(GtkWidget *toggle_button)
53 {
54         if ( gtk_toggle_button_get_inconsistent(GTK_TOGGLE_BUTTON (toggle_button)) )
55         {
56                 gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON (toggle_button), FALSE);
57         }
58 }
59
60 void clear_all_inconsistent(void)
61 {
62         int i;
63
64         for (i = 0; i < MAX_BUTTONS; i++) {
65                 clear_inconsistent( surface_buttons[i] );
66                 clear_inconsistent( content_buttons[i] );
67         }
68 }
69
70 void clear_all_buttons_and_values()
71 {
72         int i;
73
74         for (i = 0; i < MAX_BUTTONS; i++) {
75                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON ( surface_buttons[i] ), FALSE);
76                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON ( content_buttons[i] ), FALSE);
77         }
78
79         gtk_entry_set_text( (GtkEntry *)value_entry, "");
80 }
81
82 void SetFlagButtons_UFOAI(texdef_to_face_t *texdef_face_list, bool b_isListEmpty)
83 {
84         int contents = 0;
85         int flags = 0;
86         int value = 0;
87         int diff_contents = 0;
88         int diff_flags = 0;
89         gboolean diff_value = FALSE;
90         char tex_buff[11];
91         texdef_t* tmp_texdef;
92         texdef_to_face_t* temp_texdef_face_list;
93         int i;
94
95         setup_buttons = TRUE;
96         working_surface_flags = 0;
97         surface_mask = 0;
98         working_content_flags = 0;
99         content_mask = 0;
100         working_value = 0;
101
102         if (!b_isListEmpty) {
103                 tmp_texdef = &texdef_face_list->texdef;
104                 contents = tmp_texdef->contents;
105                 flags = tmp_texdef->flags;
106                 value = tmp_texdef->value;
107
108                 Sys_Printf("Surface: %d\tContents: %d\tValue: %d\ttmp_texdef\n",tmp_texdef->flags,tmp_texdef->contents,tmp_texdef->value);
109                 Sys_Printf("Surface: %d\tContents: %d\tValue: %d\n",flags,contents,value);
110
111                 for (temp_texdef_face_list = texdef_face_list->next; temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
112                 {
113                         tmp_texdef = &temp_texdef_face_list->texdef;
114                         diff_contents |= contents ^ tmp_texdef->contents;  // Figure out which buttons are inconsistent
115                         diff_flags |= flags ^ tmp_texdef->flags;
116                         if (tmp_texdef->value != value)
117                                 diff_value = TRUE;
118
119                         Sys_Printf("Surface: %d\tContents: %d\tValue: %d\ttmp_texdef\n",tmp_texdef->flags,tmp_texdef->contents,tmp_texdef->value);
120                         Sys_Printf("Surface: %d\tContents: %d\tValue: %d\n",flags,contents,value);
121                 }
122         }
123
124         clear_all_inconsistent();
125
126         // If no faces/brushes are selected, clear everything and bail
127         if (b_isListEmpty) {
128                 clear_all_buttons_and_values();
129                 setup_buttons = FALSE;
130                 return;
131         }
132
133         for (i = 0; i < MAX_BUTTONS; i++) {
134                 // Set surface buttons to reflect brush/face flags, contents, and values
135                 if(diff_flags & (1 << i))
136                         set_inconsistent(surface_buttons[i]);
137                 else if(flags & (1 << i))
138                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (surface_buttons[i]), TRUE);
139                 else
140                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (surface_buttons[i]), FALSE);
141
142                 if(diff_contents & (1 << i))
143                         set_inconsistent(content_buttons[i]);
144                 else if(contents & (1 << i))
145                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (content_buttons[i]), TRUE);
146                 else
147                         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (content_buttons[i]), FALSE);
148         }
149
150         // Set Value
151         if (diff_value)
152                 gtk_entry_set_text( (GtkEntry *)value_entry, "");
153         else {
154                 working_value = value;
155                 sprintf( tex_buff, "%d", value);
156                 gtk_entry_set_text( (GtkEntry *)value_entry, tex_buff);
157         }
158
159         setup_buttons = FALSE;
160 }
161
162 void SetChangeInFlags_Face_UFOAI (texdef_to_face_t *texdef_face_list)
163 {
164         texdef_to_face_t *temp_texdef_face_list;
165         texdef_t *tmp_texdef;
166
167         for (temp_texdef_face_list = texdef_face_list; temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next)
168         {
169                 tmp_texdef = &temp_texdef_face_list->texdef;
170                 tmp_texdef->flags = (tmp_texdef->flags & ~surface_mask) | working_surface_flags;
171                 tmp_texdef->contents = (tmp_texdef->contents & ~content_mask) | working_content_flags;
172                 tmp_texdef->value = working_value;
173                 Sys_Printf("content_flag: %d     content_mask: %d\n",working_content_flags,content_mask);
174                 Sys_Printf("content: %d\n",tmp_texdef->contents);
175         }
176 }
177
178 inline void change_surfaceflag (GtkWidget *togglebutton, int sur_flag, gboolean change_flag_to)
179 {
180         if (!setup_buttons) // If we're setting up the buttons, we really don't need to
181         {                   // set flags that are already set
182                 if (gtk_toggle_button_get_inconsistent(GTK_TOGGLE_BUTTON (togglebutton))) // Clear out inconsistent, if set
183                         clear_inconsistent(GTK_WIDGET (togglebutton));
184
185                 surface_mask |= sur_flag;
186
187                 if (change_flag_to)
188                         working_surface_flags |= sur_flag;
189                 else
190                         working_surface_flags &= ~sur_flag;
191         }
192 }
193
194 inline void change_contentflag (GtkWidget *togglebutton, int content_flag, gboolean change_flag_to)
195 {
196         if ( (!setup_buttons) )  // If we're setting up the buttons, we really don't need to
197         {                        // set flags that are already set
198                 if (gtk_toggle_button_get_inconsistent(GTK_TOGGLE_BUTTON (togglebutton)))
199                         clear_inconsistent(togglebutton);
200                 //if (g_ptrSelectedFaces.GetSize() == 0)  // Only changing content flags on whole brushes, not faces.
201                 //{
202                 content_mask |= content_flag;
203
204                 if (change_flag_to)
205                         working_content_flags |= content_flag;
206                 else
207                         working_content_flags &= ~content_flag;
208                 //}
209                 Sys_Printf("content_flag: %d     content_mask: %d\n",content_flag,content_mask);
210         }
211 }
212
213 // Surface Flags Callbacks
214 void on_surface_button_toggled (GtkToggleButton *togglebutton, gpointer user_data)
215 {
216         int flag = GPOINTER_TO_INT(user_data);
217         change_surfaceflag(GTK_WIDGET (togglebutton), flag, (GTK_TOGGLE_BUTTON (togglebutton)->active));
218 }
219
220 // Content Flags Callbacks
221 void on_content_button_toggled (GtkToggleButton *togglebutton, gpointer user_data)
222 {
223         int flag = GPOINTER_TO_INT(user_data);
224         change_contentflag(GTK_WIDGET (togglebutton), flag, (GTK_TOGGLE_BUTTON (togglebutton)->active));
225 }
226
227 // Value Entry Callback
228 void on_value_entry_changed (GtkEditable *editable, gpointer user_data)
229 {
230         if ( (!setup_buttons) )  // If we're setting up the buttons, don't change value
231         working_value = atoi( gtk_entry_get_text( (GtkEntry*)editable) );
232 }
233
234 void on_value_entry_insert_text (GtkEditable *editable, gchar *new_text, gint new_text_length, gint *position, gpointer user_data)
235 {
236         int i, count=0;
237         gchar *result;
238
239         // Limit input to digits, throwing out anything else
240         // Modified from Gtk FAQ for text filtering of GtkEntry
241         result = g_new (gchar, new_text_length);
242
243         for (i=0; i < new_text_length; i++) {
244                 if (!isdigit(new_text[i]))
245                         continue;
246                 result[count++] = new_text[i];
247         }
248
249         if (count > 0) {
250                 gtk_signal_handler_block_by_func (GTK_OBJECT (editable),
251                                                 GTK_SIGNAL_FUNC (on_value_entry_insert_text),
252                                                 user_data);
253                 gtk_editable_insert_text (editable, result, count, position);
254                 gtk_signal_handler_unblock_by_func (GTK_OBJECT (editable),
255                                                 GTK_SIGNAL_FUNC (on_value_entry_insert_text),
256                                                 user_data);
257         }
258         gtk_signal_emit_stop_by_name (GTK_OBJECT (editable), "insert_text");
259
260         g_free (result);
261 }
262
263 void on_surfacebutton_clicked (GtkButton *button, gpointer user_data)
264 {
265         gtk_notebook_set_page (GTK_NOTEBOOK(notebook1), 0);
266 }
267
268 void on_contentbutton_clicked (GtkButton *button, gpointer user_data)
269 {
270         gtk_notebook_set_page (GTK_NOTEBOOK(notebook1), 1);
271 }
272
273 #define UFOAI_FLAG_BUTTON_BORDER 3
274
275 GtkWidget* Create_UFOAIFlagsDialog (GtkWidget* surfacedialog_widget)
276 {
277         GtkWidget *frame1;
278         GtkWidget *vbox1;
279         GtkWidget *vbox2;
280         GtkWidget *vbox3;
281         GtkWidget *vbox4;
282         GtkWidget *table4;
283         GtkWidget *hbox2;
284         GtkWidget *hbox3;
285         GtkWidget *hseparator1;
286         GtkWidget *value_label;
287         GtkWidget *label5;
288         GtkWidget *table3;
289         GtkWidget *label6;
290         int i, x, y;
291         const char *buttonLabel;
292         char buffer[8];
293
294         frame1 = gtk_frame_new ("Flags");
295         gtk_widget_show (frame1);
296         gtk_container_add (GTK_CONTAINER (surfacedialog_widget), frame1);
297
298         vbox1 = gtk_vbox_new (FALSE, 0);
299         gtk_widget_show (vbox1);
300         gtk_container_add (GTK_CONTAINER (frame1), vbox1);
301
302         notebook1 = gtk_notebook_new ();
303         gtk_widget_show (notebook1);
304         gtk_box_pack_start (GTK_BOX (vbox1), notebook1, TRUE, TRUE, 0);
305         gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook1), TRUE);
306         gtk_container_set_border_width (GTK_CONTAINER (notebook1), 5);
307
308         vbox2 = gtk_vbox_new (FALSE, 0);
309         gtk_widget_show (vbox2);
310         gtk_container_add (GTK_CONTAINER (notebook1), vbox2);
311
312         table4 = gtk_table_new (8, 4, FALSE);
313         gtk_widget_show (table4);
314         gtk_box_pack_start (GTK_BOX (vbox2), table4, TRUE, TRUE, 0);
315
316         y = -1;
317         for (i = 0; i < MAX_BUTTONS; i++) {
318                 if (!(i % 4))
319                         y++;
320                 x = i % 4;
321                 snprintf(buffer, sizeof(buffer) - 1, "surf%i", i + 1);
322                 buttonLabel = g_FuncTable.m_pfnReadProjectKey(buffer);
323                 Sys_Printf("%s: %s\n", buffer, buttonLabel);
324                 surface_buttons[i] = gtk_toggle_button_new_with_label (buttonLabel);
325                 gtk_signal_connect(GTK_OBJECT (surface_buttons[i]), "toggled", GTK_SIGNAL_FUNC(on_surface_button_toggled), GINT_TO_POINTER(1 << i));
326                 gtk_widget_show(surface_buttons[i]);
327                 gtk_table_attach(GTK_TABLE (table4), surface_buttons[i], 0 + x, 1 + x, (0 + y), (1 + y),
328                                                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
329                                                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
330                 gtk_container_set_border_width (GTK_CONTAINER (surface_buttons[i]), UFOAI_FLAG_BUTTON_BORDER);
331         }
332
333         hseparator1 = gtk_hseparator_new ();
334         gtk_widget_show (hseparator1);
335         gtk_box_pack_start (GTK_BOX (vbox2), hseparator1, FALSE, FALSE, 0);
336         gtk_widget_set_usize (hseparator1, -2, 5);
337
338         hbox2 = gtk_hbox_new (FALSE, 0);
339         gtk_widget_show (hbox2);
340         gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);
341
342         hbox3 = gtk_hbox_new (FALSE, 0);
343         gtk_widget_show (hbox3);
344         gtk_box_pack_start (GTK_BOX (hbox2), hbox3, TRUE, TRUE, 0);
345
346         vbox4 = gtk_vbox_new (FALSE, 0);
347         gtk_widget_show (vbox4);
348         gtk_box_pack_start (GTK_BOX (hbox3), vbox4, TRUE, TRUE, 0);
349
350         value_label = gtk_label_new (" Value: ");
351         gtk_widget_show (value_label);
352         gtk_box_pack_start (GTK_BOX (hbox3), value_label, FALSE, FALSE, 0);
353
354         value_entry = gtk_entry_new ();
355         gtk_signal_connect (GTK_OBJECT (value_entry), "changed",
356                                                 GTK_SIGNAL_FUNC (on_value_entry_changed),
357                                                 NULL);
358         gtk_signal_connect (GTK_OBJECT (value_entry), "insert_text",
359                                                 GTK_SIGNAL_FUNC (on_value_entry_insert_text),
360                                                 NULL);
361         gtk_entry_set_max_length( (GtkEntry *)value_entry, 11);
362         gtk_widget_show (value_entry);
363         gtk_box_pack_start (GTK_BOX (hbox3), value_entry, TRUE, TRUE, 0);
364
365         vbox3 = gtk_vbox_new (FALSE, 0);
366         gtk_widget_show (vbox3);
367         gtk_box_pack_start (GTK_BOX (hbox3), vbox3, TRUE, TRUE, 0);
368
369         label5 = gtk_label_new ("Surface Flags");
370         gtk_widget_show (label5);
371         gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 0), label5);
372
373         table3 = gtk_table_new (8, 4, FALSE);
374         gtk_widget_show (table3);
375         gtk_container_add (GTK_CONTAINER (notebook1), table3);
376
377         y = -1;
378         for (i = 0; i < MAX_BUTTONS; i++) {
379                 if (!(i % 4))
380                         y++;
381                 x = i % 4;
382                 snprintf(buffer, sizeof(buffer) - 1, "cont%i", i + 1);
383                 buttonLabel = g_FuncTable.m_pfnReadProjectKey(buffer);
384                 content_buttons[i] = gtk_toggle_button_new_with_label(buttonLabel);
385                 gtk_signal_connect(GTK_OBJECT (content_buttons[i]), "toggled", GTK_SIGNAL_FUNC (on_content_button_toggled), GINT_TO_POINTER(1 << i));
386                 gtk_widget_show(content_buttons[i]);
387                 gtk_table_attach(GTK_TABLE (table3), content_buttons[i], 0 + x, 1 + x, (0 + y), (1 + y),
388                                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
389                                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
390                 gtk_container_set_border_width (GTK_CONTAINER (content_buttons[i]), UFOAI_FLAG_BUTTON_BORDER);
391         }
392
393         label6 = gtk_label_new ("Content Flags");
394         gtk_widget_show (label6);
395         gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 1), label6);
396
397         return frame1;
398 }
399