2 BobToolz plugin for GtkRadiant
3 Copyright (C) 2001 Gordon Biggans
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.
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.
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
20 #include "dialogs-gtk.h"
21 #include "../funchandlers.h"
26 #include "gtkutil/pointer.h"
32 /*--------------------------------
34 ---------------------------------*/
37 ui::Widget cbTexChange{ui::null};
38 ui::Widget editTexOld{ui::null}, editTexNew{ui::null};
40 ui::Widget cbScaleHor{ui::null}, cbScaleVert{ui::null};
41 ui::Widget editScaleHor{ui::null}, editScaleVert{ui::null};
43 ui::Widget cbShiftHor{ui::null}, cbShiftVert{ui::null};
44 ui::Widget editShiftHor{ui::null}, editShiftVert{ui::null};
46 ui::Widget cbRotation{ui::null};
47 ui::Widget editRotation{ui::null};
50 dlg_texReset_t dlgTexReset;
52 void Update_TextureReseter();
54 static void dialog_button_callback_texreset_update(ui::Widget widget, gpointer data)
56 Update_TextureReseter();
59 void Update_TextureReseter()
63 check = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlgTexReset.cbTexChange));
64 gtk_editable_set_editable(GTK_EDITABLE(dlgTexReset.editTexNew), check);
65 gtk_editable_set_editable(GTK_EDITABLE(dlgTexReset.editTexOld), check);
67 check = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlgTexReset.cbScaleHor));
68 gtk_editable_set_editable(GTK_EDITABLE(dlgTexReset.editScaleHor), check);
70 check = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlgTexReset.cbScaleVert));
71 gtk_editable_set_editable(GTK_EDITABLE(dlgTexReset.editScaleVert), check);
73 check = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlgTexReset.cbShiftHor));
74 gtk_editable_set_editable(GTK_EDITABLE(dlgTexReset.editShiftHor), check);
76 check = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlgTexReset.cbShiftVert));
77 gtk_editable_set_editable(GTK_EDITABLE(dlgTexReset.editShiftVert), check);
79 check = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlgTexReset.cbRotation));
80 gtk_editable_set_editable(GTK_EDITABLE(dlgTexReset.editRotation), check);
83 static void dialog_button_callback(ui::Widget widget, gpointer data)
86 EMessageBoxReturn *ret;
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");
93 *ret = (EMessageBoxReturn) gpointer_to_int(data);
96 static gint dialog_delete_callback(ui::Widget widget, GdkEvent *event, gpointer data)
99 int *loop = (int *) g_object_get_data(G_OBJECT(widget), "loop");
104 static void dialog_button_callback_settex(ui::Widget widget, gpointer data)
106 TwinWidget *tw = (TwinWidget *) data;
108 auto entry = ui::Entry::from(tw->one);
109 auto combo = tw->two;
111 const gchar *tex = gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(combo)));
112 gtk_entry_set_text(entry, tex);
115 /*--------------------------------
116 Data validation Routines
117 ---------------------------------*/
119 bool ValidateTextFloat(const char *pData, const char *error_title, float *value)
122 float testNum = (float) atof(pData);
124 if ((testNum == 0.0f) && strcmp(pData, "0")) {
125 DoMessageBox("Please Enter A Floating Point Number", error_title, eMB_OK);
133 DoMessageBox("Please Enter A Floating Point Number", error_title, eMB_OK);
137 bool ValidateTextFloatRange(const char *pData, float min, float max, const char *error_title, float *value)
139 char error_buffer[256];
140 sprintf(error_buffer, "Please Enter A Floating Point Number Between %.3f and %.3f", min, max);
143 float testNum = (float) atof(pData);
145 if ((testNum < min) || (testNum > max)) {
146 DoMessageBox(error_buffer, error_title, eMB_OK);
154 DoMessageBox(error_buffer, error_title, eMB_OK);
158 bool ValidateTextIntRange(const char *pData, int min, int max, const char *error_title, int *value)
160 char error_buffer[256];
161 sprintf(error_buffer, "Please Enter An Integer Between %i and %i", min, max);
164 int testNum = atoi(pData);
166 if ((testNum < min) || (testNum > max)) {
167 DoMessageBox(error_buffer, error_title, eMB_OK);
175 DoMessageBox(error_buffer, error_title, eMB_OK);
179 bool ValidateTextInt(const char *pData, const char *error_title, int *value)
182 int testNum = atoi(pData);
184 if ((testNum == 0) && strcmp(pData, "0")) {
185 DoMessageBox("Please Enter An Integer", error_title, eMB_OK);
193 DoMessageBox("Please Enter An Integer", error_title, eMB_OK);
197 /*--------------------------------
199 ---------------------------------*/
203 Major clean up of variable names etc required, excluding Mars's ones,
204 which are nicely done :)
208 EMessageBoxReturn DoMessageBox(const char *lpText, const char *lpCaption, EMessageBoxType type)
210 ui::Widget w{ui::null};
211 EMessageBoxReturn ret;
214 auto window = ui::Window(ui::window_type::TOP);
215 window.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL);
216 window.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL);
217 gtk_window_set_title(window, lpCaption);
218 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
219 g_object_set_data(G_OBJECT(window), "loop", &loop);
220 g_object_set_data(G_OBJECT(window), "ret", &ret);
221 gtk_widget_realize(window);
223 auto vbox = ui::VBox(FALSE, 10);
227 w = ui::Label(lpText);
228 vbox.pack_start(w, FALSE, FALSE, 2);
229 gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
232 w = ui::Widget::from(gtk_hseparator_new());
233 vbox.pack_start(w, FALSE, FALSE, 2);
236 auto hbox = ui::HBox(FALSE, 10);
237 vbox.pack_start(hbox, FALSE, FALSE, 2);
240 if (type == eMB_OK) {
241 w = ui::Button("Ok");
242 hbox.pack_start(w, TRUE, TRUE, 0);
243 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDOK));
244 gtk_widget_set_can_default(w, true);
245 gtk_widget_grab_default(w);
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);
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));
261 } else if (type == eMB_YESNOCANCEL) {
262 w = ui::Button("Yes");
263 hbox.pack_start(w, TRUE, TRUE, 0);
264 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDYES));
265 gtk_widget_set_can_default(w, true);
266 gtk_widget_grab_default(w);
269 w = ui::Button("No");
270 hbox.pack_start(w, TRUE, TRUE, 0);
271 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDNO));
274 w = ui::Button("Cancel");
275 hbox.pack_start(w, TRUE, TRUE, 0);
276 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDCANCEL));
279 } else /* if (mode == MB_YESNO) */
281 w = ui::Button("Yes");
282 hbox.pack_start(w, TRUE, TRUE, 0);
283 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDYES));
284 gtk_widget_set_can_default(w, true);
285 gtk_widget_grab_default(w);
288 w = ui::Button("No");
289 hbox.pack_start(w, TRUE, TRUE, 0);
290 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDNO));
295 gtk_window_set_position(window, GTK_WIN_POS_CENTER);
297 gtk_grab_add(window);
300 gtk_main_iteration();
303 gtk_grab_remove(window);
309 EMessageBoxReturn DoIntersectBox(IntersectRS *rs)
311 EMessageBoxReturn ret;
314 auto window = ui::Window(ui::window_type::TOP);
316 window.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL);
317 window.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL);
319 gtk_window_set_title(window, "Intersect");
320 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
322 g_object_set_data(G_OBJECT(window), "loop", &loop);
323 g_object_set_data(G_OBJECT(window), "ret", &ret);
325 gtk_widget_realize(window);
328 auto vbox = ui::VBox(FALSE, 10);
335 auto radio1 = ui::Widget::from(gtk_radio_button_new_with_label(NULL, "Use Whole Map"));
336 vbox.pack_start(radio1, FALSE, FALSE, 2);
339 auto radio2 = ui::Widget::from(gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio1)),
340 "Use Selected Brushes"));
341 vbox.pack_start(radio2, FALSE, FALSE, 2);
344 auto hsep = ui::Widget::from(gtk_hseparator_new());
345 vbox.pack_start(hsep, FALSE, FALSE, 2);
348 auto check1 = ui::CheckButton("Include Detail Brushes");
349 vbox.pack_start(check1, FALSE, FALSE, 0);
352 auto check2 = ui::CheckButton("Select Duplicate Brushes Only");
353 vbox.pack_start(check2, FALSE, FALSE, 0);
356 auto hbox = ui::HBox(FALSE, 10);
357 vbox.pack_start(hbox, FALSE, FALSE, 2);
360 // ---- hbox ---- ok/cancel buttons
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));
366 gtk_widget_set_can_default(w, true);
367 gtk_widget_grab_default(w);
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));
380 gtk_window_set_position(window, GTK_WIN_POS_CENTER);
382 gtk_grab_add(window);
385 gtk_main_iteration();
388 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio1))) {
389 rs->nBrushOptions = BRUSH_OPT_WHOLE_MAP;
390 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio2))) {
391 rs->nBrushOptions = BRUSH_OPT_SELECTED;
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;
397 gtk_grab_remove(window);
403 EMessageBoxReturn DoPolygonBox(PolygonRS *rs)
405 EMessageBoxReturn ret;
408 auto window = ui::Window(ui::window_type::TOP);
410 window.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL);
411 window.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL);
413 gtk_window_set_title(window, "Polygon Builder");
414 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
416 g_object_set_data(G_OBJECT(window), "loop", &loop);
417 g_object_set_data(G_OBJECT(window), "ret", &ret);
419 gtk_widget_realize(window);
422 auto vbox = ui::VBox(FALSE, 10);
428 auto hbox = ui::HBox(FALSE, 10);
429 vbox.pack_start(hbox, FALSE, FALSE, 2);
435 auto vbox2 = ui::VBox(FALSE, 10);
436 hbox.pack_start(vbox2, FALSE, FALSE, 2);
441 auto hbox2 = ui::HBox(FALSE, 10);
442 vbox2.pack_start(hbox2, FALSE, FALSE, 2);
447 auto text1 = ui::Entry(256);
448 gtk_entry_set_text(text1, "3");
449 hbox2.pack_start(text1, FALSE, FALSE, 2);
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);
459 hbox2 = ui::HBox(FALSE, 10);
460 vbox2.pack_start(hbox2, FALSE, FALSE, 2);
465 auto text2 = ui::Entry(256);
466 gtk_entry_set_text(text2, "8");
467 hbox2.pack_start(text2, FALSE, FALSE, 2);
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);
481 vbox2 = ui::VBox(FALSE, 10);
482 hbox.pack_start(vbox2, FALSE, FALSE, 2);
487 auto check1 = ui::CheckButton("Use Border");
488 vbox2.pack_start(check1, FALSE, FALSE, 0);
492 auto check2 = ui::CheckButton("Inverse Polygon");
493 vbox2.pack_start(check2, FALSE, FALSE, 0);
497 auto check3 = ui::CheckButton("Align Top Edge");
498 vbox2.pack_start(check3, FALSE, FALSE, 0);
505 hbox = ui::HBox(FALSE, 10);
506 vbox.pack_start(hbox, FALSE, FALSE, 2);
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));
515 gtk_widget_set_can_default(w, true);
516 gtk_widget_grab_default(w);
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));
529 gtk_window_set_position(window, GTK_WIN_POS_CENTER);
531 gtk_grab_add(window);
533 bool dialogError = TRUE;
534 while (dialogError) {
537 gtk_main_iteration();
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;
547 if (!ValidateTextIntRange(gtk_entry_get_text(text1), 3, 32, "Number Of Sides", &rs->nSides)) {
551 if (rs->bUseBorder) {
552 if (!ValidateTextIntRange(gtk_entry_get_text(text2), 8, 256, "Border Width", &rs->nBorderWidth)) {
559 gtk_grab_remove(window);
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)
570 GSList *radioDirection, *radioStyle;
571 EMessageBoxReturn ret;
574 const char *text = "Please set a value in the boxes below and press 'OK' to build the stairs";
576 auto window = ui::Window(ui::window_type::TOP);
578 window.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL);
579 window.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL);
581 gtk_window_set_title(window, "Stair Builder");
583 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
585 g_object_set_data(G_OBJECT(window), "loop", &loop);
586 g_object_set_data(G_OBJECT(window), "ret", &ret);
588 gtk_widget_realize(window);
591 auto vbox = ui::VBox(FALSE, 10);
595 auto hbox = ui::HBox(FALSE, 10);
599 // dunno if you want this text or not ...
600 ui::Widget w = ui::Label(text);
601 hbox.pack_start(w, FALSE, FALSE, 0); // not entirely sure on all the parameters / what they do ...
604 w = ui::Widget::from(gtk_hseparator_new());
605 vbox.pack_start(w, FALSE, FALSE, 0);
608 // ------------------------- // indenting == good way of keeping track of lines :)
611 hbox = ui::HBox(FALSE, 10);
612 vbox.pack_start(hbox, FALSE, FALSE, 0);
615 auto textStairHeight = ui::Entry(256);
616 hbox.pack_start(textStairHeight, FALSE, FALSE, 1);
617 textStairHeight.show();
619 w = ui::Label("Stair Height");
620 hbox.pack_start(w, FALSE, FALSE, 1);
623 // ------------------------- //
625 hbox = ui::HBox(FALSE, 10);
626 vbox.pack_start(hbox, FALSE, FALSE, 0);
629 w = ui::Label("Direction:");
630 hbox.pack_start(w, FALSE, FALSE, 5);
633 // -------------------------- //
635 hbox = ui::HBox(FALSE, 10);
636 vbox.pack_start(hbox, FALSE, FALSE, 0);
639 // radio buttons confuse me ...
640 // but this _looks_ right
642 // djbob: actually it looks very nice :), slightly better than the way i did it
643 // edit: actually it doesn't work :P, you must pass the last radio item each time, ugh
645 auto radioNorth = ui::Widget::from(gtk_radio_button_new_with_label(NULL, "North"));
646 hbox.pack_start(radioNorth, FALSE, FALSE, 3);
649 radioDirection = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radioNorth));
651 auto radioSouth = ui::Widget::from(gtk_radio_button_new_with_label(radioDirection, "South"));
652 hbox.pack_start(radioSouth, FALSE, FALSE, 2);
655 radioDirection = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radioSouth));
657 auto radioEast = ui::Widget::from(gtk_radio_button_new_with_label(radioDirection, "East"));
658 hbox.pack_start(radioEast, FALSE, FALSE, 1);
661 radioDirection = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radioEast));
663 auto radioWest = ui::Widget::from(gtk_radio_button_new_with_label(radioDirection, "West"));
664 hbox.pack_start(radioWest, FALSE, FALSE, 0);
667 // --------------------------- //
669 hbox = ui::HBox(FALSE, 10);
670 vbox.pack_start(hbox, FALSE, FALSE, 0);
673 w = ui::Label("Style:");
674 hbox.pack_start(w, FALSE, FALSE, 5);
677 // --------------------------- //
679 hbox = ui::HBox(FALSE, 10);
680 vbox.pack_start(hbox, FALSE, FALSE, 0);
683 auto radioOldStyle = ui::Widget::from(gtk_radio_button_new_with_label(NULL, "Original"));
684 hbox.pack_start(radioOldStyle, FALSE, FALSE, 0);
685 radioOldStyle.show();
687 radioStyle = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radioOldStyle));
689 auto radioBobStyle = ui::Widget::from(gtk_radio_button_new_with_label(radioStyle, "Bob's Style"));
690 hbox.pack_start(radioBobStyle, FALSE, FALSE, 0);
691 radioBobStyle.show();
693 radioStyle = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radioBobStyle));
695 auto radioCornerStyle = ui::Widget::from(gtk_radio_button_new_with_label(radioStyle, "Corner Style"));
696 hbox.pack_start(radioCornerStyle, FALSE, FALSE, 0);
697 radioCornerStyle.show();
699 // err, the q3r has an if or something so you need bob style checked before this
700 // is "ungreyed out" but you'll need to do that, as i suck :)
702 // djbob: er.... yeah um, im not at all sure how i'm gonna sort this
703 // djbob: think we need some button callback functions or smuffin
704 // FIXME: actually get around to doing what i suggested!!!!
706 auto checkUseDetail = ui::CheckButton("Use Detail Brushes");
707 hbox.pack_start(checkUseDetail, FALSE, FALSE, 0);
708 checkUseDetail.show();
710 // --------------------------- //
712 hbox = ui::HBox(FALSE, 10);
713 vbox.pack_start(hbox, FALSE, FALSE, 0);
716 auto textMainTex = ui::Entry(512);
717 gtk_entry_set_text(GTK_ENTRY(textMainTex), rs->mainTexture);
718 hbox.pack_start(textMainTex, FALSE, FALSE, 0);
721 w = ui::Label("Main Texture");
722 hbox.pack_start(w, FALSE, FALSE, 1);
725 // -------------------------- //
727 hbox = ui::HBox(FALSE, 10);
728 vbox.pack_start(hbox, FALSE, FALSE, 0);
731 auto textRiserTex = ui::Entry(512);
732 hbox.pack_start(textRiserTex, FALSE, FALSE, 0);
735 w = ui::Label("Riser Texture");
736 hbox.pack_start(w, FALSE, FALSE, 1);
739 // -------------------------- //
740 w = ui::Widget::from(gtk_hseparator_new());
741 vbox.pack_start(w, FALSE, FALSE, 0);
744 hbox = ui::HBox(FALSE, 10);
745 vbox.pack_start(hbox, FALSE, FALSE, 0);
748 w = ui::Button("OK");
749 hbox.pack_start(w, TRUE, TRUE, 0);
750 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDOK));
751 gtk_widget_set_can_default(w, true);
752 gtk_widget_grab_default(w);
755 w = ui::Button("Cancel");
756 hbox.pack_start(w, TRUE, TRUE, 0);
757 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDCANCEL));
762 // +djbob: need our "little" modal loop mars :P
763 gtk_window_set_position(window, GTK_WIN_POS_CENTER);
765 gtk_grab_add(window);
767 bool dialogError = TRUE;
768 while (dialogError) {
771 gtk_main_iteration();
777 rs->bUseDetail = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkUseDetail)) ? true : false;
779 strcpy(rs->riserTexture, gtk_entry_get_text(textRiserTex));
780 strcpy(rs->mainTexture, gtk_entry_get_text(textMainTex));
782 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioNorth))) {
783 rs->direction = MOVE_NORTH;
784 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioSouth))) {
785 rs->direction = MOVE_SOUTH;
786 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioEast))) {
787 rs->direction = MOVE_EAST;
788 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioWest))) {
789 rs->direction = MOVE_WEST;
792 if (!ValidateTextInt(gtk_entry_get_text(textStairHeight), "Stair Height", &rs->stairHeight)) {
796 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioOldStyle))) {
797 rs->style = STYLE_ORIGINAL;
798 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioBobStyle))) {
799 rs->style = STYLE_BOB;
800 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioCornerStyle))) {
801 rs->style = STYLE_CORNER;
806 gtk_grab_remove(window);
812 // there we go, all done ... on my end at least, not bad for a night's work
815 EMessageBoxReturn DoDoorsBox(DoorRS *rs)
817 GSList *radioOrientation;
819 EMessageBoxReturn ret;
822 auto window = ui::Window(ui::window_type::TOP);
824 window.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL);
825 window.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL);
827 gtk_window_set_title(window, "Door Builder");
829 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
831 g_object_set_data(G_OBJECT(window), "loop", &loop);
832 g_object_set_data(G_OBJECT(window), "ret", &ret);
834 gtk_widget_realize(window);
837 auto listMainTextures = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING));
838 auto listTrimTextures = ui::ListStore::from(gtk_list_store_new(1, G_TYPE_STRING));
839 LoadGList(GetFilename(buffer, "plugins/bt/door-tex.txt"), listMainTextures);
840 LoadGList(GetFilename(buffer, "plugins/bt/door-tex-trim.txt"), listTrimTextures);
842 auto vbox = ui::VBox(FALSE, 10);
846 // -------------------------- //
848 auto hbox = ui::HBox(FALSE, 10);
849 vbox.pack_start(hbox, FALSE, FALSE, 0);
852 auto textFrontBackTex = ui::Entry(512);
853 gtk_entry_set_text(GTK_ENTRY(textFrontBackTex), rs->mainTexture);
854 hbox.pack_start(textFrontBackTex, FALSE, FALSE, 0);
855 textFrontBackTex.show();
857 ui::Widget w = ui::Label("Door Front/Back Texture");
858 hbox.pack_start(w, FALSE, FALSE, 0);
861 // ------------------------ //
863 hbox = ui::HBox(FALSE, 10);
864 vbox.pack_start(hbox, FALSE, FALSE, 0);
867 auto textTrimTex = ui::Entry(512);
868 hbox.pack_start(textTrimTex, FALSE, FALSE, 0);
871 w = ui::Label("Door Trim Texture");
872 hbox.pack_start(w, FALSE, FALSE, 0);
875 // ----------------------- //
877 hbox = ui::HBox(FALSE, 10);
878 vbox.pack_start(hbox, FALSE, FALSE, 0);
881 // sp: horizontally ????
882 // djbob: yes mars, u can spell :]
883 auto checkScaleMainH = ui::CheckButton("Scale Main Texture Horizontally");
884 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkScaleMainH), TRUE);
885 hbox.pack_start(checkScaleMainH, FALSE, FALSE, 0);
886 checkScaleMainH.show();
888 auto checkScaleTrimH = ui::CheckButton("Scale Trim Texture Horizontally");
889 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkScaleTrimH), TRUE);
890 hbox.pack_start(checkScaleTrimH, FALSE, FALSE, 0);
891 checkScaleTrimH.show();
893 // ---------------------- //
895 hbox = ui::HBox(FALSE, 10);
896 vbox.pack_start(hbox, FALSE, FALSE, 0);
899 auto checkScaleMainV = ui::CheckButton("Scale Main Texture Vertically");
900 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkScaleMainV), TRUE);
901 hbox.pack_start(checkScaleMainV, FALSE, FALSE, 0);
902 checkScaleMainV.show();
904 auto checkScaleTrimV = ui::CheckButton("Scale Trim Texture Vertically");
905 hbox.pack_start(checkScaleTrimV, FALSE, FALSE, 0);
906 checkScaleTrimV.show();
908 // --------------------- //
910 hbox = ui::HBox(FALSE, 10);
911 vbox.pack_start(hbox, FALSE, FALSE, 0);
914 // djbob: lists added
916 auto comboMain = ui::ComboBox::from(gtk_combo_box_new_with_model_and_entry(listMainTextures));
917 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(comboMain), 0);
918 hbox.pack_start(comboMain, FALSE, FALSE, 0);
921 tw1.one = textFrontBackTex;
924 auto buttonSetMain = ui::Button("Set As Main Texture");
925 buttonSetMain.connect("clicked", G_CALLBACK(dialog_button_callback_settex), &tw1);
926 hbox.pack_start(buttonSetMain, FALSE, FALSE, 0);
927 buttonSetMain.show();
929 // ------------------- //
931 hbox = ui::HBox(FALSE, 10);
932 vbox.pack_start(hbox, FALSE, FALSE, 0);
935 auto comboTrim = ui::ComboBox::from(gtk_combo_box_new_with_model_and_entry(listTrimTextures));
936 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(comboMain), 0);
937 hbox.pack_start(comboTrim, FALSE, FALSE, 0);
940 tw2.one = textTrimTex;
943 auto buttonSetTrim = ui::Button("Set As Trim Texture");
944 buttonSetTrim.connect("clicked", G_CALLBACK(dialog_button_callback_settex), &tw2);
945 hbox.pack_start(buttonSetTrim, FALSE, FALSE, 0);
946 buttonSetTrim.show();
948 // ------------------ //
950 hbox = ui::HBox(FALSE, 10);
951 vbox.pack_start(hbox, FALSE, FALSE, 0);
954 w = ui::Label("Orientation");
955 hbox.pack_start(w, FALSE, FALSE, 0);
958 // argh more radio buttons!
959 auto radioNS = ui::Widget::from(gtk_radio_button_new_with_label(NULL, "North - South"));
960 hbox.pack_start(radioNS, FALSE, FALSE, 0);
963 radioOrientation = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radioNS));
965 auto radioEW = ui::Widget::from(gtk_radio_button_new_with_label(radioOrientation, "East - West"));
966 hbox.pack_start(radioEW, FALSE, FALSE, 0);
969 // ----------------- //
971 w = ui::Widget::from(gtk_hseparator_new());
972 vbox.pack_start(w, FALSE, FALSE, 0);
975 // ----------------- //
977 hbox = ui::HBox(FALSE, 10);
978 vbox.pack_start(hbox, FALSE, FALSE, 0);
981 w = ui::Button("OK");
982 hbox.pack_start(w, TRUE, TRUE, 0);
983 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDOK));
984 gtk_widget_set_can_default(w, true);
985 gtk_widget_grab_default(w);
988 w = ui::Button("Cancel");
989 hbox.pack_start(w, TRUE, TRUE, 0);
990 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDCANCEL));
994 // ----------------- //
997 gtk_window_set_position(window, GTK_WIN_POS_CENTER);
999 gtk_grab_add(window);
1002 gtk_main_iteration();
1005 strcpy(rs->mainTexture, gtk_entry_get_text(GTK_ENTRY(textFrontBackTex)));
1006 strcpy(rs->trimTexture, gtk_entry_get_text(GTK_ENTRY(textTrimTex)));
1008 rs->bScaleMainH = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkScaleMainH)) ? true : false;
1009 rs->bScaleMainV = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkScaleMainV)) ? true : false;
1010 rs->bScaleTrimH = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkScaleTrimH)) ? true : false;
1011 rs->bScaleTrimV = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkScaleTrimV)) ? true : false;
1013 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioNS))) {
1014 rs->nOrientation = DIRECTION_NS;
1015 } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioEW))) {
1016 rs->nOrientation = DIRECTION_EW;
1019 gtk_grab_remove(window);
1026 EMessageBoxReturn DoPathPlotterBox(PathPlotterRS *rs)
1028 ui::Widget w{ui::null};
1030 EMessageBoxReturn ret;
1033 auto window = ui::Window(ui::window_type::TOP);
1035 window.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL);
1036 window.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL);
1038 gtk_window_set_title(window, "Texture Reset");
1039 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
1041 g_object_set_data(G_OBJECT(window), "loop", &loop);
1042 g_object_set_data(G_OBJECT(window), "ret", &ret);
1044 gtk_widget_realize(window);
1047 auto vbox = ui::VBox(FALSE, 10);
1053 auto hbox = ui::HBox(FALSE, 10);
1054 vbox.pack_start(hbox, FALSE, FALSE, 2);
1059 auto text1 = ui::Entry(256);
1060 gtk_entry_set_text(text1, "25");
1061 hbox.pack_start(text1, FALSE, FALSE, 2);
1064 w = ui::Label("Number Of Points");
1065 hbox.pack_start(w, FALSE, FALSE, 2);
1066 gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
1071 hbox = ui::HBox(FALSE, 10);
1072 vbox.pack_start(hbox, FALSE, FALSE, 2);
1077 auto text2 = ui::Entry(256);
1078 gtk_entry_set_text(text2, "3");
1079 hbox.pack_start(text2, FALSE, FALSE, 2);
1082 w = ui::Label("Multipler");
1083 hbox.pack_start(w, FALSE, FALSE, 2);
1084 gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
1089 w = ui::Label("Path Distance = dist(start -> apex) * multiplier");
1090 vbox.pack_start(w, FALSE, FALSE, 0);
1091 gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
1094 hbox = ui::HBox(FALSE, 10);
1095 vbox.pack_start(hbox, FALSE, FALSE, 2);
1100 auto text3 = ui::Entry(256);
1101 gtk_entry_set_text(text3, "-800");
1102 hbox.pack_start(text3, FALSE, FALSE, 2);
1105 w = ui::Label("Gravity");
1106 hbox.pack_start(w, FALSE, FALSE, 2);
1107 gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
1112 w = ui::Widget::from(gtk_hseparator_new());
1113 vbox.pack_start(w, FALSE, FALSE, 0);
1116 auto check1 = ui::CheckButton("No Dynamic Update");
1117 vbox.pack_start(check1, FALSE, FALSE, 0);
1120 auto check2 = ui::CheckButton("Show Bounding Lines");
1121 vbox.pack_start(check2, FALSE, FALSE, 0);
1127 // ----------------- //
1129 w = ui::Widget::from(gtk_hseparator_new());
1130 vbox.pack_start(w, FALSE, FALSE, 0);
1133 // ----------------- //
1135 hbox = ui::HBox(FALSE, 10);
1136 vbox.pack_start(hbox, FALSE, FALSE, 0);
1139 w = ui::Button("Enable");
1140 hbox.pack_start(w, TRUE, TRUE, 0);
1141 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDYES));
1144 gtk_widget_set_can_default(w, true);
1145 gtk_widget_grab_default(w);
1147 w = ui::Button("Disable");
1148 hbox.pack_start(w, TRUE, TRUE, 0);
1149 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDNO));
1152 w = ui::Button("Cancel");
1153 hbox.pack_start(w, TRUE, TRUE, 0);
1154 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDCANCEL));
1159 // ----------------- //
1161 gtk_window_set_position(window, GTK_WIN_POS_CENTER);
1163 gtk_grab_add(window);
1165 bool dialogError = TRUE;
1166 while (dialogError) {
1169 gtk_main_iteration();
1172 dialogError = FALSE;
1174 if (ret == eIDYES) {
1175 if (!ValidateTextIntRange(gtk_entry_get_text(GTK_ENTRY(text1)), 1, 200, "Number Of Points", &rs->nPoints)) {
1179 if (!ValidateTextFloatRange(gtk_entry_get_text(GTK_ENTRY(text2)), 1.0f, 10.0f, "Multiplier",
1180 &rs->fMultiplier)) {
1184 if (!ValidateTextFloatRange(gtk_entry_get_text(GTK_ENTRY(text3)), -10000.0f, -1.0f, "Gravity",
1189 rs->bNoUpdate = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check1)) ? true : false;
1190 rs->bShowExtra = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check2)) ? true : false;
1194 gtk_grab_remove(window);
1200 EMessageBoxReturn DoCTFColourChangeBox()
1202 ui::Widget w{ui::null};
1203 EMessageBoxReturn ret;
1206 auto window = ui::Window(ui::window_type::TOP);
1208 window.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL);
1209 window.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL);
1211 gtk_window_set_title(window, "CTF Colour Changer");
1212 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
1214 g_object_set_data(G_OBJECT(window), "loop", &loop);
1215 g_object_set_data(G_OBJECT(window), "ret", &ret);
1217 gtk_widget_realize(window);
1220 auto vbox = ui::VBox(FALSE, 10);
1226 auto hbox = ui::HBox(FALSE, 10);
1227 vbox.pack_start(hbox, TRUE, TRUE, 0);
1230 // ---- hbox ---- ok/cancel buttons
1232 w = ui::Button("Red->Blue");
1233 hbox.pack_start(w, TRUE, TRUE, 0);
1234 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDOK));
1236 gtk_widget_set_can_default(w, true);
1237 gtk_widget_grab_default(w);
1240 w = ui::Button("Blue->Red");
1241 hbox.pack_start(w, TRUE, TRUE, 0);
1242 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDYES));
1245 w = ui::Button("Cancel");
1246 hbox.pack_start(w, TRUE, TRUE, 0);
1247 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDCANCEL));
1255 gtk_window_set_position(window, GTK_WIN_POS_CENTER);
1257 gtk_grab_add(window);
1260 gtk_main_iteration();
1263 gtk_grab_remove(window);
1269 EMessageBoxReturn DoResetTextureBox(ResetTextureRS *rs)
1273 ui::Widget w{ui::null};
1275 EMessageBoxReturn ret;
1278 auto window = ui::Window(ui::window_type::TOP);
1280 window.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL);
1281 window.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL);
1283 gtk_window_set_title(window, "Texture Reset");
1284 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
1286 g_object_set_data(G_OBJECT(window), "loop", &loop);
1287 g_object_set_data(G_OBJECT(window), "ret", &ret);
1289 gtk_widget_realize(window);
1291 auto vbox = ui::VBox(FALSE, 10);
1297 auto hbox = ui::HBox(FALSE, 10);
1298 vbox.pack_start(hbox, FALSE, FALSE, 2);
1303 texSelected = "Currently Selected Texture: ";
1304 texSelected += GetCurrentTexture();
1306 w = ui::Label(texSelected);
1307 hbox.pack_start(w, FALSE, FALSE, 2);
1308 gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
1313 auto frame = ui::Frame("Reset Texture Names");
1315 vbox.pack_start(frame, FALSE, TRUE, 0);
1317 auto table = ui::Table(2, 3, TRUE);
1320 gtk_table_set_row_spacings(table, 5);
1321 gtk_table_set_col_spacings(table, 5);
1322 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1326 dlgTexReset.cbTexChange = ui::CheckButton("Enabled");
1327 dlgTexReset.cbTexChange.connect("toggled", G_CALLBACK(dialog_button_callback_texreset_update), NULL);
1328 dlgTexReset.cbTexChange.show();
1329 table.attach(dlgTexReset.cbTexChange, {0, 1, 0, 1}, {GTK_FILL, 0});
1331 w = ui::Label("Old Name: ");
1332 table.attach(w, {1, 2, 0, 1}, {GTK_FILL, 0});
1335 dlgTexReset.editTexOld = ui::Entry(256);
1336 gtk_entry_set_text(GTK_ENTRY(dlgTexReset.editTexOld), rs->textureName);
1337 table.attach(dlgTexReset.editTexOld, {2, 3, 0, 1}, {GTK_FILL, 0});
1338 dlgTexReset.editTexOld.show();
1340 w = ui::Label("New Name: ");
1341 table.attach(w, {1, 2, 1, 2}, {GTK_FILL, 0});
1344 dlgTexReset.editTexNew = ui::Entry(256);
1345 gtk_entry_set_text(GTK_ENTRY(dlgTexReset.editTexNew), rs->textureName);
1346 table.attach(dlgTexReset.editTexNew, {2, 3, 1, 2}, {GTK_FILL, 0});
1347 dlgTexReset.editTexNew.show();
1351 frame = ui::Frame("Reset Scales");
1353 vbox.pack_start(frame, FALSE, TRUE, 0);
1355 table = ui::Table(2, 3, TRUE);
1358 gtk_table_set_row_spacings(table, 5);
1359 gtk_table_set_col_spacings(table, 5);
1360 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1364 dlgTexReset.cbScaleHor = ui::CheckButton("Enabled");
1365 dlgTexReset.cbScaleHor.connect("toggled", G_CALLBACK(dialog_button_callback_texreset_update), NULL);
1366 dlgTexReset.cbScaleHor.show();
1367 table.attach(dlgTexReset.cbScaleHor, {0, 1, 0, 1}, {GTK_FILL, 0});
1369 w = ui::Label("New Horizontal Scale: ");
1370 table.attach(w, {1, 2, 0, 1}, {GTK_FILL, 0});
1373 dlgTexReset.editScaleHor = ui::Entry(256);
1374 gtk_entry_set_text(GTK_ENTRY(dlgTexReset.editScaleHor), "0.5");
1375 table.attach(dlgTexReset.editScaleHor, {2, 3, 0, 1}, {GTK_FILL, 0});
1376 dlgTexReset.editScaleHor.show();
1379 dlgTexReset.cbScaleVert = ui::CheckButton("Enabled");
1380 dlgTexReset.cbScaleVert.connect("toggled", G_CALLBACK(dialog_button_callback_texreset_update), NULL);
1381 dlgTexReset.cbScaleVert.show();
1382 table.attach(dlgTexReset.cbScaleVert, {0, 1, 1, 2}, {GTK_FILL, 0});
1384 w = ui::Label("New Vertical Scale: ");
1385 table.attach(w, {1, 2, 1, 2}, {GTK_FILL, 0});
1388 dlgTexReset.editScaleVert = ui::Entry(256);
1389 gtk_entry_set_text(GTK_ENTRY(dlgTexReset.editScaleVert), "0.5");
1390 table.attach(dlgTexReset.editScaleVert, {2, 3, 1, 2}, {GTK_FILL, 0});
1391 dlgTexReset.editScaleVert.show();
1395 frame = ui::Frame("Reset Shift");
1397 vbox.pack_start(frame, FALSE, TRUE, 0);
1399 table = ui::Table(2, 3, TRUE);
1402 gtk_table_set_row_spacings(table, 5);
1403 gtk_table_set_col_spacings(table, 5);
1404 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1408 dlgTexReset.cbShiftHor = ui::CheckButton("Enabled");
1409 dlgTexReset.cbShiftHor.connect("toggled", G_CALLBACK(dialog_button_callback_texreset_update), NULL);
1410 dlgTexReset.cbShiftHor.show();
1411 table.attach(dlgTexReset.cbShiftHor, {0, 1, 0, 1}, {GTK_FILL, 0});
1413 w = ui::Label("New Horizontal Shift: ");
1414 table.attach(w, {1, 2, 0, 1}, {GTK_FILL, 0});
1417 dlgTexReset.editShiftHor = ui::Entry(256);
1418 gtk_entry_set_text(GTK_ENTRY(dlgTexReset.editShiftHor), "0");
1419 table.attach(dlgTexReset.editShiftHor, {2, 3, 0, 1}, {GTK_FILL, 0});
1420 dlgTexReset.editShiftHor.show();
1423 dlgTexReset.cbShiftVert = ui::CheckButton("Enabled");
1424 dlgTexReset.cbShiftVert.connect("toggled", G_CALLBACK(dialog_button_callback_texreset_update), NULL);
1425 dlgTexReset.cbShiftVert.show();
1426 table.attach(dlgTexReset.cbShiftVert, {0, 1, 1, 2}, {GTK_FILL, 0});
1428 w = ui::Label("New Vertical Shift: ");
1429 table.attach(w, {1, 2, 1, 2}, {GTK_FILL, 0});
1432 dlgTexReset.editShiftVert = ui::Entry(256);
1433 gtk_entry_set_text(GTK_ENTRY(dlgTexReset.editShiftVert), "0");
1434 table.attach(dlgTexReset.editShiftVert, {2, 3, 1, 2}, {GTK_FILL, 0});
1435 dlgTexReset.editShiftVert.show();
1439 frame = ui::Frame("Reset Rotation");
1441 vbox.pack_start(frame, FALSE, TRUE, 0);
1443 table = ui::Table(1, 3, TRUE);
1446 gtk_table_set_row_spacings(table, 5);
1447 gtk_table_set_col_spacings(table, 5);
1448 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1452 dlgTexReset.cbRotation = ui::CheckButton("Enabled");
1453 dlgTexReset.cbRotation.show();
1454 table.attach(dlgTexReset.cbRotation, {0, 1, 0, 1}, {GTK_FILL, 0});
1456 w = ui::Label("New Rotation Value: ");
1457 table.attach(w, {1, 2, 0, 1}, {GTK_FILL, 0});
1460 dlgTexReset.editRotation = ui::Entry(256);
1461 gtk_entry_set_text(GTK_ENTRY(dlgTexReset.editRotation), "0");
1462 table.attach(dlgTexReset.editRotation, {2, 3, 0, 1}, {GTK_FILL, 0});
1463 dlgTexReset.editRotation.show();
1467 hbox = ui::HBox(FALSE, 10);
1468 vbox.pack_start(hbox, FALSE, FALSE, 2);
1473 w = ui::Button("Use Selected Brushes");
1474 hbox.pack_start(w, TRUE, TRUE, 0);
1475 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDOK));
1477 gtk_widget_set_can_default(w, true);
1478 gtk_widget_grab_default(w);
1481 w = ui::Button("Use All Brushes");
1482 hbox.pack_start(w, TRUE, TRUE, 0);
1483 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDYES));
1486 w = ui::Button("Cancel");
1487 hbox.pack_start(w, TRUE, TRUE, 0);
1488 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDCANCEL));
1496 gtk_window_set_position(window, GTK_WIN_POS_CENTER);
1498 gtk_grab_add(window);
1500 Update_TextureReseter();
1502 bool dialogError = TRUE;
1503 while (dialogError) {
1506 gtk_main_iteration();
1509 dialogError = FALSE;
1511 if (ret != eIDCANCEL) {
1512 rs->bResetRotation = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlgTexReset.cbRotation));
1513 if (rs->bResetRotation) {
1514 if (!ValidateTextInt(gtk_entry_get_text(GTK_ENTRY(dlgTexReset.editRotation)), "Rotation",
1520 rs->bResetScale[0] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlgTexReset.cbScaleHor));
1521 if (rs->bResetScale[0]) {
1522 if (!ValidateTextFloat(gtk_entry_get_text(GTK_ENTRY(dlgTexReset.editScaleHor)), "Horizontal Scale",
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",
1536 rs->bResetShift[0] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlgTexReset.cbShiftHor));
1537 if (rs->bResetShift[0]) {
1538 if (!ValidateTextFloat(gtk_entry_get_text(GTK_ENTRY(dlgTexReset.editShiftHor)), "Horizontal Shift",
1544 rs->bResetShift[1] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlgTexReset.cbShiftVert));
1545 if (rs->bResetShift[1]) {
1546 if (!ValidateTextFloat(gtk_entry_get_text(GTK_ENTRY(dlgTexReset.editShiftVert)), "Vertical Shift",
1552 rs->bResetTextureName = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dlgTexReset.cbTexChange));
1553 if (rs->bResetTextureName) {
1554 strcpy(rs->textureName, gtk_entry_get_text(GTK_ENTRY(dlgTexReset.editTexOld)));
1555 strcpy(rs->newTextureName, gtk_entry_get_text(GTK_ENTRY(dlgTexReset.editTexNew)));
1560 gtk_grab_remove(window);
1566 EMessageBoxReturn DoTrainThingBox(TrainThingRS *rs)
1570 ui::Widget w{ui::null};
1572 ui::Widget radiusX{ui::null}, radiusY{ui::null};
1573 ui::Widget angleStart{ui::null}, angleEnd{ui::null};
1574 ui::Widget heightStart{ui::null}, heightEnd{ui::null};
1575 ui::Widget numPoints{ui::null};
1577 EMessageBoxReturn ret;
1580 auto window = ui::Window(ui::window_type::TOP);
1582 window.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL);
1583 window.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL);
1585 gtk_window_set_title(window, "Train Thing");
1586 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
1588 g_object_set_data(G_OBJECT(window), "loop", &loop);
1589 g_object_set_data(G_OBJECT(window), "ret", &ret);
1591 gtk_widget_realize(window);
1593 auto vbox = ui::VBox(FALSE, 10);
1599 auto hbox = ui::HBox(FALSE, 10);
1600 vbox.pack_start(hbox, FALSE, FALSE, 2);
1605 auto frame = ui::Frame("Radii");
1607 vbox.pack_start(frame, FALSE, TRUE, 0);
1609 auto table = ui::Table(2, 3, TRUE);
1612 gtk_table_set_row_spacings(table, 5);
1613 gtk_table_set_col_spacings(table, 5);
1614 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1618 w = ui::Label("X: ");
1619 table.attach(w, {0, 1, 0, 1}, {GTK_FILL, 0});
1622 radiusX = ui::Entry(256);
1623 gtk_entry_set_text(GTK_ENTRY(radiusX), "100");
1624 table.attach(radiusX, {1, 2, 0, 1}, {GTK_FILL, 0});
1628 w = ui::Label("Y: ");
1629 table.attach(w, {0, 1, 1, 2}, {GTK_FILL, 0});
1632 radiusY = ui::Entry(256);
1633 gtk_entry_set_text(GTK_ENTRY(radiusY), "100");
1634 table.attach(radiusY, {1, 2, 1, 2}, {GTK_FILL, 0});
1638 frame = ui::Frame("Angles");
1640 vbox.pack_start(frame, FALSE, TRUE, 0);
1642 table = ui::Table(2, 3, TRUE);
1645 gtk_table_set_row_spacings((table), 5);
1646 gtk_table_set_col_spacings((table), 5);
1647 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1651 w = ui::Label("Start: ");
1652 table.attach(w, {0, 1, 0, 1}, {GTK_FILL, 0});
1655 angleStart = ui::Entry(256);
1656 gtk_entry_set_text(GTK_ENTRY(angleStart), "0");
1657 table.attach(angleStart, {1, 2, 0, 1}, {GTK_FILL, 0});
1661 w = ui::Label("End: ");
1662 table.attach(w, {0, 1, 1, 2}, {GTK_FILL, 0});
1665 angleEnd = ui::Entry(256);
1666 gtk_entry_set_text(GTK_ENTRY(angleEnd), "90");
1667 table.attach(angleEnd, {1, 2, 1, 2}, {GTK_FILL, 0});
1671 frame = ui::Frame("Height");
1673 vbox.pack_start(frame, FALSE, TRUE, 0);
1675 table = ui::Table(2, 3, TRUE);
1678 gtk_table_set_row_spacings(table, 5);
1679 gtk_table_set_col_spacings(table, 5);
1680 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1684 w = ui::Label("Start: ");
1685 table.attach(w, {0, 1, 0, 1}, {GTK_FILL, 0});
1688 heightStart = ui::Entry(256);
1689 gtk_entry_set_text(GTK_ENTRY(heightStart), "0");
1690 table.attach(heightStart, {1, 2, 0, 1}, {GTK_FILL, 0});
1694 w = ui::Label("End: ");
1695 table.attach(w, {0, 1, 1, 2}, {GTK_FILL, 0});
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});
1704 frame = ui::Frame("Points");
1706 vbox.pack_start(frame, FALSE, TRUE, 0);
1708 table = ui::Table(2, 3, TRUE);
1711 gtk_table_set_row_spacings(table, 5);
1712 gtk_table_set_col_spacings(table, 5);
1713 gtk_container_set_border_width(GTK_CONTAINER(table), 5);
1717 w = ui::Label("Number: ");
1718 table.attach(w, {0, 1, 0, 1}, {GTK_FILL, 0});
1721 numPoints = ui::Entry(256);
1722 gtk_entry_set_text(GTK_ENTRY(numPoints), "0");
1723 table.attach(numPoints, {1, 2, 0, 1}, {GTK_FILL, 0});
1727 hbox = ui::HBox(FALSE, 10);
1728 vbox.pack_start(hbox, FALSE, FALSE, 2);
1733 w = ui::Button("Ok");
1734 hbox.pack_start(w, TRUE, TRUE, 0);
1735 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDOK));
1737 gtk_widget_set_can_default(w, true);
1738 gtk_widget_grab_default(w);
1741 w = ui::Button("Cancel");
1742 hbox.pack_start(w, TRUE, TRUE, 0);
1743 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDCANCEL));
1751 gtk_window_set_position(window, GTK_WIN_POS_CENTER);
1753 gtk_grab_add(window);
1755 bool dialogError = TRUE;
1756 while (dialogError) {
1759 gtk_main_iteration();
1762 dialogError = FALSE;
1764 if (ret != eIDCANCEL) {
1765 if (!ValidateTextFloat(gtk_entry_get_text(GTK_ENTRY(radiusX)), "Radius (X)", &rs->fRadiusX)) {
1769 if (!ValidateTextFloat(gtk_entry_get_text(GTK_ENTRY(radiusY)), "Radius (Y)", &rs->fRadiusY)) {
1773 if (!ValidateTextFloat(gtk_entry_get_text(GTK_ENTRY(angleStart)), "Angle (Start)", &rs->fStartAngle)) {
1777 if (!ValidateTextFloat(gtk_entry_get_text(GTK_ENTRY(angleEnd)), "Angle (End)", &rs->fEndAngle)) {
1781 if (!ValidateTextFloat(gtk_entry_get_text(GTK_ENTRY(heightStart)), "Height (Start)", &rs->fStartHeight)) {
1785 if (!ValidateTextFloat(gtk_entry_get_text(GTK_ENTRY(heightEnd)), "Height (End)", &rs->fEndHeight)) {
1789 if (!ValidateTextInt(gtk_entry_get_text(GTK_ENTRY(numPoints)), "Num Points", &rs->iNumPoints)) {
1795 gtk_grab_remove(window);
1802 // add a simple input for the MakeChain thing..
1803 EMessageBoxReturn DoMakeChainBox(MakeChainRS *rs)
1805 ui::Widget w{ui::null};
1806 ui::Entry textlinkNum{ui::null}, textlinkName{ui::null};
1807 EMessageBoxReturn ret;
1810 const char *text = "Please set a value in the boxes below and press 'OK' to make a chain";
1812 auto window = ui::Window(ui::window_type::TOP);
1814 window.connect("delete_event", G_CALLBACK(dialog_delete_callback), NULL);
1815 window.connect("destroy", G_CALLBACK(gtk_widget_destroy), NULL);
1817 gtk_window_set_title(window, "Make Chain");
1819 gtk_container_set_border_width(GTK_CONTAINER(window), 10);
1821 g_object_set_data(G_OBJECT(window), "loop", &loop);
1822 g_object_set_data(G_OBJECT(window), "ret", &ret);
1824 gtk_widget_realize(window);
1827 auto vbox = ui::VBox(FALSE, 10);
1831 auto hbox = ui::HBox(FALSE, 10);
1835 // dunno if you want this text or not ...
1836 w = ui::Label(text);
1837 hbox.pack_start(w, FALSE, FALSE, 0);
1840 w = ui::Widget::from(gtk_hseparator_new());
1841 vbox.pack_start(w, FALSE, FALSE, 0);
1844 // ------------------------- //
1847 hbox = ui::HBox(FALSE, 10);
1848 vbox.pack_start(hbox, FALSE, FALSE, 0);
1851 textlinkNum = ui::Entry(256);
1852 hbox.pack_start(textlinkNum, FALSE, FALSE, 1);
1855 w = ui::Label("Number of elements in chain");
1856 hbox.pack_start(w, FALSE, FALSE, 1);
1859 // -------------------------- //
1861 hbox = ui::HBox(FALSE, 10);
1862 vbox.pack_start(hbox, FALSE, FALSE, 0);
1865 textlinkName = ui::Entry(256);
1866 hbox.pack_start(textlinkName, FALSE, FALSE, 0);
1867 textlinkName.show();
1869 w = ui::Label("Basename for chain's targetnames.");
1870 hbox.pack_start(w, FALSE, FALSE, 1);
1874 w = ui::Button("OK");
1875 hbox.pack_start(w, TRUE, TRUE, 0);
1876 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDOK));
1877 gtk_widget_set_can_default(w, true);
1878 gtk_widget_grab_default(w);
1881 w = ui::Button("Cancel");
1882 hbox.pack_start(w, TRUE, TRUE, 0);
1883 w.connect("clicked", G_CALLBACK(dialog_button_callback), GINT_TO_POINTER(eIDCANCEL));
1888 gtk_window_set_position(window, GTK_WIN_POS_CENTER);
1890 gtk_grab_add(window);
1892 bool dialogError = TRUE;
1893 while (dialogError) {
1896 gtk_main_iteration();
1899 dialogError = FALSE;
1902 strcpy(rs->linkName, gtk_entry_get_text(textlinkName));
1903 if (!ValidateTextInt(gtk_entry_get_text(textlinkNum), "Elements", &rs->linkNum)) {
1909 gtk_grab_remove(window);