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