]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/dialogs/dialogs-gtk.cpp
Revert partially (auto) "reformat code! now the code is only ugly on the *inside*"
[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(ui::Widget 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(ui::Widget widget, gpointer data ){
101         TwinWidget* tw = (TwinWidget*)data;
102
103     auto entry = ui::Entry::from( tw->one );
104         auto combo = 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::from(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::from(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::from(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::from(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( 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( 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( text1 ), 3, 32, "Number Of Sides", &rs->nSides ) ) {
547                                 dialogError = TRUE;
548                         }
549
550                         if ( rs->bUseBorder ) {
551                                 if ( !ValidateTextIntRange( gtk_entry_get_text( 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::from(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::from(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::from(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::from(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::from(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::from(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::from(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::from(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::from(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( textRiserTex ) );
778                         strcpy( rs->mainTexture, gtk_entry_get_text( 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( 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         auto listMainTextures = ui::ListStore::from(gtk_list_store_new( 1, G_TYPE_STRING ));
840         auto listTrimTextures = ui::ListStore::from(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::from(gtk_combo_box_new_with_model_and_entry(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::from(gtk_combo_box_new_with_model_and_entry(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::from(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::from(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::from(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::from(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::from(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(table, 5);
1319         gtk_table_set_col_spacings(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         table.attach(dlgTexReset.cbTexChange, {0, 1, 0, 1}, {GTK_FILL, 0});
1328
1329         w = ui::Label( "Old Name: " );
1330         table.attach(w, {1, 2, 0, 1}, {GTK_FILL, 0});
1331         w.show();
1332
1333         dlgTexReset.editTexOld = ui::Entry( 256 );
1334         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editTexOld ), rs->textureName );
1335         table.attach(dlgTexReset.editTexOld, {2, 3, 0, 1}, {GTK_FILL, 0});
1336         dlgTexReset.editTexOld.show();
1337
1338         w = ui::Label( "New Name: " );
1339         table.attach(w, {1, 2, 1, 2}, {GTK_FILL, 0});
1340         w.show();
1341
1342         dlgTexReset.editTexNew = ui::Entry( 256 );
1343         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editTexNew ), rs->textureName );
1344         table.attach(dlgTexReset.editTexNew, {2, 3, 1, 2}, {GTK_FILL, 0});
1345         dlgTexReset.editTexNew.show();
1346
1347         // ---- /frame ----
1348
1349         frame = ui::Frame( "Reset Scales" );
1350         frame.show();
1351         vbox.pack_start( frame, FALSE, TRUE, 0 );
1352
1353         table = ui::Table( 2, 3, TRUE );
1354         table.show();
1355         frame.add(table);
1356         gtk_table_set_row_spacings(table, 5);
1357         gtk_table_set_col_spacings(table, 5);
1358         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1359
1360         // ---- frame ----
1361
1362         dlgTexReset.cbScaleHor = ui::CheckButton( "Enabled" );
1363         dlgTexReset.cbScaleHor.connect( "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL );
1364         dlgTexReset.cbScaleHor.show();
1365         table.attach(dlgTexReset.cbScaleHor, {0, 1, 0, 1}, {GTK_FILL, 0});
1366
1367         w = ui::Label( "New Horizontal Scale: " );
1368         table.attach(w, {1, 2, 0, 1}, {GTK_FILL, 0});
1369         w.show();
1370
1371         dlgTexReset.editScaleHor = ui::Entry( 256 );
1372         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editScaleHor ), "0.5" );
1373         table.attach(dlgTexReset.editScaleHor, {2, 3, 0, 1}, {GTK_FILL, 0});
1374         dlgTexReset.editScaleHor.show();
1375
1376
1377         dlgTexReset.cbScaleVert = ui::CheckButton( "Enabled" );
1378         dlgTexReset.cbScaleVert.connect( "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL );
1379         dlgTexReset.cbScaleVert.show();
1380         table.attach(dlgTexReset.cbScaleVert, {0, 1, 1, 2}, {GTK_FILL, 0});
1381
1382         w = ui::Label( "New Vertical Scale: " );
1383         table.attach(w, {1, 2, 1, 2}, {GTK_FILL, 0});
1384         w.show();
1385
1386         dlgTexReset.editScaleVert = ui::Entry( 256 );
1387         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editScaleVert ), "0.5" );
1388         table.attach(dlgTexReset.editScaleVert, {2, 3, 1, 2}, {GTK_FILL, 0});
1389         dlgTexReset.editScaleVert.show();
1390
1391         // ---- /frame ----
1392
1393         frame = ui::Frame( "Reset Shift" );
1394         frame.show();
1395         vbox.pack_start( frame, FALSE, TRUE, 0 );
1396
1397         table = ui::Table( 2, 3, TRUE );
1398         table.show();
1399         frame.add(table);
1400         gtk_table_set_row_spacings(table, 5);
1401         gtk_table_set_col_spacings(table, 5);
1402         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1403
1404         // ---- frame ----
1405
1406         dlgTexReset.cbShiftHor = ui::CheckButton( "Enabled" );
1407         dlgTexReset.cbShiftHor.connect( "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL );
1408         dlgTexReset.cbShiftHor.show();
1409         table.attach(dlgTexReset.cbShiftHor, {0, 1, 0, 1}, {GTK_FILL, 0});
1410
1411         w = ui::Label( "New Horizontal Shift: " );
1412         table.attach(w, {1, 2, 0, 1}, {GTK_FILL, 0});
1413         w.show();
1414
1415         dlgTexReset.editShiftHor = ui::Entry( 256 );
1416         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editShiftHor ), "0" );
1417         table.attach(dlgTexReset.editShiftHor, {2, 3, 0, 1}, {GTK_FILL, 0});
1418         dlgTexReset.editShiftHor.show();
1419
1420
1421         dlgTexReset.cbShiftVert = ui::CheckButton( "Enabled" );
1422         dlgTexReset.cbShiftVert.connect( "toggled", G_CALLBACK( dialog_button_callback_texreset_update ), NULL );
1423         dlgTexReset.cbShiftVert.show();
1424         table.attach(dlgTexReset.cbShiftVert, {0, 1, 1, 2}, {GTK_FILL, 0});
1425
1426         w = ui::Label( "New Vertical Shift: " );
1427         table.attach(w, {1, 2, 1, 2}, {GTK_FILL, 0});
1428         w.show();
1429
1430         dlgTexReset.editShiftVert = ui::Entry( 256 );
1431         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editShiftVert ), "0" );
1432         table.attach(dlgTexReset.editShiftVert, {2, 3, 1, 2}, {GTK_FILL, 0});
1433         dlgTexReset.editShiftVert.show();
1434
1435         // ---- /frame ----
1436
1437         frame = ui::Frame( "Reset Rotation" );
1438         frame.show();
1439         vbox.pack_start( frame, FALSE, TRUE, 0 );
1440
1441         table = ui::Table( 1, 3, TRUE );
1442         table.show();
1443         frame.add(table);
1444         gtk_table_set_row_spacings(table, 5);
1445         gtk_table_set_col_spacings(table, 5);
1446         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1447
1448         // ---- frame ----
1449
1450         dlgTexReset.cbRotation = ui::CheckButton( "Enabled" );
1451         dlgTexReset.cbRotation.show();
1452         table.attach(dlgTexReset.cbRotation, {0, 1, 0, 1}, {GTK_FILL, 0});
1453
1454         w = ui::Label( "New Rotation Value: " );
1455         table.attach(w, {1, 2, 0, 1}, {GTK_FILL, 0});
1456         w.show();
1457
1458         dlgTexReset.editRotation = ui::Entry( 256 );
1459         gtk_entry_set_text( GTK_ENTRY( dlgTexReset.editRotation ), "0" );
1460         table.attach(dlgTexReset.editRotation, {2, 3, 0, 1}, {GTK_FILL, 0});
1461         dlgTexReset.editRotation.show();
1462
1463         // ---- /frame ----
1464
1465         hbox = ui::HBox( FALSE, 10 );
1466         vbox.pack_start( hbox, FALSE, FALSE, 2 );
1467         hbox.show();
1468
1469         // ---- hbox ----
1470
1471         w = ui::Button( "Use Selected Brushes" );
1472         hbox.pack_start( w, TRUE, TRUE, 0 );
1473         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
1474
1475         gtk_widget_set_can_default( w, true );
1476         gtk_widget_grab_default( w );
1477         w.show();
1478
1479         w = ui::Button( "Use All Brushes" );
1480         hbox.pack_start( w, TRUE, TRUE, 0 );
1481         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDYES ) );
1482         w.show();
1483
1484         w = ui::Button( "Cancel" );
1485         hbox.pack_start( w, TRUE, TRUE, 0 );
1486         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
1487         w.show();
1488         ret = eIDCANCEL;
1489
1490         // ---- /hbox ----
1491
1492         // ---- /vbox ----
1493
1494         gtk_window_set_position( window, GTK_WIN_POS_CENTER );
1495         window.show();
1496         gtk_grab_add( window );
1497
1498         Update_TextureReseter();
1499
1500         bool dialogError = TRUE;
1501         while ( dialogError )
1502         {
1503                 loop = 1;
1504                 while ( loop )
1505                         gtk_main_iteration();
1506
1507                 dialogError = FALSE;
1508
1509                 if ( ret != eIDCANCEL ) {
1510                         rs->bResetRotation =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbRotation ) );
1511                         if ( rs->bResetRotation ) {
1512                                 if ( !ValidateTextInt( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editRotation ) ), "Rotation", &rs->rotation ) ) {
1513                                         dialogError = TRUE;
1514                                 }
1515                         }
1516
1517                         rs->bResetScale[0] =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbScaleHor ) );
1518                         if ( rs->bResetScale[0] ) {
1519                                 if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editScaleHor ) ), "Horizontal Scale", &rs->fScale[0] ) ) {
1520                                         dialogError = TRUE;
1521                                 }
1522                         }
1523
1524                         rs->bResetScale[1] =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbScaleVert ) );
1525                         if ( rs->bResetScale[1] ) {
1526                                 if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editScaleVert ) ), "Vertical Scale", &rs->fScale[1] ) ) {
1527                                         dialogError = TRUE;
1528                                 }
1529                         }
1530
1531                         rs->bResetShift[0] =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbShiftHor ) );
1532                         if ( rs->bResetShift[0] ) {
1533                                 if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editShiftHor ) ), "Horizontal Shift", &rs->fShift[0] ) ) {
1534                                         dialogError = TRUE;
1535                                 }
1536                         }
1537
1538                         rs->bResetShift[1] =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbShiftVert ) );
1539                         if ( rs->bResetShift[1] ) {
1540                                 if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editShiftVert ) ), "Vertical Shift", &rs->fShift[1] ) ) {
1541                                         dialogError = TRUE;
1542                                 }
1543                         }
1544
1545                         rs->bResetTextureName =  gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( dlgTexReset.cbTexChange ) );
1546                         if ( rs->bResetTextureName ) {
1547                                 strcpy( rs->textureName,     gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editTexOld ) ) );
1548                                 strcpy( rs->newTextureName,  gtk_entry_get_text( GTK_ENTRY( dlgTexReset.editTexNew ) ) );
1549                         }
1550                 }
1551         }
1552
1553         gtk_grab_remove( window );
1554         window.destroy();
1555
1556         return ret;
1557 }
1558
1559 EMessageBoxReturn DoTrainThingBox( TrainThingRS* rs ){
1560         Str texSelected;
1561
1562         ui::Widget w{ui::null};
1563
1564         ui::Widget radiusX{ui::null}, radiusY{ui::null};
1565         ui::Widget angleStart{ui::null}, angleEnd{ui::null};
1566         ui::Widget heightStart{ui::null}, heightEnd{ui::null};
1567         ui::Widget numPoints{ui::null};
1568
1569         EMessageBoxReturn ret;
1570         int loop = 1;
1571
1572         auto window = ui::Window( ui::window_type::TOP );
1573
1574         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
1575         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
1576
1577         gtk_window_set_title( window, "Train Thing" );
1578         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
1579
1580         g_object_set_data( G_OBJECT( window ), "loop", &loop );
1581         g_object_set_data( G_OBJECT( window ), "ret", &ret );
1582
1583         gtk_widget_realize( window );
1584
1585         auto vbox = ui::VBox( FALSE, 10 );
1586         window.add(vbox);
1587         vbox.show();
1588
1589         // ---- vbox ----
1590
1591         auto hbox = ui::HBox( FALSE, 10 );
1592         vbox.pack_start( hbox, FALSE, FALSE, 2 );
1593         hbox.show();
1594
1595         // ---- /hbox ----
1596
1597         auto frame = ui::Frame( "Radii" );
1598         frame.show();
1599         vbox.pack_start( frame, FALSE, TRUE, 0 );
1600
1601         auto table = ui::Table( 2, 3, TRUE );
1602         table.show();
1603         frame.add(table);
1604         gtk_table_set_row_spacings(table, 5);
1605         gtk_table_set_col_spacings(table, 5);
1606         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1607
1608         // ---- frame ----
1609
1610         w = ui::Label( "X: " );
1611         table.attach(w, {0, 1, 0, 1}, {GTK_FILL, 0});
1612         w.show();
1613
1614         radiusX = ui::Entry( 256 );
1615         gtk_entry_set_text( GTK_ENTRY( radiusX ), "100" );
1616         table.attach(radiusX, {1, 2, 0, 1}, {GTK_FILL, 0});
1617         radiusX.show();
1618
1619
1620
1621         w = ui::Label( "Y: " );
1622         table.attach(w, {0, 1, 1, 2}, {GTK_FILL, 0});
1623         w.show();
1624
1625         radiusY = ui::Entry( 256 );
1626         gtk_entry_set_text( GTK_ENTRY( radiusY ), "100" );
1627         table.attach(radiusY, {1, 2, 1, 2}, {GTK_FILL, 0});
1628         radiusY.show();
1629
1630
1631
1632         frame = ui::Frame( "Angles" );
1633         frame.show();
1634         vbox.pack_start( frame, FALSE, TRUE, 0 );
1635
1636         table = ui::Table( 2, 3, TRUE );
1637         table.show();
1638         frame.add(table);
1639         gtk_table_set_row_spacings((table), 5);
1640         gtk_table_set_col_spacings((table), 5);
1641         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1642
1643         // ---- frame ----
1644
1645         w = ui::Label( "Start: " );
1646         table.attach(w, {0, 1, 0, 1}, {GTK_FILL, 0});
1647         w.show();
1648
1649         angleStart = ui::Entry( 256 );
1650         gtk_entry_set_text( GTK_ENTRY( angleStart ), "0" );
1651         table.attach(angleStart, {1, 2, 0, 1}, {GTK_FILL, 0});
1652         angleStart.show();
1653
1654
1655
1656         w = ui::Label( "End: " );
1657         table.attach(w, {0, 1, 1, 2}, {GTK_FILL, 0});
1658         w.show();
1659
1660         angleEnd = ui::Entry( 256 );
1661         gtk_entry_set_text( GTK_ENTRY( angleEnd ), "90" );
1662         table.attach(angleEnd, {1, 2, 1, 2}, {GTK_FILL, 0});
1663         angleEnd.show();
1664
1665
1666         frame = ui::Frame( "Height" );
1667         frame.show();
1668         vbox.pack_start( frame, FALSE, TRUE, 0 );
1669
1670         table = ui::Table( 2, 3, TRUE );
1671         table.show();
1672         frame.add(table);
1673         gtk_table_set_row_spacings(table, 5);
1674         gtk_table_set_col_spacings(table, 5);
1675         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1676
1677         // ---- frame ----
1678
1679         w = ui::Label( "Start: " );
1680         table.attach(w, {0, 1, 0, 1}, {GTK_FILL, 0});
1681         w.show();
1682
1683         heightStart = ui::Entry( 256 );
1684         gtk_entry_set_text( GTK_ENTRY( heightStart ), "0" );
1685         table.attach(heightStart, {1, 2, 0, 1}, {GTK_FILL, 0});
1686         heightStart.show();
1687
1688
1689
1690         w = ui::Label( "End: " );
1691         table.attach(w, {0, 1, 1, 2}, {GTK_FILL, 0});
1692         w.show();
1693
1694         heightEnd = ui::Entry( 256 );
1695         gtk_entry_set_text( GTK_ENTRY( heightEnd ), "0" );
1696         table.attach(heightEnd, {1, 2, 1, 2}, {GTK_FILL, 0});
1697         heightEnd.show();
1698
1699
1700
1701         frame = ui::Frame( "Points" );
1702         frame.show();
1703         vbox.pack_start( frame, FALSE, TRUE, 0 );
1704
1705         table = ui::Table( 2, 3, TRUE );
1706         table.show();
1707         frame.add(table);
1708         gtk_table_set_row_spacings(table, 5);
1709         gtk_table_set_col_spacings(table, 5);
1710         gtk_container_set_border_width( GTK_CONTAINER( table ), 5 );
1711
1712         // ---- frame ----
1713
1714         w = ui::Label( "Number: " );
1715         table.attach(w, {0, 1, 0, 1}, {GTK_FILL, 0});
1716         w.show();
1717
1718         numPoints = ui::Entry( 256 );
1719         gtk_entry_set_text( GTK_ENTRY( numPoints ), "0" );
1720         table.attach(numPoints, {1, 2, 0, 1}, {GTK_FILL, 0});
1721         numPoints.show();
1722
1723
1724         hbox = ui::HBox( FALSE, 10 );
1725         vbox.pack_start( hbox, FALSE, FALSE, 2 );
1726         hbox.show();
1727
1728         // ---- hbox ----
1729
1730         w = ui::Button( "Ok" );
1731         hbox.pack_start( w, TRUE, TRUE, 0 );
1732         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
1733
1734         gtk_widget_set_can_default( w, true );
1735         gtk_widget_grab_default( w );
1736         w.show();
1737
1738         w = ui::Button( "Cancel" );
1739         hbox.pack_start( w, TRUE, TRUE, 0 );
1740         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
1741         w.show();
1742         ret = eIDCANCEL;
1743
1744         // ---- /hbox ----
1745
1746
1747
1748         gtk_window_set_position( window, GTK_WIN_POS_CENTER );
1749         window.show();
1750         gtk_grab_add( window );
1751
1752         bool dialogError = TRUE;
1753         while ( dialogError )
1754         {
1755                 loop = 1;
1756                 while ( loop )
1757                         gtk_main_iteration();
1758
1759                 dialogError = FALSE;
1760
1761                 if ( ret != eIDCANCEL ) {
1762                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( radiusX ) ), "Radius (X)", &rs->fRadiusX ) ) {
1763                                 dialogError = TRUE;
1764                         }
1765
1766                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( radiusY ) ), "Radius (Y)", &rs->fRadiusY ) ) {
1767                                 dialogError = TRUE;
1768                         }
1769
1770                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( angleStart ) ), "Angle (Start)", &rs->fStartAngle ) ) {
1771                                 dialogError = TRUE;
1772                         }
1773
1774                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( angleEnd ) ), "Angle (End)", &rs->fEndAngle ) ) {
1775                                 dialogError = TRUE;
1776                         }
1777
1778                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( heightStart ) ), "Height (Start)", &rs->fStartHeight ) ) {
1779                                 dialogError = TRUE;
1780                         }
1781
1782                         if ( !ValidateTextFloat( gtk_entry_get_text( GTK_ENTRY( heightEnd ) ), "Height (End)", &rs->fEndHeight ) ) {
1783                                 dialogError = TRUE;
1784                         }
1785
1786                         if ( !ValidateTextInt( gtk_entry_get_text( GTK_ENTRY( numPoints ) ), "Num Points", &rs->iNumPoints ) ) {
1787                                 dialogError = TRUE;
1788                         }
1789                 }
1790         }
1791
1792         gtk_grab_remove( window );
1793         window.destroy();
1794
1795         return ret;
1796 }
1797 // ailmanki
1798 // add a simple input for the MakeChain thing..
1799 EMessageBoxReturn DoMakeChainBox( MakeChainRS* rs ){
1800         ui::Widget   w{ui::null};
1801         ui::Entry textlinkNum{ui::null}, textlinkName{ui::null};
1802         EMessageBoxReturn ret;
1803         int loop = 1;
1804
1805         const char *text = "Please set a value in the boxes below and press 'OK' to make a chain";
1806
1807         auto window = ui::Window( ui::window_type::TOP );
1808
1809         window.connect( "delete_event", G_CALLBACK( dialog_delete_callback ), NULL );
1810         window.connect( "destroy", G_CALLBACK( gtk_widget_destroy ), NULL );
1811
1812         gtk_window_set_title( window, "Make Chain" );
1813
1814         gtk_container_set_border_width( GTK_CONTAINER( window ), 10 );
1815
1816         g_object_set_data( G_OBJECT( window ), "loop", &loop );
1817         g_object_set_data( G_OBJECT( window ), "ret", &ret );
1818
1819         gtk_widget_realize( window );
1820
1821         // new vbox
1822         auto vbox = ui::VBox( FALSE, 10 );
1823         window.add(vbox);
1824         vbox.show();
1825
1826         auto hbox = ui::HBox( FALSE, 10 );
1827         vbox.add(hbox);
1828         hbox.show();
1829
1830         // dunno if you want this text or not ...
1831         w = ui::Label( text );
1832         hbox.pack_start( w, FALSE, FALSE, 0 );
1833         w.show();
1834
1835         w = ui::Widget::from(gtk_hseparator_new());
1836         vbox.pack_start( w, FALSE, FALSE, 0 );
1837         w.show();
1838
1839         // ------------------------- //
1840
1841         // new hbox
1842         hbox = ui::HBox( FALSE, 10 );
1843         vbox.pack_start( hbox, FALSE, FALSE, 0 );
1844         hbox.show();
1845
1846         textlinkNum = ui::Entry( 256 );
1847         hbox.pack_start( textlinkNum, FALSE, FALSE, 1 );
1848         textlinkNum.show();
1849
1850         w = ui::Label( "Number of elements in chain" );
1851         hbox.pack_start( w, FALSE, FALSE, 1 );
1852         w.show();
1853
1854         // -------------------------- //
1855
1856         hbox = ui::HBox( FALSE, 10 );
1857         vbox.pack_start( hbox, FALSE, FALSE, 0 );
1858         hbox.show();
1859
1860         textlinkName = ui::Entry( 256 );
1861         hbox.pack_start( textlinkName, FALSE, FALSE, 0 );
1862         textlinkName.show();
1863
1864         w = ui::Label( "Basename for chain's targetnames." );
1865         hbox.pack_start( w, FALSE, FALSE, 1 );
1866         w.show();
1867
1868
1869         w = ui::Button( "OK" );
1870         hbox.pack_start( w, TRUE, TRUE, 0 );
1871         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDOK ) );
1872         gtk_widget_set_can_default( w, true );
1873         gtk_widget_grab_default( w );
1874         w.show();
1875
1876         w = ui::Button( "Cancel" );
1877         hbox.pack_start( w, TRUE, TRUE, 0 );
1878         w.connect( "clicked", G_CALLBACK( dialog_button_callback ), GINT_TO_POINTER( eIDCANCEL ) );
1879         w.show();
1880
1881         ret = eIDCANCEL;
1882
1883         gtk_window_set_position(  window, GTK_WIN_POS_CENTER );
1884         window.show();
1885         gtk_grab_add( window );
1886
1887         bool dialogError = TRUE;
1888         while ( dialogError )
1889         {
1890                 loop = 1;
1891                 while ( loop )
1892                         gtk_main_iteration();
1893
1894                 dialogError = FALSE;
1895
1896                 if ( ret == eIDOK ) {
1897                         strcpy( rs->linkName, gtk_entry_get_text( textlinkName ) );
1898                         if ( !ValidateTextInt( gtk_entry_get_text( textlinkNum ), "Elements", &rs->linkNum ) ) {
1899                                 dialogError = TRUE;
1900                         }
1901                 }
1902         }
1903
1904         gtk_grab_remove( window );
1905         window.destroy();
1906
1907         return ret;
1908 }