1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
13
14 /**********************************************************************
15 optiondlg.c - description
16 -------------------
17 begin : Sun Aug 11 2002
18 copyright : (C) 2002 by Rafał Bursig
19 email : Rafał Bursig <bursig@poczta.fm>
20 **********************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 #include <fc_config.h>
24 #endif
25
26 #include <stdarg.h>
27 #include <stdlib.h>
28
29 /* SDL */
30 #include <SDL/SDL.h>
31
32 /* utility */
33 #include "fcintl.h"
34 #include "log.h"
35 #include "string_vector.h"
36
37 /* common */
38 #include "fc_types.h"
39 #include "game.h"
40
41 /* client */
42 #include "client_main.h"
43 #include "climisc.h"
44 #include "clinet.h"
45 #include "connectdlg_common.h"
46 #include "global_worklist.h"
47
48 /* gui-sdl */
49 #include "colors.h"
50 #include "connectdlg.h"
51 #include "dialogs.h"
52 #include "graphics.h"
53 #include "gui_iconv.h"
54 #include "gui_id.h"
55 #include "gui_main.h"
56 #include "gui_tilespec.h"
57 #include "helpdlg.h"
58 #include "mapctrl.h"
59 #include "mapview.h"
60 #include "menu.h"
61 #include "messagewin.h"
62 #include "pages.h"
63 #include "themespec.h"
64 #include "widget.h"
65 #include "wldlg.h"
66
67 #include "optiondlg.h"
68
69 enum option_dialog_mode {
70 ODM_MAIN,
71 ODM_OPTSET,
72 ODM_WORKLIST
73 };
74
75 struct option_dialog_optset {
76 const struct option_set *poptset;
77 struct widget *widget_list;
78 int category;
79 };
80
81 struct option_dialog_worklist {
82 struct widget *edited_name;
83 };
84
85 struct option_dialog {
86 struct widget *end_widget_list;
87 struct widget *core_widget_list;
88 struct widget *main_widget_list;
89 struct widget *begin_widget_list;
90 struct ADVANCED_DLG *advanced;
91 enum option_dialog_mode mode;
92 union {
93 struct option_dialog_optset optset;
94 struct option_dialog_worklist worklist;
95 };
96 };
97
98
99 static struct option_dialog *option_dialog = NULL;
100 struct widget *pOptions_Button = NULL;
101 static bool restore_meswin_dialog = FALSE;
102
103
104 static struct widget *option_widget_new(struct option *poption,
105 struct widget *window,
106 bool hide);
107 static void option_widget_update(struct option *poption);
108 static void option_widget_apply(struct option *poption);
109
110 static struct option_dialog *option_dialog_new(void);
111 static void option_dialog_destroy(struct option_dialog *pdialog);
112
113 static void option_dialog_optset(struct option_dialog *pdialog,
114 const struct option_set *poptset);
115 static void option_dialog_optset_category(struct option_dialog *pdialog,
116 int category);
117
118 static void option_dialog_worklist(struct option_dialog *pdialog);
119
120 /****************************************************************************
121 Arrange the widgets. NB: end argument is excluded. End the argument
122 list with the icons on the top, terminated by NULL.
123 ****************************************************************************/
arrange_widgets(struct widget * window,int widgets_per_row,int rows_shown,struct widget * begin,struct widget * end,...)124 static void arrange_widgets(struct widget *window, int widgets_per_row,
125 int rows_shown, struct widget *begin,
126 struct widget *end, ...)
127 {
128 struct widget *widget;
129 SDL_Surface *logo;
130 SDL_Rect area;
131 int longest[widgets_per_row], xpos[widgets_per_row];
132 int w, h, i, j;
133 va_list args;
134
135 fc_assert_ret(NULL != window);
136 fc_assert_ret(NULL != begin);
137 fc_assert_ret(NULL != end);
138 fc_assert_ret(0 < widgets_per_row);
139
140 /* Get window dimensions. */
141 memset(longest, 0, sizeof(longest));
142 for (widget = begin, i = 0; widget != end; widget = widget->next, i++) {
143 j = i % widgets_per_row;
144 longest[j] = MAX(longest[j], widget->size.w);
145 }
146
147 fc_assert(0 == i % widgets_per_row);
148
149 if (-1 == rows_shown) {
150 h = 30 * (i / widgets_per_row);
151 } else {
152 h = 30 * MIN((i / widgets_per_row), rows_shown);
153 }
154
155 w = (1 - widgets_per_row) * adj_size(20);
156 for (j = 0; j < widgets_per_row; j++) {
157 w += longest[j];
158 }
159 if (-1 != rows_shown) {
160 w += adj_size(20);
161 }
162
163 /* Clear former area. */
164 area = window->area;
165 area.w += window->size.x;
166 area.h += window->size.y;
167 sdl_dirty_rect(area);
168
169 /* Resize window. */
170 logo = theme_get_background(theme, BACKGROUND_OPTIONDLG);
171 if (resize_window(window, logo, NULL,
172 adj_size(w + 80), adj_size(h + 80))) {
173 FREESURFACE(logo);
174 }
175
176 /* Set window position. */
177 widget_set_position(window, (Main.screen->w - window->size.w) / 2,
178 (Main.screen->h - window->size.h) / 2);
179
180 area = window->area;
181
182 /* Set icons position. */
183 va_start(args, end);
184 w = 0;
185 while ((widget = va_arg(args, struct widget *))) {
186 w += widget->size.w;
187 widget_set_position(widget, area.x + area.w - w - 1,
188 window->size.y + adj_size(2));
189 }
190 va_end(args);
191
192 if (1 < widgets_per_row) {
193 xpos[widgets_per_row - 1] = area.x + adj_size(20);
194 for (j = widgets_per_row - 2; j >= 0; j--) {
195 xpos[j] = xpos[j + 1] + adj_size(20) + longest[j + 1];
196 }
197 }
198
199 /* Set button position. */
200 h = 30 * (i / widgets_per_row + 1);
201 for (widget = begin, i = 0; widget != end; widget = widget->next, i++) {
202
203 j = i % widgets_per_row;
204 if (0 == j) {
205 h -= 30;
206 }
207 widget_resize(widget, longest[j], widget->size.h);
208 if (1 == widgets_per_row) {
209 widget_set_position(widget, area.x + (area.w - widget->size.w) / 2,
210 area.y + adj_size(h));
211 } else {
212 widget_set_position(widget, xpos[j], area.y + adj_size(h));
213 }
214 }
215
216 redraw_group(begin, window, 0);
217 widget_mark_dirty(window);
218 flush_all();
219 }
220
221 /****************************************************************************
222 ...
223 ****************************************************************************/
main_optiondlg_callback(struct widget * pWindow)224 static int main_optiondlg_callback(struct widget *pWindow)
225 {
226 if (NULL != option_dialog && Main.event.button.button == SDL_BUTTON_LEFT) {
227 move_window_group(option_dialog->begin_widget_list,
228 option_dialog->end_widget_list);
229 }
230 return -1;
231 }
232
233 /****************************************************************************
234 Back requested.
235 ****************************************************************************/
back_callback(struct widget * pWidget)236 static int back_callback(struct widget *pWidget)
237 {
238 if (NULL == option_dialog || Main.event.button.button != SDL_BUTTON_LEFT) {
239 return -1;
240 }
241
242 if (ODM_MAIN == option_dialog->mode) {
243 if (client.conn.established) {
244 /* Back to game. */
245 popdown_optiondlg(FALSE);
246 enable_options_button();
247 widget_redraw(pOptions_Button);
248 widget_mark_dirty(pOptions_Button);
249 flush_dirty();
250 } else {
251 /* Back to main page. */
252 popdown_optiondlg(TRUE);
253 set_client_page(PAGE_MAIN);
254 }
255 return -1;
256 }
257
258 if (ODM_OPTSET == option_dialog->mode
259 && -1 != option_dialog->optset.category) {
260 /* Back to option set category menu. */
261 options_iterate(option_dialog->optset.poptset, poption) {
262 if (option_dialog->optset.category == option_category(poption)) {
263 option_set_gui_data(poption, NULL);
264 }
265 } options_iterate_end;
266 option_dialog->optset.category = -1;
267 FC_FREE(option_dialog->advanced->pScroll);
268 FC_FREE(option_dialog->advanced);
269
270 del_group_of_widgets_from_gui_list(option_dialog->begin_widget_list,
271 option_dialog->optset.widget_list->prev);
272
273 option_dialog->begin_widget_list = option_dialog->optset.widget_list;
274
275 show_group(option_dialog->begin_widget_list,
276 option_dialog->main_widget_list->prev);
277
278 arrange_widgets(option_dialog->end_widget_list, 1, -1,
279 option_dialog->begin_widget_list,
280 option_dialog->main_widget_list,
281 option_dialog->core_widget_list, NULL);
282 return -1;
283 }
284
285 if (ODM_WORKLIST == option_dialog->mode
286 && NULL != option_dialog->advanced) {
287 FC_FREE(option_dialog->advanced->pScroll);
288 FC_FREE(option_dialog->advanced);
289 option_dialog->worklist.edited_name = NULL;
290 }
291
292 /* Back to main options menu. */
293 del_group_of_widgets_from_gui_list(option_dialog->begin_widget_list,
294 option_dialog->main_widget_list->prev);
295
296 option_dialog->begin_widget_list = option_dialog->main_widget_list;
297
298 show_group(option_dialog->begin_widget_list,
299 option_dialog->core_widget_list->prev);
300 option_dialog->mode = ODM_MAIN;
301 arrange_widgets(option_dialog->end_widget_list, 1, -1,
302 option_dialog->begin_widget_list,
303 option_dialog->core_widget_list,
304 option_dialog->core_widget_list, NULL);
305
306 return -1;
307 }
308
309 /****************************************************************************
310 Create the client options dialog.
311 ****************************************************************************/
client_options_callback(struct widget * pWidget)312 static int client_options_callback(struct widget *pWidget)
313 {
314 if (Main.event.button.button == SDL_BUTTON_LEFT) {
315 option_dialog_popup(_("Local Options"), client_optset);
316 }
317 return -1;
318 }
319
320 /****************************************************************************
321 Create the server options dialog.
322 ****************************************************************************/
server_options_callback(struct widget * pWidget)323 static int server_options_callback(struct widget *pWidget)
324 {
325 if (Main.event.button.button == SDL_BUTTON_LEFT) {
326 option_dialog_popup(_("Server options"), server_optset);
327 }
328 return -1;
329 }
330
331 /****************************************************************************
332 Create the worklist editor.
333 ****************************************************************************/
work_lists_callback(struct widget * widget)334 static int work_lists_callback(struct widget *widget)
335 {
336 if (Main.event.button.button == SDL_BUTTON_LEFT) {
337 option_dialog_worklist(option_dialog);
338 }
339 return -1;
340 }
341
342 /****************************************************************************
343 Option set category selected.
344 ****************************************************************************/
save_client_options_callback(struct widget * pWidget)345 static int save_client_options_callback(struct widget *pWidget)
346 {
347 if (Main.event.button.button == SDL_BUTTON_LEFT) {
348 options_save(NULL);
349 }
350 return -1;
351 }
352
353 /****************************************************************************
354 Save game callback.
355 ****************************************************************************/
save_game_callback(struct widget * pWidget)356 static int save_game_callback(struct widget *pWidget)
357 {
358 if (Main.event.button.button == SDL_BUTTON_LEFT) {
359 send_save_game(NULL);
360 back_callback(NULL);
361 }
362 return -1;
363 }
364
365 /****************************************************************************
366 Open Help Browser callback
367 ****************************************************************************/
help_browser_callback(struct widget * pwidget)368 static int help_browser_callback(struct widget *pwidget)
369 {
370 if (Main.event.button.button == SDL_BUTTON_LEFT) {
371 popup_help_browser();
372 }
373
374 return -1;
375 }
376
377 /****************************************************************************
378 Client disconnect from server callback.
379 ****************************************************************************/
disconnect_callback(struct widget * pWidget)380 static int disconnect_callback(struct widget *pWidget)
381 {
382 if (Main.event.button.button == SDL_BUTTON_LEFT) {
383 popdown_optiondlg(TRUE);
384 enable_options_button();
385 disconnect_from_server();
386 }
387 return -1;
388 }
389
390 /****************************************************************************
391 Exit callback.
392 ****************************************************************************/
exit_callback(struct widget * pWidget)393 static int exit_callback(struct widget *pWidget)
394 {
395 if (Main.event.button.button == SDL_BUTTON_LEFT) {
396 popdown_optiondlg(TRUE);
397 force_exit_from_event_loop();
398 }
399 return 0;
400 }
401
402 /****************************************************************************
403 Option set category selected.
404 ****************************************************************************/
option_category_callback(struct widget * widget)405 static int option_category_callback(struct widget *widget)
406 {
407 if (Main.event.button.button == SDL_BUTTON_LEFT) {
408 option_dialog_optset_category(option_dialog, MAX_ID - widget->ID);
409 }
410 return -1;
411 }
412
413 /****************************************************************************
414 Apply the changes for the option category.
415 ****************************************************************************/
apply_callback(struct widget * widget)416 static int apply_callback(struct widget *widget)
417 {
418 if (Main.event.button.button == SDL_BUTTON_LEFT
419 && NULL != option_dialog
420 && ODM_OPTSET == option_dialog->mode
421 && -1 != option_dialog->optset.category) {
422 options_iterate(option_dialog->optset.poptset, poption) {
423 if (option_dialog->optset.category == option_category(poption)) {
424 option_widget_apply(poption);
425 }
426 } options_iterate_end;
427 }
428 return back_callback(widget);
429 }
430
431 /****************************************************************************
432 Dummy callback. Disable exit().
433 ****************************************************************************/
none_callback(struct widget * widget)434 static int none_callback(struct widget *widget)
435 {
436 return -1;
437 }
438
439 /****************************************************************************
440 Return a string vector containing all video modes.
441 ****************************************************************************/
video_mode_list(void)442 static struct strvec *video_mode_list(void)
443 {
444 struct strvec *video_modes = strvec_new();
445 /* Don't free this. */
446 SDL_Rect **mode = SDL_ListModes(NULL, SDL_FULLSCREEN | Main.screen->flags);
447 char buf[64];
448
449 for (; NULL != *mode; mode++) {
450 struct video_mode vmode = {.width = (*mode)->w, .height = (*mode)->h };
451
452 if (video_mode_to_string(buf, sizeof(buf), &vmode)) {
453 strvec_append(video_modes, buf);
454 }
455 }
456
457 return video_modes;
458 }
459
460 /****************************************************************************
461 Free correctly the memory assigned to the enum_widget.
462 ****************************************************************************/
enum_widget_destroy(struct widget * widget)463 static void enum_widget_destroy(struct widget *widget)
464 {
465 strvec_destroy((struct strvec *) widget->data.vector);
466 }
467
468 /****************************************************************************
469 Free correctly the memory assigned to the video_mode_widget.
470 ****************************************************************************/
video_mode_widget_destroy(struct widget * widget)471 static void video_mode_widget_destroy(struct widget *widget)
472 {
473 combo_popdown(widget);
474 strvec_destroy((struct strvec *) widget->data.vector);
475 }
476
477 /****************************************************************************
478 Create a widget for the option.
479 ****************************************************************************/
option_widget_new(struct option * poption,struct widget * window,bool hide)480 static struct widget *option_widget_new(struct option *poption,
481 struct widget *window,
482 bool hide)
483 {
484 struct widget *widget;
485 char *help_text;
486 Uint32 flags = (hide ? WF_HIDDEN | WF_RESTORE_BACKGROUND
487 : WF_RESTORE_BACKGROUND);
488
489 fc_assert_ret_val(NULL != poption, NULL);
490 fc_assert_ret_val(NULL != window, NULL);
491
492 help_text = fc_strdup(option_help_text(poption));
493 fc_break_lines(help_text, 50);
494
495 widget = create_iconlabel_from_chars(NULL, window->dst,
496 option_description(poption),
497 adj_font(12),
498 flags | WF_WIDGET_HAS_INFO_LABEL);
499 widget->string16->style |= TTF_STYLE_BOLD;
500 widget->info_label = create_str16_from_char(help_text, adj_font(12));
501 widget->action = none_callback;
502 set_wstate(widget, FC_WS_NORMAL);
503 remake_label_size(widget);
504 add_to_gui_list(MAX_ID - option_number(poption), widget);
505
506 widget = NULL;
507 switch (option_type(poption)) {
508 case OT_BOOLEAN:
509 widget = create_checkbox(window->dst, option_bool_get(poption),
510 flags | WF_WIDGET_HAS_INFO_LABEL);
511 break;
512
513 case OT_INTEGER:
514 {
515 char buf[64];
516
517 fc_snprintf(buf, sizeof(buf), "%d", option_int_get(poption));
518 widget = create_edit_from_chars(NULL, window->dst, buf, adj_font(12),
519 adj_size(25),
520 flags | WF_WIDGET_HAS_INFO_LABEL);
521 }
522 break;
523
524 case OT_STRING:
525 {
526 const struct strvec *values = option_str_values(poption);
527
528 if (NULL != values) {
529 widget = combo_new_from_chars(NULL, window->dst, adj_font(12),
530 option_str_get(poption), values,
531 adj_size(25),
532 flags | WF_WIDGET_HAS_INFO_LABEL);
533 } else {
534 widget = create_edit_from_chars(NULL, window->dst,
535 option_str_get(poption),
536 adj_font(12), adj_size(25),
537 flags | WF_WIDGET_HAS_INFO_LABEL);
538 }
539 }
540 break;
541
542 case OT_ENUM:
543 {
544 const struct strvec *values = option_enum_values(poption);
545 struct strvec *translated_values = strvec_new();
546 int i;
547
548 strvec_reserve(translated_values, strvec_size(values));
549 for (i = 0; i < strvec_size(values); i++) {
550 strvec_set(translated_values, i, _(strvec_get(values, i)));
551 }
552
553 widget = combo_new_from_chars(NULL, window->dst, adj_font(12),
554 _(option_enum_get_str(poption)),
555 translated_values, adj_size(25),
556 flags | WF_WIDGET_HAS_INFO_LABEL);
557 widget->destroy = enum_widget_destroy;
558 }
559 break;
560
561 case OT_VIDEO_MODE:
562 {
563 char buf[64];
564 struct video_mode vmode = option_video_mode_get(poption);
565
566 if (!video_mode_to_string(buf, sizeof(buf), &vmode)) {
567 /* Always fails. */
568 fc_assert(video_mode_to_string(buf, sizeof(buf), &vmode));
569 }
570
571 widget = combo_new_from_chars(NULL, window->dst, adj_font(12),
572 buf, video_mode_list(), adj_size(25),
573 flags | WF_WIDGET_HAS_INFO_LABEL);
574 widget->destroy = video_mode_widget_destroy;
575 }
576 break;
577
578 case OT_BITWISE:
579 case OT_FONT:
580 case OT_COLOR:
581 log_error("Option type %s (%d) not supported yet.",
582 option_type_name(option_type(poption)),
583 option_type(poption));
584 break;
585 }
586
587 if (NULL == widget) {
588 /* Not implemented. */
589 widget = create_iconlabel_from_chars(NULL, window->dst, "",
590 adj_font(12), flags);
591 } else {
592 widget->info_label = create_str16_from_char(help_text, adj_font(12));
593 widget->action = none_callback;
594 if (option_is_changeable(poption)) {
595 set_wstate(widget, FC_WS_NORMAL);
596 }
597 }
598
599 add_to_gui_list(MAX_ID - option_number(poption), widget);
600 option_set_gui_data(poption, widget);
601
602 free(help_text);
603
604 return widget;
605 }
606
607 /****************************************************************************
608 Update the widget of the option.
609 ****************************************************************************/
option_widget_update(struct option * poption)610 static void option_widget_update(struct option *poption)
611 {
612 struct widget *widget;
613
614 fc_assert_ret(NULL != poption);
615 widget = (struct widget *) option_get_gui_data(poption);
616 fc_assert_ret(NULL != widget);
617
618 set_wstate(widget, option_is_changeable(poption)
619 ? FC_WS_NORMAL : FC_WS_DISABLED);
620
621 switch (option_type(poption)) {
622 case OT_BOOLEAN:
623 if (option_bool_get(poption) != get_checkbox_state(widget)) {
624 togle_checkbox(widget);
625 }
626 break;
627
628 case OT_INTEGER:
629 {
630 char buf[64];
631
632 fc_snprintf(buf, sizeof(buf), "%d", option_int_get(poption));
633 copy_chars_to_string16(widget->string16, buf);
634 }
635 break;
636
637 case OT_STRING:
638 copy_chars_to_string16(widget->string16, option_str_get(poption));
639 break;
640
641 case OT_ENUM:
642 copy_chars_to_string16(widget->string16,
643 _(option_enum_get_str(poption)));
644 break;
645
646 case OT_VIDEO_MODE:
647 {
648 char buf[64];
649 struct video_mode vmode = option_video_mode_get(poption);
650
651 if (video_mode_to_string(buf, sizeof(buf), &vmode)) {
652 copy_chars_to_string16(widget->string16, buf);
653 } else {
654 /* Always fails. */
655 fc_assert(video_mode_to_string(buf, sizeof(buf), &vmode));
656 }
657 }
658 break;
659
660 case OT_BITWISE:
661 case OT_FONT:
662 case OT_COLOR:
663 log_error("Option type %s (%d) not supported yet.",
664 option_type_name(option_type(poption)),
665 option_type(poption));
666 break;
667 }
668
669 widget_redraw(widget);
670 widget_mark_dirty(widget);
671 }
672
673 /****************************************************************************
674 Apply the changes for the option.
675 ****************************************************************************/
option_widget_apply(struct option * poption)676 static void option_widget_apply(struct option *poption)
677 {
678 struct widget *widget;
679
680 fc_assert_ret(NULL != poption);
681 widget = (struct widget *) option_get_gui_data(poption);
682 fc_assert_ret(NULL != widget);
683
684 switch (option_type(poption)) {
685 case OT_BOOLEAN:
686 (void) option_bool_set(poption, get_checkbox_state(widget));
687 break;
688
689 case OT_INTEGER:
690 {
691 char *str = convert_to_chars(widget->string16->text);
692 int value;
693
694 if (str_to_int(str, &value)) {
695 (void) option_int_set(poption, value);
696 }
697 free(str);
698 }
699 break;
700
701 case OT_STRING:
702 {
703 char *str = convert_to_chars(widget->string16->text);
704
705 (void) option_str_set(poption, str);
706 free(str);
707 }
708 break;
709
710 case OT_ENUM:
711 {
712 char *str = convert_to_chars(widget->string16->text);
713 int i;
714
715 /* 'str' is translated, so we cannot use directly
716 * option_enum_set_str(). */
717 for (i = 0; i < strvec_size(widget->data.vector); i++) {
718 if (0 == strcmp(strvec_get(widget->data.vector, i), str)) {
719 (void) option_enum_set_int(poption, i);
720 break;
721 }
722 }
723 free(str);
724 }
725 break;
726
727 case OT_VIDEO_MODE:
728 {
729 char *str = convert_to_chars(widget->string16->text);
730 struct video_mode mode;
731
732 if (string_to_video_mode(str, &mode)) {
733 option_video_mode_set(poption, mode);
734 } else {
735 /* Always fails. */
736 fc_assert(string_to_video_mode(str, &mode));
737 }
738 free(str);
739 }
740 break;
741
742 case OT_BITWISE:
743 case OT_FONT:
744 case OT_COLOR:
745 log_error("Option type %s (%d) not supported yet.",
746 option_type_name(option_type(poption)),
747 option_type(poption));
748 break;
749 }
750 }
751
752 /****************************************************************************
753 Return a new option dialog.
754 ****************************************************************************/
option_dialog_new(void)755 static struct option_dialog *option_dialog_new(void)
756 {
757 struct option_dialog *pdialog = fc_calloc(1, sizeof(*pdialog));
758 struct widget *window, *close_button, *widget;
759 SDL_String16 *str;
760
761 pdialog->mode = ODM_MAIN;
762
763 /* Create window widget. */
764 str = create_str16_from_char(_("Options"), adj_font(12));
765 str->style |= TTF_STYLE_BOLD;
766
767 window = create_window_skeleton(NULL, str, 0);
768 window->action = main_optiondlg_callback;
769
770 set_wstate(window, FC_WS_NORMAL);
771 add_to_gui_list(ID_OPTIONS_WINDOW, window);
772 pdialog->end_widget_list = window;
773
774 /* Create close button widget. */
775 close_button = create_themeicon(current_theme->Small_CANCEL_Icon, window->dst,
776 WF_WIDGET_HAS_INFO_LABEL
777 | WF_RESTORE_BACKGROUND);
778 close_button->info_label = create_str16_from_char(_("Close Dialog (Esc)"),
779 adj_font(12));
780 close_button->action = back_callback;
781 set_wstate(close_button, FC_WS_NORMAL);
782 close_button->key = SDLK_ESCAPE;
783 add_to_gui_list(ID_OPTIONS_BACK_BUTTON, close_button);
784 pdialog->core_widget_list = close_button;
785
786 /* Create client options button widget. */
787 widget = create_icon_button_from_chars(NULL, window->dst,
788 _("Local options"),
789 adj_font(12), 0);
790 widget->action = client_options_callback;
791 set_wstate(widget, FC_WS_NORMAL);
792 widget_resize(widget, widget->size.w, widget->size.h + adj_size(4));
793 add_to_gui_list(ID_OPTIONS_CLIENT_BUTTON, widget);
794
795 /* Create server options button widget. */
796 widget = create_icon_button_from_chars(NULL, window->dst,
797 _("Server options"),
798 adj_font(12), 0);
799 widget->action = server_options_callback;
800 if (client.conn.established) {
801 set_wstate(widget, FC_WS_NORMAL);
802 }
803 widget_resize(widget, widget->size.w, widget->size.h + adj_size(4));
804 add_to_gui_list(ID_OPTIONS_SERVER_BUTTON, widget);
805
806 /* Create global worklists button widget. */
807 widget = create_icon_button_from_chars(NULL, window->dst,
808 _("Worklists"), adj_font(12), 0);
809 widget->action = work_lists_callback;
810 if (C_S_RUNNING == client_state()) {
811 set_wstate(widget, FC_WS_NORMAL);
812 }
813 widget_resize(widget, widget->size.w, widget->size.h + adj_size(4));
814 add_to_gui_list(ID_OPTIONS_WORKLIST_BUTTON, widget);
815
816 /* Create save game button widget. */
817 widget = create_icon_button_from_chars(NULL, window->dst,
818 _("Save Local Options"),
819 adj_font(12), 0);
820 widget->action = save_client_options_callback;
821 set_wstate(widget, FC_WS_NORMAL);
822 widget_resize(widget, widget->size.w, widget->size.h + adj_size(4));
823 add_to_gui_list(ID_OPTIONS_SAVE_BUTTON, widget);
824
825 /* Create save game button widget. */
826 widget = create_icon_button_from_chars(NULL, window->dst,
827 _("Save Game"), adj_font(12), 0);
828 widget->action = save_game_callback;
829 if (C_S_RUNNING == client_state()) {
830 set_wstate(widget, FC_WS_NORMAL);
831 }
832 widget_resize(widget, widget->size.w, widget->size.h + adj_size(4));
833 add_to_gui_list(ID_OPTIONS_SAVE_GAME_BUTTON, widget);
834
835 /* Create help browser button widget. */
836 widget = create_icon_button_from_chars(NULL, window->dst,
837 _("Help Browser"), adj_font(12), 0);
838 widget->action = help_browser_callback;
839 widget->key = SDLK_h;
840 if (client.conn.established) {
841 set_wstate(widget, FC_WS_NORMAL);
842 }
843 widget_resize(widget, widget->size.w, widget->size.h + adj_size(4));
844 add_to_gui_list(ID_OPTIONS_HELP_BROWSER_BUTTON, widget);
845
846 /* Create leave game button widget. */
847 widget = create_icon_button_from_chars(NULL, window->dst,
848 _("Leave Game"), adj_font(12), 0);
849 widget->action = disconnect_callback;
850 widget->key = SDLK_q;
851 if (client.conn.established) {
852 set_wstate(widget, FC_WS_NORMAL);
853 }
854 widget_resize(widget, widget->size.w, widget->size.h + adj_size(4));
855 add_to_gui_list(ID_OPTIONS_DISC_BUTTON, widget);
856
857 /* Create quit widget button. */
858 widget = create_icon_button_from_chars(NULL, window->dst,
859 _("Quit"), adj_font(12), 0);
860 widget->action = exit_callback;
861 widget->key = SDLK_q;
862 set_wstate(widget, FC_WS_NORMAL);
863 widget_resize(widget, widget->size.w, widget->size.h + adj_size(4));
864 add_to_gui_list(ID_OPTIONS_EXIT_BUTTON, widget);
865
866 pdialog->begin_widget_list = widget;
867 pdialog->main_widget_list = widget;
868
869 arrange_widgets(window, 1, -1, widget, pdialog->core_widget_list,
870 pdialog->core_widget_list, NULL);
871
872 return pdialog;
873 }
874
875 /****************************************************************************
876 Destroys an option dialog.
877 ****************************************************************************/
option_dialog_destroy(struct option_dialog * pdialog)878 static void option_dialog_destroy(struct option_dialog *pdialog)
879 {
880 fc_assert_ret(NULL != pdialog);
881
882 if (ODM_OPTSET == pdialog->mode && -1 != pdialog->optset.category) {
883 options_iterate(pdialog->optset.poptset, poption) {
884 if (pdialog->optset.category == option_category(poption)) {
885 option_set_gui_data(poption, NULL);
886 }
887 } options_iterate_end;
888 }
889
890 if (NULL != pdialog->advanced) {
891 free(pdialog->advanced->pScroll);
892 free(pdialog->advanced);
893 }
894
895 popdown_window_group_dialog(pdialog->begin_widget_list,
896 pdialog->end_widget_list);
897
898 free(pdialog);
899 }
900
901 /****************************************************************************
902 Return the number of options of the category.
903 ****************************************************************************/
optset_category_option_count(const struct option_set * poptset,int category)904 static int optset_category_option_count(const struct option_set *poptset,
905 int category)
906 {
907 int count = 0;
908
909 options_iterate(poptset, poption) {
910 if (category == option_category(poption)) {
911 count++;
912 }
913 } options_iterate_end;
914 return count;
915 }
916
917 /****************************************************************************
918 Initialize a option set page.
919 ****************************************************************************/
option_dialog_optset(struct option_dialog * pdialog,const struct option_set * poptset)920 static void option_dialog_optset(struct option_dialog *pdialog,
921 const struct option_set *poptset)
922 {
923 struct option_dialog_optset *poptset_dialog;
924 struct widget *window;
925 struct widget *widget = NULL;
926 int i, category_num;
927
928 fc_assert_ret(NULL != pdialog);
929 fc_assert_ret(NULL != poptset);
930 category_num = optset_category_number(poptset);
931 fc_assert_ret(0 < category_num);
932
933 poptset_dialog = &pdialog->optset;
934 pdialog->mode = ODM_OPTSET;
935 poptset_dialog->poptset = poptset;
936 poptset_dialog->category = -1;
937
938 window = pdialog->end_widget_list;
939
940 /* Hide ODM_MAIN widget group. */
941 hide_group(pdialog->main_widget_list, pdialog->core_widget_list->prev);
942
943 /* Otherwise we don't enter next loop at all, and widget will remain NULL */
944 fc_assert(category_num > 0);
945
946 /* Make the category buttons. */
947 for (i = 0; i < category_num; i++) {
948 if (0 == optset_category_option_count(poptset, i)) {
949 continue;
950 }
951
952 widget = create_icon_button_from_chars(NULL, window->dst,
953 optset_category_name(poptset, i),
954 adj_font(12), 0);
955 widget->action = option_category_callback;
956 set_wstate(widget, FC_WS_NORMAL);
957 widget_resize(widget, widget->size.w, widget->size.h + adj_size(4));
958 add_to_gui_list(MAX_ID - i, widget);
959 }
960
961 poptset_dialog->widget_list = widget;
962 pdialog->begin_widget_list = widget;
963
964 arrange_widgets(window, 1, -1, widget, pdialog->main_widget_list,
965 pdialog->core_widget_list, NULL);
966 }
967
968 /****************************************************************************
969 Initialize a option set category page.
970 ****************************************************************************/
option_dialog_optset_category(struct option_dialog * pdialog,int category)971 static void option_dialog_optset_category(struct option_dialog *pdialog,
972 int category)
973 {
974 struct option_dialog_optset *poptset_dialog;
975 const struct option_set *poptset;
976 struct widget *window, *widget = NULL, *apply_button;
977 const int MAX_SHOWN = 10;
978 SDL_Rect area;
979 int i;
980
981 fc_assert_ret(NULL != pdialog);
982 fc_assert_ret(ODM_OPTSET == pdialog->mode);
983 fc_assert_ret(NULL == pdialog->advanced);
984 poptset_dialog = &pdialog->optset;
985 poptset = poptset_dialog->poptset;
986 fc_assert_ret(0 < optset_category_option_count(poptset, category));
987
988 /* Hide ODM_OPTSET widget group. */
989 hide_group(poptset_dialog->widget_list, pdialog->main_widget_list->prev);
990
991 poptset_dialog->category = category;
992 window = pdialog->end_widget_list;
993
994 /* Create the apply button. */
995 apply_button = create_themeicon(current_theme->Small_OK_Icon, window->dst,
996 WF_WIDGET_HAS_INFO_LABEL
997 | WF_RESTORE_BACKGROUND);
998 apply_button->info_label = create_str16_from_char(_("Apply changes"),
999 adj_font(12));
1000 apply_button->action = apply_callback;
1001 set_wstate(apply_button, FC_WS_NORMAL);
1002 add_to_gui_list(ID_OPTIONS_APPLY_BUTTON, apply_button);
1003
1004 /* Create the option widgets. */
1005 i = 0;
1006 options_iterate(poptset, poption) {
1007 if (category != option_category(poption)) {
1008 continue;
1009 }
1010
1011 widget = option_widget_new(poption, window, i >= MAX_SHOWN);
1012 i++;
1013 } options_iterate_end;
1014
1015 /* Scrollbar. */
1016 pdialog->advanced = fc_calloc(1, sizeof(*pdialog->advanced));
1017 pdialog->advanced->pEndWidgetList = pdialog->end_widget_list;
1018 pdialog->advanced->pEndActiveWidgetList = apply_button->prev;
1019 pdialog->advanced->pBeginWidgetList = widget;
1020 pdialog->advanced->pBeginActiveWidgetList = widget;
1021
1022 create_vertical_scrollbar(pdialog->advanced, 2, MAX_SHOWN, TRUE, TRUE);
1023
1024 if (i >= MAX_SHOWN) {
1025 pdialog->advanced->pActiveWidgetList =
1026 pdialog->advanced->pEndActiveWidgetList;
1027 } else {
1028 hide_scrollbar(pdialog->advanced->pScroll);
1029 }
1030
1031 pdialog->begin_widget_list = pdialog->advanced->pBeginWidgetList;
1032
1033 arrange_widgets(window, 2, MAX_SHOWN,
1034 pdialog->advanced->pBeginActiveWidgetList,
1035 apply_button, pdialog->core_widget_list,
1036 apply_button, NULL);
1037
1038 area = window->area;
1039 setup_vertical_scrollbar_area(pdialog->advanced->pScroll,
1040 area.x + area.w - 1, area.y + 1,
1041 area.h - adj_size(32), TRUE);
1042
1043 redraw_group(pdialog->begin_widget_list,
1044 pdialog->advanced->pActiveWidgetList, 0);
1045 widget_flush(window);
1046 }
1047
1048
1049 /****************************************************************************
1050 Clicked on a global worklist name.
1051 ****************************************************************************/
edit_worklist_callback(struct widget * widget)1052 static int edit_worklist_callback(struct widget *widget)
1053 {
1054 struct global_worklist *pgwl = global_worklist_by_id(MAX_ID - widget->ID);
1055
1056 if (NULL == option_dialog
1057 || ODM_WORKLIST != option_dialog->mode
1058 || NULL == pgwl) {
1059 return -1;
1060 }
1061
1062 if (Main.event.type == SDL_MOUSEBUTTONDOWN) {
1063 switch (Main.event.button.button) {
1064 case SDL_BUTTON_LEFT:
1065 /* Edit. */
1066 option_dialog->worklist.edited_name = widget;
1067 popup_worklist_editor(NULL, pgwl);
1068 break;
1069
1070 case SDL_BUTTON_RIGHT:
1071 {
1072 /* Delete. */
1073 struct ADVANCED_DLG *advanced = option_dialog->advanced;
1074 bool scroll = (NULL != advanced->pActiveWidgetList);
1075
1076 global_worklist_destroy(pgwl);
1077 del_widget_from_vertical_scroll_widget_list(advanced, widget);
1078
1079 /* Find if there was scrollbar hide. */
1080 if (scroll && advanced->pActiveWidgetList == NULL) {
1081 int len = advanced->pScroll->pUp_Left_Button->size.w;
1082
1083 widget = advanced->pEndActiveWidgetList->next;
1084 do {
1085 widget = widget->prev;
1086 widget->size.w += len;
1087 FREESURFACE(widget->gfx);
1088 } while(widget != advanced->pBeginActiveWidgetList);
1089 }
1090
1091 redraw_group(option_dialog->begin_widget_list,
1092 option_dialog->end_widget_list, 0);
1093 widget_mark_dirty(option_dialog->end_widget_list);
1094 flush_dirty();
1095 }
1096 break;
1097 }
1098 }
1099
1100 return -1;
1101 }
1102
1103
1104 /****************************************************************************
1105 Callback to append a global worklist.
1106 ****************************************************************************/
add_new_worklist_callback(struct widget * widget)1107 static int add_new_worklist_callback(struct widget *widget)
1108 {
1109 if (Main.event.button.button == SDL_BUTTON_LEFT) {
1110 struct widget *new_worklist_widget = NULL;
1111 struct widget *window = option_dialog->end_widget_list;
1112 struct global_worklist *pgwl = global_worklist_new(_("empty worklist"));
1113 struct ADVANCED_DLG *advanced = option_dialog->advanced;
1114 bool scroll = advanced->pActiveWidgetList == NULL;
1115 bool redraw_all = FALSE;
1116
1117 set_wstate(widget, FC_WS_NORMAL);
1118 pSellected_Widget = NULL;
1119
1120 /* Create list element. */
1121 new_worklist_widget =
1122 create_iconlabel_from_chars(NULL, widget->dst,
1123 global_worklist_name(pgwl),
1124 adj_font(12), WF_RESTORE_BACKGROUND);
1125 new_worklist_widget->ID = MAX_ID - global_worklist_id(pgwl);
1126 new_worklist_widget->string16->style |= SF_CENTER;
1127 set_wstate(new_worklist_widget, FC_WS_NORMAL);
1128 new_worklist_widget->size.w = widget->size.w;
1129 new_worklist_widget->action = edit_worklist_callback;
1130
1131 /* Add to widget list. */
1132 redraw_all = add_widget_to_vertical_scroll_widget_list(advanced,
1133 new_worklist_widget, widget, TRUE,
1134 window->area.x + adj_size(17),
1135 window->area.y + adj_size(17));
1136
1137 /* Find if there was scrollbar shown. */
1138 if (scroll && advanced->pActiveWidgetList != NULL) {
1139 int len = advanced->pScroll->pUp_Left_Button->size.w;
1140
1141 window = advanced->pEndActiveWidgetList->next;
1142 do {
1143 window = window->prev;
1144 window->size.w -= len;
1145 window->area.w -= len;
1146 FREESURFACE(window->gfx);
1147 } while(window != advanced->pBeginActiveWidgetList);
1148 }
1149
1150 if (redraw_all) {
1151 redraw_group(option_dialog->begin_widget_list,
1152 option_dialog->end_widget_list, 0);
1153 widget_mark_dirty(option_dialog->end_widget_list);
1154 } else {
1155 /* Redraw only new widget and dock widget. */
1156 if (!widget->gfx && (get_wflags(widget) & WF_RESTORE_BACKGROUND)) {
1157 refresh_widget_background(widget);
1158 }
1159 widget_redraw(widget);
1160 widget_mark_dirty(widget);
1161
1162 if (!new_worklist_widget->gfx &&
1163 (get_wflags(new_worklist_widget) & WF_RESTORE_BACKGROUND)) {
1164 refresh_widget_background(new_worklist_widget);
1165 }
1166 widget_redraw(new_worklist_widget);
1167 widget_mark_dirty(new_worklist_widget);
1168 }
1169 flush_dirty();
1170 }
1171 return -1;
1172 }
1173
1174 /****************************************************************************
1175 The Worklist Report part of Options dialog shows all the global worklists
1176 that the player has defined.
1177 ****************************************************************************/
option_dialog_worklist(struct option_dialog * pdialog)1178 static void option_dialog_worklist(struct option_dialog *pdialog)
1179 {
1180 SDL_Color bg_color = {255, 255, 255, 128};
1181 struct widget *widget, *window, *background;
1182 int count = 0, scrollbar_width = 0, longest = 0;
1183 SDL_Rect area;
1184
1185 pdialog->mode = ODM_WORKLIST;
1186 pdialog->worklist.edited_name = NULL;
1187 window = pdialog->end_widget_list;
1188
1189 /* Hide main widget group. */
1190 hide_group(pdialog->main_widget_list, pdialog->core_widget_list->prev);
1191
1192 /* Create white background. */
1193 background = create_iconlabel(NULL, window->dst, NULL, WF_FREE_THEME);
1194 add_to_gui_list(ID_LABEL, background);
1195
1196 /* Build the global worklists list. */
1197 global_worklists_iterate(pgwl) {
1198 widget = create_iconlabel_from_chars(NULL, window->dst,
1199 global_worklist_name(pgwl),
1200 adj_font(12),
1201 WF_RESTORE_BACKGROUND);
1202 set_wstate(widget, FC_WS_NORMAL);
1203 add_to_gui_list(MAX_ID - global_worklist_id(pgwl), widget);
1204 widget->action = edit_worklist_callback;
1205 widget->string16->style |= SF_CENTER;
1206 longest = MAX(longest, widget->size.w);
1207 count++;
1208
1209 if (count > 13) {
1210 set_wflag(widget, WF_HIDDEN);
1211 }
1212 } global_worklists_iterate_end;
1213
1214 /* Create the adding item. */
1215 widget = create_iconlabel_from_chars(NULL, window->dst,
1216 _("Add new worklist"), adj_font(12),
1217 WF_RESTORE_BACKGROUND);
1218 set_wstate(widget, FC_WS_NORMAL);
1219 add_to_gui_list(ID_ADD_NEW_WORKLIST, widget);
1220 widget->action = add_new_worklist_callback;
1221 widget->string16->style |= SF_CENTER;
1222 longest = MAX(longest, widget->size.w);
1223 count++;
1224
1225 if (count > 13) {
1226 set_wflag(widget, WF_HIDDEN);
1227 }
1228
1229 /* Advanced dialog. */
1230 pdialog->advanced = fc_calloc(1, sizeof(*pdialog->advanced));
1231 pdialog->advanced->pEndWidgetList = pdialog->end_widget_list;
1232 pdialog->advanced->pEndActiveWidgetList =
1233 pdialog->main_widget_list->prev->prev;
1234 pdialog->advanced->pBeginWidgetList = widget;
1235 pdialog->advanced->pBeginActiveWidgetList = widget;
1236
1237 /* Clear former area. */
1238 area = window->area;
1239 area.w += window->size.x;
1240 area.h += window->size.y;
1241 sdl_dirty_rect(area);
1242
1243 /* Resize window. */
1244 resize_window(window, NULL, NULL,
1245 adj_size(longest + 40), window->size.h);
1246 area = window->area;
1247
1248 /* Move close button. */
1249 widget = pdialog->core_widget_list;
1250 widget_set_position(widget, area.x + area.w - widget->size.w - 1,
1251 window->size.y + adj_size(2));
1252
1253 /* Resize white background. */
1254 area.x += adj_size(12);
1255 area.y += adj_size(12);
1256 area.w -= adj_size(12) + adj_size(12);
1257 area.h -= adj_size(12) + adj_size(12);
1258 background->theme = create_surf_alpha(area.w, area.h, SDL_SWSURFACE);
1259 widget_set_area(background, area);
1260 widget_set_position(background, area.x, area.y);
1261 SDL_FillRect(background->theme, NULL,
1262 map_rgba(background->theme->format, bg_color));
1263 putframe(background->theme,
1264 0, 0, background->theme->w - 1, background->theme->h - 1,
1265 get_theme_color(COLOR_THEME_OPTIONDLG_WORKLISTLIST_FRAME));
1266
1267 /* Create the Scrollbar. */
1268 scrollbar_width = create_vertical_scrollbar(pdialog->advanced,
1269 1, 13, TRUE, TRUE);
1270 setup_vertical_scrollbar_area(pdialog->advanced->pScroll,
1271 area.x + area.w - 1, area.y + 1,
1272 area.h - adj_size(32), TRUE);
1273
1274 if (count > 13) {
1275 pdialog->advanced->pActiveWidgetList =
1276 pdialog->advanced->pEndActiveWidgetList;
1277 } else {
1278 hide_scrollbar(pdialog->advanced->pScroll);
1279 scrollbar_width = 0;
1280 }
1281
1282 /* Draw! */
1283 setup_vertical_widgets_position(1, area.x + adj_size(5),
1284 area.y + adj_size(5),
1285 area.w - adj_size(10) - scrollbar_width, 0,
1286 pdialog->advanced->pBeginActiveWidgetList,
1287 pdialog->advanced->pEndActiveWidgetList);
1288
1289 pdialog->begin_widget_list = pdialog->advanced->pBeginWidgetList;
1290
1291 redraw_group(pdialog->begin_widget_list, pdialog->end_widget_list, 0);
1292 widget_flush(window);
1293 }
1294
1295 /**************************************************************************
1296 ...
1297 **************************************************************************/
optiondlg_callback(struct widget * pButton)1298 int optiondlg_callback(struct widget *pButton)
1299 {
1300 if (Main.event.button.button == SDL_BUTTON_LEFT) {
1301 set_wstate(pButton, FC_WS_DISABLED);
1302 clear_surface(pButton->dst->surface, &pButton->size);
1303 widget_redraw(pButton);
1304 widget_flush(pButton);
1305
1306 popup_optiondlg();
1307 }
1308 return -1;
1309 }
1310
1311 /* ===================================================================== */
1312 /* =================================== Public ========================== */
1313 /* ===================================================================== */
1314
enable_options_button(void)1315 void enable_options_button(void)
1316 {
1317 set_wstate(pOptions_Button, FC_WS_NORMAL);
1318 }
1319
disable_options_button(void)1320 void disable_options_button(void)
1321 {
1322 set_wstate(pOptions_Button, FC_WS_DISABLED);
1323 }
1324
init_options_button(void)1325 void init_options_button(void)
1326 {
1327 char buf[256];
1328
1329 pOptions_Button = create_themeicon(current_theme->Options_Icon, Main.gui,
1330 WF_WIDGET_HAS_INFO_LABEL
1331 | WF_RESTORE_BACKGROUND);
1332 pOptions_Button->action = optiondlg_callback;
1333 fc_snprintf(buf, sizeof(buf), "%s (%s)", _("Options"), "Esc");
1334 pOptions_Button->info_label = create_str16_from_char(buf, adj_font(12));
1335 pOptions_Button->key = SDLK_ESCAPE;
1336 set_wflag(pOptions_Button, WF_HIDDEN);
1337 widget_set_position(pOptions_Button, adj_size(5), adj_size(5));
1338
1339 #ifndef SMALL_SCREEN
1340 add_to_gui_list(ID_CLIENT_OPTIONS, pOptions_Button);
1341 #endif
1342
1343 enable_options_button();
1344 }
1345
1346 /**************************************************************************
1347 If the Options Dlg is open, force Worklist List contents to be updated.
1348 This function is call by exiting worklist editor to update changed
1349 worklist name in global worklist report ( Options Dlg )
1350 **************************************************************************/
update_worklist_report_dialog(void)1351 void update_worklist_report_dialog(void)
1352 {
1353 struct global_worklist *pgwl;
1354
1355 if (NULL != option_dialog && ODM_WORKLIST == option_dialog->mode) {
1356 pgwl = global_worklist_by_id(MAX_ID
1357 - option_dialog->worklist.edited_name->ID);
1358
1359 if (NULL != pgwl) {
1360 copy_chars_to_string16(option_dialog->worklist.edited_name->string16,
1361 global_worklist_name(pgwl));
1362 option_dialog->worklist.edited_name = NULL;
1363 }
1364
1365 redraw_group(option_dialog->begin_widget_list,
1366 option_dialog->end_widget_list, 0);
1367 widget_mark_dirty(option_dialog->end_widget_list);
1368 }
1369 }
1370
1371 /****************************************************************************
1372 Popup the main option menu dialog.
1373 ****************************************************************************/
popup_optiondlg(void)1374 void popup_optiondlg(void)
1375 {
1376 if (NULL != option_dialog) {
1377 return;
1378 }
1379
1380 restore_meswin_dialog = meswin_dialog_is_open();
1381 popdown_all_game_dialogs();
1382 flush_dirty();
1383
1384 option_dialog = option_dialog_new();
1385
1386 disable_main_widgets();
1387 flush_dirty();
1388 }
1389
1390 /**************************************************************************
1391 Close option dialog.
1392 **************************************************************************/
popdown_optiondlg(bool leave_game)1393 void popdown_optiondlg(bool leave_game)
1394 {
1395 if (NULL == option_dialog) {
1396 return;
1397 }
1398
1399 option_dialog_destroy(option_dialog);
1400 option_dialog = NULL;
1401
1402 if (!leave_game) {
1403 enable_main_widgets();
1404 }
1405
1406 if (restore_meswin_dialog) {
1407 meswin_dialog_popup(TRUE);
1408 }
1409 }
1410
1411 /****************************************************************************
1412 Popup the option dialog for the option set.
1413 ****************************************************************************/
option_dialog_popup(const char * name,const struct option_set * poptset)1414 void option_dialog_popup(const char *name, const struct option_set *poptset)
1415 {
1416 if (NULL == option_dialog) {
1417 popup_optiondlg();
1418 } else if (ODM_OPTSET == option_dialog->mode
1419 && poptset == option_dialog->optset.poptset) {
1420 /* Already in use. */
1421 return;
1422 } else {
1423 while (ODM_MAIN != option_dialog->mode) {
1424 back_callback(NULL);
1425 }
1426 }
1427
1428 option_dialog_optset(option_dialog, poptset);
1429 }
1430
1431 /****************************************************************************
1432 Popdown the option dialog for the option set.
1433 ****************************************************************************/
option_dialog_popdown(const struct option_set * poptset)1434 void option_dialog_popdown(const struct option_set *poptset)
1435 {
1436 while (NULL != option_dialog
1437 && ODM_OPTSET == option_dialog->mode
1438 && poptset == option_dialog->optset.poptset) {
1439 back_callback(NULL);
1440 }
1441 }
1442
1443 /****************************************************************************
1444 Update the GUI for the option.
1445 ****************************************************************************/
option_gui_update(struct option * poption)1446 void option_gui_update(struct option *poption)
1447 {
1448 if (NULL != option_dialog
1449 && ODM_OPTSET == option_dialog->mode
1450 && option_optset(poption) == option_dialog->optset.poptset
1451 && option_category(poption) == option_dialog->optset.category) {
1452 option_widget_update(poption);
1453 }
1454
1455 if (!strcmp(option_name(poption), "nationset")) {
1456 nationset_changed();
1457 }
1458 }
1459
1460 /****************************************************************************
1461 Add the GUI for the option.
1462 ****************************************************************************/
option_gui_add(struct option * poption)1463 void option_gui_add(struct option *poption)
1464 {
1465 if (NULL != option_dialog
1466 && ODM_OPTSET == option_dialog->mode
1467 && option_optset(poption) == option_dialog->optset.poptset
1468 && option_category(poption) == option_dialog->optset.category) {
1469 back_callback(NULL);
1470 option_dialog_optset_category(option_dialog, option_category(poption));
1471 }
1472 }
1473
1474 /****************************************************************************
1475 Remove the GUI for the option.
1476 ****************************************************************************/
option_gui_remove(struct option * poption)1477 void option_gui_remove(struct option *poption)
1478 {
1479 if (NULL != option_dialog
1480 && ODM_OPTSET == option_dialog->mode
1481 && option_optset(poption) == option_dialog->optset.poptset
1482 && option_category(poption) == option_dialog->optset.category) {
1483 back_callback(NULL);
1484 option_dialog_optset_category(option_dialog, option_category(poption));
1485 }
1486 }
1487