* modified ufoai surface plugin to read the surface and content flag names from the...
[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 #define UFOAI_FLAG_BUTTON_BORDER 3
273
274 GtkWidget* Create_UFOAIFlagsDialog (GtkWidget* surfacedialog_widget)
275 {
276         GtkWidget *frame1;
277         GtkWidget *vbox1;
278         GtkWidget *vbox2;
279         GtkWidget *vbox3;
280         GtkWidget *vbox4;
281         GtkWidget *table4;
282         GtkWidget *hbox2;
283         GtkWidget *hbox3;
284         GtkWidget *hseparator1;
285         GtkWidget *value_label;
286         GtkWidget *label5;
287         GtkWidget *table3;
288         GtkWidget *label6;
289         int i, x, y;
290         const char *buttonLabel;
291         char buffer[8];
292
293         frame1 = gtk_frame_new ("Flags");
294         gtk_widget_show (frame1);
295         gtk_container_add (GTK_CONTAINER (surfacedialog_widget), frame1);
296
297         vbox1 = gtk_vbox_new (FALSE, 0);
298         gtk_widget_show (vbox1);
299         gtk_container_add (GTK_CONTAINER (frame1), vbox1);
300
301         notebook1 = gtk_notebook_new ();
302         gtk_widget_show (notebook1);
303         gtk_box_pack_start (GTK_BOX (vbox1), notebook1, TRUE, TRUE, 0);
304         gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook1), TRUE);
305         gtk_container_set_border_width (GTK_CONTAINER (notebook1), 5);
306
307         vbox2 = gtk_vbox_new (FALSE, 0);
308         gtk_widget_show (vbox2);
309         gtk_container_add (GTK_CONTAINER (notebook1), vbox2);
310
311         table4 = gtk_table_new (8, 4, FALSE);
312         gtk_widget_show (table4);
313         gtk_box_pack_start (GTK_BOX (vbox2), table4, TRUE, TRUE, 0);
314
315         y = -1;
316         for (i = 0; i < MAX_BUTTONS; i++) {
317                 if (!(i % 4))
318                         y++;
319                 x = i % 4;
320                 snprintf(buffer, sizeof(buffer) - 1, "surf%i", i + 1);
321                 buttonLabel = g_FuncTable.m_pfnReadProjectKey(buffer);
322                 Sys_Printf("%s: %s\n", buffer, buttonLabel);
323                 surface_buttons[i] = gtk_toggle_button_new_with_label (buttonLabel);
324                 gtk_signal_connect(GTK_OBJECT (surface_buttons[i]), "toggled", GTK_SIGNAL_FUNC(on_surface_button_toggled), GINT_TO_POINTER(1 << i));
325                 gtk_widget_show(surface_buttons[i]);
326                 gtk_table_attach(GTK_TABLE (table4), surface_buttons[i], 0 + x, 1 + x, (0 + y), (1 + y),
327                                                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
328                                                         (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
329                 gtk_container_set_border_width (GTK_CONTAINER (surface_buttons[i]), UFOAI_FLAG_BUTTON_BORDER);
330         }
331
332         hseparator1 = gtk_hseparator_new ();
333         gtk_widget_show (hseparator1);
334         gtk_box_pack_start (GTK_BOX (vbox2), hseparator1, FALSE, FALSE, 0);
335         gtk_widget_set_usize (hseparator1, -2, 5);
336
337         hbox2 = gtk_hbox_new (FALSE, 0);
338         gtk_widget_show (hbox2);
339         gtk_box_pack_start (GTK_BOX (vbox2), hbox2, FALSE, FALSE, 0);
340
341         hbox3 = gtk_hbox_new (FALSE, 0);
342         gtk_widget_show (hbox3);
343         gtk_box_pack_start (GTK_BOX (hbox2), hbox3, TRUE, TRUE, 0);
344
345         vbox4 = gtk_vbox_new (FALSE, 0);
346         gtk_widget_show (vbox4);
347         gtk_box_pack_start (GTK_BOX (hbox3), vbox4, TRUE, TRUE, 0);
348
349         value_label = gtk_label_new (" Value: ");
350         gtk_widget_show (value_label);
351         gtk_box_pack_start (GTK_BOX (hbox3), value_label, FALSE, FALSE, 0);
352
353         value_entry = gtk_entry_new ();
354         gtk_signal_connect (GTK_OBJECT (value_entry), "changed",
355                                                 GTK_SIGNAL_FUNC (on_value_entry_changed),
356                                                 NULL);
357         gtk_signal_connect (GTK_OBJECT (value_entry), "insert_text",
358                                                 GTK_SIGNAL_FUNC (on_value_entry_insert_text),
359                                                 NULL);
360         gtk_entry_set_max_length( (GtkEntry *)value_entry, 11);
361         gtk_widget_show (value_entry);
362         gtk_box_pack_start (GTK_BOX (hbox3), value_entry, TRUE, TRUE, 0);
363
364         vbox3 = gtk_vbox_new (FALSE, 0);
365         gtk_widget_show (vbox3);
366         gtk_box_pack_start (GTK_BOX (hbox3), vbox3, TRUE, TRUE, 0);
367
368         label5 = gtk_label_new ("Surface Flags");
369         gtk_widget_show (label5);
370         gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 0), label5);
371
372         table3 = gtk_table_new (8, 4, FALSE);
373         gtk_widget_show (table3);
374         gtk_container_add (GTK_CONTAINER (notebook1), table3);
375
376         y = -1;
377         for (i = 0; i < MAX_BUTTONS; i++) {
378                 if (!(i % 4))
379                         y++;
380                 x = i % 4;
381                 snprintf(buffer, sizeof(buffer) - 1, "cont%i", i + 1);
382                 buttonLabel = g_FuncTable.m_pfnReadProjectKey(buffer);
383                 content_buttons[i] = gtk_toggle_button_new_with_label(buttonLabel);
384                 gtk_signal_connect(GTK_OBJECT (content_buttons[i]), "toggled", GTK_SIGNAL_FUNC (on_content_button_toggled), GINT_TO_POINTER(1 << i));
385                 gtk_widget_show(content_buttons[i]);
386                 gtk_table_attach(GTK_TABLE (table3), content_buttons[i], 0 + x, 1 + x, (0 + y), (1 + y),
387                                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
388                                                 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
389                 gtk_container_set_border_width (GTK_CONTAINER (content_buttons[i]), UFOAI_FLAG_BUTTON_BORDER);
390         }
391
392         label6 = gtk_label_new ("Content Flags");
393         gtk_widget_show (label6);
394         gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 1), label6);
395
396         return frame1;
397 }
398