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)
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 ***********************************************************************/
14 /***********************************************************************
15 dialogs.c - description
17 begin : Wed Jul 24 2002
18 copyright : (C) 2002 by Rafał Bursig
19 email : Rafał Bursig <bursig@poczta.fm>
20 ***********************************************************************/
23 #include <fc_config.h>
27 #ifdef SDL2_PLAIN_INCLUDE
29 #else /* SDL2_PLAIN_INCLUDE */
31 #endif /* SDL2_PLAIN_INCLUDE */
34 #include "bitvector.h"
42 #include "government.h"
47 #include "client_main.h"
48 #include "climap.h" /* for client_tile_get_known() */
50 #include "helpdata.h" /* for helptext_nation() */
63 #include "gui_iconv.h"
66 #include "gui_tilespec.h"
72 #include "messagewin.h"
73 #include "optiondlg.h"
78 #include "themespec.h"
84 struct player
*races_player
;
86 extern bool is_unit_move_blocked
;
87 extern void popdown_diplomat_dialog(void);
88 extern void popdown_incite_dialog(void);
89 extern void popdown_bribe_dialog(void);
91 void popdown_advanced_terrain_dialog(void);
92 int advanced_terrain_window_dlg_callback(struct widget
*pWindow
);
93 int exit_advanced_terrain_dlg_callback(struct widget
*pWidget
);
95 static char *pLeaderName
= NULL
;
97 static void unit_select_dialog_popdown(void);
98 static void popdown_terrain_info_dialog(void);
99 static void popdown_pillage_dialog(void);
100 static void popdown_connect_dialog(void);
101 static void popdown_revolution_dialog(void);
102 static void popdown_unit_upgrade_dlg(void);
103 static void popdown_unit_disband_dlg(void);
105 /**********************************************************************
106 Place window near given tile on screen.
107 ***********************************************************************/
108 void put_window_near_map_tile(struct widget
*pWindow
,
109 int window_width
, int window_height
,
112 float canvas_x
, canvas_y
;
113 int window_x
= 0, window_y
= 0;
115 if (tile_to_canvas_pos(&canvas_x
, &canvas_y
, ptile
)) {
116 if (canvas_x
+ tileset_tile_width(tileset
) + window_width
>= main_window_width()) {
117 if (canvas_x
- window_width
< 0) {
118 window_x
= (main_window_width() - window_width
) / 2;
120 window_x
= canvas_x
- window_width
;
123 window_x
= canvas_x
+ tileset_tile_width(tileset
);
126 canvas_y
+= (tileset_tile_height(tileset
) - window_height
) / 2;
127 if (canvas_y
+ window_height
>= main_window_height()) {
128 window_y
= main_window_height() - window_height
- 1;
137 window_x
= (main_window_width() - window_width
) / 2;
138 window_y
= (main_window_height() - window_height
) / 2;
141 widget_set_position(pWindow
, window_x
, window_y
);
144 /**********************************************************************
145 This function is called when the client disconnects or the game is
146 over. It should close all dialog windows for that game.
147 ***********************************************************************/
148 void popdown_all_game_dialogs(void)
150 unit_select_dialog_popdown();
151 popdown_advanced_terrain_dialog();
152 popdown_terrain_info_dialog();
153 popdown_newcity_dialog();
154 popdown_optiondlg(TRUE
);
155 undraw_order_widgets();
156 popdown_diplomat_dialog();
157 popdown_pillage_dialog();
158 popdown_incite_dialog();
159 popdown_connect_dialog();
160 popdown_bribe_dialog();
161 popdown_find_dialog();
162 popdown_revolution_dialog();
163 science_report_dialogs_popdown_all();
164 meswin_dialog_popdown();
165 popdown_worklist_editor();
166 popdown_all_city_dialogs();
167 city_report_dialog_popdown();
168 economy_report_dialog_popdown();
169 units_report_dialog_popdown();
170 popdown_intel_dialogs();
171 popdown_players_nations_dialog();
172 popdown_players_dialog();
173 popdown_goto_airlift_dialog();
174 popdown_unit_upgrade_dlg();
175 popdown_unit_disband_dlg();
176 popdown_help_dialog();
177 popdown_notify_goto_dialog();
179 /* clear gui buffer */
180 if (C_S_PREPARING
== client_state()) {
181 clear_surface(Main
.gui
->surface
, NULL
);
185 /* ======================================================================= */
187 /**************************************************************************
188 Find the my unit's (focus) chance of success at attacking/defending the
189 given enemy unit. Return FALSE if the values cannot be determined (e.g., no
191 **************************************************************************/
192 static bool sdl_get_chance_to_win(int *att_chance
, int *def_chance
,
193 struct unit
*enemy_unit
, struct unit
*my_unit
)
195 if (!my_unit
|| !enemy_unit
) {
199 /* chance to win when active unit is attacking the selected unit */
200 *att_chance
= unit_win_chance(my_unit
, enemy_unit
) * 100;
202 /* chance to win when selected unit is attacking the active unit */
203 *def_chance
= (1.0 - unit_win_chance(enemy_unit
, my_unit
)) * 100;
208 /**************************************************************************
210 **************************************************************************/
211 struct notify_goto_data
{
217 #define SPECLIST_TAG notify_goto
218 #define SPECLIST_TYPE struct notify_goto_data
219 #include "speclist.h"
221 struct notify_goto_dialog
{
222 struct widget
*window
;
223 struct widget
*close_button
;
224 struct widget
*label
;
225 struct notify_goto_list
*datas
;
228 static struct notify_goto_dialog
*notify_goto_dialog
= NULL
;
230 static void notify_goto_dialog_advance(struct notify_goto_dialog
*pdialog
);
232 /**************************************************************************
233 Create a notify goto data.
234 **************************************************************************/
235 static struct notify_goto_data
*notify_goto_data_new(const char *headline
,
239 struct notify_goto_data
*pdata
= fc_malloc(sizeof(*pdata
));
241 pdata
->headline
= fc_strdup(headline
);
242 pdata
->lines
= fc_strdup(lines
);
243 pdata
->ptile
= ptile
;
248 /**************************************************************************
249 Destroy a notify goto data.
250 **************************************************************************/
251 static void notify_goto_data_destroy(struct notify_goto_data
*pdata
)
253 free(pdata
->headline
);
257 /**************************************************************************
258 Move the notify dialog.
259 **************************************************************************/
260 static int notify_goto_dialog_callback(struct widget
*widget
)
262 struct notify_goto_dialog
*pdialog
=
263 (struct notify_goto_dialog
*) widget
->data
.ptr
;
265 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
266 move_window_group(pdialog
->label
, pdialog
->window
);
272 /**************************************************************************
273 Close the notify dialog.
274 **************************************************************************/
275 static int notify_goto_dialog_close_callback(struct widget
*widget
)
277 struct notify_goto_dialog
*pdialog
=
278 (struct notify_goto_dialog
*) widget
->data
.ptr
;
280 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
281 notify_goto_dialog_advance(pdialog
);
287 /**************************************************************************
289 **************************************************************************/
290 static int notify_goto_dialog_goto_callback(struct widget
*widget
)
292 struct notify_goto_dialog
*pdialog
=
293 (struct notify_goto_dialog
*) widget
->data
.ptr
;
294 const struct notify_goto_data
*pdata
= notify_goto_list_get(pdialog
->datas
,
297 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
298 if (NULL
!= pdata
->ptile
) {
299 center_tile_mapcanvas(pdata
->ptile
);
301 } else if (Main
.event
.button
.button
== SDL_BUTTON_RIGHT
) {
304 if (NULL
!= pdata
->ptile
&& (pcity
= tile_city(pdata
->ptile
))) {
305 popup_city_dialog(pcity
);
312 /**************************************************************************
313 Create a notify dialog.
314 **************************************************************************/
315 static struct notify_goto_dialog
*notify_goto_dialog_new(void)
317 struct notify_goto_dialog
*pdialog
= fc_malloc(sizeof(*pdialog
));
321 str
= create_utf8_from_char("", adj_font(12));
322 str
->style
|= TTF_STYLE_BOLD
;
324 pdialog
->window
= create_window_skeleton(NULL
, str
, 0);
325 pdialog
->window
->action
= notify_goto_dialog_callback
;
326 pdialog
->window
->data
.ptr
= pdialog
;
327 set_wstate(pdialog
->window
, FC_WS_NORMAL
);
328 add_to_gui_list(ID_WINDOW
, pdialog
->window
);
331 pdialog
->close_button
= create_themeicon(current_theme
->Small_CANCEL_Icon
,
332 pdialog
->window
->dst
,
333 WF_WIDGET_HAS_INFO_LABEL
334 | WF_RESTORE_BACKGROUND
);
335 pdialog
->close_button
->info_label
=
336 create_utf8_from_char(_("Close Dialog (Esc)"), adj_font(12));
337 pdialog
->close_button
->action
= notify_goto_dialog_close_callback
;
338 pdialog
->close_button
->data
.ptr
= pdialog
;
339 set_wstate(pdialog
->close_button
, FC_WS_NORMAL
);
340 pdialog
->close_button
->key
= SDLK_ESCAPE
;
341 add_to_gui_list(ID_BUTTON
, pdialog
->close_button
);
343 pdialog
->label
= NULL
;
346 pdialog
->datas
= notify_goto_list_new_full(notify_goto_data_destroy
);
351 /**************************************************************************
352 Destroy a notify dialog.
353 **************************************************************************/
354 static void notify_goto_dialog_destroy(struct notify_goto_dialog
*pdialog
)
356 widget_undraw(pdialog
->window
);
357 widget_mark_dirty(pdialog
->window
);
358 remove_gui_layer(pdialog
->window
->dst
);
360 del_widget_pointer_from_gui_list(pdialog
->window
);
361 del_widget_pointer_from_gui_list(pdialog
->close_button
);
362 if (NULL
!= pdialog
->label
) {
363 del_widget_pointer_from_gui_list(pdialog
->label
);
366 notify_goto_list_destroy(pdialog
->datas
);
370 /**************************************************************************
371 Update a notify dialog.
372 **************************************************************************/
373 static void notify_goto_dialog_update(struct notify_goto_dialog
*pdialog
)
375 const struct notify_goto_data
*pdata
= notify_goto_list_get(pdialog
->datas
,
382 widget_undraw(pdialog
->window
);
383 widget_mark_dirty(pdialog
->window
);
385 copy_chars_to_utf8_str(pdialog
->window
->string_utf8
, pdata
->headline
);
386 if (NULL
!= pdialog
->label
) {
387 del_widget_pointer_from_gui_list(pdialog
->label
);
389 pdialog
->label
= create_iconlabel_from_chars(NULL
, pdialog
->window
->dst
,
390 pdata
->lines
, adj_font(12),
391 WF_RESTORE_BACKGROUND
);
392 pdialog
->label
->action
= notify_goto_dialog_goto_callback
;
393 pdialog
->label
->data
.ptr
= pdialog
;
394 set_wstate(pdialog
->label
, FC_WS_NORMAL
);
395 add_to_gui_list(ID_LABEL
, pdialog
->label
);
397 resize_window(pdialog
->window
, NULL
, NULL
,
398 adj_size(pdialog
->label
->size
.w
+ 40),
399 adj_size(pdialog
->label
->size
.h
+ 60));
400 widget_set_position(pdialog
->window
,
401 (main_window_width() - pdialog
->window
->size
.w
) / 2,
402 (main_window_height() - pdialog
->window
->size
.h
) / 2);
403 widget_set_position(pdialog
->close_button
, pdialog
->window
->size
.w
404 - pdialog
->close_button
->size
.w
- 1,
405 pdialog
->window
->size
.y
+ adj_size(2));
406 widget_set_position(pdialog
->label
, adj_size(20), adj_size(40));
408 widget_redraw(pdialog
->window
);
409 widget_redraw(pdialog
->close_button
);
410 widget_redraw(pdialog
->label
);
411 widget_mark_dirty(pdialog
->window
);
415 /**************************************************************************
416 Update a notify dialog.
417 **************************************************************************/
418 static void notify_goto_dialog_advance(struct notify_goto_dialog
*pdialog
)
420 if (1 < notify_goto_list_size(pdialog
->datas
)) {
421 notify_goto_list_remove(pdialog
->datas
,
422 notify_goto_list_get(pdialog
->datas
, 0));
423 notify_goto_dialog_update(pdialog
);
425 notify_goto_dialog_destroy(pdialog
);
426 if (pdialog
== notify_goto_dialog
) {
427 notify_goto_dialog
= NULL
;
432 /**************************************************************************
433 Popup a dialog to display information about an event that has a
434 specific location. The user should be given the option to goto that
436 **************************************************************************/
437 void popup_notify_goto_dialog(const char *headline
, const char *lines
,
438 const struct text_tag_list
*tags
,
441 if (NULL
== notify_goto_dialog
) {
442 notify_goto_dialog
= notify_goto_dialog_new();
445 fc_assert(NULL
!= notify_goto_dialog
);
447 notify_goto_list_prepend(notify_goto_dialog
->datas
,
448 notify_goto_data_new(headline
, lines
, ptile
));
449 notify_goto_dialog_update(notify_goto_dialog
);
452 /**************************************************************************
453 Popdown the notify goto dialog.
454 **************************************************************************/
455 void popdown_notify_goto_dialog(void)
457 if (NULL
!= notify_goto_dialog
) {
458 notify_goto_dialog_destroy(notify_goto_dialog
);
459 notify_goto_dialog
= NULL
;
463 /**************************************************************************
464 Popup a dialog to display connection message from server.
465 **************************************************************************/
466 void popup_connect_msg(const char *headline
, const char *message
)
468 log_error("popup_connect_msg() PORT ME");
471 /* ----------------------------------------------------------------------- */
472 struct ADVANCED_DLG
*pNotifyDlg
= NULL
;
474 /**************************************************************************
475 User interacted with generic notify dialog.
476 **************************************************************************/
477 static int notify_dialog_window_callback(struct widget
*pWindow
)
479 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
480 move_window_group(pNotifyDlg
->pBeginWidgetList
, pWindow
);
486 /**************************************************************************
487 User interacted with notify dialog close button.
488 **************************************************************************/
489 static int exit_notify_dialog_callback(struct widget
*pWidget
)
491 if (Main
.event
.type
== SDL_KEYDOWN
492 || (Main
.event
.type
== SDL_MOUSEBUTTONDOWN
493 && Main
.event
.button
.button
== SDL_BUTTON_LEFT
)) {
495 popdown_window_group_dialog(pNotifyDlg
->pBeginWidgetList
,
496 pNotifyDlg
->pEndWidgetList
);
497 FC_FREE(pNotifyDlg
->pScroll
);
505 /**************************************************************************
506 Popup a generic dialog to display some generic information.
507 **************************************************************************/
508 void popup_notify_dialog(const char *caption
, const char *headline
,
511 struct widget
*pBuf
, *pWindow
;
513 SDL_Surface
*pHeadline
, *pLines
;
521 pNotifyDlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
523 pstr
= create_utf8_from_char(caption
, adj_font(12));
524 pstr
->style
|= TTF_STYLE_BOLD
;
526 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
528 pWindow
->action
= notify_dialog_window_callback
;
529 set_wstate(pWindow
, FC_WS_NORMAL
);
531 add_to_gui_list(ID_WINDOW
, pWindow
);
532 pNotifyDlg
->pEndWidgetList
= pWindow
;
534 area
= pWindow
->area
;
537 /* create exit button */
538 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
539 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
540 pBuf
->info_label
= create_utf8_from_char(_("Close Dialog (Esc)"),
542 pBuf
->action
= exit_notify_dialog_callback
;
543 set_wstate(pBuf
, FC_WS_NORMAL
);
544 pBuf
->key
= SDLK_ESCAPE
;
545 area
.w
+= (pBuf
->size
.w
+ adj_size(10));
547 add_to_gui_list(ID_BUTTON
, pBuf
);
548 pNotifyDlg
->pBeginWidgetList
= pBuf
;
550 pstr
= create_utf8_from_char(headline
, adj_font(16));
551 pstr
->style
|= TTF_STYLE_BOLD
;
553 pHeadline
= create_text_surf_from_utf8(pstr
);
555 if (lines
&& *lines
!= '\0') {
556 change_ptsize_utf8(pstr
, adj_font(12));
557 pstr
->style
&= ~TTF_STYLE_BOLD
;
558 copy_chars_to_utf8_str(pstr
, lines
);
559 pLines
= create_text_surf_from_utf8(pstr
);
566 area
.w
= MAX(area
.w
, pHeadline
->w
);
568 area
.w
= MAX(area
.w
, pLines
->w
);
570 area
.w
+= adj_size(60);
571 area
.h
= MAX(area
.h
, adj_size(10) + pHeadline
->h
+ adj_size(10));
573 area
.h
+= pLines
->h
+ adj_size(10);
576 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
577 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
578 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
580 area
= pWindow
->area
;
582 widget_set_position(pWindow
,
583 (main_window_width() - pWindow
->size
.w
) / 2,
584 (main_window_height() - pWindow
->size
.h
) / 2);
586 dst
.x
= area
.x
+ (area
.w
- pHeadline
->w
) / 2;
587 dst
.y
= area
.y
+ adj_size(10);
589 alphablit(pHeadline
, NULL
, pWindow
->theme
, &dst
, 255);
591 dst
.y
+= pHeadline
->h
+ adj_size(10);
592 if (pHeadline
->w
< pLines
->w
) {
593 dst
.x
= area
.x
+ (area
.w
- pLines
->w
) / 2;
596 alphablit(pLines
, NULL
, pWindow
->theme
, &dst
, 255);
599 FREESURFACE(pHeadline
);
603 pBuf
= pWindow
->prev
;
604 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
605 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
608 redraw_group(pNotifyDlg
->pBeginWidgetList
, pWindow
, 0);
609 widget_flush(pWindow
);
612 /* =======================================================================*/
613 /* ========================= UNIT UPGRADE DIALOG =========================*/
614 /* =======================================================================*/
615 static struct SMALL_DLG
*pUnit_Upgrade_Dlg
= NULL
;
617 /****************************************************************
618 User interacted with upgrade unit widget.
619 *****************************************************************/
620 static int upgrade_unit_window_callback(struct widget
*pWindow
)
622 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
623 move_window_group(pUnit_Upgrade_Dlg
->pBeginWidgetList
, pWindow
);
628 /****************************************************************
629 User interacted with upgrade unit dialog cancel -button
630 *****************************************************************/
631 static int cancel_upgrade_unit_callback(struct widget
*pWidget
)
633 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
634 popdown_unit_upgrade_dlg();
635 /* enable city dlg */
636 enable_city_dlg_widgets();
642 /****************************************************************
643 User interacted with unit upgrade dialog "Upgrade" -button.
644 *****************************************************************/
645 static int ok_upgrade_unit_window_callback(struct widget
*pWidget
)
647 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
648 struct unit
*pUnit
= pWidget
->data
.unit
;
650 popdown_unit_upgrade_dlg();
651 /* enable city dlg */
652 enable_city_dlg_widgets();
653 free_city_units_lists();
654 request_unit_upgrade(pUnit
);
660 /****************************************************************
661 Open unit upgrade dialog.
662 *****************************************************************/
663 void popup_unit_upgrade_dlg(struct unit
*pUnit
, bool city
)
666 struct widget
*pBuf
= NULL
, *pWindow
;
670 int window_x
= 0, window_y
= 0;
671 enum unit_upgrade_result unit_upgrade_result
;
674 if (pUnit_Upgrade_Dlg
) {
680 pUnit_Upgrade_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
682 unit_upgrade_result
= unit_upgrade_info(pUnit
, cBuf
, sizeof(cBuf
));
684 pstr
= create_utf8_from_char(_("Upgrade Obsolete Units"), adj_font(12));
685 pstr
->style
|= TTF_STYLE_BOLD
;
687 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
689 pWindow
->action
= upgrade_unit_window_callback
;
690 set_wstate(pWindow
, FC_WS_NORMAL
);
692 pUnit_Upgrade_Dlg
->pEndWidgetList
= pWindow
;
694 add_to_gui_list(ID_WINDOW
, pWindow
);
696 area
= pWindow
->area
;
698 /* ============================================================= */
700 /* create text label */
701 pstr
= create_utf8_from_char(cBuf
, adj_font(10));
702 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
703 pstr
->fgcol
= *get_theme_color(COLOR_THEME_UNITUPGRADE_TEXT
);
705 pText
= create_text_surf_from_utf8(pstr
);
708 area
.w
= MAX(area
.w
, pText
->w
+ adj_size(20));
709 area
.h
+= (pText
->h
+ adj_size(10));
712 pBuf
= create_themeicon_button_from_chars(current_theme
->CANCEL_Icon
,
713 pWindow
->dst
, _("Cancel"),
716 pBuf
->action
= cancel_upgrade_unit_callback
;
717 set_wstate(pBuf
, FC_WS_NORMAL
);
719 area
.h
+= (pBuf
->size
.h
+ adj_size(20));
721 add_to_gui_list(ID_BUTTON
, pBuf
);
723 if (UU_OK
== unit_upgrade_result
) {
724 pBuf
= create_themeicon_button_from_chars(current_theme
->OK_Icon
, pWindow
->dst
,
725 _("Upgrade"), adj_font(12), 0);
727 pBuf
->action
= ok_upgrade_unit_window_callback
;
728 set_wstate(pBuf
, FC_WS_NORMAL
);
729 pBuf
->data
.unit
= pUnit
;
730 add_to_gui_list(ID_BUTTON
, pBuf
);
731 pBuf
->size
.w
= MAX(pBuf
->size
.w
, pBuf
->next
->size
.w
);
732 pBuf
->next
->size
.w
= pBuf
->size
.w
;
733 area
.w
= MAX(area
.w
, adj_size(30) + pBuf
->size
.w
* 2);
735 area
.w
= MAX(area
.w
, pBuf
->size
.w
+ adj_size(20));
737 /* ============================================ */
739 pUnit_Upgrade_Dlg
->pBeginWidgetList
= pBuf
;
741 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
742 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
743 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
745 area
= pWindow
->area
;
748 window_x
= Main
.event
.motion
.x
;
749 window_y
= Main
.event
.motion
.y
;
751 put_window_near_map_tile(pWindow
, pWindow
->size
.w
, pWindow
->size
.h
,
755 widget_set_position(pWindow
, window_x
, window_y
);
757 /* setup rest of widgets */
759 dst
.x
= area
.x
+ (area
.w
- pText
->w
) / 2;
760 dst
.y
= area
.y
+ adj_size(10);
761 alphablit(pText
, NULL
, pWindow
->theme
, &dst
, 255);
765 pBuf
= pWindow
->prev
;
766 pBuf
->size
.y
= area
.y
+ area
.h
- pBuf
->size
.h
- adj_size(7);
768 if (UU_OK
== unit_upgrade_result
) {
771 pBuf
->size
.x
= area
.x
+ (area
.w
- (2 * pBuf
->size
.w
+ adj_size(10))) / 2;
772 pBuf
->size
.y
= pBuf
->next
->size
.y
;
775 pBuf
->next
->size
.x
= pBuf
->size
.x
+ pBuf
->size
.w
+ adj_size(10);
777 /* x position of cancel button */
778 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- adj_size(10);
781 /* ================================================== */
783 redraw_group(pUnit_Upgrade_Dlg
->pBeginWidgetList
, pWindow
, 0);
785 widget_mark_dirty(pWindow
);
789 /****************************************************************
790 Close unit upgrade dialog.
791 *****************************************************************/
792 static void popdown_unit_upgrade_dlg(void)
794 if (pUnit_Upgrade_Dlg
) {
795 popdown_window_group_dialog(pUnit_Upgrade_Dlg
->pBeginWidgetList
,
796 pUnit_Upgrade_Dlg
->pEndWidgetList
);
797 FC_FREE(pUnit_Upgrade_Dlg
);
801 /* =======================================================================*/
802 /* ========================= UNIT DISBAND DIALOG =========================*/
803 /* =======================================================================*/
804 static struct SMALL_DLG
*pUnit_Disband_Dlg
= NULL
;
806 /****************************************************************
807 User interacted with disband unit widget.
808 *****************************************************************/
809 static int disband_unit_window_callback(struct widget
*pWindow
)
811 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
812 move_window_group(pUnit_Disband_Dlg
->pBeginWidgetList
, pWindow
);
818 /****************************************************************
819 User interacted with disband unit dialog cancel -button
820 *****************************************************************/
821 static int cancel_disband_unit_callback(struct widget
*pWidget
)
823 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
824 popdown_unit_disband_dlg();
825 /* enable city dlg */
826 enable_city_dlg_widgets();
832 /****************************************************************
833 User interacted with unit disband dialog "Disband" -button.
834 *****************************************************************/
835 static int ok_disband_unit_window_callback(struct widget
*pWidget
)
837 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
838 struct unit
*pUnit
= pWidget
->data
.unit
;
840 popdown_unit_disband_dlg();
841 /* enable city dlg */
842 enable_city_dlg_widgets();
843 free_city_units_lists();
844 request_unit_disband(pUnit
);
850 /****************************************************************
851 Open unit disband dialog.
852 *****************************************************************/
853 void popup_unit_disband_dlg(struct unit
*pUnit
, bool city
)
856 struct widget
*pBuf
= NULL
, *pWindow
;
860 int window_x
= 0, window_y
= 0;
861 bool unit_disband_result
;
864 if (pUnit_Disband_Dlg
) {
870 pUnit_Disband_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
873 struct unit_list
*pUnits
= unit_list_new();
875 unit_list_append(pUnits
, pUnit
);
876 unit_disband_result
= get_units_disband_info(cBuf
, sizeof(cBuf
), pUnits
);
877 unit_list_destroy(pUnits
);
880 pstr
= create_utf8_from_char(_("Disband Units"), adj_font(12));
881 pstr
->style
|= TTF_STYLE_BOLD
;
883 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
885 pWindow
->action
= disband_unit_window_callback
;
886 set_wstate(pWindow
, FC_WS_NORMAL
);
888 pUnit_Disband_Dlg
->pEndWidgetList
= pWindow
;
890 add_to_gui_list(ID_WINDOW
, pWindow
);
892 area
= pWindow
->area
;
894 /* ============================================================= */
896 /* create text label */
897 pstr
= create_utf8_from_char(cBuf
, adj_font(10));
898 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
899 pstr
->fgcol
= *get_theme_color(COLOR_THEME_UNITDISBAND_TEXT
);
901 pText
= create_text_surf_from_utf8(pstr
);
904 area
.w
= MAX(area
.w
, pText
->w
+ adj_size(20));
905 area
.h
+= (pText
->h
+ adj_size(10));
908 pBuf
= create_themeicon_button_from_chars(current_theme
->CANCEL_Icon
,
909 pWindow
->dst
, _("Cancel"),
912 pBuf
->action
= cancel_disband_unit_callback
;
913 set_wstate(pBuf
, FC_WS_NORMAL
);
915 area
.h
+= (pBuf
->size
.h
+ adj_size(20));
917 add_to_gui_list(ID_BUTTON
, pBuf
);
919 if (unit_disband_result
) {
920 pBuf
= create_themeicon_button_from_chars(current_theme
->OK_Icon
, pWindow
->dst
,
921 _("Disband"), adj_font(12), 0);
923 pBuf
->action
= ok_disband_unit_window_callback
;
924 set_wstate(pBuf
, FC_WS_NORMAL
);
925 pBuf
->data
.unit
= pUnit
;
926 add_to_gui_list(ID_BUTTON
, pBuf
);
927 pBuf
->size
.w
= MAX(pBuf
->size
.w
, pBuf
->next
->size
.w
);
928 pBuf
->next
->size
.w
= pBuf
->size
.w
;
929 area
.w
= MAX(area
.w
, adj_size(30) + pBuf
->size
.w
* 2);
931 area
.w
= MAX(area
.w
, pBuf
->size
.w
+ adj_size(20));
933 /* ============================================ */
935 pUnit_Disband_Dlg
->pBeginWidgetList
= pBuf
;
937 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
938 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
939 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
941 area
= pWindow
->area
;
944 window_x
= Main
.event
.motion
.x
;
945 window_y
= Main
.event
.motion
.y
;
947 put_window_near_map_tile(pWindow
, pWindow
->size
.w
, pWindow
->size
.h
,
951 widget_set_position(pWindow
, window_x
, window_y
);
953 /* setup rest of widgets */
955 dst
.x
= area
.x
+ (area
.w
- pText
->w
) / 2;
956 dst
.y
= area
.y
+ adj_size(10);
957 alphablit(pText
, NULL
, pWindow
->theme
, &dst
, 255);
961 pBuf
= pWindow
->prev
;
962 pBuf
->size
.y
= area
.y
+ area
.h
- pBuf
->size
.h
- adj_size(7);
964 if (unit_disband_result
) {
967 pBuf
->size
.x
= area
.x
+ (area
.w
- (2 * pBuf
->size
.w
+ adj_size(10))) / 2;
968 pBuf
->size
.y
= pBuf
->next
->size
.y
;
971 pBuf
->next
->size
.x
= pBuf
->size
.x
+ pBuf
->size
.w
+ adj_size(10);
973 /* x position of cancel button */
974 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- adj_size(10);
977 /* ================================================== */
979 redraw_group(pUnit_Disband_Dlg
->pBeginWidgetList
, pWindow
, 0);
981 widget_mark_dirty(pWindow
);
985 /****************************************************************
986 Close unit disband dialog.
987 *****************************************************************/
988 static void popdown_unit_disband_dlg(void)
990 if (pUnit_Disband_Dlg
) {
991 popdown_window_group_dialog(pUnit_Disband_Dlg
->pBeginWidgetList
,
992 pUnit_Disband_Dlg
->pEndWidgetList
);
993 FC_FREE(pUnit_Disband_Dlg
);
997 /* =======================================================================*/
998 /* ======================== UNIT SELECTION DIALOG ========================*/
999 /* =======================================================================*/
1000 static struct ADVANCED_DLG
*pUnit_Select_Dlg
= NULL
;
1002 /**************************************************************************
1003 User interacted with unit selection window.
1004 **************************************************************************/
1005 static int unit_select_window_callback(struct widget
*pWindow
)
1007 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1008 move_window_group(pUnit_Select_Dlg
->pBeginWidgetList
, pWindow
);
1014 /**************************************************************************
1015 User requested unit select window to be closed.
1016 **************************************************************************/
1017 static int exit_unit_select_callback(struct widget
*pWidget
)
1019 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1020 unit_select_dialog_popdown();
1021 is_unit_move_blocked
= FALSE
;
1027 /**************************************************************************
1028 User selected unit from unit select window.
1029 **************************************************************************/
1030 static int unit_select_callback(struct widget
*pWidget
)
1032 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1033 struct unit
*pUnit
=
1034 player_unit_by_number(client_player(), MAX_ID
- pWidget
->ID
);
1036 unit_select_dialog_popdown();
1038 request_new_unit_activity(pUnit
, ACTIVITY_IDLE
);
1039 unit_focus_set(pUnit
);
1045 /**************************************************************************
1046 Popdown a dialog window to select units on a particular tile.
1047 **************************************************************************/
1048 static void unit_select_dialog_popdown(void)
1050 if (pUnit_Select_Dlg
) {
1051 is_unit_move_blocked
= FALSE
;
1052 popdown_window_group_dialog(pUnit_Select_Dlg
->pBeginWidgetList
,
1053 pUnit_Select_Dlg
->pEndWidgetList
);
1055 FC_FREE(pUnit_Select_Dlg
->pScroll
);
1056 FC_FREE(pUnit_Select_Dlg
);
1061 /**************************************************************************
1062 Popup a dialog window to select units on a particular tile.
1063 **************************************************************************/
1064 void unit_select_dialog_popup(struct tile
*ptile
)
1066 struct widget
*pBuf
= NULL
, *pWindow
;
1068 struct unit
*pUnit
= NULL
, *pFocus
= head_of_units_in_focus();
1069 struct unit_type
*pUnitType
;
1076 n
= unit_list_size(ptile
->units
);
1078 if (!n
|| pUnit_Select_Dlg
) {
1082 is_unit_move_blocked
= TRUE
;
1083 pUnit_Select_Dlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
1085 fc_snprintf(cBuf
, sizeof(cBuf
),"%s (%d)", _("Unit selection") , n
);
1086 pstr
= create_utf8_from_char(cBuf
, adj_font(12));
1087 pstr
->style
|= TTF_STYLE_BOLD
;
1089 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
1091 pWindow
->action
= unit_select_window_callback
;
1092 set_wstate(pWindow
, FC_WS_NORMAL
);
1094 add_to_gui_list(ID_UNIT_SELECT_DLG_WINDOW
, pWindow
);
1095 pUnit_Select_Dlg
->pEndWidgetList
= pWindow
;
1097 area
= pWindow
->area
;
1100 /* create exit button */
1101 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
1102 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
1103 pBuf
->info_label
= create_utf8_from_char(_("Close Dialog (Esc)"),
1105 pBuf
->action
= exit_unit_select_callback
;
1106 set_wstate(pBuf
, FC_WS_NORMAL
);
1107 pBuf
->key
= SDLK_ESCAPE
;
1108 area
.w
+= (pBuf
->size
.w
+ adj_size(10));
1110 add_to_gui_list(ID_UNIT_SELECT_DLG_EXIT_BUTTON
, pBuf
);
1114 for (i
= 0; i
< n
; i
++) {
1115 const char *vetname
;
1117 pUnit
= unit_list_get(ptile
->units
, i
);
1118 pUnitType
= unit_type_get(pUnit
);
1119 vetname
= utype_veteran_name_translation(pUnitType
, pUnit
->veteran
);
1121 if (unit_owner(pUnit
) == client
.conn
.playing
) {
1122 fc_snprintf(cBuf
, sizeof(cBuf
), _("Contact %s (%d / %d) %s(%d,%d,%s) %s"),
1123 (vetname
!= NULL
? vetname
: ""),
1124 pUnit
->hp
, pUnitType
->hp
,
1125 utype_name_translation(pUnitType
),
1126 pUnitType
->attack_strength
,
1127 pUnitType
->defense_strength
,
1128 move_points_text(pUnitType
->move_rate
, FALSE
),
1129 unit_activity_text(pUnit
));
1131 int att_chance
, def_chance
;
1133 fc_snprintf(cBuf
, sizeof(cBuf
), _("%s %s %s(A:%d D:%d M:%s FP:%d) HP:%d%%"),
1134 nation_adjective_for_player(unit_owner(pUnit
)),
1135 (vetname
!= NULL
? vetname
: ""),
1136 utype_name_translation(pUnitType
),
1137 pUnitType
->attack_strength
,
1138 pUnitType
->defense_strength
,
1139 move_points_text(pUnitType
->move_rate
, FALSE
),
1140 pUnitType
->firepower
,
1141 (pUnit
->hp
* 100 / pUnitType
->hp
+ 9) / 10);
1143 /* calculate chance to win */
1144 if (sdl_get_chance_to_win(&att_chance
, &def_chance
, pUnit
, pFocus
)) {
1145 /* TRANS: "CtW" = "Chance to Win" */
1146 cat_snprintf(cBuf
, sizeof(cBuf
), _(" CtW: Att:%d%% Def:%d%%"),
1147 att_chance
, def_chance
);
1151 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
, cBuf
,
1152 unit_select_callback
);
1154 add_to_gui_list(MAX_ID
- pUnit
->id
, pBuf
);
1156 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1157 area
.h
+= pBuf
->size
.h
;
1158 if (unit_owner(pUnit
) == client
.conn
.playing
) {
1159 set_wstate(pBuf
, FC_WS_NORMAL
);
1162 if (i
> NUM_SEEN
- 1) {
1163 set_wflag(pBuf
, WF_HIDDEN
);
1167 pUnit_Select_Dlg
->pBeginWidgetList
= pBuf
;
1168 pUnit_Select_Dlg
->pBeginActiveWidgetList
= pUnit_Select_Dlg
->pBeginWidgetList
;
1169 pUnit_Select_Dlg
->pEndActiveWidgetList
= pWindow
->prev
->prev
;
1170 pUnit_Select_Dlg
->pActiveWidgetList
= pUnit_Select_Dlg
->pEndActiveWidgetList
;
1172 area
.w
+= adj_size(2);
1174 n
= create_vertical_scrollbar(pUnit_Select_Dlg
, 1, NUM_SEEN
, TRUE
, TRUE
);
1177 /* ------- window ------- */
1178 area
.h
= NUM_SEEN
* pWindow
->prev
->prev
->size
.h
;
1181 resize_window(pWindow
, NULL
, NULL
,
1182 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
1183 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
1185 area
= pWindow
->area
;
1187 put_window_near_map_tile(pWindow
, pWindow
->size
.w
, pWindow
->size
.h
,
1192 if (pUnit_Select_Dlg
->pScroll
) {
1197 pBuf
= pWindow
->prev
;
1198 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
1199 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
1202 setup_vertical_widgets_position(1, area
.x
+ 1, area
.y
, w
, 0,
1203 pUnit_Select_Dlg
->pBeginActiveWidgetList
,
1206 if (pUnit_Select_Dlg
->pScroll
) {
1207 setup_vertical_scrollbar_area(pUnit_Select_Dlg
->pScroll
,
1208 area
.x
+ area
.w
, area
.y
,
1212 /* ==================================================== */
1214 redraw_group(pUnit_Select_Dlg
->pBeginWidgetList
, pWindow
, 0);
1216 widget_flush(pWindow
);
1219 /**************************************************************************
1220 Update the dialog window to select units on a particular tile.
1221 **************************************************************************/
1222 void unit_select_dialog_update_real(void)
1227 /* ====================================================================== */
1228 /* ============================ TERRAIN INFO ============================ */
1229 /* ====================================================================== */
1230 static struct SMALL_DLG
*pTerrain_Info_Dlg
= NULL
;
1233 /**************************************************************************
1234 Popdown terrain information dialog.
1235 **************************************************************************/
1236 static int terrain_info_window_dlg_callback(struct widget
*pWindow
)
1238 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1239 move_window_group(pTerrain_Info_Dlg
->pBeginWidgetList
, pWindow
);
1244 /**************************************************************************
1245 Popdown terrain information dialog.
1246 **************************************************************************/
1247 static void popdown_terrain_info_dialog(void)
1249 if (pTerrain_Info_Dlg
) {
1250 popdown_window_group_dialog(pTerrain_Info_Dlg
->pBeginWidgetList
,
1251 pTerrain_Info_Dlg
->pEndWidgetList
);
1252 FC_FREE(pTerrain_Info_Dlg
);
1257 /**************************************************************************
1258 Popdown terrain information dialog.
1259 **************************************************************************/
1260 static int exit_terrain_info_dialog_callback(struct widget
*pButton
)
1262 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1263 popdown_terrain_info_dialog();
1268 /**************************************************************************
1269 Return a (static) string with terrain defense bonus.
1270 This does not include bonuses some units may get out of bases.
1271 **************************************************************************/
1272 const char *sdl_get_tile_defense_info_text(struct tile
*ptile
)
1274 static char buffer
[64];
1275 int bonus
= (tile_terrain(ptile
)->defense_bonus
- 10) * 10;
1277 extra_type_iterate(pextra
) {
1278 if (tile_has_extra(ptile
, pextra
)
1279 && pextra
->category
== ECAT_NATURAL
) {
1280 bonus
+= pextra
->defense_bonus
;
1282 } extra_type_iterate_end
;
1284 fc_snprintf(buffer
, sizeof(buffer
), _("Terrain Defense Bonus: +%d%% "), bonus
);
1289 /**************************************************************************
1290 Popup terrain information dialog.
1291 **************************************************************************/
1292 static void popup_terrain_info_dialog(SDL_Surface
*pDest
, struct tile
*ptile
)
1295 struct widget
*pBuf
, *pWindow
;
1300 if (pTerrain_Info_Dlg
) {
1305 pSurf
= get_terrain_surface(ptile
);
1306 pTerrain_Info_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
1309 fc_snprintf(cBuf
, sizeof(cBuf
), "%s [%d,%d]", _("Terrain Info"),
1312 pWindow
= create_window_skeleton(NULL
, create_utf8_from_char(cBuf
, adj_font(12)), 0);
1313 pWindow
->string_utf8
->style
|= TTF_STYLE_BOLD
;
1315 pWindow
->action
= terrain_info_window_dlg_callback
;
1316 set_wstate(pWindow
, FC_WS_NORMAL
);
1318 add_to_gui_list(ID_TERRAIN_INFO_DLG_WINDOW
, pWindow
);
1319 pTerrain_Info_Dlg
->pEndWidgetList
= pWindow
;
1321 area
= pWindow
->area
;
1324 pstr
= create_utf8_from_char(popup_info_text(ptile
), adj_font(12));
1325 pstr
->style
|= SF_CENTER
;
1326 pBuf
= create_iconlabel(pSurf
, pWindow
->dst
, pstr
, 0);
1328 pBuf
->size
.h
+= tileset_tile_height(tileset
) / 2;
1330 add_to_gui_list(ID_LABEL
, pBuf
);
1332 /* ------ window ---------- */
1333 area
.w
= MAX(area
.w
, pBuf
->size
.w
+ adj_size(20));
1334 area
.h
= MAX(area
.h
, pBuf
->size
.h
);
1336 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
1337 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
1338 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
1340 area
= pWindow
->area
;
1342 put_window_near_map_tile(pWindow
, pWindow
->size
.w
, pWindow
->size
.h
, ptile
);
1344 /* ------------------------ */
1346 pBuf
->size
.x
= area
.x
+ adj_size(10);
1347 pBuf
->size
.y
= area
.y
;
1350 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
1351 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
1352 pBuf
->info_label
= create_utf8_from_char(_("Close Dialog (Esc)"),
1354 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
1355 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
1356 pBuf
->action
= exit_terrain_info_dialog_callback
;
1357 set_wstate(pBuf
, FC_WS_NORMAL
);
1358 pBuf
->key
= SDLK_ESCAPE
;
1360 add_to_gui_list(ID_TERRAIN_INFO_DLG_EXIT_BUTTON
, pBuf
);
1362 pTerrain_Info_Dlg
->pBeginWidgetList
= pBuf
;
1363 /* --------------------------------- */
1365 redraw_group(pTerrain_Info_Dlg
->pBeginWidgetList
, pWindow
, 0);
1366 widget_mark_dirty(pWindow
);
1370 /* ====================================================================== */
1371 /* ========================= ADVANCED_TERRAIN_MENU ====================== */
1372 /* ====================================================================== */
1373 struct ADVANCED_DLG
*pAdvanced_Terrain_Dlg
= NULL
;
1375 /**************************************************************************
1376 Popdown a generic dialog to display some generic information about
1377 terrain : tile, units , cities, etc.
1378 **************************************************************************/
1379 void popdown_advanced_terrain_dialog(void)
1381 if (pAdvanced_Terrain_Dlg
) {
1382 is_unit_move_blocked
= FALSE
;
1383 popdown_window_group_dialog(pAdvanced_Terrain_Dlg
->pBeginWidgetList
,
1384 pAdvanced_Terrain_Dlg
->pEndWidgetList
);
1386 FC_FREE(pAdvanced_Terrain_Dlg
->pScroll
);
1387 FC_FREE(pAdvanced_Terrain_Dlg
);
1391 /**************************************************************************
1392 User selected "Advanced Menu"
1393 **************************************************************************/
1394 int advanced_terrain_window_dlg_callback(struct widget
*pWindow
)
1396 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1397 move_window_group(pAdvanced_Terrain_Dlg
->pBeginWidgetList
, pWindow
);
1402 /**************************************************************************
1403 User requested closing of advanced terrain dialog.
1404 **************************************************************************/
1405 int exit_advanced_terrain_dlg_callback(struct widget
*pWidget
)
1407 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1408 popdown_advanced_terrain_dialog();
1414 /**************************************************************************
1415 User requested terrain info.
1416 **************************************************************************/
1417 static int terrain_info_callback(struct widget
*pWidget
)
1419 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1420 int x
= pWidget
->data
.cont
->id0
;
1421 int y
= pWidget
->data
.cont
->id1
;
1423 popdown_advanced_terrain_dialog();
1425 popup_terrain_info_dialog(NULL
, map_pos_to_tile(x
, y
));
1430 /**************************************************************************
1431 User requested zoom to city.
1432 **************************************************************************/
1433 static int zoom_to_city_callback(struct widget
*pWidget
)
1435 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1436 struct city
*pCity
= pWidget
->data
.city
;
1438 popdown_advanced_terrain_dialog();
1440 popup_city_dialog(pCity
);
1445 /**************************************************************************
1446 User requested production change.
1447 **************************************************************************/
1448 static int change_production_callback(struct widget
*pWidget
)
1450 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1451 struct city
*pCity
= pWidget
->data
.city
;
1453 popdown_advanced_terrain_dialog();
1454 popup_worklist_editor(pCity
, NULL
);
1459 /**************************************************************************
1460 User requested hurry production.
1461 **************************************************************************/
1462 static int hurry_production_callback(struct widget
*pWidget
)
1464 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1465 struct city
*pCity
= pWidget
->data
.city
;
1467 popdown_advanced_terrain_dialog();
1469 popup_hurry_production_dialog(pCity
, NULL
);
1474 /**************************************************************************
1475 User requested opening of cma settings.
1476 **************************************************************************/
1477 static int cma_callback(struct widget
*pWidget
)
1479 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1480 struct city
*pCity
= pWidget
->data
.city
;
1482 popdown_advanced_terrain_dialog();
1483 popup_city_cma_dialog(pCity
);
1488 /**************************************************************************
1490 **************************************************************************/
1491 static int adv_unit_select_callback(struct widget
*pWidget
)
1493 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1494 struct unit
*pUnit
= pWidget
->data
.unit
;
1496 popdown_advanced_terrain_dialog();
1499 request_new_unit_activity(pUnit
, ACTIVITY_IDLE
);
1500 unit_focus_set(pUnit
);
1506 /**************************************************************************
1507 User selected all units from tile.
1508 **************************************************************************/
1509 static int adv_unit_select_all_callback(struct widget
*pWidget
)
1511 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1512 struct unit
*pUnit
= pWidget
->data
.unit
;
1514 popdown_advanced_terrain_dialog();
1517 activate_all_units(unit_tile(pUnit
));
1523 /**************************************************************************
1524 Sentry unit widget contains.
1525 **************************************************************************/
1526 static int adv_unit_sentry_idle_callback(struct widget
*pWidget
)
1528 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1529 struct unit
*pUnit
= pWidget
->data
.unit
;
1531 popdown_advanced_terrain_dialog();
1534 struct tile
*ptile
= unit_tile(pUnit
);
1536 unit_list_iterate(ptile
->units
, punit
) {
1537 if (unit_owner(punit
) == client
.conn
.playing
1538 && ACTIVITY_IDLE
== punit
->activity
1539 && !punit
->ai_controlled
1540 && can_unit_do_activity(punit
, ACTIVITY_SENTRY
)) {
1541 request_new_unit_activity(punit
, ACTIVITY_SENTRY
);
1543 } unit_list_iterate_end
;
1549 /**************************************************************************
1550 Initiate goto to selected tile.
1551 **************************************************************************/
1552 static int goto_here_callback(struct widget
*pWidget
)
1554 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1555 int x
= pWidget
->data
.cont
->id0
;
1556 int y
= pWidget
->data
.cont
->id1
;
1558 popdown_advanced_terrain_dialog();
1561 send_goto_tile(head_of_units_in_focus(), map_pos_to_tile(x
, y
));
1566 /**************************************************************************
1567 Initiate patrol to selected tile.
1568 **************************************************************************/
1569 static int patrol_here_callback(struct widget
*pWidget
)
1571 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1575 int x
= pWidget
->data
.cont
->id0
;
1576 int y
= pWidget
->data
.cont
->id1
;
1577 struct unit
*pUnit
= head_of_units_in_focus();
1580 popdown_advanced_terrain_dialog();
1584 enter_goto_state(pUnit
);
1586 do_unit_patrol_to(pUnit
, map_pos_to_tile(x
, y
));
1594 /**************************************************************************
1595 Initiate paradrop to selected tile.
1596 **************************************************************************/
1597 static int paradrop_here_callback(struct widget
*pWidget
)
1599 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1602 int x
= pWidget
->data
.cont
->id0
;
1603 int y
= pWidget
->data
.cont
->id1
;
1606 popdown_advanced_terrain_dialog();
1610 do_unit_paradrop_to(get_unit_in_focus(), map_pos_to_tile(x
, y
));
1616 /**************************************************************************
1617 Show help about unit type.
1618 **************************************************************************/
1619 static int unit_help_callback(struct widget
*pWidget
)
1621 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1622 Unit_type_id unit_id
= MAX_ID
- pWidget
->ID
;
1624 popdown_advanced_terrain_dialog();
1625 popup_unit_info(unit_id
);
1630 /**************************************************************************
1631 Popup a generic dialog to display some generic information about
1632 terrain : tile, units , cities, etc.
1633 **************************************************************************/
1634 void popup_advanced_terrain_dialog(struct tile
*ptile
, Uint16 pos_x
, Uint16 pos_y
)
1636 struct widget
*pWindow
= NULL
, *pBuf
= NULL
;
1638 struct unit
*pFocus_Unit
;
1641 struct CONTAINER
*pCont
;
1643 int n
, w
= 0, h
, units_h
= 0;
1646 if (pAdvanced_Terrain_Dlg
) {
1650 pCity
= tile_city(ptile
);
1651 n
= unit_list_size(ptile
->units
);
1652 pFocus_Unit
= head_of_units_in_focus();
1654 if (!n
&& !pCity
&& !pFocus_Unit
) {
1655 popup_terrain_info_dialog(NULL
, ptile
);
1660 area
.h
= adj_size(2);
1661 is_unit_move_blocked
= TRUE
;
1663 pAdvanced_Terrain_Dlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
1665 pCont
= fc_calloc(1, sizeof(struct CONTAINER
));
1666 pCont
->id0
= index_to_map_pos_x(tile_index(ptile
));
1667 pCont
->id1
= index_to_map_pos_y(tile_index(ptile
));
1669 pstr
= create_utf8_from_char(_("Advanced Menu") , adj_font(12));
1670 pstr
->style
|= TTF_STYLE_BOLD
;
1672 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
1674 pWindow
->action
= advanced_terrain_window_dlg_callback
;
1675 set_wstate(pWindow
, FC_WS_NORMAL
);
1677 add_to_gui_list(ID_TERRAIN_ADV_DLG_WINDOW
, pWindow
);
1678 pAdvanced_Terrain_Dlg
->pEndWidgetList
= pWindow
;
1680 area
= pWindow
->area
;
1684 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
1685 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
1686 pBuf
->info_label
= create_utf8_from_char(_("Close Dialog (Esc)"),
1688 area
.w
+= pBuf
->size
.w
+ adj_size(10);
1689 pBuf
->action
= exit_advanced_terrain_dlg_callback
;
1690 set_wstate(pBuf
, FC_WS_NORMAL
);
1691 pBuf
->key
= SDLK_ESCAPE
;
1693 add_to_gui_list(ID_TERRAIN_ADV_DLG_EXIT_BUTTON
, pBuf
);
1696 pstr
= create_utf8_from_char(_("Terrain Info") , adj_font(10));
1697 pstr
->style
|= TTF_STYLE_BOLD
;
1699 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
,
1700 (WF_RESTORE_BACKGROUND
|WF_DRAW_TEXT_LABEL_WITH_SPACE
|WF_FREE_DATA
));
1702 pBuf
->string_utf8
->bgcol
= (SDL_Color
) {0, 0, 0, 0};
1704 pBuf
->data
.cont
= pCont
;
1706 pBuf
->action
= terrain_info_callback
;
1707 set_wstate(pBuf
, FC_WS_NORMAL
);
1709 add_to_gui_list(ID_LABEL
, pBuf
);
1711 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1712 area
.h
+= pBuf
->size
.h
;
1715 if (pCity
&& city_owner(pCity
) == client
.conn
.playing
) {
1717 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
1719 add_to_gui_list(ID_SEPARATOR
, pBuf
);
1720 area
.h
+= pBuf
->next
->size
.h
;
1721 /* ------------------ */
1723 fc_snprintf(cBuf
, sizeof(cBuf
), _("Zoom to : %s"), city_name_get(pCity
));
1725 create_active_iconlabel(pBuf
, pWindow
->dst
,
1726 pstr
, cBuf
, zoom_to_city_callback
);
1727 pBuf
->data
.city
= pCity
;
1728 set_wstate(pBuf
, FC_WS_NORMAL
);
1730 add_to_gui_list(ID_LABEL
, pBuf
);
1732 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1733 area
.h
+= pBuf
->size
.h
;
1736 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
,
1737 _("Change Production"), change_production_callback
);
1739 pBuf
->data
.city
= pCity
;
1740 set_wstate(pBuf
, FC_WS_NORMAL
);
1742 add_to_gui_list(ID_LABEL
, pBuf
);
1744 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1745 area
.h
+= pBuf
->size
.h
;
1746 /* -------------- */
1748 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
,
1749 _("Hurry production"), hurry_production_callback
);
1751 pBuf
->data
.city
= pCity
;
1752 set_wstate(pBuf
, FC_WS_NORMAL
);
1754 add_to_gui_list(ID_LABEL
, pBuf
);
1756 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1757 area
.h
+= pBuf
->size
.h
;
1760 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
,
1761 _("Change City Governor settings"), cma_callback
);
1763 pBuf
->data
.city
= pCity
;
1764 set_wstate(pBuf
, FC_WS_NORMAL
);
1766 add_to_gui_list(ID_LABEL
, pBuf
);
1768 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1769 area
.h
+= pBuf
->size
.h
;
1774 && (tile_index(unit_tile(pFocus_Unit
)) != tile_index(ptile
))) {
1776 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
1778 add_to_gui_list(ID_SEPARATOR
, pBuf
);
1779 area
.h
+= pBuf
->next
->size
.h
;
1780 /* ------------------ */
1782 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
, _("Goto here"),
1783 goto_here_callback
);
1784 pBuf
->data
.cont
= pCont
;
1785 set_wstate(pBuf
, FC_WS_NORMAL
);
1787 add_to_gui_list(MAX_ID
- 1000 - pFocus_Unit
->id
, pBuf
);
1789 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1790 area
.h
+= pBuf
->size
.h
;
1793 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
, _("Patrol here"),
1794 patrol_here_callback
);
1795 pBuf
->data
.cont
= pCont
;
1796 set_wstate(pBuf
, FC_WS_NORMAL
);
1798 add_to_gui_list(MAX_ID
- 1000 - pFocus_Unit
->id
, pBuf
);
1800 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1801 area
.h
+= pBuf
->size
.h
;
1804 #if 0 /* FIXME: specific connect buttons */
1805 if (unit_has_type_flag(pFocus_Unit
, F_SETTLERS
)) {
1806 create_active_iconlabel(pBuf
, pWindow
->dst
->surface
, pstr
, _("Connect here"),
1807 connect_here_callback
);
1808 pBuf
->data
.cont
= pCont
;
1809 set_wstate(pBuf
, FC_WS_NORMAL
);
1811 add_to_gui_list(ID_LABEL
, pBuf
);
1813 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1814 area
.h
+= pBuf
->size
.h
;
1818 /* FIXME: This logic seems to try to mirror do_paradrop() why? */
1819 if (can_unit_paradrop(pFocus_Unit
) && client_tile_get_known(ptile
)
1820 && !(((pCity
&& pplayers_non_attack(client
.conn
.playing
, city_owner(pCity
)))
1821 || is_non_attack_unit_tile(ptile
, client
.conn
.playing
)))
1822 && (unit_type_get(pFocus_Unit
)->paratroopers_range
>=
1823 real_map_distance(unit_tile(pFocus_Unit
), ptile
))) {
1825 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
, _("Paradrop here"),
1826 paradrop_here_callback
);
1827 pBuf
->data
.cont
= pCont
;
1828 set_wstate(pBuf
, FC_WS_NORMAL
);
1830 add_to_gui_list(ID_LABEL
, pBuf
);
1832 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1833 area
.h
+= pBuf
->size
.h
;
1837 pAdvanced_Terrain_Dlg
->pBeginWidgetList
= pBuf
;
1843 struct unit_type
*pUnitType
= NULL
;
1847 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
1849 add_to_gui_list(ID_SEPARATOR
, pBuf
);
1850 area
.h
+= pBuf
->next
->size
.h
;
1853 struct unit
*pDefender
, *pAttacker
;
1854 struct widget
*pLast
= pBuf
;
1857 const char *vetname
;
1859 #define ADV_NUM_SEEN 15
1861 pDefender
= (pFocus_Unit
? get_defender(pFocus_Unit
, ptile
) : NULL
);
1862 pAttacker
= (pFocus_Unit
? get_attacker(pFocus_Unit
, ptile
) : NULL
);
1863 for (i
= 0; i
< n
; i
++) {
1864 pUnit
= unit_list_get(ptile
->units
, i
);
1865 if (pUnit
== pFocus_Unit
) {
1868 pUnitType
= unit_type_get(pUnit
);
1869 vetname
= utype_veteran_name_translation(pUnitType
, pUnit
->veteran
);
1871 if (unit_owner(pUnit
) == client
.conn
.playing
) {
1872 fc_snprintf(cBuf
, sizeof(cBuf
),
1873 _("Activate %s (%d / %d) %s (%d,%d,%s) %s"),
1874 (vetname
!= NULL
? vetname
: ""),
1875 pUnit
->hp
, pUnitType
->hp
,
1876 utype_name_translation(pUnitType
),
1877 pUnitType
->attack_strength
,
1878 pUnitType
->defense_strength
,
1879 move_points_text(pUnitType
->move_rate
, FALSE
),
1880 unit_activity_text(pUnit
));
1882 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
,
1883 cBuf
, adv_unit_select_callback
);
1884 pBuf
->data
.unit
= pUnit
;
1885 set_wstate(pBuf
, FC_WS_NORMAL
);
1886 add_to_gui_list(ID_LABEL
, pBuf
);
1889 int att_chance
, def_chance
;
1891 fc_snprintf(cBuf
, sizeof(cBuf
), _("%s %s %s (A:%d D:%d M:%s FP:%d) HP:%d%%"),
1892 nation_adjective_for_player(unit_owner(pUnit
)),
1893 (vetname
!= NULL
? vetname
: ""),
1894 utype_name_translation(pUnitType
),
1895 pUnitType
->attack_strength
,
1896 pUnitType
->defense_strength
,
1897 move_points_text(pUnitType
->move_rate
, FALSE
),
1898 pUnitType
->firepower
,
1899 ((pUnit
->hp
* 100) / pUnitType
->hp
));
1901 /* calculate chance to win */
1902 if (sdl_get_chance_to_win(&att_chance
, &def_chance
, pUnit
, pFocus_Unit
)) {
1903 /* TRANS: "CtW" = "Chance to Win" */
1904 cat_snprintf(cBuf
, sizeof(cBuf
), _(" CtW: Att:%d%% Def:%d%%"),
1905 att_chance
, def_chance
);
1908 if (pAttacker
&& pAttacker
== pUnit
) {
1909 pstr
->fgcol
= *(get_game_color(COLOR_OVERVIEW_ENEMY_UNIT
));
1912 if (pDefender
&& pDefender
== pUnit
) {
1913 pstr
->fgcol
= *(get_game_color(COLOR_OVERVIEW_MY_UNIT
));
1918 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
, cBuf
, NULL
);
1921 pstr
->fgcol
= *get_theme_color(COLOR_THEME_ADVANCEDTERRAINDLG_TEXT
);
1925 add_to_gui_list(ID_LABEL
, pBuf
);
1928 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1929 units_h
+= pBuf
->size
.h
;
1931 if (i
> ADV_NUM_SEEN
- 1) {
1932 set_wflag(pBuf
, WF_HIDDEN
);
1936 pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
= pLast
->prev
;
1937 pAdvanced_Terrain_Dlg
->pActiveWidgetList
= pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
;
1938 pAdvanced_Terrain_Dlg
->pBeginWidgetList
= pBuf
;
1939 pAdvanced_Terrain_Dlg
->pBeginActiveWidgetList
= pAdvanced_Terrain_Dlg
->pBeginWidgetList
;
1941 if (n
> ADV_NUM_SEEN
) {
1942 units_h
= ADV_NUM_SEEN
* pBuf
->size
.h
;
1943 n
= create_vertical_scrollbar(pAdvanced_Terrain_Dlg
,
1944 1, ADV_NUM_SEEN
, TRUE
, TRUE
);
1949 fc_snprintf(cBuf
, sizeof(cBuf
), "%s (%d)", _("Ready all"), my_units
);
1950 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
,
1951 cBuf
, adv_unit_select_all_callback
);
1952 pBuf
->data
.unit
= pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
->data
.unit
;
1953 set_wstate(pBuf
, FC_WS_NORMAL
);
1954 pBuf
->ID
= ID_LABEL
;
1955 DownAdd(pBuf
, pLast
);
1956 area
.h
+= pBuf
->size
.h
;
1958 fc_snprintf(cBuf
, sizeof(cBuf
), "%s (%d)", _("Sentry idle"), my_units
);
1959 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
,
1960 cBuf
, adv_unit_sentry_idle_callback
);
1961 pBuf
->data
.unit
= pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
->data
.unit
;
1962 set_wstate(pBuf
, FC_WS_NORMAL
);
1963 pBuf
->ID
= ID_LABEL
;
1964 DownAdd(pBuf
, pLast
->prev
);
1965 area
.h
+= pBuf
->size
.h
;
1968 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
1969 pBuf
->ID
= ID_SEPARATOR
;
1970 DownAdd(pBuf
, pLast
->prev
->prev
);
1971 area
.h
+= pBuf
->next
->size
.h
;
1974 } else { /* n == 1 */
1975 /* one unit - give orders */
1976 pUnit
= unit_list_get(ptile
->units
, 0);
1977 pUnitType
= unit_type_get(pUnit
);
1978 if (pUnit
!= pFocus_Unit
) {
1979 const char *vetname
;
1981 vetname
= utype_veteran_name_translation(pUnitType
, pUnit
->veteran
);
1982 if ((pCity
&& city_owner(pCity
) == client
.conn
.playing
)
1983 || (unit_owner(pUnit
) == client
.conn
.playing
)) {
1984 fc_snprintf(cBuf
, sizeof(cBuf
),
1985 _("Activate %s (%d / %d) %s (%d,%d,%s) %s"),
1986 (vetname
!= NULL
? vetname
: ""),
1987 pUnit
->hp
, pUnitType
->hp
,
1988 utype_name_translation(pUnitType
),
1989 pUnitType
->attack_strength
,
1990 pUnitType
->defense_strength
,
1991 move_points_text(pUnitType
->move_rate
, FALSE
),
1992 unit_activity_text(pUnit
));
1994 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
,
1995 cBuf
, adv_unit_select_callback
);
1996 pBuf
->data
.unit
= pUnit
;
1997 set_wstate(pBuf
, FC_WS_NORMAL
);
1999 add_to_gui_list(ID_LABEL
, pBuf
);
2001 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
2002 units_h
+= pBuf
->size
.h
;
2003 /* ---------------- */
2005 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
2007 add_to_gui_list(ID_SEPARATOR
, pBuf
);
2008 area
.h
+= pBuf
->next
->size
.h
;
2010 int att_chance
, def_chance
;
2012 fc_snprintf(cBuf
, sizeof(cBuf
), _("%s %s %s (A:%d D:%d M:%s FP:%d) HP:%d%%"),
2013 nation_adjective_for_player(unit_owner(pUnit
)),
2014 (vetname
!= NULL
? vetname
: ""),
2015 utype_name_translation(pUnitType
),
2016 pUnitType
->attack_strength
,
2017 pUnitType
->defense_strength
,
2018 move_points_text(pUnitType
->move_rate
, FALSE
),
2019 pUnitType
->firepower
,
2020 ((pUnit
->hp
* 100) / pUnitType
->hp
));
2022 /* calculate chance to win */
2023 if (sdl_get_chance_to_win(&att_chance
, &def_chance
, pUnit
, pFocus_Unit
)) {
2024 cat_snprintf(cBuf
, sizeof(cBuf
), _(" CtW: Att:%d%% Def:%d%%"),
2025 att_chance
, def_chance
);
2027 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
, cBuf
, NULL
);
2028 add_to_gui_list(ID_LABEL
, pBuf
);
2029 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
2030 units_h
+= pBuf
->size
.h
;
2031 /* ---------------- */
2034 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
2036 add_to_gui_list(ID_SEPARATOR
, pBuf
);
2037 area
.h
+= pBuf
->next
->size
.h
;
2040 /* ---------------- */
2041 fc_snprintf(cBuf
, sizeof(cBuf
),
2042 _("Look up \"%s\" in the Help Browser"),
2043 utype_name_translation(pUnitType
));
2044 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
,
2045 cBuf
, unit_help_callback
);
2046 set_wstate(pBuf
, FC_WS_NORMAL
);
2047 add_to_gui_list(MAX_ID
- utype_number(pUnitType
), pBuf
);
2049 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
2050 units_h
+= pBuf
->size
.h
;
2051 /* ---------------- */
2052 pAdvanced_Terrain_Dlg
->pBeginWidgetList
= pBuf
;
2058 area
.w
+= adj_size(2);
2061 resize_window(pWindow
, NULL
, NULL
,
2062 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
2063 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
2065 area
= pWindow
->area
;
2067 widget_set_position(pWindow
, pos_x
, pos_y
);
2069 w
= area
.w
- adj_size(2);
2071 if (pAdvanced_Terrain_Dlg
->pScroll
) {
2078 pBuf
= pWindow
->prev
;
2080 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
2081 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
2086 pBuf
->size
.x
= area
.x
+ 1;
2087 pBuf
->size
.y
= area
.y
+ 1;
2091 area2
.x
= adj_size(10);
2092 area2
.h
= adj_size(2);
2096 if (pBuf
== pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
) {
2101 pBuf
->size
.x
= pBuf
->next
->size
.x
;
2102 pBuf
->size
.y
= pBuf
->next
->size
.y
+ pBuf
->next
->size
.h
;
2104 if (pBuf
->ID
== ID_SEPARATOR
) {
2105 FREESURFACE(pBuf
->theme
);
2107 pBuf
->theme
= create_surf(w
, h
, SDL_SWSURFACE
);
2109 area2
.y
= pBuf
->size
.h
/ 2 - 1;
2110 area2
.w
= pBuf
->size
.w
- adj_size(20);
2112 SDL_FillRect(pBuf
->theme
, &area2
, map_rgba(pBuf
->theme
->format
,
2113 *get_theme_color(COLOR_THEME_ADVANCEDTERRAINDLG_TEXT
)));
2116 if (pBuf
== pAdvanced_Terrain_Dlg
->pBeginWidgetList
2117 || pBuf
== pAdvanced_Terrain_Dlg
->pBeginActiveWidgetList
) {
2123 if (pAdvanced_Terrain_Dlg
->pScroll
) {
2124 setup_vertical_scrollbar_area(pAdvanced_Terrain_Dlg
->pScroll
,
2126 pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
->size
.y
,
2127 area
.y
- pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
->size
.y
+ area
.h
,
2131 /* -------------------- */
2133 redraw_group(pAdvanced_Terrain_Dlg
->pBeginWidgetList
, pWindow
, 0);
2135 widget_flush(pWindow
);
2138 /* ====================================================================== */
2139 /* ============================ PILLAGE DIALOG ========================== */
2140 /* ====================================================================== */
2141 static struct SMALL_DLG
*pPillage_Dlg
= NULL
;
2143 /**************************************************************************
2144 User interacted with pillage dialog.
2145 **************************************************************************/
2146 static int pillage_window_callback(struct widget
*pWindow
)
2148 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2149 move_window_group(pPillage_Dlg
->pBeginWidgetList
, pWindow
);
2154 /**************************************************************************
2155 User selected what to pillage.
2156 **************************************************************************/
2157 static int pillage_callback(struct widget
*pWidget
)
2159 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2160 struct unit
*pUnit
= pWidget
->data
.unit
;
2161 int what
= MAX_ID
- pWidget
->ID
;
2163 popdown_pillage_dialog();
2166 struct extra_type
*target
= extra_by_number(what
);
2168 request_new_unit_activity_targeted(pUnit
, ACTIVITY_PILLAGE
, target
);
2174 /**************************************************************************
2175 User requested closing of pillage dialog.
2176 **************************************************************************/
2177 static int exit_pillage_dlg_callback(struct widget
*pWidget
)
2179 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2180 popdown_pillage_dialog();
2185 /**************************************************************************
2186 Popdown a dialog asking the unit which improvement they would like to
2188 **************************************************************************/
2189 static void popdown_pillage_dialog(void)
2192 is_unit_move_blocked
= FALSE
;
2193 popdown_window_group_dialog(pPillage_Dlg
->pBeginWidgetList
,
2194 pPillage_Dlg
->pEndWidgetList
);
2195 FC_FREE(pPillage_Dlg
);
2200 /**************************************************************************
2201 Popup a dialog asking the unit which improvement they would like to
2203 **************************************************************************/
2204 void popup_pillage_dialog(struct unit
*pUnit
, bv_extras extras
)
2206 struct widget
*pWindow
= NULL
, *pBuf
= NULL
;
2209 struct extra_type
*tgt
;
2215 is_unit_move_blocked
= TRUE
;
2216 pPillage_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
2219 pstr
= create_utf8_from_char(_("What To Pillage") , adj_font(12));
2220 pstr
->style
|= TTF_STYLE_BOLD
;
2222 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
2224 pWindow
->action
= pillage_window_callback
;
2225 set_wstate(pWindow
, FC_WS_NORMAL
);
2227 add_to_gui_list(ID_PILLAGE_DLG_WINDOW
, pWindow
);
2228 pPillage_Dlg
->pEndWidgetList
= pWindow
;
2230 area
= pWindow
->area
;
2232 area
.h
= MAX(area
.h
, adj_size(2));
2236 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
2237 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
2238 pBuf
->info_label
= create_utf8_from_char(_("Close Dialog (Esc)"),
2240 area
.w
+= pBuf
->size
.w
+ adj_size(10);
2241 pBuf
->action
= exit_pillage_dlg_callback
;
2242 set_wstate(pBuf
, FC_WS_NORMAL
);
2243 pBuf
->key
= SDLK_ESCAPE
;
2245 add_to_gui_list(ID_PILLAGE_DLG_EXIT_BUTTON
, pBuf
);
2248 while ((tgt
= get_preferred_pillage(extras
))) {
2249 const char *name
= NULL
;
2252 BV_CLR(extras
, extra_index(tgt
));
2253 name
= extra_name_translation(tgt
);
2254 what
= extra_index(tgt
);
2256 fc_assert(name
!= NULL
);
2258 create_active_iconlabel(pBuf
, pWindow
->dst
, pstr
,
2259 (char *) name
, pillage_callback
);
2261 pBuf
->data
.unit
= pUnit
;
2262 set_wstate(pBuf
, FC_WS_NORMAL
);
2264 add_to_gui_list(MAX_ID
- what
, pBuf
);
2266 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
2267 area
.h
+= pBuf
->size
.h
;
2269 pPillage_Dlg
->pBeginWidgetList
= pBuf
;
2271 /* setup window size and start position */
2273 resize_window(pWindow
, NULL
, NULL
,
2274 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
2275 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
2277 area
= pWindow
->area
;
2279 put_window_near_map_tile(pWindow
, pWindow
->size
.w
, pWindow
->size
.h
,
2282 /* setup widget size and start position */
2285 pBuf
= pWindow
->prev
;
2286 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
2287 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
2289 /* first special to pillage */
2291 setup_vertical_widgets_position(1,
2292 area
.x
, area
.y
+ 1, area
.w
, 0,
2293 pPillage_Dlg
->pBeginWidgetList
, pBuf
);
2295 /* --------------------- */
2297 redraw_group(pPillage_Dlg
->pBeginWidgetList
, pWindow
, 0);
2299 widget_flush(pWindow
);
2302 /* ======================================================================= */
2303 /* =========================== CONNECT DIALOG ============================ */
2304 /* ======================================================================= */
2305 static struct SMALL_DLG
*pConnect_Dlg
= NULL
;
2307 /**************************************************************************
2308 Popdown a dialog asking the unit how they want to "connect" their
2309 location to the destination.
2310 **************************************************************************/
2311 static void popdown_connect_dialog(void)
2314 is_unit_move_blocked
= FALSE
;
2315 popdown_window_group_dialog(pConnect_Dlg
->pBeginWidgetList
,
2316 pConnect_Dlg
->pEndWidgetList
);
2317 FC_FREE(pConnect_Dlg
);
2321 /**************************************************************************
2323 **************************************************************************/
2324 static struct SMALL_DLG
*pRevolutionDlg
= NULL
;
2326 /**************************************************************************
2327 User confirmed revolution.
2328 **************************************************************************/
2329 static int revolution_dlg_ok_callback(struct widget
*pButton
)
2331 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2334 popdown_revolution_dialog();
2341 /**************************************************************************
2342 User cancelled revolution.
2343 **************************************************************************/
2344 static int revolution_dlg_cancel_callback(struct widget
*pCancel_Button
)
2346 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2347 popdown_revolution_dialog();
2353 /**************************************************************************
2354 User requested move of revolution dialog.
2355 **************************************************************************/
2356 static int move_revolution_dlg_callback(struct widget
*pWindow
)
2358 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2359 move_window_group(pRevolutionDlg
->pBeginWidgetList
, pWindow
);
2364 /**************************************************************************
2365 Close the revolution dialog.
2366 **************************************************************************/
2367 static void popdown_revolution_dialog(void)
2369 if (pRevolutionDlg
) {
2370 popdown_window_group_dialog(pRevolutionDlg
->pBeginWidgetList
,
2371 pRevolutionDlg
->pEndWidgetList
);
2372 FC_FREE(pRevolutionDlg
);
2373 enable_and_redraw_revolution_button();
2377 /* ==================== Public ========================= */
2379 /**************************************************************************
2380 Select Goverment Type
2381 **************************************************************************/
2382 static struct SMALL_DLG
*pGov_Dlg
= NULL
;
2384 /**************************************************************************
2385 Close the government dialog.
2386 **************************************************************************/
2387 static void popdown_government_dialog(void)
2390 popdown_window_group_dialog(pGov_Dlg
->pBeginWidgetList
,
2391 pGov_Dlg
->pEndWidgetList
);
2393 enable_and_redraw_revolution_button();
2397 /**************************************************************************
2398 User selected government button.
2399 **************************************************************************/
2400 static int government_dlg_callback(struct widget
*pGov_Button
)
2402 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2403 set_government_choice(government_by_number(MAX_ID
- pGov_Button
->ID
));
2405 popdown_government_dialog();
2410 /**************************************************************************
2411 User requested move of government dialog.
2412 **************************************************************************/
2413 static int move_government_dlg_callback(struct widget
*pWindow
)
2415 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2416 move_window_group(pGov_Dlg
->pBeginWidgetList
, pWindow
);
2421 /**************************************************************************
2424 Popup a dialog asking the player what government to switch to (this
2425 happens after a revolution completes).
2426 **************************************************************************/
2427 static void popup_government_dialog(void)
2429 SDL_Surface
*pLogo
= NULL
;
2430 struct utf8_str
*pstr
= NULL
;
2431 struct widget
*pGov_Button
= NULL
;
2432 struct widget
*pWindow
= NULL
;
2434 Uint16 max_w
= 0, max_h
= 0;
2441 pGov_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
2444 pstr
= create_utf8_from_char(_("Choose Your New Government"), adj_font(12));
2445 pstr
->style
|= TTF_STYLE_BOLD
;
2446 /* this win. size is temp. */
2447 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
2448 pWindow
->action
= move_government_dlg_callback
;
2449 add_to_gui_list(ID_GOVERNMENT_DLG_WINDOW
, pWindow
);
2451 pGov_Dlg
->pEndWidgetList
= pWindow
;
2453 area
= pWindow
->area
;
2455 /* create gov. buttons */
2457 governments_iterate(pGov
) {
2458 if (pGov
== game
.government_during_revolution
) {
2462 if (can_change_to_government(client
.conn
.playing
, pGov
)) {
2463 pstr
= create_utf8_from_char(government_name_translation(pGov
), adj_font(12));
2465 create_icon_button(get_government_surface(pGov
), pWindow
->dst
, pstr
, 0);
2466 pGov_Button
->action
= government_dlg_callback
;
2468 max_w
= MAX(max_w
, pGov_Button
->size
.w
);
2469 max_h
= MAX(max_h
, pGov_Button
->size
.h
);
2472 add_to_gui_list((MAX_ID
- government_number(pGov
)), pGov_Button
);
2476 } governments_iterate_end
;
2478 pGov_Dlg
->pBeginWidgetList
= pGov_Button
;
2480 max_w
+= adj_size(10);
2481 max_h
+= adj_size(4);
2483 area
.w
= MAX(area
.w
, max_w
+ adj_size(20));
2484 area
.h
= MAX(area
.h
, j
* (max_h
+ adj_size(10)) + adj_size(5));
2486 /* create window background */
2487 pLogo
= theme_get_background(theme
, BACKGROUND_CHOOSEGOVERNMENTDLG
);
2488 if (resize_window(pWindow
, pLogo
, NULL
,
2489 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
2490 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
)) {
2494 area
= pWindow
->area
;
2496 /* set window start positions */
2497 widget_set_position(pWindow
,
2498 (main_window_width() - pWindow
->size
.w
) / 2,
2499 (main_window_height() - pWindow
->size
.h
) / 2);
2501 /* set buttons start positions and size */
2503 while (pGov_Button
!= pGov_Dlg
->pEndWidgetList
) {
2504 pGov_Button
->size
.w
= max_w
;
2505 pGov_Button
->size
.h
= max_h
;
2506 pGov_Button
->size
.x
= area
.x
+ adj_size(10);
2507 pGov_Button
->size
.y
= area
.y
+ area
.h
- (j
++) * (max_h
+ adj_size(10));
2508 set_wstate(pGov_Button
, FC_WS_NORMAL
);
2510 pGov_Button
= pGov_Button
->next
;
2513 set_wstate(pWindow
, FC_WS_NORMAL
);
2516 redraw_group(pGov_Dlg
->pBeginWidgetList
, pWindow
, 0);
2518 widget_flush(pWindow
);
2521 /**************************************************************************
2522 Popup a dialog asking if the player wants to start a revolution.
2523 **************************************************************************/
2524 void popup_revolution_dialog(void)
2527 utf8_str
*pstr
= NULL
;
2528 struct widget
*pLabel
= NULL
;
2529 struct widget
*pWindow
= NULL
;
2530 struct widget
*pCancel_Button
= NULL
;
2531 struct widget
*pOK_Button
= NULL
;
2534 if (pRevolutionDlg
) {
2538 if (0 <= client
.conn
.playing
->revolution_finishes
) {
2539 popup_government_dialog();
2543 pRevolutionDlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
2545 pstr
= create_utf8_from_char(_("REVOLUTION!"), adj_font(12));
2546 pstr
->style
|= TTF_STYLE_BOLD
;
2548 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
2549 pWindow
->action
= move_revolution_dlg_callback
;
2550 set_wstate(pWindow
, FC_WS_NORMAL
);
2551 add_to_gui_list(ID_REVOLUTION_DLG_WINDOW
, pWindow
);
2552 pRevolutionDlg
->pEndWidgetList
= pWindow
;
2554 area
= pWindow
->area
;
2556 /* create text label */
2557 pstr
= create_utf8_from_char(_("You say you wanna revolution?"), adj_font(10));
2558 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
2559 pstr
->fgcol
= *get_theme_color(COLOR_THEME_REVOLUTIONDLG_TEXT
);
2560 pLabel
= create_iconlabel(NULL
, pWindow
->dst
, pstr
, 0);
2561 add_to_gui_list(ID_REVOLUTION_DLG_LABEL
, pLabel
);
2563 /* create cancel button */
2565 create_themeicon_button_from_chars(current_theme
->Small_CANCEL_Icon
,
2566 pWindow
->dst
, _("Cancel"), adj_font(10), 0);
2567 pCancel_Button
->action
= revolution_dlg_cancel_callback
;
2568 pCancel_Button
->size
.w
+= adj_size(6);
2569 set_wstate(pCancel_Button
, FC_WS_NORMAL
);
2570 add_to_gui_list(ID_REVOLUTION_DLG_CANCEL_BUTTON
, pCancel_Button
);
2572 /* create ok button */
2574 create_themeicon_button_from_chars(current_theme
->Small_OK_Icon
,
2575 pWindow
->dst
, _("Revolution!"),
2577 pOK_Button
->action
= revolution_dlg_ok_callback
;
2578 pOK_Button
->key
= SDLK_RETURN
;
2579 set_wstate(pOK_Button
, FC_WS_NORMAL
);
2580 add_to_gui_list(ID_REVOLUTION_DLG_OK_BUTTON
, pOK_Button
);
2582 pRevolutionDlg
->pBeginWidgetList
= pOK_Button
;
2584 if ((pOK_Button
->size
.w
+ pCancel_Button
->size
.w
+ adj_size(30)) >
2585 pLabel
->size
.w
+ adj_size(20)) {
2586 area
.w
= MAX(area
.w
, pOK_Button
->size
.w
+ pCancel_Button
->size
.w
+ adj_size(30));
2588 area
.w
= MAX(area
.w
, pLabel
->size
.w
+ adj_size(20));
2591 area
.h
= MAX(area
.h
, pOK_Button
->size
.h
+ pLabel
->size
.h
+ adj_size(24));
2593 /* create window background */
2594 pLogo
= theme_get_background(theme
, BACKGROUND_REVOLUTIONDLG
);
2595 if (resize_window(pWindow
, pLogo
, NULL
,
2596 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
2597 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
)) {
2601 area
= pWindow
->area
;
2603 /* set start positions */
2604 widget_set_position(pWindow
,
2605 (main_window_width() - pWindow
->size
.w
) / 2,
2606 (main_window_height() - pWindow
->size
.h
) / 2);
2608 pOK_Button
->size
.x
= area
.x
+ adj_size(10);
2609 pOK_Button
->size
.y
= area
.y
+ area
.h
- pOK_Button
->size
.h
- adj_size(10);
2611 pCancel_Button
->size
.y
= pOK_Button
->size
.y
;
2612 pCancel_Button
->size
.x
= area
.x
+ area
.w
- pCancel_Button
->size
.w
- adj_size(10);
2614 pLabel
->size
.x
= area
.x
;
2615 pLabel
->size
.y
= area
.y
+ adj_size(4);
2616 pLabel
->size
.w
= area
.w
;
2619 redraw_group(pOK_Button
, pWindow
, 0);
2620 widget_mark_dirty(pWindow
);
2624 /**************************************************************************
2626 **************************************************************************/
2627 static struct ADVANCED_DLG
*pNationDlg
= NULL
;
2628 static struct SMALL_DLG
*pHelpDlg
= NULL
;
2631 unsigned char nation_style
; /* selected style */
2632 unsigned char selected_leader
; /* if not unique -> selected leader */
2633 Nation_type_id nation
; /* selected nation */
2634 bool leader_sex
; /* selected leader sex */
2635 struct nation_set
*set
;
2636 struct widget
*pChange_Sex
;
2637 struct widget
*pName_Edit
;
2638 struct widget
*pName_Next
;
2639 struct widget
*pName_Prev
;
2640 struct widget
*pset_name
;
2641 struct widget
*pset_next
;
2642 struct widget
*pset_prev
;
2645 static int next_set_callback(struct widget
*next_button
);
2646 static int prev_set_callback(struct widget
*prev_button
);
2647 static int nations_dialog_callback(struct widget
*pWindow
);
2648 static int nation_button_callback(struct widget
*pNation
);
2649 static int races_dialog_ok_callback(struct widget
*pStart_Button
);
2650 static int races_dialog_cancel_callback(struct widget
*pButton
);
2651 static int next_name_callback(struct widget
*pNext_Button
);
2652 static int prev_name_callback(struct widget
*pPrev_Button
);
2653 static int change_sex_callback(struct widget
*pSex
);
2654 static void select_random_leader(Nation_type_id nation
);
2655 static void change_nation_label(void);
2657 /**************************************************************************
2658 User interacted with nations dialog.
2659 **************************************************************************/
2660 static int nations_dialog_callback(struct widget
*pWindow
)
2662 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2663 if (select_window_group_dialog(pNationDlg
->pBeginWidgetList
, pWindow
)) {
2664 widget_flush(pWindow
);
2670 /**************************************************************************
2671 User accepted nation.
2672 **************************************************************************/
2673 static int races_dialog_ok_callback(struct widget
*pStart_Button
)
2675 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2676 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2677 char *pstr
= pSetup
->pName_Edit
->string_utf8
->text
;
2679 /* perform a minimum of sanity test on the name */
2680 if (strlen(pstr
) == 0) {
2681 output_window_append(ftc_client
, _("You must type a legal name."));
2682 selected_widget
= pStart_Button
;
2683 set_wstate(pStart_Button
, FC_WS_SELECTED
);
2684 widget_redraw(pStart_Button
);
2685 widget_flush(pStart_Button
);
2690 dsend_packet_nation_select_req(&client
.conn
, player_number(races_player
),
2692 pSetup
->leader_sex
, pstr
,
2693 pSetup
->nation_style
);
2695 popdown_races_dialog();
2702 /**************************************************************************
2703 User requested leader gender change.
2704 **************************************************************************/
2705 static int change_sex_callback(struct widget
*pSex
)
2707 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2708 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2710 if (pSetup
->leader_sex
) {
2711 copy_chars_to_utf8_str(pSetup
->pChange_Sex
->string_utf8
, _("Female"));
2713 copy_chars_to_utf8_str(pSetup
->pChange_Sex
->string_utf8
, _("Male"));
2715 pSetup
->leader_sex
= !pSetup
->leader_sex
;
2718 selected_widget
= pSex
;
2719 set_wstate(pSex
, FC_WS_SELECTED
);
2721 widget_redraw(pSex
);
2728 /**************************************************************************
2729 User requested next leader name.
2730 **************************************************************************/
2731 static int next_name_callback(struct widget
*pNext
)
2733 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2734 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2735 const struct nation_leader_list
*leaders
=
2736 nation_leaders(nation_by_number(pSetup
->nation
));
2737 const struct nation_leader
*pleader
;
2739 pSetup
->selected_leader
++;
2740 pleader
= nation_leader_list_get(leaders
, pSetup
->selected_leader
);
2742 /* change leader sex */
2743 if (pSetup
->leader_sex
!= nation_leader_is_male(pleader
)) {
2744 change_sex_callback(NULL
);
2747 /* change leader name */
2748 copy_chars_to_utf8_str(pSetup
->pName_Edit
->string_utf8
,
2749 nation_leader_name(pleader
));
2751 FC_FREE(pLeaderName
);
2752 pLeaderName
= fc_strdup(nation_leader_name(pleader
));
2754 if (nation_leader_list_size(leaders
) - 1 == pSetup
->selected_leader
) {
2755 set_wstate(pSetup
->pName_Next
, FC_WS_DISABLED
);
2758 if (get_wstate(pSetup
->pName_Prev
) == FC_WS_DISABLED
) {
2759 set_wstate(pSetup
->pName_Prev
, FC_WS_NORMAL
);
2762 if (!(get_wstate(pSetup
->pName_Next
) == FC_WS_DISABLED
)) {
2763 selected_widget
= pSetup
->pName_Next
;
2764 set_wstate(pSetup
->pName_Next
, FC_WS_SELECTED
);
2767 widget_redraw(pSetup
->pName_Edit
);
2768 widget_redraw(pSetup
->pName_Prev
);
2769 widget_redraw(pSetup
->pName_Next
);
2770 widget_mark_dirty(pSetup
->pName_Edit
);
2771 widget_mark_dirty(pSetup
->pName_Prev
);
2772 widget_mark_dirty(pSetup
->pName_Next
);
2774 widget_redraw(pSetup
->pChange_Sex
);
2775 widget_mark_dirty(pSetup
->pChange_Sex
);
2782 /**************************************************************************
2783 User requested previous leader name.
2784 **************************************************************************/
2785 static int prev_name_callback(struct widget
*pPrev
)
2787 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2788 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2789 const struct nation_leader_list
*leaders
=
2790 nation_leaders(nation_by_number(pSetup
->nation
));
2791 const struct nation_leader
*pleader
;
2793 pSetup
->selected_leader
--;
2794 pleader
= nation_leader_list_get(leaders
, pSetup
->selected_leader
);
2796 /* change leader sex */
2797 if (pSetup
->leader_sex
!= nation_leader_is_male(pleader
)) {
2798 change_sex_callback(NULL
);
2801 /* change leader name */
2802 copy_chars_to_utf8_str(pSetup
->pName_Edit
->string_utf8
,
2803 nation_leader_name(pleader
));
2805 FC_FREE(pLeaderName
);
2806 pLeaderName
= fc_strdup(nation_leader_name(pleader
));
2808 if (!pSetup
->selected_leader
) {
2809 set_wstate(pSetup
->pName_Prev
, FC_WS_DISABLED
);
2812 if (get_wstate(pSetup
->pName_Next
) == FC_WS_DISABLED
) {
2813 set_wstate(pSetup
->pName_Next
, FC_WS_NORMAL
);
2816 if (!(get_wstate(pSetup
->pName_Prev
) == FC_WS_DISABLED
)) {
2817 selected_widget
= pSetup
->pName_Prev
;
2818 set_wstate(pSetup
->pName_Prev
, FC_WS_SELECTED
);
2821 widget_redraw(pSetup
->pName_Edit
);
2822 widget_redraw(pSetup
->pName_Prev
);
2823 widget_redraw(pSetup
->pName_Next
);
2824 widget_mark_dirty(pSetup
->pName_Edit
);
2825 widget_mark_dirty(pSetup
->pName_Prev
);
2826 widget_mark_dirty(pSetup
->pName_Next
);
2828 widget_redraw(pSetup
->pChange_Sex
);
2829 widget_mark_dirty(pSetup
->pChange_Sex
);
2836 /**************************************************************************
2837 User requested next nationset
2838 **************************************************************************/
2839 static int next_set_callback(struct widget
*next_button
)
2841 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2842 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2843 struct option
*poption
= optset_option_by_name(server_optset
, "nationset");
2845 fc_assert(pSetup
->set
!= NULL
2846 && nation_set_index(pSetup
->set
) < nation_set_count() - 1);
2848 pSetup
->set
= nation_set_by_number(nation_set_index(pSetup
->set
) + 1);
2850 option_str_set(poption
, nation_set_rule_name(pSetup
->set
));
2856 /**************************************************************************
2857 User requested prev nationset
2858 **************************************************************************/
2859 static int prev_set_callback(struct widget
*prev_button
)
2861 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2862 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2863 struct option
*poption
= optset_option_by_name(server_optset
, "nationset");
2865 fc_assert(pSetup
->set
!= NULL
&& nation_set_index(pSetup
->set
) > 0);
2867 pSetup
->set
= nation_set_by_number(nation_set_index(pSetup
->set
) - 1);
2869 option_str_set(poption
, nation_set_rule_name(pSetup
->set
));
2875 /**************************************************************************
2876 User cancelled nations dialog.
2877 **************************************************************************/
2878 static int races_dialog_cancel_callback(struct widget
*pButton
)
2880 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2881 popdown_races_dialog();
2887 /**************************************************************************
2888 User interacted with style widget.
2889 **************************************************************************/
2890 static int style_callback(struct widget
*pWidget
)
2892 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2893 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2894 struct widget
*pGUI
= get_widget_pointer_form_main_list(MAX_ID
- 1000 -
2895 pSetup
->nation_style
);
2897 set_wstate(pGUI
, FC_WS_NORMAL
);
2898 widget_redraw(pGUI
);
2899 widget_mark_dirty(pGUI
);
2901 set_wstate(pWidget
, FC_WS_DISABLED
);
2902 widget_redraw(pWidget
);
2903 widget_mark_dirty(pWidget
);
2905 pSetup
->nation_style
= MAX_ID
- 1000 - pWidget
->ID
;
2908 selected_widget
= NULL
;
2913 /**************************************************************************
2914 User interacted with help dialog.
2915 **************************************************************************/
2916 static int help_dlg_callback(struct widget
*pWindow
)
2921 /**************************************************************************
2922 User requested closing of help dialog.
2923 **************************************************************************/
2924 static int cancel_help_dlg_callback(struct widget
*pWidget
)
2926 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2928 popdown_window_group_dialog(pHelpDlg
->pBeginWidgetList
,
2929 pHelpDlg
->pEndWidgetList
);
2939 /**************************************************************************
2940 User selected nation.
2941 **************************************************************************/
2942 static int nation_button_callback(struct widget
*pNationButton
)
2944 set_wstate(pNationButton
, FC_WS_SELECTED
);
2945 selected_widget
= pNationButton
;
2947 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2948 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2950 if (pSetup
->nation
== MAX_ID
- pNationButton
->ID
) {
2951 widget_redraw(pNationButton
);
2952 widget_flush(pNationButton
);
2956 pSetup
->nation
= MAX_ID
- pNationButton
->ID
;
2958 change_nation_label();
2960 enable(MAX_ID
- 1000 - pSetup
->nation_style
);
2961 pSetup
->nation_style
= style_number(style_of_nation(nation_by_number(pSetup
->nation
)));
2962 disable(MAX_ID
- 1000 - pSetup
->nation_style
);
2964 select_random_leader(pSetup
->nation
);
2966 redraw_group(pNationDlg
->pBeginWidgetList
, pNationDlg
->pEndWidgetList
, 0);
2967 widget_flush(pNationDlg
->pEndWidgetList
);
2969 /* pop up nation description */
2970 struct widget
*pWindow
, *pOK_Button
;
2973 SDL_Rect area
, area2
;
2974 struct nation_type
*pNation
= nation_by_number(MAX_ID
- pNationButton
->ID
);
2976 widget_redraw(pNationButton
);
2977 widget_mark_dirty(pNationButton
);
2980 pHelpDlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
2982 pstr
= create_utf8_from_char(nation_plural_translation(pNation
),
2984 pstr
->style
|= TTF_STYLE_BOLD
;
2986 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
2987 pWindow
->action
= help_dlg_callback
;
2989 set_wstate(pWindow
, FC_WS_NORMAL
);
2991 pHelpDlg
->pEndWidgetList
= pWindow
;
2992 add_to_gui_list(ID_WINDOW
, pWindow
);
2994 pOK_Button
= create_themeicon_button_from_chars(current_theme
->OK_Icon
,
2995 pWindow
->dst
, _("OK"), adj_font(14), 0);
2996 pOK_Button
->action
= cancel_help_dlg_callback
;
2997 set_wstate(pOK_Button
, FC_WS_NORMAL
);
2998 pOK_Button
->key
= SDLK_ESCAPE
;
2999 add_to_gui_list(ID_BUTTON
, pOK_Button
);
3000 pHelpDlg
->pBeginWidgetList
= pOK_Button
;
3002 pWindow
= pHelpDlg
->pEndWidgetList
;
3003 pOK_Button
= pHelpDlg
->pBeginWidgetList
;
3005 widget_undraw(pWindow
);
3006 widget_mark_dirty(pWindow
);
3009 area
= pWindow
->area
;
3014 helptext_nation(info
, sizeof(info
), pNation
, NULL
);
3015 pstr
= create_utf8_from_char(info
, adj_font(12));
3018 pstr
->fgcol
= *get_theme_color(COLOR_THEME_NATIONDLG_LEGEND
);
3019 pText
= create_text_surf_smaller_than_w(pstr
, main_window_width() - adj_size(20));
3023 /* create window background */
3024 area
.w
= MAX(area
.w
, pText
->w
+ adj_size(20));
3025 area
.w
= MAX(area
.w
, pOK_Button
->size
.w
+ adj_size(20));
3026 area
.h
= MAX(area
.h
, adj_size(9) + pText
->h
3027 + adj_size(10) + pOK_Button
->size
.h
+ adj_size(10));
3029 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
3030 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
3031 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
3033 widget_set_position(pWindow
,
3034 (main_window_width() - pWindow
->size
.w
) / 2,
3035 (main_window_height() - pWindow
->size
.h
) / 2);
3037 area2
.x
= area
.x
+ adj_size(7);
3038 area2
.y
= area
.y
+ adj_size(6);
3039 alphablit(pText
, NULL
, pWindow
->theme
, &area2
, 255);
3042 pOK_Button
->size
.x
= area
.x
+ (area
.w
- pOK_Button
->size
.w
) / 2;
3043 pOK_Button
->size
.y
= area
.y
+ area
.h
- pOK_Button
->size
.h
- adj_size(10);
3046 redraw_group(pOK_Button
, pWindow
, 0);
3048 widget_mark_dirty(pWindow
);
3056 /**************************************************************************
3057 User interacted with leader name edit widget.
3058 **************************************************************************/
3059 static int leader_name_edit_callback(struct widget
*pEdit
)
3061 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
3062 if (pEdit
->string_utf8
->text
!= NULL
) {
3063 /* empty input -> restore previous content */
3064 copy_chars_to_utf8_str(pEdit
->string_utf8
, pLeaderName
);
3065 widget_redraw(pEdit
);
3066 widget_mark_dirty(pEdit
);
3073 /* =========================================================== */
3075 /**************************************************************************
3076 Update nation label.
3077 **************************************************************************/
3078 static void change_nation_label(void)
3080 SDL_Surface
*pTmp_Surf
, *pTmp_Surf_zoomed
;
3081 struct widget
*pWindow
= pNationDlg
->pEndWidgetList
;
3082 struct NAT
*pSetup
= (struct NAT
*)(pWindow
->data
.ptr
);
3083 struct widget
*pLabel
= pSetup
->pName_Edit
->next
;
3084 struct nation_type
*pNation
= nation_by_number(pSetup
->nation
);
3086 pTmp_Surf
= get_nation_flag_surface(pNation
);
3087 pTmp_Surf_zoomed
= zoomSurface(pTmp_Surf
, DEFAULT_ZOOM
* 1.0, DEFAULT_ZOOM
* 1.0, 1);
3089 FREESURFACE(pLabel
->theme
);
3090 pLabel
->theme
= pTmp_Surf_zoomed
;
3092 copy_chars_to_utf8_str(pLabel
->string_utf8
, nation_plural_translation(pNation
));
3094 remake_label_size(pLabel
);
3096 pLabel
->size
.x
= pWindow
->size
.x
+ pWindow
->size
.w
/ 2 +
3097 (pWindow
->size
.w
/2 - pLabel
->size
.w
) / 2;
3101 /**************************************************************************
3102 Selectes a leader and the appropriate sex. Updates the gui elements
3103 and the selected_* variables.
3104 **************************************************************************/
3105 static void select_random_leader(Nation_type_id nation
)
3107 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
3108 const struct nation_leader_list
*leaders
=
3109 nation_leaders(nation_by_number(pSetup
->nation
));
3110 const struct nation_leader
*pleader
;
3112 pSetup
->selected_leader
= fc_rand(nation_leader_list_size(leaders
));
3113 pleader
= nation_leader_list_get(leaders
, pSetup
->selected_leader
);
3114 copy_chars_to_utf8_str(pSetup
->pName_Edit
->string_utf8
,
3115 nation_leader_name(pleader
));
3117 FC_FREE(pLeaderName
);
3118 pLeaderName
= fc_strdup(nation_leader_name(pleader
));
3120 /* initialize leader sex */
3121 pSetup
->leader_sex
= nation_leader_is_male(pleader
);
3123 if (pSetup
->leader_sex
) {
3124 copy_chars_to_utf8_str(pSetup
->pChange_Sex
->string_utf8
, _("Male"));
3126 copy_chars_to_utf8_str(pSetup
->pChange_Sex
->string_utf8
, _("Female"));
3129 /* disable navigation buttons */
3130 set_wstate(pSetup
->pName_Prev
, FC_WS_DISABLED
);
3131 set_wstate(pSetup
->pName_Next
, FC_WS_DISABLED
);
3133 if (1 < nation_leader_list_size(leaders
)) {
3134 /* if selected leader is not the first leader, enable "previous leader" button */
3135 if (pSetup
->selected_leader
> 0) {
3136 set_wstate(pSetup
->pName_Prev
, FC_WS_NORMAL
);
3139 /* if selected leader is not the last leader, enable "next leader" button */
3140 if (pSetup
->selected_leader
< (nation_leader_list_size(leaders
) - 1)) {
3141 set_wstate(pSetup
->pName_Next
, FC_WS_NORMAL
);
3146 /**************************************************************************
3147 Count available playable nations.
3148 **************************************************************************/
3149 static int get_playable_nation_count(void)
3151 int playable_nation_count
= 0;
3153 nations_iterate(pnation
) {
3154 if (pnation
->is_playable
&& !pnation
->player
3155 && is_nation_pickable(pnation
))
3156 playable_nation_count
++;
3157 } nations_iterate_end
;
3159 return playable_nation_count
;
3162 /**************************************************************************
3163 Popup the nation selection dialog.
3164 **************************************************************************/
3165 void popup_races_dialog(struct player
*pplayer
)
3167 SDL_Color bg_color
= {255,255,255,128};
3169 struct widget
*pWindow
, *pWidget
= NULL
, *pBuf
, *pLast_City_Style
;
3172 int w
= adj_size(10), h
= adj_size(10);
3173 SDL_Surface
*pTmp_Surf
, *pTmp_Surf_zoomed
= NULL
;
3174 SDL_Surface
*pMain_Bg
, *pText_Name
, *pText_Class
;
3180 struct nation_type
*pnat
;
3181 struct widget
*nationsets
= NULL
;
3182 int natinfo_y
, natinfo_h
;
3184 #define TARGETS_ROW 5
3185 #define TARGETS_COL 1
3191 races_player
= pplayer
;
3193 pNationDlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
3195 /* create window widget */
3196 pstr
= create_utf8_from_char(_("What nation will you be?"), adj_font(12));
3197 pstr
->style
|= TTF_STYLE_BOLD
;
3199 pWindow
= create_window(NULL
, pstr
, w
, h
, WF_FREE_DATA
);
3200 pWindow
->action
= nations_dialog_callback
;
3201 set_wstate(pWindow
, FC_WS_NORMAL
);
3202 pSetup
= fc_calloc(1, sizeof(struct NAT
));
3203 pWindow
->data
.ptr
= (void *)pSetup
;
3205 pNationDlg
->pEndWidgetList
= pWindow
;
3206 add_to_gui_list(ID_NATION_WIZARD_WINDOW
, pWindow
);
3207 /* --------------------------------------------------------- */
3208 /* create nations list */
3210 /* Create Imprv Background Icon */
3211 pMain_Bg
= create_surf(adj_size(96*2), adj_size(64), SDL_SWSURFACE
);
3213 SDL_FillRect(pMain_Bg
, NULL
, map_rgba(pMain_Bg
->format
, bg_color
));
3215 create_frame(pMain_Bg
,
3216 0, 0, pMain_Bg
->w
- 1, pMain_Bg
->h
- 1,
3217 get_theme_color(COLOR_THEME_NATIONDLG_FRAME
));
3219 pstr
= create_utf8_str(NULL
, 0, adj_font(12));
3220 pstr
->style
|= (SF_CENTER
|TTF_STYLE_BOLD
);
3221 pstr
->bgcol
= (SDL_Color
) {0, 0, 0, 0};
3226 nations_iterate(pNation
) {
3227 if (!is_nation_playable(pNation
) || !is_nation_pickable(pNation
)) {
3231 pTmp_Surf_zoomed
= adj_surf(get_nation_flag_surface(pNation
));
3233 pTmp_Surf
= crop_rect_from_surface(pMain_Bg
, NULL
);
3235 copy_chars_to_utf8_str(pstr
, nation_plural_translation(pNation
));
3236 change_ptsize_utf8(pstr
, adj_font(12));
3237 pText_Name
= create_text_surf_smaller_than_w(pstr
, pTmp_Surf
->w
- adj_size(4));
3239 if (pNation
->legend
&& *(pNation
->legend
) != '\0') {
3240 copy_chars_to_utf8_str(pstr
, pNation
->legend
);
3241 change_ptsize_utf8(pstr
, adj_font(10));
3242 pText_Class
= create_text_surf_smaller_than_w(pstr
, pTmp_Surf
->w
- adj_size(4));
3245 dst
.x
= (pTmp_Surf
->w
- pTmp_Surf_zoomed
->w
) / 2;
3246 len
= pTmp_Surf_zoomed
->h
+
3247 adj_size(10) + pText_Name
->h
+ (pText_Class
? pText_Class
->h
: 0);
3248 dst
.y
= (pTmp_Surf
->h
- len
) / 2;
3249 alphablit(pTmp_Surf_zoomed
, NULL
, pTmp_Surf
, &dst
, 255);
3250 dst
.y
+= (pTmp_Surf_zoomed
->h
+ adj_size(10));
3252 dst
.x
= (pTmp_Surf
->w
- pText_Name
->w
) / 2;
3253 alphablit(pText_Name
, NULL
, pTmp_Surf
, &dst
, 255);
3254 dst
.y
+= pText_Name
->h
;
3255 FREESURFACE(pText_Name
);
3258 dst
.x
= (pTmp_Surf
->w
- pText_Class
->w
) / 2;
3259 alphablit(pText_Class
, NULL
, pTmp_Surf
, &dst
, 255);
3260 FREESURFACE(pText_Class
);
3263 pWidget
= create_icon2(pTmp_Surf
, pWindow
->dst
,
3264 (WF_RESTORE_BACKGROUND
|WF_FREE_THEME
));
3266 set_wstate(pWidget
, FC_WS_NORMAL
);
3268 pWidget
->action
= nation_button_callback
;
3270 w
= MAX(w
, pWidget
->size
.w
);
3271 h
= MAX(h
, pWidget
->size
.h
);
3273 add_to_gui_list(MAX_ID
- nation_index(pNation
), pWidget
);
3275 if (nation_index(pNation
) > (TARGETS_ROW
* TARGETS_COL
- 1)) {
3276 set_wflag(pWidget
, WF_HIDDEN
);
3279 } nations_iterate_end
;
3281 FREESURFACE(pMain_Bg
);
3283 pNationDlg
->pEndActiveWidgetList
= pWindow
->prev
;
3284 pNationDlg
->pBeginWidgetList
= pWidget
;
3285 pNationDlg
->pBeginActiveWidgetList
= pNationDlg
->pBeginWidgetList
;
3287 if (get_playable_nation_count() > TARGETS_ROW
* TARGETS_COL
) {
3288 pNationDlg
->pActiveWidgetList
= pNationDlg
->pEndActiveWidgetList
;
3289 create_vertical_scrollbar(pNationDlg
,
3290 TARGETS_COL
, TARGETS_ROW
, TRUE
, TRUE
);
3293 /* ----------------------------------------------------------------- */
3295 /* nation set selection */
3296 if (nation_set_count() > 1) {
3297 utf8_str
*natset_str
;
3298 struct option
*poption
;
3300 natset_str
= create_utf8_from_char(_("Nation set"), adj_font(12));
3301 change_ptsize_utf8(natset_str
, adj_font(24));
3302 nationsets
= create_iconlabel(NULL
, pWindow
->dst
, natset_str
, 0);
3303 add_to_gui_list(ID_LABEL
, nationsets
);
3305 /* create nation set name label */
3306 poption
= optset_option_by_name(server_optset
, "nationset");
3307 pSetup
->set
= nation_set_by_setting_value(option_str_get(poption
));
3309 natset_str
= create_utf8_from_char(nation_set_name_translation(pSetup
->set
),
3311 change_ptsize_utf8(natset_str
, adj_font(24));
3313 pWidget
= create_iconlabel(NULL
, pWindow
->dst
, natset_str
, 0);
3315 add_to_gui_list(ID_LABEL
, pWidget
);
3316 pSetup
->pset_name
= pWidget
;
3318 /* create next nationset button */
3319 pWidget
= create_themeicon_button(current_theme
->R_ARROW_Icon
,
3320 pWindow
->dst
, NULL
, 0);
3321 pWidget
->action
= next_set_callback
;
3322 if (nation_set_index(pSetup
->set
) < nation_set_count() - 1) {
3323 set_wstate(pWidget
, FC_WS_NORMAL
);
3325 add_to_gui_list(ID_NATION_NEXT_NATIONSET_BUTTON
, pWidget
);
3326 pWidget
->size
.h
= pWidget
->next
->size
.h
;
3327 pSetup
->pset_next
= pWidget
;
3329 /* create prev nationset button */
3330 pWidget
= create_themeicon_button(current_theme
->L_ARROW_Icon
,
3331 pWindow
->dst
, NULL
, 0);
3332 pWidget
->action
= prev_set_callback
;
3333 if (nation_set_index(pSetup
->set
) > 0) {
3334 set_wstate(pWidget
, FC_WS_NORMAL
);
3336 add_to_gui_list(ID_NATION_PREV_NATIONSET_BUTTON
, pWidget
);
3337 pWidget
->size
.h
= pWidget
->next
->size
.h
;
3338 pSetup
->pset_prev
= pWidget
;
3342 pSetup
->nation
= fc_rand(get_playable_nation_count());
3343 pnat
= nation_by_number(pSetup
->nation
);
3344 pSetup
->nation_style
= style_number(style_of_nation(pnat
));
3346 copy_chars_to_utf8_str(pstr
, nation_plural_translation(pnat
));
3347 change_ptsize_utf8(pstr
, adj_font(24));
3349 pstr
->fgcol
= *get_theme_color(COLOR_THEME_NATIONDLG_TEXT
);
3351 pTmp_Surf_zoomed
= adj_surf(get_nation_flag_surface(pnat
));
3353 pWidget
= create_iconlabel(pTmp_Surf_zoomed
, pWindow
->dst
, pstr
,
3354 (WF_ICON_ABOVE_TEXT
|WF_ICON_CENTER
|WF_FREE_GFX
));
3355 if (nationsets
== NULL
) {
3361 add_to_gui_list(ID_LABEL
, pWidget
);
3363 /* create leader name edit */
3364 pWidget
= create_edit_from_chars(NULL
, pWindow
->dst
,
3365 NULL
, adj_font(16), adj_size(200), 0);
3366 pWidget
->size
.h
= adj_size(24);
3368 set_wstate(pWidget
, FC_WS_NORMAL
);
3369 pWidget
->action
= leader_name_edit_callback
;
3370 add_to_gui_list(ID_NATION_WIZARD_LEADER_NAME_EDIT
, pWidget
);
3371 pSetup
->pName_Edit
= pWidget
;
3373 /* create next leader name button */
3374 pWidget
= create_themeicon_button(current_theme
->R_ARROW_Icon
,
3375 pWindow
->dst
, NULL
, 0);
3376 pWidget
->action
= next_name_callback
;
3377 add_to_gui_list(ID_NATION_WIZARD_NEXT_LEADER_NAME_BUTTON
, pWidget
);
3378 pWidget
->size
.h
= pWidget
->next
->size
.h
;
3379 pSetup
->pName_Next
= pWidget
;
3381 /* create prev leader name button */
3382 pWidget
= create_themeicon_button(current_theme
->L_ARROW_Icon
,
3383 pWindow
->dst
, NULL
, 0);
3384 pWidget
->action
= prev_name_callback
;
3385 add_to_gui_list(ID_NATION_WIZARD_PREV_LEADER_NAME_BUTTON
, pWidget
);
3386 pWidget
->size
.h
= pWidget
->next
->size
.h
;
3387 pSetup
->pName_Prev
= pWidget
;
3389 /* change sex button */
3390 pWidget
= create_icon_button_from_chars(NULL
, pWindow
->dst
, _("Male"), adj_font(14), 0);
3391 pWidget
->action
= change_sex_callback
;
3392 pWidget
->size
.w
= adj_size(100);
3393 pWidget
->size
.h
= adj_size(22);
3394 set_wstate(pWidget
, FC_WS_NORMAL
);
3395 pSetup
->pChange_Sex
= pWidget
;
3397 /* add to main widget list */
3398 add_to_gui_list(ID_NATION_WIZARD_CHANGE_SEX_BUTTON
, pWidget
);
3400 /* ---------------------------------------------------------- */
3402 zoom
= DEFAULT_ZOOM
* 1.0;
3405 styles_iterate(pstyle
) {
3406 i
= basic_city_style_for_style(pstyle
);
3408 pTmp_Surf
= get_sample_city_surface(i
);
3410 if (pTmp_Surf
->w
> 48) {
3411 zoom
= DEFAULT_ZOOM
* (48.0 / pTmp_Surf
->w
);
3414 pTmp_Surf_zoomed
= zoomSurface(get_sample_city_surface(i
), zoom
, zoom
, 0);
3416 pWidget
= create_icon2(pTmp_Surf_zoomed
, pWindow
->dst
, WF_RESTORE_BACKGROUND
);
3417 pWidget
->action
= style_callback
;
3418 if (i
!= pSetup
->nation_style
) {
3419 set_wstate(pWidget
, FC_WS_NORMAL
);
3421 len
+= pWidget
->size
.w
;
3422 add_to_gui_list(MAX_ID
- 1000 - i
, pWidget
);
3423 } styles_iterate_end
;
3425 pLast_City_Style
= pWidget
;
3426 /* ---------------------------------------------------------- */
3428 /* create Cancel button */
3429 pWidget
= create_themeicon_button_from_chars(current_theme
->CANCEL_Icon
,
3430 pWindow
->dst
, _("Cancel"),
3432 pWidget
->action
= races_dialog_cancel_callback
;
3433 set_wstate(pWidget
, FC_WS_NORMAL
);
3435 add_to_gui_list(ID_NATION_WIZARD_DISCONNECT_BUTTON
, pWidget
);
3437 /* create OK button */
3439 create_themeicon_button_from_chars(current_theme
->OK_Icon
, pWindow
->dst
,
3440 _("OK"), adj_font(12), 0);
3441 pWidget
->action
= races_dialog_ok_callback
;
3443 set_wstate(pWidget
, FC_WS_NORMAL
);
3444 add_to_gui_list(ID_NATION_WIZARD_START_BUTTON
, pWidget
);
3445 pWidget
->size
.w
= MAX(pWidget
->size
.w
, pWidget
->next
->size
.w
);
3446 pWidget
->next
->size
.w
= pWidget
->size
.w
;
3448 pNationDlg
->pBeginWidgetList
= pWidget
;
3449 /* ---------------------------------------------------------- */
3451 pMain_Bg
= theme_get_background(theme
, BACKGROUND_NATIONDLG
);
3452 if (resize_window(pWindow
, pMain_Bg
, NULL
, adj_size(640), adj_size(480))) {
3453 FREESURFACE(pMain_Bg
);
3456 area
= pWindow
->area
;
3458 widget_set_position(pWindow
,
3459 (main_window_width() - pWindow
->size
.w
) / 2,
3460 (main_window_height() - pWindow
->size
.h
) / 2);
3464 h
= pNationDlg
->pEndActiveWidgetList
->size
.h
* TARGETS_ROW
;
3465 i
= (area
.h
- adj_size(43) - h
) / 2;
3466 setup_vertical_widgets_position(TARGETS_COL
,
3467 area
.x
+ adj_size(10),
3468 area
.y
+ i
- adj_size(4),
3469 0, 0, pNationDlg
->pBeginActiveWidgetList
,
3470 pNationDlg
->pEndActiveWidgetList
);
3472 if (pNationDlg
->pScroll
) {
3475 w
= pNationDlg
->pEndActiveWidgetList
->size
.w
* TARGETS_COL
;
3476 setup_vertical_scrollbar_area(pNationDlg
->pScroll
,
3477 area
.x
+ w
+ adj_size(12),
3478 area
.y
+ i
- adj_size(4), h
, FALSE
);
3480 area2
.x
= area
.x
+ w
+ adj_size(11);
3481 area2
.y
= area
.y
+ i
- adj_size(4);
3482 area2
.w
= pNationDlg
->pScroll
->pUp_Left_Button
->size
.w
+ adj_size(2);
3484 fill_rect_alpha(pWindow
->theme
, &area2
, &bg_color
);
3486 create_frame(pWindow
->theme
,
3487 area2
.x
, area2
.y
- 1, area2
.w
, area2
.h
+ 1,
3488 get_theme_color(COLOR_THEME_NATIONDLG_FRAME
));
3491 if (nationsets
!= NULL
) {
3492 /* Nationsets header */
3493 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/ 2 - pBuf
->size
.w
) / 2;
3494 pBuf
->size
.y
= area
.y
+ adj_size(46);
3496 natinfo_y
= pBuf
->size
.y
;
3497 natinfo_h
= area
.h
-= pBuf
->size
.y
;
3499 /* Nationset name */
3501 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/ 2 - pBuf
->size
.w
) / 2;
3502 pBuf
->size
.y
= natinfo_y
+ adj_size(46);
3504 natinfo_y
+= adj_size(46);
3505 natinfo_h
-= adj_size(46);
3507 /* Next Nationset Button */
3509 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
;
3510 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3512 /* Prev Nationset Button */
3514 pBuf
->size
.x
= pBuf
->next
->next
->size
.x
- pBuf
->size
.w
;
3515 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3523 /* Selected Nation Name */
3524 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/ 2 - pBuf
->size
.w
) / 2;
3525 pBuf
->size
.y
= natinfo_y
+ adj_size(46);
3527 /* Leader Name Edit */
3529 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/2 - pBuf
->size
.w
) / 2;
3530 pBuf
->size
.y
= natinfo_y
+ (natinfo_h
- pBuf
->size
.h
) / 2 - adj_size(30);
3532 /* Next Leader Name Button */
3534 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
;
3535 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3537 /* Prev Leader Name Button */
3539 pBuf
->size
.x
= pBuf
->next
->next
->size
.x
- pBuf
->size
.w
;
3540 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3542 /* Change Leader Sex Button */
3544 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/2 - pBuf
->size
.w
) / 2;
3545 pBuf
->size
.y
= pBuf
->next
->size
.y
+ pBuf
->next
->size
.h
+ adj_size(20);
3547 /* First Style Button */
3549 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/2 - len
) / 2 - adj_size(20);
3550 pBuf
->size
.y
= pBuf
->next
->size
.y
+ pBuf
->next
->size
.h
+ adj_size(20);
3552 /* Rest Style Buttons */
3553 while (pBuf
!= pLast_City_Style
) {
3555 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(3);
3556 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3559 create_line(pWindow
->theme
,
3561 natinfo_y
+ natinfo_h
- adj_size(7) - pBuf
->prev
->size
.h
- adj_size(10),
3563 natinfo_y
+ natinfo_h
- adj_size(7) - pBuf
->prev
->size
.h
- adj_size(10),
3564 get_theme_color(COLOR_THEME_NATIONDLG_FRAME
));
3566 /* Disconnect Button */
3568 pBuf
->size
.x
= area
.x
+ adj_size(10);
3569 pBuf
->size
.y
= natinfo_y
+ natinfo_h
- adj_size(7) - pBuf
->size
.h
;
3573 pBuf
->size
.x
= area
.w
- adj_size(10) - pBuf
->size
.w
;
3574 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3576 /* -------------------------------------------------------------------- */
3578 select_random_leader(pSetup
->nation
);
3580 redraw_group(pNationDlg
->pBeginWidgetList
, pWindow
, 0);
3582 widget_flush(pWindow
);
3585 /**************************************************************************
3586 Close the nation selection dialog. This should allow the user to
3587 (at least) select a unit to activate.
3588 **************************************************************************/
3589 void popdown_races_dialog(void)
3592 popdown_window_group_dialog(pNationDlg
->pBeginWidgetList
,
3593 pNationDlg
->pEndWidgetList
);
3595 cancel_help_dlg_callback(NULL
);
3597 FC_FREE(pLeaderName
);
3599 FC_FREE(pNationDlg
->pScroll
);
3600 FC_FREE(pNationDlg
);
3604 /**************************************************************************
3605 The server has changed the set of selectable nations.
3606 **************************************************************************/
3607 void races_update_pickable(bool nationset_change
)
3609 /* If this is because of nationset change, update will take
3610 * place later when the new option value is received */
3611 if (pNationDlg
!= NULL
&& !nationset_change
) {
3612 popdown_races_dialog();
3613 popup_races_dialog(client
.conn
.playing
);
3617 /**************************************************************************
3618 Nationset selection update
3619 **************************************************************************/
3620 void nationset_changed(void)
3622 if (pNationDlg
!= NULL
) {
3623 popdown_races_dialog();
3624 popup_races_dialog(client
.conn
.playing
);
3628 /**************************************************************************
3629 In the nation selection dialog, make already-taken nations unavailable.
3630 This information is contained in the packet_nations_used packet.
3631 **************************************************************************/
3632 void races_toggles_set_sensitive()
3635 bool change
= FALSE
;
3636 struct widget
*pNat
;
3642 pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
3644 nations_iterate(nation
) {
3645 if (!is_nation_pickable(nation
) || nation
->player
) {
3646 log_debug(" [%d]: %d = %s", nation_index(nation
),
3647 (!is_nation_pickable(nation
) || nation
->player
),
3648 nation_rule_name(nation
));
3650 pNat
= get_widget_pointer_form_main_list(MAX_ID
- nation_index(nation
));
3651 set_wstate(pNat
, FC_WS_DISABLED
);
3653 if (nation_index(nation
) == pSetup
->nation
) {
3657 } nations_iterate_end
;
3661 pSetup
->nation
= fc_rand(get_playable_nation_count());
3662 pNat
= get_widget_pointer_form_main_list(MAX_ID
- pSetup
->nation
);
3663 } while (get_wstate(pNat
) == FC_WS_DISABLED
);
3665 if (get_wstate(pSetup
->pName_Edit
) == FC_WS_PRESSED
) {
3666 force_exit_from_event_loop();
3667 set_wstate(pSetup
->pName_Edit
, FC_WS_NORMAL
);
3669 change_nation_label();
3670 enable(MAX_ID
- 1000 - pSetup
->nation_style
);
3671 pSetup
->nation_style
= style_number(style_of_nation(nation_by_number(pSetup
->nation
)));
3672 disable(MAX_ID
- 1000 - pSetup
->nation_style
);
3673 select_random_leader(pSetup
->nation
);
3675 redraw_group(pNationDlg
->pBeginWidgetList
, pNationDlg
->pEndWidgetList
, 0);
3676 widget_flush(pNationDlg
->pEndWidgetList
);
3679 /**************************************************************************
3680 Ruleset (modpack) has suggested loading certain tileset. Confirm from
3682 **************************************************************************/
3683 void popup_tileset_suggestion_dialog(void)
3687 /****************************************************************
3688 Ruleset (modpack) has suggested loading certain soundset. Confirm from
3690 *****************************************************************/
3691 void popup_soundset_suggestion_dialog(void)
3695 /****************************************************************
3696 Ruleset (modpack) has suggested loading certain musicset. Confirm from
3698 *****************************************************************/
3699 void popup_musicset_suggestion_dialog(void)
3703 /**************************************************************************
3704 Tileset (modpack) has suggested loading certain theme. Confirm from
3706 **************************************************************************/
3707 bool popup_theme_suggestion_dialog(const char *theme_name
)
3713 /****************************************************************
3714 Player has gained a new tech.
3715 *****************************************************************/
3716 void show_tech_gained_dialog(Tech_type_id tech
)
3721 /****************************************************************
3722 Show tileset error dialog.
3723 *****************************************************************/
3724 void show_tileset_error(const char *msg
)
3729 /****************************************************************
3730 Give a warning when user is about to edit scenario with manually
3732 *****************************************************************/
3733 bool handmade_scenario_warning(void)
3735 /* Just tell the client common code to handle this. */
3739 /****************************************************************
3740 Update multipliers (policies) dialog.
3741 *****************************************************************/
3742 void real_multipliers_dialog_update(void)
3747 /****************************************************************
3748 Unit wants to get into some transport on given tile.
3749 *****************************************************************/
3750 bool request_transport(struct unit
*pcargo
, struct tile
*ptile
)
3752 return FALSE
; /* Unit was not handled here. */
3755 /***************************************************************************
3756 Popup detailed information about battle or save information for
3757 some kind of statistics
3758 ***************************************************************************/
3759 void popup_combat_info(int attacker_unit_id
, int defender_unit_id
,
3760 int attacker_hp
, int defender_hp
,
3761 bool make_winner_veteran
)