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