Wrap more GTK
[xonotic/netradiant.git] / contrib / bobtoolz / dialogs / dialogs-gtk.cpp
1 /*
2    BobToolz plugin for GtkRadiant
3    Copyright (C) 2001 Gordon Biggans
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include "dialogs-gtk.h"
21 #include "../funchandlers.h"
22
23 #include "str.h"
24 #include <list>
25 #include <gtk/gtk.h>
26 #include "gtkutil/pointer.h"
27
28 #include "../lists.h"
29 #include "../misc.h"
30
31
32 /*--------------------------------
33         Callback Functions
34    ---------------------------------*/
35
36 typedef struct {
37         ui::Widget cbTexChange{ui::null};
38         ui::Widget editTexOld{ui::null}, editTexNew{ui::null};
39
40         ui::Widget cbScaleHor{ui::null}, cbScaleVert{ui::null};
41         ui::Widget editScaleHor{ui::null}, editScaleVert{ui::null};
42
43         ui::Widget cbShiftHor{ui::null}, cbShiftVert{ui::null};
44         ui::Widget editShiftHor{ui::null}, editShiftVert{ui::null};
45
46         ui::Widget cbRotation{ui::null};
47         ui::Widget editRotation{ui::null};
48 }dlg_texReset_t;
49
50 dlg_texReset_t dlgTexReset;
51
52 void Update_TextureReseter();
53
54 static void dialog_button_callback_texreset_update( GtkWidget *widget, gpointer data ){
55         Update_TextureReseter();
56 }
57
58 void Update_TextureReseter(){
59         gboolean check;
60
61         check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbTexChange ) );
62         gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editTexNew ), check );
63         gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editTexOld ), check );
64
65         check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbScaleHor ) );
66         gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editScaleHor ), check );
67
68         check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbScaleVert ) );
69         gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editScaleVert ), check );
70
71         check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbShiftHor ) );
72         gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editShiftHor ), check );
73
74         check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbShiftVert ) );
75         gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editShiftVert ), check );
76
77         check = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbRotation ) );
78         gtk_editable_set_editable( GTK_EDITABLE( dlgTexReset.editRotation ), check );
79 }
80
81 static void dialog_button_callback( ui::Widget widget, gpointer data ){
82         int *loop;
83         EMessageBoxReturn *ret;
84
85         auto parent = widget.window();
86         loop = (int*)g_object_get_data( G_OBJECT( parent ), "loop" );
87         ret = (EMessageBoxReturn*)g_object_get_data( G_OBJECT( parent ), "ret" );
88
89         *loop = 0;
90         *ret = (EMessageBoxReturn)gpointer_to_int( data );
91 }
92
93 static gint dialog_delete_callback( ui::Widget widget, GdkEvent* event, gpointer data ){
94         widget.hide();
95         int *loop = (int *) g_object_get_data(G_OBJECT(widget), "loop");
96         *loop = 0;
97         return TRUE;
98 }
99
100 static void dialog_button_callback_settex( GtkWidget *widget, gpointer data ){
101         TwinWidget* tw = (TwinWidget*)data;
102
103         GtkEntry* entry = GTK_ENTRY( tw->one );
104         auto* combo = GTK_BIN(tw->two);
105
106         const gchar *tex = gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(combo)));
107         gtk_entry_set_text( entry, tex );
108 }
109
110 /*--------------------------------
111     Data validation Routines
112    ---------------------------------*/
113
114 bool ValidateTextFloat( const char* pData, const char* error_title, float* value ){
115         if ( pData ) {
116                 float testNum = (float)atof( pData );
117
118                 if ( ( testNum == 0.0f ) && strcmp( pData, "0" ) ) {
119                         DoMessageBox( "Please Enter A Floating Point Number", error_title, eMB_OK );
120                         return FALSE;
121                 }
122                 else
123                 {
124                         *value = testNum;
125                         return TRUE;
126                 }
127         }
128
129         DoMessageBox( "Please Enter A Floating Point Number", error_title, eMB_OK );
130         return FALSE;
131 }
132
133 bool ValidateTextFloatRange( const char* pData, float min, float max, const char* error_title, float* value ){
134         char error_buffer[256];
135         sprintf( error_buffer, "Please Enter A Floating Point Number Between %.3f and %.3f", min, max );
136
137         if ( pData ) {
138                 float testNum = (float)atof( pData );
139
140                 if ( ( testNum < min ) || ( testNum > max ) ) {
141                         DoMessageBox( error_buffer, error_title, eMB_OK );
142                         return FALSE;
143                 }
144                 else
145                 {
146                         *value = testNum;
147                         return TRUE;
148                 }
149         }
150
151         DoMessageBox( error_buffer, error_title, eMB_OK );
152         return FALSE;
153 }
154
155 bool ValidateTextIntRange( const char* pData, int min, int max, const char* error_title, int* value ){
156         char error_buffer[256];
157         sprintf( error_buffer, "Please Enter An Integer Between %i and %i", min, max );
158
159         if ( pData ) {
160                 int testNum = atoi( pData );
161
162                 if ( ( testNum < min ) || ( testNum > max ) ) {
163                         DoMessageBox( error_buffer, error_title, eMB_OK );
164                         return FALSE;
165                 }
166                 else
167                 {
168                         *value = testNum;
169                         return TRUE;
170                 }
171         }
172
173         DoMessageBox( error_buffer, error_title, eMB_OK );
174         return FALSE;
175 }
176
177 bool ValidateTextInt( const char* pData, const char* error_title, int* value ){
178         if ( pData ) {
179                 int testNum = atoi( pData );
180
181                 if ( ( testNum == 0 ) && strcmp( pData, "0" ) ) {
182                         DoMessageBox( "Please Enter An Integer", error_title, eMB_OK );
183                         return FALSE;
184                 }
185                 else
186                 {
187                         *value = testNum;
188                         return TRUE;
189                 }
190         }
191
192         DoMessageBox( "Please Enter An Integer", error_title, eMB_OK );
193         return FALSE;
194 }
195
196 /*--------------------------------
197         Modal Dialog Boxes
198    ---------------------------------*/
199
200 /*
201
202    Major clean up of variable names etc required, excluding Mars's ones,
203    which are nicely done :)
204
205  */
206
207 EMessageBoxReturn DoMessageBox( const char* lpText, const char* lpCaption, EMessageBoxType type ){
208         ui::Widget w{ui::null};
209         EMessageBoxReturn ret;
210         int loop = 1;
211
212         auto window = ui::Window( ui::window_type::TOP );
213         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
214         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
215         gtk_window_set_title( window, lpCaption );
216         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
217         g_object_set_data( G_OBJECT( window ), "loop", &loop );
218         g_object_set_data( G_OBJECT( window ), "ret", &ret );
219         gtk_widget_realize( window );
220
221         auto vbox = ui::VBox( FALSE, 10 );
222         window.add(vbox);
223         vbox.show();
224
225         w = ui::Label( lpText );
226         vbox.pack_start( w, FALSE, FALSE, 2 );
227         gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT );
228         w.show();
229
230         w = ui::Widget(gtk_hseparator_new());
231         vbox.pack_start( w, FALSE, FALSE, 2 );
232         w.show();
233
234         auto hbox = ui::HBox( FALSE, 10 );
235         vbox.pack_start( hbox, FALSE, FALSE, 2 );
236         hbox.show();
237
238         if ( type == eMB_OK ) {
239                 w = ui::Button( "Ok" );
240                 hbox.pack_start( w, TRUE, TRUE, 0 );
241                 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
242                 gtk_widget_set_can_default(w, true);
243                 gtk_widget_grab_default( w );
244                 w.show();
245                 ret = eIDOK;
246         }
247         else if ( type ==  eMB_OKCANCEL ) {
248                 w = ui::Button( "Ok" );
249                 hbox.pack_start( w, TRUE, TRUE, 0 );
250                 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
251                 gtk_widget_set_can_default( w, true );
252                 gtk_widget_grab_default( w );
253                 w.show();
254
255                 w = ui::Button( "Cancel" );
256                 hbox.pack_start( w, TRUE, TRUE, 0 );
257                 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
258                 w.show();
259                 ret = eIDCANCEL;
260         }
261         else if ( type == eMB_YESNOCANCEL ) {
262                 w = ui::Button( "Yes" );
263                 hbox.pack_start( w, TRUE, TRUE, 0 );
264                 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDYES ) );
265                 gtk_widget_set_can_default( w, true );
266                 gtk_widget_grab_default( w );
267                 w.show();
268
269                 w = ui::Button( "No" );
270                 hbox.pack_start( w, TRUE, TRUE, 0 );
271                 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDNO ) );
272                 w.show();
273
274                 w = ui::Button( "Cancel" );
275                 hbox.pack_start( w, TRUE, TRUE, 0 );
276                 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
277                 w.show();
278                 ret = eIDCANCEL;
279         }
280         else /* if (mode == MB_YESNO) */
281         {
282                 w = ui::Button( "Yes" );
283                 hbox.pack_start( w, TRUE, TRUE, 0 );
284                 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDYES ) );
285                 gtk_widget_set_can_default( w, true );
286                 gtk_widget_grab_default( w );
287                 w.show();
288
289                 w = ui::Button( "No" );
290                 hbox.pack_start( w, TRUE, TRUE, 0 );
291                 w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDNO ) );
292                 w.show();
293                 ret = eIDNO;
294         }
295
296         gtk_window_set_position( window, GTK_WIN_POS_CENTER );
297         window.show();
298         gtk_grab_add( window );
299
300         while ( loop )
301                 gtk_main_iteration();
302
303         gtk_grab_remove( window );
304         window.destroy();
305
306         return ret;
307 }
308
309 EMessageBoxReturn DoIntersectBox( IntersectRS* rs ){
310         EMessageBoxReturn ret;
311         int loop = 1;
312
313         auto window = ui::Window( ui::window_type::TOP );
314
315         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
316         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
317
318         gtk_window_set_title( window, "Intersect" );
319         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
320
321         g_object_set_data( G_OBJECT( window ), "loop", &loop );
322         g_object_set_data( G_OBJECT( window ), "ret", &ret );
323
324         gtk_widget_realize( window );
325
326
327
328         auto vbox = ui::VBox( FALSE, 10 );
329         window.add(vbox);
330         vbox.show();
331
332         // ---- vbox ----
333
334
335         auto radio1 = ui::Widget(gtk_radio_button_new_with_label( NULL, "Use Whole Map" ));
336         vbox.pack_start( radio1, FALSE, FALSE, 2 );
337         radio1.show();
338
339         auto radio2 = ui::Widget(gtk_radio_button_new_with_label( gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio1)), "Use Selected Brushes" ));
340         vbox.pack_start( radio2, FALSE, FALSE, 2 );
341         radio2.show();
342
343         auto hsep = ui::Widget(gtk_hseparator_new());
344         vbox.pack_start( hsep, FALSE, FALSE, 2 );
345         hsep.show();
346
347         auto check1 = ui::CheckButton( "Include Detail Brushes" );
348         vbox.pack_start( check1, FALSE, FALSE, 0 );
349         check1.show();
350
351         auto check2 = ui::CheckButton( "Select Duplicate Brushes Only" );
352         vbox.pack_start( check2, FALSE, FALSE, 0 );
353         check2.show();
354
355         auto hbox = ui::HBox( FALSE, 10 );
356         vbox.pack_start( hbox, FALSE, FALSE, 2 );
357         hbox.show();
358
359         // ---- hbox ---- ok/cancel buttons
360
361         auto w = ui::Button( "Ok" );
362         hbox.pack_start( w, TRUE, TRUE, 0 );
363         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
364
365         gtk_widget_set_can_default( w, true );
366         gtk_widget_grab_default( w );
367         w.show();
368
369         w = ui::Button( "Cancel" );
370         hbox.pack_start( w, TRUE, TRUE, 0 );
371         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
372         w.show();
373         ret = eIDCANCEL;
374
375         // ---- /hbox ----
376
377         // ---- /vbox ----
378
379         gtk_window_set_position( window, GTK_WIN_POS_CENTER );
380         window.show();
381         gtk_grab_add( window );
382
383         while ( loop )
384                 gtk_main_iteration();
385
386         if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(radio1) ) ) {
387                 rs->nBrushOptions = BRUSH_OPT_WHOLE_MAP;
388         }
389         else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(radio2) ) ) {
390                 rs->nBrushOptions = BRUSH_OPT_SELECTED;
391         }
392
393         rs->bUseDetail = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(check1) ) ? true : false;
394         rs->bDuplicateOnly = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(check2) ) ? true : false;
395
396         gtk_grab_remove( window );
397         window.destroy();
398
399         return ret;
400 }
401
402 EMessageBoxReturn DoPolygonBox( PolygonRS* rs ){
403         EMessageBoxReturn ret;
404         int loop = 1;
405
406         auto window = ui::Window( ui::window_type::TOP );
407
408         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
409         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
410
411         gtk_window_set_title( window, "Polygon Builder" );
412         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
413
414         g_object_set_data( G_OBJECT( window ), "loop", &loop );
415         g_object_set_data( G_OBJECT( window ), "ret", &ret );
416
417         gtk_widget_realize( window );
418
419
420
421         auto vbox = ui::VBox( FALSE, 10 );
422         window.add(vbox);
423         vbox.show();
424
425         // ---- vbox ----
426
427     auto hbox = ui::HBox( FALSE, 10 );
428         vbox.pack_start( hbox, FALSE, FALSE, 2 );
429         hbox.show();
430
431         // ---- hbox ----
432
433
434     auto vbox2 = ui::VBox( FALSE, 10 );
435         hbox.pack_start( vbox2, FALSE, FALSE, 2 );
436         vbox2.show();
437
438         // ---- vbox2 ----
439
440     auto hbox2 = ui::HBox( FALSE, 10 );
441         vbox2.pack_start( hbox2, FALSE, FALSE, 2 );
442         hbox2.show();
443
444         // ---- hbox2 ----
445
446     auto text1 = ui::Entry( 256 );
447         gtk_entry_set_text( (GtkEntry*)text1, "3" );
448         hbox2.pack_start( text1, FALSE, FALSE, 2 );
449         text1.show();
450
451         auto l = ui::Label( "Number Of Sides" );
452         hbox2.pack_start( l, FALSE, FALSE, 2 );
453         gtk_label_set_justify( GTK_LABEL( l ), GTK_JUSTIFY_LEFT );
454         l.show();
455
456         // ---- /hbox2 ----
457
458         hbox2 = ui::HBox( FALSE, 10 );
459         vbox2.pack_start( hbox2, FALSE, FALSE, 2 );
460         hbox2.show();
461
462         // ---- hbox2 ----
463
464     auto text2 = ui::Entry( 256 );
465         gtk_entry_set_text( (GtkEntry*)text2, "8" );
466         hbox2.pack_start( text2, FALSE, FALSE, 2 );
467         text2.show();
468
469         l = ui::Label( "Border Width" );
470         hbox2.pack_start( l, FALSE, FALSE, 2 );
471         gtk_label_set_justify( GTK_LABEL( l ), GTK_JUSTIFY_LEFT );
472         l.show();
473
474         // ---- /hbox2 ----
475
476         // ---- /vbox2 ----
477
478
479
480         vbox2 = ui::VBox( FALSE, 10 );
481         hbox.pack_start( vbox2, FALSE, FALSE, 2 );
482         vbox2.show();
483
484         // ---- vbox2 ----
485
486     auto check1 = ui::CheckButton( "Use Border" );
487         vbox2.pack_start( check1, FALSE, FALSE, 0 );
488         check1.show();
489
490
491     auto check2 = ui::CheckButton( "Inverse Polygon" );
492         vbox2.pack_start( check2, FALSE, FALSE, 0 );
493         check2.show();
494
495
496     auto check3 = ui::CheckButton( "Align Top Edge" );
497         vbox2.pack_start( check3, FALSE, FALSE, 0 );
498         check3.show();
499
500         // ---- /vbox2 ----
501
502         // ---- /hbox ----
503
504         hbox = ui::HBox( FALSE, 10 );
505         vbox.pack_start( hbox, FALSE, FALSE, 2 );
506         hbox.show();
507
508         // ---- hbox ----
509
510         auto w = ui::Button( "Ok" );
511         hbox.pack_start( w, TRUE, TRUE, 0 );
512         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
513
514         gtk_widget_set_can_default( w, true );
515         gtk_widget_grab_default( w );
516         w.show();
517
518         w = ui::Button( "Cancel" );
519         hbox.pack_start( w, TRUE, TRUE, 0 );
520         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
521         w.show();
522         ret = eIDCANCEL;
523
524         // ---- /hbox ----
525
526         // ---- /vbox ----
527
528         gtk_window_set_position( window, GTK_WIN_POS_CENTER );
529         window.show();
530         gtk_grab_add( window );
531
532         bool dialogError = TRUE;
533         while ( dialogError )
534         {
535                 loop = 1;
536                 while ( loop )
537                         gtk_main_iteration();
538
539                 dialogError = FALSE;
540
541                 if ( ret == eIDOK ) {
542                         rs->bUseBorder = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(check1) ) ? true : false;
543                         rs->bInverse = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(check2) ) ? true : false;
544                         rs->bAlignTop = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(check3) ) ? true : false;
545
546                         if ( !ValidateTextIntRange( gtk_entry_get_text( (GtkEntry*)text1 ), 3, 32, "Number Of Sides", &rs->nSides ) ) {
547                                 dialogError = TRUE;
548                         }
549
550                         if ( rs->bUseBorder ) {
551                                 if ( !ValidateTextIntRange( gtk_entry_get_text( (GtkEntry*)text2 ), 8, 256, "Border Width", &rs->nBorderWidth ) ) {
552                                         dialogError = TRUE;
553                                 }
554                         }
555                 }
556         }
557
558         gtk_grab_remove( window );
559         window.destroy();
560
561         return ret;
562 }
563
564 // mars
565 // for stair builder stuck as close as i could to the MFC version
566 // obviously feel free to change it at will :)
567 EMessageBoxReturn DoBuildStairsBox( BuildStairsRS* rs ){
568         GSList      *radioDirection, *radioStyle;
569         EMessageBoxReturn ret;
570         int loop = 1;
571
572         const char *text = "Please set a value in the boxes below and press 'OK' to build the stairs";
573
574         auto window = ui::Window( ui::window_type::TOP );
575
576         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
577         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
578
579         gtk_window_set_title( window, "Stair Builder" );
580
581         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
582
583         g_object_set_data( G_OBJECT( window ), "loop", &loop );
584         g_object_set_data( G_OBJECT( window ), "ret", &ret );
585
586         gtk_widget_realize( window );
587
588         // new vbox
589         auto vbox = ui::VBox( FALSE, 10 );
590         window.add(vbox);
591         vbox.show();
592
593         auto hbox = ui::HBox( FALSE, 10 );
594         vbox.add(hbox);
595         hbox.show();
596
597         // dunno if you want this text or not ...
598         ui::Widget w = ui::Label( text );
599         hbox.pack_start( w, FALSE, FALSE, 0 ); // not entirely sure on all the parameters / what they do ...
600         w.show();
601
602         w = ui::Widget(gtk_hseparator_new());
603         vbox.pack_start( w, FALSE, FALSE, 0 );
604         w.show();
605
606         // ------------------------- // indenting == good way of keeping track of lines :)
607
608         // new hbox
609         hbox = ui::HBox( FALSE, 10 );
610         vbox.pack_start( hbox, FALSE, FALSE, 0 );
611         hbox.show();
612
613     auto textStairHeight = ui::Entry( 256 );
614         hbox.pack_start( textStairHeight, FALSE, FALSE, 1 );
615         textStairHeight.show();
616
617         w = ui::Label( "Stair Height" );
618         hbox.pack_start( w, FALSE, FALSE, 1 );
619         w.show();
620
621         // ------------------------- //
622
623         hbox = ui::HBox( FALSE, 10 );
624         vbox.pack_start( hbox, FALSE, FALSE, 0 );
625         hbox.show();
626
627         w = ui::Label( "Direction:" );
628         hbox.pack_start( w, FALSE, FALSE, 5 );
629         w.show();
630
631         // -------------------------- //
632
633         hbox = ui::HBox( FALSE, 10 );
634         vbox.pack_start( hbox, FALSE, FALSE, 0 );
635         hbox.show();
636
637         // radio buttons confuse me ...
638         // but this _looks_ right
639
640         // djbob: actually it looks very nice :), slightly better than the way i did it
641         // edit: actually it doesn't work :P, you must pass the last radio item each time, ugh
642
643     auto radioNorth = ui::Widget(gtk_radio_button_new_with_label( NULL, "North" ));
644         hbox.pack_start( radioNorth, FALSE, FALSE, 3 );
645         radioNorth.show();
646
647         radioDirection = gtk_radio_button_get_group( GTK_RADIO_BUTTON( radioNorth ) );
648
649     auto radioSouth = ui::Widget(gtk_radio_button_new_with_label( radioDirection, "South" ));
650         hbox.pack_start( radioSouth, FALSE, FALSE, 2 );
651         radioSouth.show();
652
653         radioDirection = gtk_radio_button_get_group( GTK_RADIO_BUTTON( radioSouth ) );
654
655     auto radioEast = ui::Widget(gtk_radio_button_new_with_label( radioDirection, "East" ));
656         hbox.pack_start( radioEast, FALSE, FALSE, 1 );
657         radioEast.show();
658
659         radioDirection = gtk_radio_button_get_group( GTK_RADIO_BUTTON( radioEast ) );
660
661     auto radioWest = ui::Widget(gtk_radio_button_new_with_label( radioDirection, "West" ));
662         hbox.pack_start( radioWest, FALSE, FALSE, 0 );
663         radioWest.show();
664
665         // --------------------------- //
666
667         hbox = ui::HBox( FALSE, 10 );
668         vbox.pack_start( hbox, FALSE, FALSE, 0 );
669         hbox.show();
670
671         w = ui::Label( "Style:" );
672         hbox.pack_start( w, FALSE, FALSE, 5 );
673         w.show();
674
675         // --------------------------- //
676
677         hbox = ui::HBox( FALSE, 10 );
678         vbox.pack_start( hbox, FALSE, FALSE, 0 );
679         hbox.show();
680
681     auto radioOldStyle = ui::Widget(gtk_radio_button_new_with_label( NULL, "Original" ));
682         hbox.pack_start( radioOldStyle, FALSE, FALSE, 0 );
683         radioOldStyle.show();
684
685         radioStyle = gtk_radio_button_get_group( GTK_RADIO_BUTTON( radioOldStyle ) );
686
687     auto radioBobStyle = ui::Widget(gtk_radio_button_new_with_label( radioStyle, "Bob's Style" ));
688         hbox.pack_start( radioBobStyle, FALSE, FALSE, 0 );
689         radioBobStyle.show();
690
691         radioStyle = gtk_radio_button_get_group( GTK_RADIO_BUTTON( radioBobStyle ) );
692
693     auto radioCornerStyle = ui::Widget(gtk_radio_button_new_with_label( radioStyle, "Corner Style" ));
694         hbox.pack_start( radioCornerStyle, FALSE, FALSE, 0 );
695         radioCornerStyle.show();
696
697         // err, the q3r has an if or something so you need bob style checked before this
698         // is "ungreyed out" but you'll need to do that, as i suck :)
699
700         // djbob: er.... yeah um, im not at all sure how i'm gonna sort this
701         // djbob: think we need some button callback functions or smuffin
702         // FIXME: actually get around to doing what i suggested!!!!
703
704     auto checkUseDetail = ui::CheckButton( "Use Detail Brushes" );
705         hbox.pack_start( checkUseDetail, FALSE, FALSE, 0 );
706         checkUseDetail.show();
707
708         // --------------------------- //
709
710         hbox = ui::HBox( FALSE, 10 );
711         vbox.pack_start( hbox, FALSE, FALSE, 0 );
712         hbox.show();
713
714     auto textMainTex = ui::Entry( 512 );
715         gtk_entry_set_text( GTK_ENTRY( textMainTex ), rs->mainTexture );
716         hbox.pack_start( textMainTex, FALSE, FALSE, 0 );
717         textMainTex.show();
718
719         w = ui::Label( "Main Texture" );
720         hbox.pack_start( w, FALSE, FALSE, 1 );
721         w.show();
722
723         // -------------------------- //
724
725         hbox = ui::HBox( FALSE, 10 );
726         vbox.pack_start( hbox, FALSE, FALSE, 0 );
727         hbox.show();
728
729         auto textRiserTex = ui::Entry( 512 );
730         hbox.pack_start( textRiserTex, FALSE, FALSE, 0 );
731         textRiserTex.show();
732
733         w = ui::Label( "Riser Texture" );
734         hbox.pack_start( w, FALSE, FALSE, 1 );
735         w.show();
736
737         // -------------------------- //
738         w = ui::Widget(gtk_hseparator_new());
739         vbox.pack_start( w, FALSE, FALSE, 0 );
740         w.show();
741
742         hbox = ui::HBox( FALSE, 10 );
743         vbox.pack_start( hbox, FALSE, FALSE, 0 );
744         hbox.show();
745
746         w = ui::Button( "OK" );
747         hbox.pack_start( w, TRUE, TRUE, 0 );
748         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
749         gtk_widget_set_can_default( w, true );
750         gtk_widget_grab_default( w );
751         w.show();
752
753         w = ui::Button( "Cancel" );
754         hbox.pack_start( w, TRUE, TRUE, 0 );
755         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
756         w.show();
757
758         ret = eIDCANCEL;
759
760 // +djbob: need our "little" modal loop mars :P
761         gtk_window_set_position( window, GTK_WIN_POS_CENTER );
762         window.show();
763         gtk_grab_add( window );
764
765         bool dialogError = TRUE;
766         while ( dialogError )
767         {
768                 loop = 1;
769                 while ( loop )
770                         gtk_main_iteration();
771
772                 dialogError = FALSE;
773
774                 if ( ret == eIDOK ) {
775                         rs->bUseDetail = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(checkUseDetail) ) ? true : false;
776
777                         strcpy( rs->riserTexture, gtk_entry_get_text( (GtkEntry*)textRiserTex ) );
778                         strcpy( rs->mainTexture, gtk_entry_get_text( (GtkEntry*)textMainTex ) );
779
780                         if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(radioNorth) ) ) {
781                                 rs->direction = MOVE_NORTH;
782                         }
783                         else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(radioSouth) ) ) {
784                                 rs->direction = MOVE_SOUTH;
785                         }
786                         else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(radioEast) ) ) {
787                                 rs->direction = MOVE_EAST;
788                         }
789                         else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(radioWest) ) ) {
790                                 rs->direction = MOVE_WEST;
791                         }
792
793                         if ( !ValidateTextInt( gtk_entry_get_text( (GtkEntry*)textStairHeight ), "Stair Height", &rs->stairHeight ) ) {
794                                 dialogError = TRUE;
795                         }
796
797                         if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(radioOldStyle) ) ) {
798                                 rs->style = STYLE_ORIGINAL;
799                         }
800                         else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(radioBobStyle) ) ) {
801                                 rs->style = STYLE_BOB;
802                         }
803                         else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(radioCornerStyle) ) ) {
804                                 rs->style = STYLE_CORNER;
805                         }
806                 }
807         }
808
809         gtk_grab_remove( window );
810         window.destroy();
811
812         return ret;
813 // -djbob
814
815         // there we go, all done ... on my end at least, not bad for a night's work
816 }
817
818 EMessageBoxReturn DoDoorsBox( DoorRS* rs ){
819         GSList      *radioOrientation;
820         TwinWidget tw1, tw2;
821         EMessageBoxReturn ret;
822         int loop = 1;
823
824         auto window = ui::Window( ui::window_type::TOP );
825
826         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
827         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
828
829         gtk_window_set_title( window, "Door Builder" );
830
831         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
832
833         g_object_set_data( G_OBJECT( window ), "loop", &loop );
834         g_object_set_data( G_OBJECT( window ), "ret", &ret );
835
836         gtk_widget_realize( window );
837
838         char buffer[256];
839         ui::ListStore listMainTextures = ui::ListStore(gtk_list_store_new( 1, G_TYPE_STRING ));
840         ui::ListStore listTrimTextures = ui::ListStore(gtk_list_store_new( 1, G_TYPE_STRING ));
841         LoadGList( GetFilename( buffer, "plugins/bt/door-tex.txt" ), listMainTextures );
842         LoadGList( GetFilename( buffer, "plugins/bt/door-tex-trim.txt" ), listTrimTextures );
843
844         auto vbox = ui::VBox( FALSE, 10 );
845         window.add(vbox);
846         vbox.show();
847
848         // -------------------------- //
849
850     auto hbox = ui::HBox( FALSE, 10 );
851         vbox.pack_start( hbox, FALSE, FALSE, 0 );
852         hbox.show();
853
854         auto textFrontBackTex = ui::Entry( 512 );
855         gtk_entry_set_text( GTK_ENTRY( textFrontBackTex ), rs->mainTexture );
856         hbox.pack_start( textFrontBackTex, FALSE, FALSE, 0 );
857         textFrontBackTex.show();
858
859         ui::Widget w = ui::Label( "Door Front/Back Texture" );
860         hbox.pack_start( w, FALSE, FALSE, 0 );
861         w.show();
862
863         // ------------------------ //
864
865         hbox = ui::HBox( FALSE, 10 );
866         vbox.pack_start( hbox, FALSE, FALSE, 0 );
867         hbox.show();
868
869         auto textTrimTex = ui::Entry( 512 );
870         hbox.pack_start( textTrimTex, FALSE, FALSE, 0 );
871         textTrimTex.show();
872
873         w = ui::Label( "Door Trim Texture" );
874         hbox.pack_start( w, FALSE, FALSE, 0 );
875         w.show();
876
877         // ----------------------- //
878
879         hbox = ui::HBox( FALSE, 10 );
880         vbox.pack_start( hbox, FALSE, FALSE, 0 );
881         hbox.show();
882
883         // sp: horizontally ????
884         // djbob: yes mars, u can spell :]
885     auto checkScaleMainH = ui::CheckButton( "Scale Main Texture Horizontally" );
886         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( checkScaleMainH ), TRUE );
887         hbox.pack_start( checkScaleMainH, FALSE, FALSE, 0 );
888         checkScaleMainH.show();
889
890     auto checkScaleTrimH = ui::CheckButton( "Scale Trim Texture Horizontally" );
891         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( checkScaleTrimH ), TRUE );
892         hbox.pack_start( checkScaleTrimH, FALSE, FALSE, 0 );
893         checkScaleTrimH.show();
894
895         // ---------------------- //
896
897         hbox = ui::HBox( FALSE, 10 );
898         vbox.pack_start( hbox, FALSE, FALSE, 0 );
899         hbox.show();
900
901     auto checkScaleMainV = ui::CheckButton( "Scale Main Texture Vertically" );
902         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( checkScaleMainV ), TRUE );
903         hbox.pack_start( checkScaleMainV, FALSE, FALSE, 0 );
904         checkScaleMainV.show();
905
906     auto checkScaleTrimV = ui::CheckButton( "Scale Trim Texture Vertically" );
907         hbox.pack_start( checkScaleTrimV, FALSE, FALSE, 0 );
908         checkScaleTrimV.show();
909
910         // --------------------- //
911
912         hbox = ui::HBox( FALSE, 10 );
913         vbox.pack_start( hbox, FALSE, FALSE, 0 );
914         hbox.show();
915
916         // djbob: lists added
917
918         auto comboMain = ui::ComboBox(GTK_COMBO_BOX(gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(listMainTextures))));
919         gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(comboMain), 0);
920         hbox.pack_start( comboMain, FALSE, FALSE, 0 );
921         comboMain.show();
922
923         tw1.one = textFrontBackTex;
924         tw1.two = comboMain;
925
926         auto buttonSetMain = ui::Button( "Set As Main Texture" );
927         buttonSetMain.connect( "clicked", G_CALLBACK( dialog_button_callback_settex ), &tw1 );
928         hbox.pack_start( buttonSetMain, FALSE, FALSE, 0 );
929         buttonSetMain.show();
930
931         // ------------------- //
932
933         hbox = ui::HBox( FALSE, 10 );
934         vbox.pack_start( hbox, FALSE, FALSE, 0 );
935         hbox.show();
936
937         auto comboTrim = ui::ComboBox(GTK_COMBO_BOX(gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(listTrimTextures))));
938         gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(comboMain), 0);
939         hbox.pack_start( comboTrim, FALSE, FALSE, 0 );
940         comboTrim.show();
941
942         tw2.one = textTrimTex;
943         tw2.two = comboTrim;
944
945         auto buttonSetTrim = ui::Button( "Set As Trim Texture" );
946         buttonSetTrim.connect( "clicked", G_CALLBACK( dialog_button_callback_settex ), &tw2 );
947         hbox.pack_start( buttonSetTrim, FALSE, FALSE, 0 );
948         buttonSetTrim.show();
949
950         // ------------------ //
951
952         hbox = ui::HBox( FALSE, 10 );
953         vbox.pack_start( hbox, FALSE, FALSE, 0 );
954         hbox.show();
955
956         w = ui::Label( "Orientation" );
957         hbox.pack_start( w, FALSE, FALSE, 0 );
958         w.show();
959
960         // argh more radio buttons!
961     auto radioNS = ui::Widget(gtk_radio_button_new_with_label( NULL, "North - South" ));
962         hbox.pack_start( radioNS, FALSE, FALSE, 0 );
963         radioNS.show();
964
965         radioOrientation = gtk_radio_button_get_group( GTK_RADIO_BUTTON( radioNS ) );
966
967     auto radioEW = ui::Widget(gtk_radio_button_new_with_label( radioOrientation, "East - West" ));
968         hbox.pack_start( radioEW, FALSE, FALSE, 0 );
969         radioEW.show();
970
971         // ----------------- //
972
973         w = ui::Widget(gtk_hseparator_new());
974         vbox.pack_start( w, FALSE, FALSE, 0 );
975         w.show();
976
977         // ----------------- //
978
979         hbox = ui::HBox( FALSE, 10 );
980         vbox.pack_start( hbox, FALSE, FALSE, 0 );
981         hbox.show();
982
983         w = ui::Button( "OK" );
984         hbox.pack_start( w, TRUE, TRUE, 0 );
985         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
986         gtk_widget_set_can_default( w, true );
987         gtk_widget_grab_default( w );
988         w.show();
989
990         w = ui::Button( "Cancel" );
991         hbox.pack_start( w, TRUE, TRUE, 0 );
992         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
993         w.show();
994         ret = eIDCANCEL;
995
996         // ----------------- //
997
998 //+djbob
999         gtk_window_set_position( window, GTK_WIN_POS_CENTER );
1000         window.show();
1001         gtk_grab_add( window );
1002
1003         while ( loop )
1004                 gtk_main_iteration();
1005
1006         strcpy( rs->mainTexture, gtk_entry_get_text( GTK_ENTRY( textFrontBackTex ) ) );
1007         strcpy( rs->trimTexture, gtk_entry_get_text( GTK_ENTRY( textTrimTex ) ) );
1008
1009         rs->bScaleMainH = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( checkScaleMainH ) ) ? true : false;
1010         rs->bScaleMainV = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( checkScaleMainV ) ) ? true : false;
1011         rs->bScaleTrimH = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( checkScaleTrimH ) ) ? true : false;
1012         rs->bScaleTrimV = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( checkScaleTrimV ) ) ? true : false;
1013
1014         if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radioNS ) ) ) {
1015                 rs->nOrientation = DIRECTION_NS;
1016         }
1017         else if ( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( radioEW ) ) ) {
1018                 rs->nOrientation = DIRECTION_EW;
1019         }
1020
1021         gtk_grab_remove( window );
1022         window.destroy();
1023
1024         return ret;
1025 //-djbob
1026 }
1027
1028 EMessageBoxReturn DoPathPlotterBox( PathPlotterRS* rs ){
1029         ui::Widget w{ui::null};
1030
1031         EMessageBoxReturn ret;
1032         int loop = 1;
1033
1034         auto window = ui::Window( ui::window_type::TOP );
1035
1036         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
1037         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
1038
1039         gtk_window_set_title( window, "Texture Reset" );
1040         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
1041
1042         g_object_set_data( G_OBJECT( window ), "loop", &loop );
1043         g_object_set_data( G_OBJECT( window ), "ret", &ret );
1044
1045         gtk_widget_realize( window );
1046
1047
1048
1049         auto vbox = ui::VBox( FALSE, 10 );
1050         window.add(vbox);
1051         vbox.show();
1052
1053         // ---- vbox ----
1054
1055         auto hbox = ui::HBox( FALSE, 10 );
1056         vbox.pack_start( hbox, FALSE, FALSE, 2 );
1057         hbox.show();
1058
1059         // ---- hbox ----
1060
1061         auto text1 = ui::Entry( 256 );
1062         gtk_entry_set_text( text1, "25" );
1063         hbox.pack_start( text1, FALSE, FALSE, 2 );
1064         text1.show();
1065
1066         w = ui::Label( "Number Of Points" );
1067         hbox.pack_start( w, FALSE, FALSE, 2 );
1068         gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT );
1069         w.show();
1070
1071         // ---- /hbox ----
1072
1073         hbox = ui::HBox( FALSE, 10 );
1074         vbox.pack_start( hbox, FALSE, FALSE, 2 );
1075         hbox.show();
1076
1077         // ---- hbox ----
1078
1079         auto text2 = ui::Entry( 256 );
1080         gtk_entry_set_text( text2, "3" );
1081         hbox.pack_start( text2, FALSE, FALSE, 2 );
1082         text2.show();
1083
1084         w = ui::Label( "Multipler" );
1085         hbox.pack_start( w, FALSE, FALSE, 2 );
1086         gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT );
1087         w.show();
1088
1089         // ---- /hbox ----
1090
1091         w = ui::Label( "Path Distance = dist(start -> apex) * multiplier" );
1092         vbox.pack_start( w, FALSE, FALSE, 0 );
1093         gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT );
1094         w.show();
1095
1096         hbox = ui::HBox( FALSE, 10 );
1097         vbox.pack_start( hbox, FALSE, FALSE, 2 );
1098         hbox.show();
1099
1100         // ---- hbox ----
1101
1102         auto text3 = ui::Entry( 256 );
1103         gtk_entry_set_text( text3, "-800" );
1104         hbox.pack_start( text3, FALSE, FALSE, 2 );
1105         text3.show();
1106
1107         w = ui::Label( "Gravity" );
1108         hbox.pack_start( w, FALSE, FALSE, 2 );
1109         gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT );
1110         w.show();
1111
1112         // ---- /hbox ----
1113
1114         w = ui::Widget(gtk_hseparator_new());
1115         vbox.pack_start( w, FALSE, FALSE, 0 );
1116         w.show();
1117
1118         auto check1 = ui::CheckButton( "No Dynamic Update" );
1119         vbox.pack_start( check1, FALSE, FALSE, 0 );
1120         check1.show();
1121
1122         auto check2 = ui::CheckButton( "Show Bounding Lines" );
1123         vbox.pack_start( check2, FALSE, FALSE, 0 );
1124         check2.show();
1125
1126         // ---- /vbox ----
1127
1128
1129         // ----------------- //
1130
1131         w = ui::Widget(gtk_hseparator_new());
1132         vbox.pack_start( w, FALSE, FALSE, 0 );
1133         w.show();
1134
1135         // ----------------- //
1136
1137         hbox = ui::HBox( FALSE, 10 );
1138         vbox.pack_start( hbox, FALSE, FALSE, 0 );
1139         hbox.show();
1140
1141         w = ui::Button( "Enable" );
1142         hbox.pack_start( w, TRUE, TRUE, 0 );
1143         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDYES ) );
1144         w.show();
1145
1146         gtk_widget_set_can_default( w, true );
1147         gtk_widget_grab_default( w );
1148
1149         w = ui::Button( "Disable" );
1150         hbox.pack_start( w, TRUE, TRUE, 0 );
1151         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDNO ) );
1152         w.show();
1153
1154         w = ui::Button( "Cancel" );
1155         hbox.pack_start( w, TRUE, TRUE, 0 );
1156         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
1157         w.show();
1158
1159         ret = eIDCANCEL;
1160
1161         // ----------------- //
1162
1163         gtk_window_set_position( window, GTK_WIN_POS_CENTER );
1164         window.show();
1165         gtk_grab_add( window );
1166
1167         bool dialogError = TRUE;
1168         while ( dialogError )
1169         {
1170                 loop = 1;
1171                 while ( loop )
1172                         gtk_main_iteration();
1173
1174                 dialogError = FALSE;
1175
1176                 if ( ret == eIDYES ) {
1177                         if ( !ValidateTextIntRange( gtk_entry_get_text( GTK_ENTRY( text1 ) ), 1, 200, "Number Of Points", &rs->nPoints ) ) {
1178                                 dialogError = TRUE;
1179                         }
1180
1181                         if ( !ValidateTextFloatRange( gtk_entry_get_text( GTK_ENTRY( text2 ) ), 1.0f, 10.0f, "Multiplier", &rs->fMultiplier ) ) {
1182                                 dialogError = TRUE;
1183                         }
1184
1185                         if ( !ValidateTextFloatRange( gtk_entry_get_text( GTK_ENTRY( text3 ) ), -10000.0f, -1.0f, "Gravity", &rs->fGravity ) ) {
1186                                 dialogError = TRUE;
1187                         }
1188
1189                         rs->bNoUpdate = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( check1 ) ) ? true : false;
1190                         rs->bShowExtra = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( check2 ) ) ? true : false;
1191                 }
1192         }
1193
1194         gtk_grab_remove( window );
1195         window.destroy();
1196
1197         return ret;
1198 }
1199
1200 EMessageBoxReturn DoCTFColourChangeBox(){
1201         ui::Widget w{ui::null};
1202         EMessageBoxReturn ret;
1203         int loop = 1;
1204
1205         auto window = ui::Window( ui::window_type::TOP );
1206
1207         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
1208         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
1209
1210         gtk_window_set_title( window, "CTF Colour Changer" );
1211         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
1212
1213         g_object_set_data( G_OBJECT( window ), "loop", &loop );
1214         g_object_set_data( G_OBJECT( window ), "ret", &ret );
1215
1216         gtk_widget_realize( window );
1217
1218
1219
1220         auto vbox = ui::VBox( FALSE, 10 );
1221         window.add(vbox);
1222         vbox.show();
1223
1224         // ---- vbox ----
1225
1226         auto hbox = ui::HBox( FALSE, 10 );
1227         vbox.pack_start( hbox, TRUE, TRUE, 0 );
1228         hbox.show();
1229
1230         // ---- hbox ---- ok/cancel buttons
1231
1232         w = ui::Button( "Red->Blue" );
1233         hbox.pack_start( w, TRUE, TRUE, 0 );
1234         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
1235
1236         gtk_widget_set_can_default( w, true );
1237         gtk_widget_grab_default( w );
1238         w.show();
1239
1240         w = ui::Button( "Blue->Red" );
1241         hbox.pack_start( w, TRUE, TRUE, 0 );
1242         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDYES ) );
1243         w.show();
1244
1245         w = ui::Button( "Cancel" );
1246         hbox.pack_start( w, TRUE, TRUE, 0 );
1247         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
1248         w.show();
1249         ret = eIDCANCEL;
1250
1251         // ---- /hbox ----
1252
1253         // ---- /vbox ----
1254
1255         gtk_window_set_position( window, GTK_WIN_POS_CENTER );
1256         window.show();
1257         gtk_grab_add( window );
1258
1259         while ( loop )
1260                 gtk_main_iteration();
1261
1262         gtk_grab_remove( window );
1263         window.destroy();
1264
1265         return ret;
1266 }
1267
1268 EMessageBoxReturn DoResetTextureBox( ResetTextureRS* rs ){
1269         Str texSelected;
1270
1271         ui::Widget w{ui::null};
1272
1273         EMessageBoxReturn ret;
1274         int loop = 1;
1275
1276         auto window = ui::Window( ui::window_type::TOP );
1277
1278         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
1279         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
1280
1281         gtk_window_set_title( window, "Texture Reset" );
1282         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
1283
1284         g_object_set_data( G_OBJECT( window ), "loop", &loop );
1285         g_object_set_data( G_OBJECT( window ), "ret", &ret );
1286
1287         gtk_widget_realize( window );
1288
1289         auto vbox = ui::VBox( FALSE, 10 );
1290         window.add(vbox);
1291         vbox.show();
1292
1293         // ---- vbox ----
1294
1295         auto hbox = ui::HBox( FALSE, 10 );
1296         vbox.pack_start( hbox, FALSE, FALSE, 2 );
1297         hbox.show();
1298
1299         // ---- hbox ----
1300
1301         texSelected = "Currently Selected Texture:   ";
1302         texSelected += GetCurrentTexture();
1303
1304         w = ui::Label( texSelected );
1305         hbox.pack_start( w, FALSE, FALSE, 2 );
1306         gtk_label_set_justify( GTK_LABEL( w ), GTK_JUSTIFY_LEFT );
1307         w.show();
1308
1309         // ---- /hbox ----
1310
1311         auto frame = ui::Frame( "Reset Texture Names" );
1312         frame.show();
1313         vbox.pack_start( frame, FALSE, TRUE, 0 );
1314
1315         auto table = ui::Table( 2, 3, TRUE );
1316         table.show();
1317         frame.add(table);
1318         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1319         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1320         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1321
1322         // ---- frame ----
1323
1324         dlgTexReset.cbTexChange = ui::CheckButton( "Enabled" );
1325         dlgTexReset.cbTexChange.connect( "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL );
1326         dlgTexReset.cbTexChange.show();
1327         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbTexChange, 0, 1, 0, 1,
1328                                           (GtkAttachOptions) ( GTK_FILL ),
1329                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1330
1331         w = ui::Label( "Old Name: " );
1332         gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 0, 1,
1333                                           (GtkAttachOptions) ( GTK_FILL ),
1334                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1335         w.show();
1336
1337         dlgTexReset.editTexOld = ui::Entry( 256 );
1338         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editTexOld ), rs->textureName );
1339         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editTexOld, 2, 3, 0, 1,
1340                                           (GtkAttachOptions) ( GTK_FILL ),
1341                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1342         dlgTexReset.editTexOld.show();
1343
1344         w = ui::Label( "New Name: " );
1345         gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 1, 2,
1346                                           (GtkAttachOptions) ( GTK_FILL ),
1347                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1348         w.show();
1349
1350         dlgTexReset.editTexNew = ui::Entry( 256 );
1351         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editTexNew ), rs->textureName );
1352         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editTexNew, 2, 3, 1, 2,
1353                                           (GtkAttachOptions) ( GTK_FILL ),
1354                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1355         dlgTexReset.editTexNew.show();
1356
1357         // ---- /frame ----
1358
1359         frame = ui::Frame( "Reset Scales" );
1360         frame.show();
1361         vbox.pack_start( frame, FALSE, TRUE, 0 );
1362
1363         table = ui::Table( 2, 3, TRUE );
1364         table.show();
1365         frame.add(table);
1366         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1367         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1368         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1369
1370         // ---- frame ----
1371
1372         dlgTexReset.cbScaleHor = ui::CheckButton( "Enabled" );
1373         dlgTexReset.cbScaleHor.connect( "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL );
1374         dlgTexReset.cbScaleHor.show();
1375         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbScaleHor, 0, 1, 0, 1,
1376                                           (GtkAttachOptions) ( GTK_FILL ),
1377                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1378
1379         w = ui::Label( "New Horizontal Scale: " );
1380         gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 0, 1,
1381                                           (GtkAttachOptions) ( GTK_FILL ),
1382                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1383         w.show();
1384
1385         dlgTexReset.editScaleHor = ui::Entry( 256 );
1386         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editScaleHor ), "0.5" );
1387         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editScaleHor, 2, 3, 0, 1,
1388                                           (GtkAttachOptions) ( GTK_FILL ),
1389                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1390         dlgTexReset.editScaleHor.show();
1391
1392
1393         dlgTexReset.cbScaleVert = ui::CheckButton( "Enabled" );
1394         dlgTexReset.cbScaleVert.connect( "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL );
1395         dlgTexReset.cbScaleVert.show();
1396         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbScaleVert, 0, 1, 1, 2,
1397                                           (GtkAttachOptions) ( GTK_FILL ),
1398                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1399
1400         w = ui::Label( "New Vertical Scale: " );
1401         gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 1, 2,
1402                                           (GtkAttachOptions) ( GTK_FILL ),
1403                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1404         w.show();
1405
1406         dlgTexReset.editScaleVert = ui::Entry( 256 );
1407         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editScaleVert ), "0.5" );
1408         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editScaleVert, 2, 3, 1, 2,
1409                                           (GtkAttachOptions) ( GTK_FILL ),
1410                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1411         dlgTexReset.editScaleVert.show();
1412
1413         // ---- /frame ----
1414
1415         frame = ui::Frame( "Reset Shift" );
1416         frame.show();
1417         vbox.pack_start( frame, FALSE, TRUE, 0 );
1418
1419         table = ui::Table( 2, 3, TRUE );
1420         table.show();
1421         frame.add(table);
1422         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1423         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1424         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1425
1426         // ---- frame ----
1427
1428         dlgTexReset.cbShiftHor = ui::CheckButton( "Enabled" );
1429         dlgTexReset.cbShiftHor.connect( "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL );
1430         dlgTexReset.cbShiftHor.show();
1431         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbShiftHor, 0, 1, 0, 1,
1432                                           (GtkAttachOptions) ( GTK_FILL ),
1433                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1434
1435         w = ui::Label( "New Horizontal Shift: " );
1436         gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 0, 1,
1437                                           (GtkAttachOptions) ( GTK_FILL ),
1438                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1439         w.show();
1440
1441         dlgTexReset.editShiftHor = ui::Entry( 256 );
1442         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editShiftHor ), "0" );
1443         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editShiftHor, 2, 3, 0, 1,
1444                                           (GtkAttachOptions) ( GTK_FILL ),
1445                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1446         dlgTexReset.editShiftHor.show();
1447
1448
1449         dlgTexReset.cbShiftVert = ui::CheckButton( "Enabled" );
1450         dlgTexReset.cbShiftVert.connect( "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL );
1451         dlgTexReset.cbShiftVert.show();
1452         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbShiftVert, 0, 1, 1, 2,
1453                                           (GtkAttachOptions) ( GTK_FILL ),
1454                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1455
1456         w = ui::Label( "New Vertical Shift: " );
1457         gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 1, 2,
1458                                           (GtkAttachOptions) ( GTK_FILL ),
1459                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1460         w.show();
1461
1462         dlgTexReset.editShiftVert = ui::Entry( 256 );
1463         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editShiftVert ), "0" );
1464         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editShiftVert, 2, 3, 1, 2,
1465                                           (GtkAttachOptions) ( GTK_FILL ),
1466                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1467         dlgTexReset.editShiftVert.show();
1468
1469         // ---- /frame ----
1470
1471         frame = ui::Frame( "Reset Rotation" );
1472         frame.show();
1473         vbox.pack_start( frame, FALSE, TRUE, 0 );
1474
1475         table = ui::Table( 1, 3, TRUE );
1476         table.show();
1477         frame.add(table);
1478         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1479         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1480         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1481
1482         // ---- frame ----
1483
1484         dlgTexReset.cbRotation = ui::CheckButton( "Enabled" );
1485         dlgTexReset.cbRotation.show();
1486         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.cbRotation, 0, 1, 0, 1,
1487                                           (GtkAttachOptions) ( GTK_FILL ),
1488                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1489
1490         w = ui::Label( "New Rotation Value: " );
1491         gtk_table_attach( GTK_TABLE( table ), w, 1, 2, 0, 1,
1492                                           (GtkAttachOptions) ( GTK_FILL ),
1493                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1494         w.show();
1495
1496         dlgTexReset.editRotation = ui::Entry( 256 );
1497         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editRotation ), "0" );
1498         gtk_table_attach( GTK_TABLE( table ), dlgTexReset.editRotation, 2, 3, 0, 1,
1499                                           (GtkAttachOptions) ( GTK_FILL ),
1500                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1501         dlgTexReset.editRotation.show();
1502
1503         // ---- /frame ----
1504
1505         hbox = ui::HBox( FALSE, 10 );
1506         vbox.pack_start( hbox, FALSE, FALSE, 2 );
1507         hbox.show();
1508
1509         // ---- hbox ----
1510
1511         w = ui::Button( "Use Selected Brushes" );
1512         hbox.pack_start( w, TRUE, TRUE, 0 );
1513         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
1514
1515         gtk_widget_set_can_default( w, true );
1516         gtk_widget_grab_default( w );
1517         w.show();
1518
1519         w = ui::Button( "Use All Brushes" );
1520         hbox.pack_start( w, TRUE, TRUE, 0 );
1521         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDYES ) );
1522         w.show();
1523
1524         w = ui::Button( "Cancel" );
1525         hbox.pack_start( w, TRUE, TRUE, 0 );
1526         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
1527         w.show();
1528         ret = eIDCANCEL;
1529
1530         // ---- /hbox ----
1531
1532         // ---- /vbox ----
1533
1534         gtk_window_set_position( window, GTK_WIN_POS_CENTER );
1535         window.show();
1536         gtk_grab_add( window );
1537
1538         Update_TextureReseter();
1539
1540         bool dialogError = TRUE;
1541         while ( dialogError )
1542         {
1543                 loop = 1;
1544                 while ( loop )
1545                         gtk_main_iteration();
1546
1547                 dialogError = FALSE;
1548
1549                 if ( ret != eIDCANCEL ) {
1550                         rs->bResetRotation =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbRotation ) );
1551                         if ( rs->bResetRotation ) {
1552                                 if ( !ValidateTextInt( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editRotation ) ), "Rotation", &rs->rotation ) ) {
1553                                         dialogError = TRUE;
1554                                 }
1555                         }
1556
1557                         rs->bResetScale[0] =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbScaleHor ) );
1558                         if ( rs->bResetScale[0] ) {
1559                                 if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editScaleHor ) ), "Horizontal Scale", &rs->fScale[0] ) ) {
1560                                         dialogError = TRUE;
1561                                 }
1562                         }
1563
1564                         rs->bResetScale[1] =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbScaleVert ) );
1565                         if ( rs->bResetScale[1] ) {
1566                                 if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editScaleVert ) ), "Vertical Scale", &rs->fScale[1] ) ) {
1567                                         dialogError = TRUE;
1568                                 }
1569                         }
1570
1571                         rs->bResetShift[0] =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbShiftHor ) );
1572                         if ( rs->bResetShift[0] ) {
1573                                 if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editShiftHor ) ), "Horizontal Shift", &rs->fShift[0] ) ) {
1574                                         dialogError = TRUE;
1575                                 }
1576                         }
1577
1578                         rs->bResetShift[1] =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbShiftVert ) );
1579                         if ( rs->bResetShift[1] ) {
1580                                 if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editShiftVert ) ), "Vertical Shift", &rs->fShift[1] ) ) {
1581                                         dialogError = TRUE;
1582                                 }
1583                         }
1584
1585                         rs->bResetTextureName =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbTexChange ) );
1586                         if ( rs->bResetTextureName ) {
1587                                 strcpy( rs->textureName,     gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editTexOld ) ) );
1588                                 strcpy( rs->newTextureName,  gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editTexNew ) ) );
1589                         }
1590                 }
1591         }
1592
1593         gtk_grab_remove( window );
1594         window.destroy();
1595
1596         return ret;
1597 }
1598
1599 EMessageBoxReturn DoTrainThingBox( TrainThingRS* rs ){
1600         Str texSelected;
1601
1602         ui::Widget w{ui::null};
1603
1604         ui::Widget radiusX{ui::null}, radiusY{ui::null};
1605         ui::Widget angleStart{ui::null}, angleEnd{ui::null};
1606         ui::Widget heightStart{ui::null}, heightEnd{ui::null};
1607         ui::Widget numPoints{ui::null};
1608
1609         EMessageBoxReturn ret;
1610         int loop = 1;
1611
1612         auto window = ui::Window( ui::window_type::TOP );
1613
1614         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
1615         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
1616
1617         gtk_window_set_title( window, "Train Thing" );
1618         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
1619
1620         g_object_set_data( G_OBJECT( window ), "loop", &loop );
1621         g_object_set_data( G_OBJECT( window ), "ret", &ret );
1622
1623         gtk_widget_realize( window );
1624
1625         auto vbox = ui::VBox( FALSE, 10 );
1626         window.add(vbox);
1627         vbox.show();
1628
1629         // ---- vbox ----
1630
1631         auto hbox = ui::HBox( FALSE, 10 );
1632         vbox.pack_start( hbox, FALSE, FALSE, 2 );
1633         hbox.show();
1634
1635         // ---- /hbox ----
1636
1637         auto frame = ui::Frame( "Radii" );
1638         frame.show();
1639         vbox.pack_start( frame, FALSE, TRUE, 0 );
1640
1641         auto table = ui::Table( 2, 3, TRUE );
1642         table.show();
1643         frame.add(table);
1644         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1645         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1646         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1647
1648         // ---- frame ----
1649
1650         w = ui::Label( "X: " );
1651         gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 0, 1,
1652                                           (GtkAttachOptions) ( GTK_FILL ),
1653                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1654         w.show();
1655
1656         radiusX = ui::Entry( 256 );
1657         gtk_entry_set_text( GTK_ENTRY( radiusX ), "100" );
1658         gtk_table_attach( GTK_TABLE( table ), radiusX, 1, 2, 0, 1,
1659                                           (GtkAttachOptions) ( GTK_FILL ),
1660                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1661         radiusX.show();
1662
1663
1664
1665         w = ui::Label( "Y: " );
1666         gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 1, 2,
1667                                           (GtkAttachOptions) ( GTK_FILL ),
1668                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1669         w.show();
1670
1671         radiusY = ui::Entry( 256 );
1672         gtk_entry_set_text( GTK_ENTRY( radiusY ), "100" );
1673         gtk_table_attach( GTK_TABLE( table ), radiusY, 1, 2, 1, 2,
1674                                           (GtkAttachOptions) ( GTK_FILL ),
1675                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1676         radiusY.show();
1677
1678
1679
1680         frame = ui::Frame( "Angles" );
1681         frame.show();
1682         vbox.pack_start( frame, FALSE, TRUE, 0 );
1683
1684         table = ui::Table( 2, 3, TRUE );
1685         table.show();
1686         frame.add(table);
1687         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1688         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1689         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1690
1691         // ---- frame ----
1692
1693         w = ui::Label( "Start: " );
1694         gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 0, 1,
1695                                           (GtkAttachOptions) ( GTK_FILL ),
1696                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1697         w.show();
1698
1699         angleStart = ui::Entry( 256 );
1700         gtk_entry_set_text( GTK_ENTRY( angleStart ), "0" );
1701         gtk_table_attach( GTK_TABLE( table ), angleStart, 1, 2, 0, 1,
1702                                           (GtkAttachOptions) ( GTK_FILL ),
1703                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1704         angleStart.show();
1705
1706
1707
1708         w = ui::Label( "End: " );
1709         gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 1, 2,
1710                                           (GtkAttachOptions) ( GTK_FILL ),
1711                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1712         w.show();
1713
1714         angleEnd = ui::Entry( 256 );
1715         gtk_entry_set_text( GTK_ENTRY( angleEnd ), "90" );
1716         gtk_table_attach( GTK_TABLE( table ), angleEnd, 1, 2, 1, 2,
1717                                           (GtkAttachOptions) ( GTK_FILL ),
1718                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1719         angleEnd.show();
1720
1721
1722         frame = ui::Frame( "Height" );
1723         frame.show();
1724         vbox.pack_start( frame, FALSE, TRUE, 0 );
1725
1726         table = ui::Table( 2, 3, TRUE );
1727         table.show();
1728         frame.add(table);
1729         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1730         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1731         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1732
1733         // ---- frame ----
1734
1735         w = ui::Label( "Start: " );
1736         gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 0, 1,
1737                                           (GtkAttachOptions) ( GTK_FILL ),
1738                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1739         w.show();
1740
1741         heightStart = ui::Entry( 256 );
1742         gtk_entry_set_text( GTK_ENTRY( heightStart ), "0" );
1743         gtk_table_attach( GTK_TABLE( table ), heightStart, 1, 2, 0, 1,
1744                                           (GtkAttachOptions) ( GTK_FILL ),
1745                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1746         heightStart.show();
1747
1748
1749
1750         w = ui::Label( "End: " );
1751         gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 1, 2,
1752                                           (GtkAttachOptions) ( GTK_FILL ),
1753                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1754         w.show();
1755
1756         heightEnd = ui::Entry( 256 );
1757         gtk_entry_set_text( GTK_ENTRY( heightEnd ), "0" );
1758         gtk_table_attach( GTK_TABLE( table ), heightEnd, 1, 2, 1, 2,
1759                                           (GtkAttachOptions) ( GTK_FILL ),
1760                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1761         heightEnd.show();
1762
1763
1764
1765         frame = ui::Frame( "Points" );
1766         frame.show();
1767         vbox.pack_start( frame, FALSE, TRUE, 0 );
1768
1769         table = ui::Table( 2, 3, TRUE );
1770         table.show();
1771         frame.add(table);
1772         gtk_table_set_row_spacings( GTK_TABLE( table ), 5 );
1773         gtk_table_set_col_spacings( GTK_TABLE( table ), 5 );
1774         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1775
1776         // ---- frame ----
1777
1778         w = ui::Label( "Number: " );
1779         gtk_table_attach( GTK_TABLE( table ), w, 0, 1, 0, 1,
1780                                           (GtkAttachOptions) ( GTK_FILL ),
1781                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1782         w.show();
1783
1784         numPoints = ui::Entry( 256 );
1785         gtk_entry_set_text( GTK_ENTRY( numPoints ), "0" );
1786         gtk_table_attach( GTK_TABLE( table ), numPoints, 1, 2, 0, 1,
1787                                           (GtkAttachOptions) ( GTK_FILL ),
1788                                           (GtkAttachOptions) ( 0 ), 0, 0 );
1789         numPoints.show();
1790
1791
1792         hbox = ui::HBox( FALSE, 10 );
1793         vbox.pack_start( hbox, FALSE, FALSE, 2 );
1794         hbox.show();
1795
1796         // ---- hbox ----
1797
1798         w = ui::Button( "Ok" );
1799         hbox.pack_start( w, TRUE, TRUE, 0 );
1800         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
1801
1802         gtk_widget_set_can_default( w, true );
1803         gtk_widget_grab_default( w );
1804         w.show();
1805
1806         w = ui::Button( "Cancel" );
1807         hbox.pack_start( w, TRUE, TRUE, 0 );
1808         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
1809         w.show();
1810         ret = eIDCANCEL;
1811
1812         // ---- /hbox ----
1813
1814
1815
1816         gtk_window_set_position( window, GTK_WIN_POS_CENTER );
1817         window.show();
1818         gtk_grab_add( window );
1819
1820         bool dialogError = TRUE;
1821         while ( dialogError )
1822         {
1823                 loop = 1;
1824                 while ( loop )
1825                         gtk_main_iteration();
1826
1827                 dialogError = FALSE;
1828
1829                 if ( ret != eIDCANCEL ) {
1830                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( radiusX ) ), "Radius (X)", &rs->fRadiusX ) ) {
1831                                 dialogError = TRUE;
1832                         }
1833
1834                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( radiusY ) ), "Radius (Y)", &rs->fRadiusY ) ) {
1835                                 dialogError = TRUE;
1836                         }
1837
1838                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( angleStart ) ), "Angle (Start)", &rs->fStartAngle ) ) {
1839                                 dialogError = TRUE;
1840                         }
1841
1842                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( angleEnd ) ), "Angle (End)", &rs->fEndAngle ) ) {
1843                                 dialogError = TRUE;
1844                         }
1845
1846                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( heightStart ) ), "Height (Start)", &rs->fStartHeight ) ) {
1847                                 dialogError = TRUE;
1848                         }
1849
1850                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( heightEnd ) ), "Height (End)", &rs->fEndHeight ) ) {
1851                                 dialogError = TRUE;
1852                         }
1853
1854                         if ( !ValidateTextInt( gtk_entry_get_text( GTK_ENTRY( numPoints ) ), "Num Points", &rs->iNumPoints ) ) {
1855                                 dialogError = TRUE;
1856                         }
1857                 }
1858         }
1859
1860         gtk_grab_remove( window );
1861         window.destroy();
1862
1863         return ret;
1864 }
1865 // ailmanki
1866 // add a simple input for the MakeChain thing..
1867 EMessageBoxReturn DoMakeChainBox( MakeChainRS* rs ){
1868         ui::Widget   w{ui::null};
1869         ui::Entry textlinkNum{ui::null}, textlinkName{ui::null};
1870         EMessageBoxReturn ret;
1871         int loop = 1;
1872
1873         const char *text = "Please set a value in the boxes below and press 'OK' to make a chain";
1874
1875         auto window = ui::Window( ui::window_type::TOP );
1876
1877         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
1878         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
1879
1880         gtk_window_set_title( window, "Make Chain" );
1881
1882         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
1883
1884         g_object_set_data( G_OBJECT( window ), "loop", &loop );
1885         g_object_set_data( G_OBJECT( window ), "ret", &ret );
1886
1887         gtk_widget_realize( window );
1888
1889         // new vbox
1890         auto vbox = ui::VBox( FALSE, 10 );
1891         window.add(vbox);
1892         vbox.show();
1893
1894         auto hbox = ui::HBox( FALSE, 10 );
1895         vbox.add(hbox);
1896         hbox.show();
1897
1898         // dunno if you want this text or not ...
1899         w = ui::Label( text );
1900         hbox.pack_start( w, FALSE, FALSE, 0 );
1901         w.show();
1902
1903         w = ui::Widget(gtk_hseparator_new());
1904         vbox.pack_start( w, FALSE, FALSE, 0 );
1905         w.show();
1906
1907         // ------------------------- //
1908
1909         // new hbox
1910         hbox = ui::HBox( FALSE, 10 );
1911         vbox.pack_start( hbox, FALSE, FALSE, 0 );
1912         hbox.show();
1913
1914         textlinkNum = ui::Entry( 256 );
1915         hbox.pack_start( textlinkNum, FALSE, FALSE, 1 );
1916         textlinkNum.show();
1917
1918         w = ui::Label( "Number of elements in chain" );
1919         hbox.pack_start( w, FALSE, FALSE, 1 );
1920         w.show();
1921
1922         // -------------------------- //
1923
1924         hbox = ui::HBox( FALSE, 10 );
1925         vbox.pack_start( hbox, FALSE, FALSE, 0 );
1926         hbox.show();
1927
1928         textlinkName = ui::Entry( 256 );
1929         hbox.pack_start( textlinkName, FALSE, FALSE, 0 );
1930         textlinkName.show();
1931
1932         w = ui::Label( "Basename for chain's targetnames." );
1933         hbox.pack_start( w, FALSE, FALSE, 1 );
1934         w.show();
1935
1936
1937         w = ui::Button( "OK" );
1938         hbox.pack_start( w, TRUE, TRUE, 0 );
1939         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
1940         gtk_widget_set_can_default( w, true );
1941         gtk_widget_grab_default( w );
1942         w.show();
1943
1944         w = ui::Button( "Cancel" );
1945         hbox.pack_start( w, TRUE, TRUE, 0 );
1946         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
1947         w.show();
1948
1949         ret = eIDCANCEL;
1950
1951         gtk_window_set_position(  window, GTK_WIN_POS_CENTER );
1952         window.show();
1953         gtk_grab_add( window );
1954
1955         bool dialogError = TRUE;
1956         while ( dialogError )
1957         {
1958                 loop = 1;
1959                 while ( loop )
1960                         gtk_main_iteration();
1961
1962                 dialogError = FALSE;
1963
1964                 if ( ret == eIDOK ) {
1965                         strcpy( rs->linkName, gtk_entry_get_text( textlinkName ) );
1966                         if ( !ValidateTextInt( gtk_entry_get_text( textlinkNum ), "Elements", &rs->linkNum ) ) {
1967                                 dialogError = TRUE;
1968                         }
1969                 }
1970         }
1971
1972         gtk_grab_remove( window );
1973         window.destroy();
1974
1975         return ret;
1976 }