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