]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - plugins/surface_ufoai/surfaceflagsdialog_ufoai.cpp
error check and bail if permission denied during gamepack install
[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         gtk_toggle_button_set_inconsistent( GTK_TOGGLE_BUTTON( toggle_button ), TRUE );
55 }
56
57 inline void clear_inconsistent( GtkWidget *toggle_button ){
58         if ( gtk_toggle_button_get_inconsistent( GTK_TOGGLE_BUTTON( toggle_button ) ) ) {
59                 gtk_toggle_button_set_inconsistent( GTK_TOGGLE_BUTTON( toggle_button ), FALSE );
60         }
61 }
62
63 void clear_all_inconsistent( void ){
64         int i;
65
66         for ( i = 0; i < MAX_BUTTONS; i++ ) {
67                 clear_inconsistent( surface_buttons[i] );
68                 clear_inconsistent( content_buttons[i] );
69         }
70 }
71
72 void clear_all_buttons_and_values(){
73         int i;
74
75         for ( i = 0; i < MAX_BUTTONS; i++ ) {
76                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( surface_buttons[i] ), FALSE );
77                 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( content_buttons[i] ), FALSE );
78         }
79
80         gtk_entry_set_text( (GtkEntry *)value_entry, "" );
81 }
82
83 void SetFlagButtons_UFOAI( texdef_to_face_t *texdef_face_list, bool b_isListEmpty ){
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
120                         Sys_Printf( "Surface: %d\tContents: %d\tValue: %d\ttmp_texdef\n",tmp_texdef->flags,tmp_texdef->contents,tmp_texdef->value );
121                         Sys_Printf( "Surface: %d\tContents: %d\tValue: %d\n",flags,contents,value );
122                 }
123         }
124
125         clear_all_inconsistent();
126
127         // If no faces/brushes are selected, clear everything and bail
128         if ( b_isListEmpty ) {
129                 clear_all_buttons_and_values();
130                 setup_buttons = FALSE;
131                 return;
132         }
133
134         for ( i = 0; i < MAX_BUTTONS; i++ ) {
135                 // Set surface buttons to reflect brush/face flags, contents, and values
136                 if ( diff_flags & ( 1 << i ) ) {
137                         set_inconsistent( surface_buttons[i] );
138                 }
139                 else if ( flags & ( 1 << i ) ) {
140                         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( surface_buttons[i] ), TRUE );
141                 }
142                 else{
143                         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( surface_buttons[i] ), FALSE );
144                 }
145
146                 if ( diff_contents & ( 1 << i ) ) {
147                         set_inconsistent( content_buttons[i] );
148                 }
149                 else if ( contents & ( 1 << i ) ) {
150                         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( content_buttons[i] ), TRUE );
151                 }
152                 else{
153                         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( content_buttons[i] ), FALSE );
154                 }
155         }
156
157         // Set Value
158         if ( diff_value ) {
159                 gtk_entry_set_text( (GtkEntry *)value_entry, "" );
160         }
161         else {
162                 working_value = value;
163                 sprintf( tex_buff, "%d", value );
164                 gtk_entry_set_text( (GtkEntry *)value_entry, tex_buff );
165         }
166
167         setup_buttons = FALSE;
168 }
169
170 void SetChangeInFlags_Face_UFOAI( texdef_to_face_t *texdef_face_list ){
171         texdef_to_face_t *temp_texdef_face_list;
172         texdef_t *tmp_texdef;
173
174         for ( temp_texdef_face_list = texdef_face_list; temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next )
175         {
176                 tmp_texdef = &temp_texdef_face_list->texdef;
177                 tmp_texdef->flags = ( tmp_texdef->flags & ~surface_mask ) | working_surface_flags;
178                 tmp_texdef->contents = ( tmp_texdef->contents & ~content_mask ) | working_content_flags;
179                 tmp_texdef->value = working_value;
180                 Sys_Printf( "content_flag: %d     content_mask: %d\n",working_content_flags,content_mask );
181                 Sys_Printf( "content: %d\n",tmp_texdef->contents );
182         }
183 }
184
185 inline void change_surfaceflag( GtkWidget *togglebutton, int sur_flag, gboolean change_flag_to ){
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
192                 surface_mask |= sur_flag;
193
194                 if ( change_flag_to ) {
195                         working_surface_flags |= sur_flag;
196                 }
197                 else{
198                         working_surface_flags &= ~sur_flag;
199                 }
200         }
201 }
202
203 inline void change_contentflag( GtkWidget *togglebutton, int content_flag, gboolean change_flag_to ){
204         if ( ( !setup_buttons ) ) { // If we're setting up the buttons, we really don't need to
205                                        // set flags that are already set
206                 if ( gtk_toggle_button_get_inconsistent( GTK_TOGGLE_BUTTON( togglebutton ) ) ) {
207                         clear_inconsistent( togglebutton );
208                 }
209                 //if (g_ptrSelectedFaces.GetSize() == 0)  // Only changing content flags on whole brushes, not faces.
210                 //{
211                 content_mask |= content_flag;
212
213                 if ( change_flag_to ) {
214                         working_content_flags |= content_flag;
215                 }
216                 else{
217                         working_content_flags &= ~content_flag;
218                 }
219                 //}
220                 Sys_Printf( "content_flag: %d     content_mask: %d\n",content_flag,content_mask );
221         }
222 }
223
224 // Surface Flags Callbacks
225 void on_surface_button_toggled( GtkToggleButton *togglebutton, gpointer user_data ){
226         int flag = GPOINTER_TO_INT( user_data );
227         change_surfaceflag( GTK_WIDGET( togglebutton ), flag, ( GTK_TOGGLE_BUTTON( togglebutton )->active ) );
228 }
229
230 // Content Flags Callbacks
231 void on_content_button_toggled( GtkToggleButton *togglebutton, gpointer user_data ){
232         int flag = GPOINTER_TO_INT( user_data );
233         change_contentflag( GTK_WIDGET( togglebutton ), flag, ( GTK_TOGGLE_BUTTON( togglebutton )->active ) );
234 }
235
236 // Value Entry Callback
237 void on_value_entry_changed( GtkEditable *editable, gpointer user_data ){
238         if ( ( !setup_buttons ) ) { // If we're setting up the buttons, don't change value
239                 working_value = atoi( gtk_entry_get_text( (GtkEntry*)editable ) );
240         }
241 }
242
243 void on_value_entry_insert_text( GtkEditable *editable, gchar *new_text, gint new_text_length, gint *position, gpointer user_data ){
244         int i, count = 0;
245         gchar *result;
246
247         // Limit input to digits, throwing out anything else
248         // Modified from Gtk FAQ for text filtering of GtkEntry
249         result = g_new( gchar, new_text_length );
250
251         for ( i = 0; i < new_text_length; i++ ) {
252                 if ( !isdigit( new_text[i] ) ) {
253                         continue;
254                 }
255                 result[count++] = new_text[i];
256         }
257
258         if ( count > 0 ) {
259                 gtk_signal_handler_block_by_func( GTK_OBJECT( editable ),
260                                                                                   GTK_SIGNAL_FUNC( on_value_entry_insert_text ),
261                                                                                   user_data );
262                 gtk_editable_insert_text( editable, result, count, position );
263                 gtk_signal_handler_unblock_by_func( GTK_OBJECT( editable ),
264                                                                                         GTK_SIGNAL_FUNC( on_value_entry_insert_text ),
265                                                                                         user_data );
266         }
267         gtk_signal_emit_stop_by_name( GTK_OBJECT( editable ), "insert_text" );
268
269         g_free( result );
270 }
271
272 void on_surfacebutton_clicked( GtkButton *button, gpointer user_data ){
273         gtk_notebook_set_page( GTK_NOTEBOOK( notebook1 ), 0 );
274 }
275
276 void on_contentbutton_clicked( GtkButton *button, gpointer user_data ){
277         gtk_notebook_set_page( GTK_NOTEBOOK( notebook1 ), 1 );
278 }
279
280 #define UFOAI_FLAG_BUTTON_BORDER 3
281
282 GtkWidget* Create_UFOAIFlagsDialog( GtkWidget* surfacedialog_widget ){
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                 }
327                 x = i % 4;
328                 snprintf( buffer, sizeof( buffer ) - 1, "surf%i", i + 1 );
329                 buttonLabel = g_FuncTable.m_pfnReadProjectKey( buffer );
330                 Sys_Printf( "%s: %s\n", buffer, buttonLabel );
331                 surface_buttons[i] = gtk_toggle_button_new_with_label( buttonLabel );
332                 gtk_signal_connect( GTK_OBJECT( surface_buttons[i] ), "toggled", GTK_SIGNAL_FUNC( on_surface_button_toggled ), GINT_TO_POINTER( 1 << i ) );
333                 gtk_widget_show( surface_buttons[i] );
334                 gtk_table_attach( GTK_TABLE( table4 ), surface_buttons[i], 0 + x, 1 + x, ( 0 + y ), ( 1 + y ),
335                                                   (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
336                                                   (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
337                 gtk_container_set_border_width( GTK_CONTAINER( surface_buttons[i] ), UFOAI_FLAG_BUTTON_BORDER );
338         }
339
340         hseparator1 = gtk_hseparator_new();
341         gtk_widget_show( hseparator1 );
342         gtk_box_pack_start( GTK_BOX( vbox2 ), hseparator1, FALSE, FALSE, 0 );
343         gtk_widget_set_usize( hseparator1, -2, 5 );
344
345         hbox2 = gtk_hbox_new( FALSE, 0 );
346         gtk_widget_show( hbox2 );
347         gtk_box_pack_start( GTK_BOX( vbox2 ), hbox2, FALSE, FALSE, 0 );
348
349         hbox3 = gtk_hbox_new( FALSE, 0 );
350         gtk_widget_show( hbox3 );
351         gtk_box_pack_start( GTK_BOX( hbox2 ), hbox3, TRUE, TRUE, 0 );
352
353         vbox4 = gtk_vbox_new( FALSE, 0 );
354         gtk_widget_show( vbox4 );
355         gtk_box_pack_start( GTK_BOX( hbox3 ), vbox4, TRUE, TRUE, 0 );
356
357         value_label = gtk_label_new( " Value: " );
358         gtk_widget_show( value_label );
359         gtk_box_pack_start( GTK_BOX( hbox3 ), value_label, FALSE, FALSE, 0 );
360
361         value_entry = gtk_entry_new();
362         gtk_signal_connect( GTK_OBJECT( value_entry ), "changed",
363                                                 GTK_SIGNAL_FUNC( on_value_entry_changed ),
364                                                 NULL );
365         gtk_signal_connect( GTK_OBJECT( value_entry ), "insert_text",
366                                                 GTK_SIGNAL_FUNC( on_value_entry_insert_text ),
367                                                 NULL );
368         gtk_entry_set_max_length( (GtkEntry *)value_entry, 11 );
369         gtk_widget_show( value_entry );
370         gtk_box_pack_start( GTK_BOX( hbox3 ), value_entry, TRUE, TRUE, 0 );
371
372         vbox3 = gtk_vbox_new( FALSE, 0 );
373         gtk_widget_show( vbox3 );
374         gtk_box_pack_start( GTK_BOX( hbox3 ), vbox3, TRUE, TRUE, 0 );
375
376         label5 = gtk_label_new( "Surface Flags" );
377         gtk_widget_show( label5 );
378         gtk_notebook_set_tab_label( GTK_NOTEBOOK( notebook1 ), gtk_notebook_get_nth_page( GTK_NOTEBOOK( notebook1 ), 0 ), label5 );
379
380         table3 = gtk_table_new( 8, 4, FALSE );
381         gtk_widget_show( table3 );
382         gtk_container_add( GTK_CONTAINER( notebook1 ), table3 );
383
384         y = -1;
385         for ( i = 0; i < MAX_BUTTONS; i++ ) {
386                 if ( !( i % 4 ) ) {
387                         y++;
388                 }
389                 x = i % 4;
390                 snprintf( buffer, sizeof( buffer ) - 1, "cont%i", i + 1 );
391                 buttonLabel = g_FuncTable.m_pfnReadProjectKey( buffer );
392                 content_buttons[i] = gtk_toggle_button_new_with_label( buttonLabel );
393                 gtk_signal_connect( GTK_OBJECT( content_buttons[i] ), "toggled", GTK_SIGNAL_FUNC( on_content_button_toggled ), GINT_TO_POINTER( 1 << i ) );
394                 gtk_widget_show( content_buttons[i] );
395                 gtk_table_attach( GTK_TABLE( table3 ), content_buttons[i], 0 + x, 1 + x, ( 0 + y ), ( 1 + y ),
396                                                   (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
397                                                   (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), 0, 0 );
398                 gtk_container_set_border_width( GTK_CONTAINER( content_buttons[i] ), UFOAI_FLAG_BUTTON_BORDER );
399         }
400
401         label6 = gtk_label_new( "Content Flags" );
402         gtk_widget_show( label6 );
403         gtk_notebook_set_tab_label( GTK_NOTEBOOK( notebook1 ), gtk_notebook_get_nth_page( GTK_NOTEBOOK( notebook1 ), 1 ), label6 );
404
405         return frame1;
406 }