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