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