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