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>
30 #include "bitvector.h"
38 #include "government.h"
43 #include "client_main.h"
44 #include "climap.h" /* for client_tile_get_known() */
46 #include "helpdata.h" /* for helptext_nation() */
59 #include "gui_iconv.h"
62 #include "gui_tilespec.h"
68 #include "messagewin.h"
69 #include "optiondlg.h"
74 #include "themespec.h"
80 struct player
*races_player
;
82 extern bool is_unit_move_blocked
;
83 extern void popdown_diplomat_dialog(void);
84 extern void popdown_incite_dialog(void);
85 extern void popdown_bribe_dialog(void);
87 void popdown_advanced_terrain_dialog(void);
88 int advanced_terrain_window_dlg_callback(struct widget
*pWindow
);
89 int exit_advanced_terrain_dlg_callback(struct widget
*pWidget
);
91 static char *pLeaderName
= NULL
;
93 static void unit_select_dialog_popdown(void);
94 static void popdown_terrain_info_dialog(void);
95 static void popdown_pillage_dialog(void);
96 static void popdown_connect_dialog(void);
97 static void popdown_revolution_dialog(void);
98 static void popdown_unit_upgrade_dlg(void);
99 static void popdown_unit_disband_dlg(void);
101 /**********************************************************************
102 Place window near given tile on screen.
103 ***********************************************************************/
104 void put_window_near_map_tile(struct widget
*pWindow
,
105 int window_width
, int window_height
,
108 float canvas_x
, canvas_y
;
109 int window_x
= 0, window_y
= 0;
111 if (tile_to_canvas_pos(&canvas_x
, &canvas_y
, ptile
)) {
112 if (canvas_x
+ tileset_tile_width(tileset
) + window_width
>= Main
.screen
->w
) {
113 if (canvas_x
- window_width
< 0) {
114 window_x
= (Main
.screen
->w
- window_width
) / 2;
116 window_x
= canvas_x
- window_width
;
119 window_x
= canvas_x
+ tileset_tile_width(tileset
);
122 canvas_y
+= (tileset_tile_height(tileset
) - window_height
) / 2;
123 if (canvas_y
+ window_height
>= Main
.screen
->h
)
125 window_y
= Main
.screen
->h
- window_height
- 1;
135 window_x
= (Main
.screen
->w
- window_width
) / 2;
136 window_y
= (Main
.screen
->h
- window_height
) / 2;
139 widget_set_position(pWindow
, window_x
, window_y
);
143 /**********************************************************************
144 This function is called when the client disconnects or the game is
145 over. It should close all dialog windows for that game.
146 ***********************************************************************/
147 void popdown_all_game_dialogs(void)
149 unit_select_dialog_popdown();
150 popdown_advanced_terrain_dialog();
151 popdown_terrain_info_dialog();
152 popdown_newcity_dialog();
153 popdown_optiondlg(TRUE
);
154 undraw_order_widgets();
155 popdown_diplomat_dialog();
156 popdown_pillage_dialog();
157 popdown_incite_dialog();
158 popdown_connect_dialog();
159 popdown_bribe_dialog();
160 popdown_find_dialog();
161 popdown_revolution_dialog();
162 science_report_dialogs_popdown_all();
163 meswin_dialog_popdown();
164 popdown_worklist_editor();
165 popdown_all_city_dialogs();
166 city_report_dialog_popdown();
167 economy_report_dialog_popdown();
168 units_report_dialog_popdown();
169 popdown_intel_dialogs();
170 popdown_players_nations_dialog();
171 popdown_players_dialog();
172 popdown_goto_airlift_dialog();
173 popdown_unit_upgrade_dlg();
174 popdown_unit_disband_dlg();
175 popdown_help_dialog();
176 popdown_notify_goto_dialog();
178 /* clear gui buffer */
179 if (C_S_PREPARING
== client_state()) {
180 clear_surface(Main
.gui
->surface
, NULL
);
184 /* ======================================================================= */
186 /**************************************************************************
187 Find the my unit's (focus) chance of success at attacking/defending the
188 given enemy unit. Return FALSE if the values cannot be determined (e.g., no
190 **************************************************************************/
191 static bool sdl_get_chance_to_win(int *att_chance
, int *def_chance
,
192 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;
209 /**************************************************************************
211 **************************************************************************/
212 struct notify_goto_data
{
218 #define SPECLIST_TAG notify_goto
219 #define SPECLIST_TYPE struct notify_goto_data
220 #include "speclist.h"
222 struct notify_goto_dialog
{
223 struct widget
*window
;
224 struct widget
*close_button
;
225 struct widget
*label
;
226 struct notify_goto_list
*datas
;
229 static struct notify_goto_dialog
*notify_goto_dialog
= NULL
;
231 static void notify_goto_dialog_advance(struct notify_goto_dialog
*pdialog
);
233 /**************************************************************************
234 Create a notify goto data.
235 **************************************************************************/
236 static struct notify_goto_data
*notify_goto_data_new(const char *headline
,
240 struct notify_goto_data
*pdata
= fc_malloc(sizeof(*pdata
));
242 pdata
->headline
= fc_strdup(headline
);
243 pdata
->lines
= fc_strdup(lines
);
244 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
);
258 /**************************************************************************
259 Move the notify dialog.
260 **************************************************************************/
261 static int notify_goto_dialog_callback(struct widget
*widget
)
263 struct notify_goto_dialog
*pdialog
=
264 (struct notify_goto_dialog
*) widget
->data
.ptr
;
266 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
267 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
);
286 /**************************************************************************
288 **************************************************************************/
289 static int notify_goto_dialog_goto_callback(struct widget
*widget
)
291 struct notify_goto_dialog
*pdialog
=
292 (struct notify_goto_dialog
*) widget
->data
.ptr
;
293 const struct notify_goto_data
*pdata
= notify_goto_list_get(pdialog
->datas
,
296 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
297 if (NULL
!= pdata
->ptile
) {
298 center_tile_mapcanvas(pdata
->ptile
);
300 } else if (Main
.event
.button
.button
== SDL_BUTTON_RIGHT
) {
303 if (NULL
!= pdata
->ptile
&& (pcity
= tile_city(pdata
->ptile
))) {
304 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_str16_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_str16_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_string16(pdialog
->window
->string16
, 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
.screen
->w
- pdialog
->window
->size
.w
) / 2,
402 (Main
.screen
->h
- 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();
444 fc_assert(NULL
!= notify_goto_dialog
);
446 notify_goto_list_prepend(notify_goto_dialog
->datas
,
447 notify_goto_data_new(headline
, lines
, ptile
));
448 notify_goto_dialog_update(notify_goto_dialog
);
451 /**************************************************************************
452 Popdown the notify goto dialog.
453 **************************************************************************/
454 void popdown_notify_goto_dialog(void)
456 if (NULL
!= notify_goto_dialog
) {
457 notify_goto_dialog_destroy(notify_goto_dialog
);
458 notify_goto_dialog
= NULL
;
462 /**************************************************************************
463 Popup a dialog to display connection message from server.
464 **************************************************************************/
465 void popup_connect_msg(const char *headline
, const char *message
)
467 log_error("popup_connect_msg() PORT ME");
470 /* ----------------------------------------------------------------------- */
471 struct ADVANCED_DLG
*pNotifyDlg
= NULL
;
473 /**************************************************************************
474 User interacted with generic notify dialog.
475 **************************************************************************/
476 static int notify_dialog_window_callback(struct widget
*pWindow
)
478 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
479 move_window_group(pNotifyDlg
->pBeginWidgetList
, pWindow
);
484 /**************************************************************************
485 User interacted with notify dialog close button.
486 **************************************************************************/
487 static int exit_notify_dialog_callback(struct widget
*pWidget
)
489 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
491 popdown_window_group_dialog(pNotifyDlg
->pBeginWidgetList
,
492 pNotifyDlg
->pEndWidgetList
);
493 FC_FREE(pNotifyDlg
->pScroll
);
501 /**************************************************************************
502 Popup a generic dialog to display some generic information.
503 **************************************************************************/
504 void popup_notify_dialog(const char *caption
, const char *headline
,
507 struct widget
*pBuf
, *pWindow
;
509 SDL_Surface
*pHeadline
, *pLines
;
517 pNotifyDlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
519 pStr
= create_str16_from_char(caption
, adj_font(12));
520 pStr
->style
|= TTF_STYLE_BOLD
;
522 pWindow
= create_window_skeleton(NULL
, pStr
, 0);
524 pWindow
->action
= notify_dialog_window_callback
;
525 set_wstate(pWindow
, FC_WS_NORMAL
);
527 add_to_gui_list(ID_WINDOW
, pWindow
);
528 pNotifyDlg
->pEndWidgetList
= pWindow
;
530 area
= pWindow
->area
;
533 /* create exit button */
534 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
535 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
536 pBuf
->info_label
= create_str16_from_char(_("Close Dialog (Esc)"),
538 pBuf
->action
= exit_notify_dialog_callback
;
539 set_wstate(pBuf
, FC_WS_NORMAL
);
540 pBuf
->key
= SDLK_ESCAPE
;
541 area
.w
+= (pBuf
->size
.w
+ adj_size(10));
543 add_to_gui_list(ID_BUTTON
, pBuf
);
544 pNotifyDlg
->pBeginWidgetList
= pBuf
;
546 pStr
= create_str16_from_char(headline
, adj_font(16));
547 pStr
->style
|= TTF_STYLE_BOLD
;
549 pHeadline
= create_text_surf_from_str16(pStr
);
551 if(lines
&& *lines
!= '\0') {
552 change_ptsize16(pStr
, adj_font(12));
553 pStr
->style
&= ~TTF_STYLE_BOLD
;
554 copy_chars_to_string16(pStr
, lines
);
555 pLines
= create_text_surf_from_str16(pStr
);
562 area
.w
= MAX(area
.w
, pHeadline
->w
);
564 area
.w
= MAX(area
.w
, pLines
->w
);
566 area
.w
+= adj_size(60);
567 area
.h
= MAX(area
.h
, adj_size(10) + pHeadline
->h
+ adj_size(10));
569 area
.h
+= pLines
->h
+ adj_size(10);
572 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
573 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
574 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
576 area
= pWindow
->area
;
578 widget_set_position(pWindow
,
579 (Main
.screen
->w
- pWindow
->size
.w
) / 2,
580 (Main
.screen
->h
- pWindow
->size
.h
) / 2);
582 dst
.x
= area
.x
+ (area
.w
- pHeadline
->w
) / 2;
583 dst
.y
= area
.y
+ adj_size(10);
585 alphablit(pHeadline
, NULL
, pWindow
->theme
, &dst
);
587 dst
.y
+= pHeadline
->h
+ adj_size(10);
588 if(pHeadline
->w
< pLines
->w
) {
589 dst
.x
= area
.x
+ (area
.w
- pLines
->w
) / 2;
592 alphablit(pLines
, NULL
, pWindow
->theme
, &dst
);
595 FREESURFACE(pHeadline
);
599 pBuf
= pWindow
->prev
;
600 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
601 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
604 redraw_group(pNotifyDlg
->pBeginWidgetList
, pWindow
, 0);
605 widget_flush(pWindow
);
608 /* =======================================================================*/
609 /* ========================= UNIT UPGRADE DIALOG =========================*/
610 /* =======================================================================*/
611 static struct SMALL_DLG
*pUnit_Upgrade_Dlg
= NULL
;
613 /****************************************************************
614 User interacted with upgrade unit widget.
615 *****************************************************************/
616 static int upgrade_unit_window_callback(struct widget
*pWindow
)
618 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
619 move_window_group(pUnit_Upgrade_Dlg
->pBeginWidgetList
, pWindow
);
624 /****************************************************************
625 User interacted with upgrade unit dialog cancel -button
626 *****************************************************************/
627 static int cancel_upgrade_unit_callback(struct widget
*pWidget
)
629 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
630 popdown_unit_upgrade_dlg();
631 /* enable city dlg */
632 enable_city_dlg_widgets();
638 /****************************************************************
639 User interacted with unit upgrade dialog "Upgrade" -button.
640 *****************************************************************/
641 static int ok_upgrade_unit_window_callback(struct widget
*pWidget
)
643 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
644 struct unit
*pUnit
= pWidget
->data
.unit
;
645 popdown_unit_upgrade_dlg();
646 /* enable city dlg */
647 enable_city_dlg_widgets();
648 free_city_units_lists();
649 request_unit_upgrade(pUnit
);
655 /****************************************************************
656 Open unit upgrade dialog.
657 *****************************************************************/
658 void popup_unit_upgrade_dlg(struct unit
*pUnit
, bool city
)
661 struct widget
*pBuf
= NULL
, *pWindow
;
665 int window_x
= 0, window_y
= 0;
666 enum unit_upgrade_result unit_upgrade_result
;
669 if (pUnit_Upgrade_Dlg
) {
675 pUnit_Upgrade_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
677 unit_upgrade_result
= unit_upgrade_info(pUnit
, cBuf
, sizeof(cBuf
));
679 pStr
= create_str16_from_char(_("Upgrade Obsolete Units"), adj_font(12));
680 pStr
->style
|= TTF_STYLE_BOLD
;
682 pWindow
= create_window_skeleton(NULL
, pStr
, 0);
684 pWindow
->action
= upgrade_unit_window_callback
;
685 set_wstate(pWindow
, FC_WS_NORMAL
);
687 pUnit_Upgrade_Dlg
->pEndWidgetList
= pWindow
;
689 add_to_gui_list(ID_WINDOW
, pWindow
);
691 area
= pWindow
->area
;
693 /* ============================================================= */
695 /* create text label */
696 pStr
= create_str16_from_char(cBuf
, adj_font(10));
697 pStr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
698 pStr
->fgcol
= *get_theme_color(COLOR_THEME_UNITUPGRADE_TEXT
);
700 pText
= create_text_surf_from_str16(pStr
);
703 area
.w
= MAX(area
.w
, pText
->w
+ adj_size(20));
704 area
.h
+= (pText
->h
+ adj_size(10));
707 pBuf
= create_themeicon_button_from_chars(current_theme
->CANCEL_Icon
,
708 pWindow
->dst
, _("Cancel"), adj_font(12), 0);
710 pBuf
->action
= cancel_upgrade_unit_callback
;
711 set_wstate(pBuf
, FC_WS_NORMAL
);
713 area
.h
+= (pBuf
->size
.h
+ adj_size(20));
715 add_to_gui_list(ID_BUTTON
, pBuf
);
717 if (UU_OK
== unit_upgrade_result
) {
718 pBuf
= create_themeicon_button_from_chars(current_theme
->OK_Icon
, pWindow
->dst
,
719 _("Upgrade"), adj_font(12), 0);
721 pBuf
->action
= ok_upgrade_unit_window_callback
;
722 set_wstate(pBuf
, FC_WS_NORMAL
);
723 pBuf
->data
.unit
= pUnit
;
724 add_to_gui_list(ID_BUTTON
, pBuf
);
725 pBuf
->size
.w
= MAX(pBuf
->size
.w
, pBuf
->next
->size
.w
);
726 pBuf
->next
->size
.w
= pBuf
->size
.w
;
727 area
.w
= MAX(area
.w
, adj_size(30) + pBuf
->size
.w
* 2);
729 area
.w
= MAX(area
.w
, pBuf
->size
.w
+ adj_size(20));
731 /* ============================================ */
733 pUnit_Upgrade_Dlg
->pBeginWidgetList
= pBuf
;
735 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
736 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
737 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
739 area
= pWindow
->area
;
742 window_x
= Main
.event
.motion
.x
;
743 window_y
= Main
.event
.motion
.y
;
745 put_window_near_map_tile(pWindow
, pWindow
->size
.w
, pWindow
->size
.h
,
749 widget_set_position(pWindow
, window_x
, window_y
);
751 /* setup rest of widgets */
753 dst
.x
= area
.x
+ (area
.w
- pText
->w
) / 2;
754 dst
.y
= area
.y
+ adj_size(10);
755 alphablit(pText
, NULL
, pWindow
->theme
, &dst
);
759 pBuf
= pWindow
->prev
;
760 pBuf
->size
.y
= area
.y
+ area
.h
- pBuf
->size
.h
- adj_size(7);
762 if (UU_OK
== unit_upgrade_result
) {
765 pBuf
->size
.x
= area
.x
+ (area
.w
- (2 * pBuf
->size
.w
+ adj_size(10))) / 2;
766 pBuf
->size
.y
= pBuf
->next
->size
.y
;
769 pBuf
->next
->size
.x
= pBuf
->size
.x
+ pBuf
->size
.w
+ adj_size(10);
771 /* x position of cancel button */
772 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- adj_size(10);
776 /* ================================================== */
778 redraw_group(pUnit_Upgrade_Dlg
->pBeginWidgetList
, pWindow
, 0);
780 widget_mark_dirty(pWindow
);
785 /****************************************************************
786 Close unit upgrade dialog.
787 *****************************************************************/
788 static void popdown_unit_upgrade_dlg(void)
790 if (pUnit_Upgrade_Dlg
) {
791 popdown_window_group_dialog(pUnit_Upgrade_Dlg
->pBeginWidgetList
,
792 pUnit_Upgrade_Dlg
->pEndWidgetList
);
793 FC_FREE(pUnit_Upgrade_Dlg
);
797 /* =======================================================================*/
798 /* ========================= UNIT DISBAND DIALOG =========================*/
799 /* =======================================================================*/
800 static struct SMALL_DLG
*pUnit_Disband_Dlg
= NULL
;
802 /****************************************************************
803 User interacted with disband unit widget.
804 *****************************************************************/
805 static int disband_unit_window_callback(struct widget
*pWindow
)
807 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
808 move_window_group(pUnit_Disband_Dlg
->pBeginWidgetList
, pWindow
);
813 /****************************************************************
814 User interacted with disband unit dialog cancel -button
815 *****************************************************************/
816 static int cancel_disband_unit_callback(struct widget
*pWidget
)
818 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
819 popdown_unit_disband_dlg();
820 /* enable city dlg */
821 enable_city_dlg_widgets();
827 /****************************************************************
828 User interacted with unit disband dialog "Disband" -button.
829 *****************************************************************/
830 static int ok_disband_unit_window_callback(struct widget
*pWidget
)
832 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
833 struct unit
*pUnit
= pWidget
->data
.unit
;
834 popdown_unit_disband_dlg();
835 /* enable city dlg */
836 enable_city_dlg_widgets();
837 free_city_units_lists();
838 request_unit_disband(pUnit
);
844 /****************************************************************
845 Open unit disband dialog.
846 *****************************************************************/
847 void popup_unit_disband_dlg(struct unit
*pUnit
, bool city
)
850 struct widget
*pBuf
= NULL
, *pWindow
;
854 int window_x
= 0, window_y
= 0;
855 bool unit_disband_result
;
858 if (pUnit_Disband_Dlg
) {
864 pUnit_Disband_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
867 struct unit_list
*pUnits
= unit_list_new();
868 unit_list_append(pUnits
, pUnit
);
869 unit_disband_result
= get_units_disband_info(cBuf
, sizeof(cBuf
), pUnits
);
870 unit_list_destroy(pUnits
);
873 pStr
= create_str16_from_char(_("Disband Units"), adj_font(12));
874 pStr
->style
|= TTF_STYLE_BOLD
;
876 pWindow
= create_window_skeleton(NULL
, pStr
, 0);
878 pWindow
->action
= disband_unit_window_callback
;
879 set_wstate(pWindow
, FC_WS_NORMAL
);
881 pUnit_Disband_Dlg
->pEndWidgetList
= pWindow
;
883 add_to_gui_list(ID_WINDOW
, pWindow
);
885 area
= pWindow
->area
;
887 /* ============================================================= */
889 /* create text label */
890 pStr
= create_str16_from_char(cBuf
, adj_font(10));
891 pStr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
892 pStr
->fgcol
= *get_theme_color(COLOR_THEME_UNITDISBAND_TEXT
);
894 pText
= create_text_surf_from_str16(pStr
);
897 area
.w
= MAX(area
.w
, pText
->w
+ adj_size(20));
898 area
.h
+= (pText
->h
+ adj_size(10));
901 pBuf
= create_themeicon_button_from_chars(current_theme
->CANCEL_Icon
,
902 pWindow
->dst
, _("Cancel"),
905 pBuf
->action
= cancel_disband_unit_callback
;
906 set_wstate(pBuf
, FC_WS_NORMAL
);
908 area
.h
+= (pBuf
->size
.h
+ adj_size(20));
910 add_to_gui_list(ID_BUTTON
, pBuf
);
912 if (unit_disband_result
) {
913 pBuf
= create_themeicon_button_from_chars(current_theme
->OK_Icon
, pWindow
->dst
,
914 _("Disband"), adj_font(12), 0);
916 pBuf
->action
= ok_disband_unit_window_callback
;
917 set_wstate(pBuf
, FC_WS_NORMAL
);
918 pBuf
->data
.unit
= pUnit
;
919 add_to_gui_list(ID_BUTTON
, pBuf
);
920 pBuf
->size
.w
= MAX(pBuf
->size
.w
, pBuf
->next
->size
.w
);
921 pBuf
->next
->size
.w
= pBuf
->size
.w
;
922 area
.w
= MAX(area
.w
, adj_size(30) + pBuf
->size
.w
* 2);
924 area
.w
= MAX(area
.w
, pBuf
->size
.w
+ adj_size(20));
926 /* ============================================ */
928 pUnit_Disband_Dlg
->pBeginWidgetList
= pBuf
;
930 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
931 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
932 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
934 area
= pWindow
->area
;
937 window_x
= Main
.event
.motion
.x
;
938 window_y
= Main
.event
.motion
.y
;
940 put_window_near_map_tile(pWindow
, pWindow
->size
.w
, pWindow
->size
.h
,
944 widget_set_position(pWindow
, window_x
, window_y
);
946 /* setup rest of widgets */
948 dst
.x
= area
.x
+ (area
.w
- pText
->w
) / 2;
949 dst
.y
= area
.y
+ adj_size(10);
950 alphablit(pText
, NULL
, pWindow
->theme
, &dst
);
954 pBuf
= pWindow
->prev
;
955 pBuf
->size
.y
= area
.y
+ area
.h
- pBuf
->size
.h
- adj_size(7);
957 if (unit_disband_result
) {
960 pBuf
->size
.x
= area
.x
+ (area
.w
- (2 * pBuf
->size
.w
+ adj_size(10))) / 2;
961 pBuf
->size
.y
= pBuf
->next
->size
.y
;
964 pBuf
->next
->size
.x
= pBuf
->size
.x
+ pBuf
->size
.w
+ adj_size(10);
966 /* x position of cancel button */
967 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- adj_size(10);
971 /* ================================================== */
973 redraw_group(pUnit_Disband_Dlg
->pBeginWidgetList
, pWindow
, 0);
975 widget_mark_dirty(pWindow
);
980 /****************************************************************
981 Close unit disband dialog.
982 *****************************************************************/
983 static void popdown_unit_disband_dlg(void)
985 if (pUnit_Disband_Dlg
) {
986 popdown_window_group_dialog(pUnit_Disband_Dlg
->pBeginWidgetList
,
987 pUnit_Disband_Dlg
->pEndWidgetList
);
988 FC_FREE(pUnit_Disband_Dlg
);
992 /* =======================================================================*/
993 /* ======================== UNIT SELECTION DIALOG ========================*/
994 /* =======================================================================*/
995 static struct ADVANCED_DLG
*pUnit_Select_Dlg
= NULL
;
997 /**************************************************************************
998 User interacted with unit selection window.
999 **************************************************************************/
1000 static int unit_select_window_callback(struct widget
*pWindow
)
1002 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1003 move_window_group(pUnit_Select_Dlg
->pBeginWidgetList
, pWindow
);
1008 /**************************************************************************
1009 User requested unit select window to be closed.
1010 **************************************************************************/
1011 static int exit_unit_select_callback( struct widget
*pWidget
)
1013 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1014 unit_select_dialog_popdown();
1015 is_unit_move_blocked
= FALSE
;
1020 /**************************************************************************
1021 User selected unit from unit select window.
1022 **************************************************************************/
1023 static int unit_select_callback( struct widget
*pWidget
)
1025 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1026 struct unit
*pUnit
=
1027 player_unit_by_number(client_player(), MAX_ID
- pWidget
->ID
);
1029 unit_select_dialog_popdown();
1031 request_new_unit_activity(pUnit
, ACTIVITY_IDLE
);
1032 unit_focus_set(pUnit
);
1038 /**************************************************************************
1039 Popdown a dialog window to select units on a particular tile.
1040 **************************************************************************/
1041 static void unit_select_dialog_popdown(void)
1043 if (pUnit_Select_Dlg
) {
1044 is_unit_move_blocked
= FALSE
;
1045 popdown_window_group_dialog(pUnit_Select_Dlg
->pBeginWidgetList
,
1046 pUnit_Select_Dlg
->pEndWidgetList
);
1048 FC_FREE(pUnit_Select_Dlg
->pScroll
);
1049 FC_FREE(pUnit_Select_Dlg
);
1054 /**************************************************************************
1055 Popup a dialog window to select units on a particular tile.
1056 **************************************************************************/
1057 void unit_select_dialog_popup(struct tile
*ptile
)
1059 struct widget
*pBuf
= NULL
, *pWindow
;
1061 struct unit
*pUnit
= NULL
, *pFocus
= head_of_units_in_focus();
1062 struct unit_type
*pUnitType
;
1069 n
= unit_list_size(ptile
->units
);
1071 if (!n
|| pUnit_Select_Dlg
) {
1075 is_unit_move_blocked
= TRUE
;
1076 pUnit_Select_Dlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
1078 fc_snprintf(cBuf
, sizeof(cBuf
),"%s (%d)", _("Unit selection") , n
);
1079 pStr
= create_str16_from_char(cBuf
, adj_font(12));
1080 pStr
->style
|= TTF_STYLE_BOLD
;
1082 pWindow
= create_window_skeleton(NULL
, pStr
, 0);
1084 pWindow
->action
= unit_select_window_callback
;
1085 set_wstate(pWindow
, FC_WS_NORMAL
);
1087 add_to_gui_list(ID_UNIT_SELLECT_DLG_WINDOW
, pWindow
);
1088 pUnit_Select_Dlg
->pEndWidgetList
= pWindow
;
1090 area
= pWindow
->area
;
1093 /* create exit button */
1094 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
1095 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
1096 pBuf
->info_label
= create_str16_from_char(_("Close Dialog (Esc)"),
1098 pBuf
->action
= exit_unit_select_callback
;
1099 set_wstate(pBuf
, FC_WS_NORMAL
);
1100 pBuf
->key
= SDLK_ESCAPE
;
1101 area
.w
+= (pBuf
->size
.w
+ adj_size(10));
1103 add_to_gui_list(ID_UNIT_SELLECT_DLG_EXIT_BUTTON
, pBuf
);
1107 for (i
= 0; i
< n
; i
++) {
1108 const char *vetname
;
1110 pUnit
= unit_list_get(ptile
->units
, i
);
1111 pUnitType
= unit_type_get(pUnit
);
1112 vetname
= utype_veteran_name_translation(pUnitType
, pUnit
->veteran
);
1114 if (unit_owner(pUnit
) == client
.conn
.playing
) {
1115 fc_snprintf(cBuf
, sizeof(cBuf
), _("Contact %s (%d / %d) %s(%d,%d,%s) %s"),
1116 (vetname
!= NULL
? vetname
: ""),
1117 pUnit
->hp
, pUnitType
->hp
,
1118 utype_name_translation(pUnitType
),
1119 pUnitType
->attack_strength
,
1120 pUnitType
->defense_strength
,
1121 move_points_text(pUnitType
->move_rate
, FALSE
),
1122 unit_activity_text(pUnit
));
1124 int att_chance
, def_chance
;
1126 fc_snprintf(cBuf
, sizeof(cBuf
), _("%s %s %s(A:%d D:%d M:%s FP:%d) HP:%d%%"),
1127 nation_adjective_for_player(unit_owner(pUnit
)),
1128 (vetname
!= NULL
? vetname
: ""),
1129 utype_name_translation(pUnitType
),
1130 pUnitType
->attack_strength
,
1131 pUnitType
->defense_strength
,
1132 move_points_text(pUnitType
->move_rate
, FALSE
),
1133 pUnitType
->firepower
,
1134 (pUnit
->hp
* 100 / pUnitType
->hp
+ 9) / 10);
1136 /* calculate chance to win */
1137 if (sdl_get_chance_to_win(&att_chance
, &def_chance
, pUnit
, pFocus
)) {
1138 /* TRANS: "CtW" = "Chance to Win" */
1139 cat_snprintf(cBuf
, sizeof(cBuf
), _(" CtW: Att:%d%% Def:%d%%"),
1140 att_chance
, def_chance
);
1144 create_active_iconlabel(pBuf
, pWindow
->dst
,
1145 pStr
, cBuf
, unit_select_callback
);
1147 add_to_gui_list(MAX_ID
- pUnit
->id
, pBuf
);
1149 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1150 area
.h
+= pBuf
->size
.h
;
1151 if (unit_owner(pUnit
) == client
.conn
.playing
) {
1152 set_wstate(pBuf
, FC_WS_NORMAL
);
1155 if (i
> NUM_SEEN
- 1)
1157 set_wflag(pBuf
, WF_HIDDEN
);
1161 pUnit_Select_Dlg
->pBeginWidgetList
= pBuf
;
1162 pUnit_Select_Dlg
->pBeginActiveWidgetList
= pUnit_Select_Dlg
->pBeginWidgetList
;
1163 pUnit_Select_Dlg
->pEndActiveWidgetList
= pWindow
->prev
->prev
;
1164 pUnit_Select_Dlg
->pActiveWidgetList
= pUnit_Select_Dlg
->pEndActiveWidgetList
;
1166 area
.w
+= adj_size(2);
1169 n
= create_vertical_scrollbar(pUnit_Select_Dlg
, 1, NUM_SEEN
, TRUE
, TRUE
);
1172 /* ------- window ------- */
1173 area
.h
= NUM_SEEN
* pWindow
->prev
->prev
->size
.h
;
1176 resize_window(pWindow
, NULL
, NULL
,
1177 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
1178 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
1180 area
= pWindow
->area
;
1182 put_window_near_map_tile(pWindow
, pWindow
->size
.w
, pWindow
->size
.h
,
1187 if(pUnit_Select_Dlg
->pScroll
) {
1192 pBuf
= pWindow
->prev
;
1193 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
1194 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
1197 setup_vertical_widgets_position(1, area
.x
+ 1, area
.y
, w
, 0,
1198 pUnit_Select_Dlg
->pBeginActiveWidgetList
, pBuf
);
1200 if(pUnit_Select_Dlg
->pScroll
) {
1201 setup_vertical_scrollbar_area(pUnit_Select_Dlg
->pScroll
,
1202 area
.x
+ area
.w
, area
.y
,
1206 /* ==================================================== */
1208 redraw_group(pUnit_Select_Dlg
->pBeginWidgetList
, pWindow
, 0);
1210 widget_flush(pWindow
);
1213 /**************************************************************************
1214 Update the dialog window to select units on a particular tile.
1215 **************************************************************************/
1216 void unit_select_dialog_update_real(void)
1221 /* ====================================================================== */
1222 /* ============================ TERRAIN INFO ============================ */
1223 /* ====================================================================== */
1224 static struct SMALL_DLG
*pTerrain_Info_Dlg
= NULL
;
1227 /**************************************************************************
1228 Popdown terrain information dialog.
1229 **************************************************************************/
1230 static int terrain_info_window_dlg_callback(struct widget
*pWindow
)
1232 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1233 move_window_group(pTerrain_Info_Dlg
->pBeginWidgetList
, pWindow
);
1238 /**************************************************************************
1239 Popdown terrain information dialog.
1240 **************************************************************************/
1241 static void popdown_terrain_info_dialog(void)
1243 if (pTerrain_Info_Dlg
) {
1244 popdown_window_group_dialog(pTerrain_Info_Dlg
->pBeginWidgetList
,
1245 pTerrain_Info_Dlg
->pEndWidgetList
);
1246 FC_FREE(pTerrain_Info_Dlg
);
1251 /**************************************************************************
1252 Popdown terrain information dialog.
1253 **************************************************************************/
1254 static int exit_terrain_info_dialog_callback(struct widget
*pButton
)
1256 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1257 popdown_terrain_info_dialog();
1262 /**************************************************************************
1263 Return a (static) string with terrain defense bonus.
1264 This does not include bonuses some units may get out of bases.
1265 **************************************************************************/
1266 const char *sdl_get_tile_defense_info_text(struct tile
*ptile
)
1268 static char buffer
[64];
1269 int bonus
= (tile_terrain(ptile
)->defense_bonus
- 10) * 10;
1271 extra_type_iterate(pextra
) {
1272 if (tile_has_extra(ptile
, pextra
)
1273 && pextra
->category
== ECAT_NATURAL
) {
1274 bonus
+= pextra
->defense_bonus
;
1276 } extra_type_iterate_end
;
1278 fc_snprintf(buffer
, sizeof(buffer
), _("Terrain Defense Bonus: +%d%% "), bonus
);
1283 /**************************************************************************
1284 Popup terrain information dialog.
1285 **************************************************************************/
1286 static void popup_terrain_info_dialog(SDL_Surface
*pDest
, struct tile
*ptile
)
1289 struct widget
*pBuf
, *pWindow
;
1294 if (pTerrain_Info_Dlg
) {
1299 pSurf
= get_terrain_surface(ptile
);
1300 pTerrain_Info_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
1303 fc_snprintf(cBuf
, sizeof(cBuf
), "%s [%d,%d]", _("Terrain Info"),
1306 pWindow
= create_window_skeleton(NULL
, create_str16_from_char(cBuf
, adj_font(12)), 0);
1307 pWindow
->string16
->style
|= TTF_STYLE_BOLD
;
1309 pWindow
->action
= terrain_info_window_dlg_callback
;
1310 set_wstate(pWindow
, FC_WS_NORMAL
);
1312 add_to_gui_list(ID_TERRAIN_INFO_DLG_WINDOW
, pWindow
);
1313 pTerrain_Info_Dlg
->pEndWidgetList
= pWindow
;
1315 area
= pWindow
->area
;
1318 pStr
= create_str16_from_char(popup_info_text(ptile
), adj_font(12));
1319 pStr
->style
|= SF_CENTER
;
1320 pBuf
= create_iconlabel(pSurf
, pWindow
->dst
, pStr
, 0);
1322 pBuf
->size
.h
+= tileset_tile_height(tileset
) / 2;
1324 add_to_gui_list(ID_LABEL
, pBuf
);
1326 /* ------ window ---------- */
1327 area
.w
= MAX(area
.w
, pBuf
->size
.w
+ adj_size(20));
1328 area
.h
= MAX(area
.h
, pBuf
->size
.h
);
1330 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
1331 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
1332 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
1334 area
= pWindow
->area
;
1336 put_window_near_map_tile(pWindow
, pWindow
->size
.w
, pWindow
->size
.h
, ptile
);
1338 /* ------------------------ */
1340 pBuf
->size
.x
= area
.x
+ adj_size(10);
1341 pBuf
->size
.y
= area
.y
;
1344 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
1345 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
1346 pBuf
->info_label
= create_str16_from_char(_("Close Dialog (Esc)"),
1348 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
1349 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
1350 pBuf
->action
= exit_terrain_info_dialog_callback
;
1351 set_wstate(pBuf
, FC_WS_NORMAL
);
1352 pBuf
->key
= SDLK_ESCAPE
;
1354 add_to_gui_list(ID_TERRAIN_INFO_DLG_EXIT_BUTTON
, pBuf
);
1356 pTerrain_Info_Dlg
->pBeginWidgetList
= pBuf
;
1357 /* --------------------------------- */
1359 redraw_group(pTerrain_Info_Dlg
->pBeginWidgetList
, pWindow
, 0);
1360 widget_mark_dirty(pWindow
);
1363 /* ====================================================================== */
1364 /* ========================= ADVANCED_TERRAIN_MENU ====================== */
1365 /* ====================================================================== */
1366 struct ADVANCED_DLG
*pAdvanced_Terrain_Dlg
= NULL
;
1368 /**************************************************************************
1369 Popdown a generic dialog to display some generic information about
1370 terrain : tile, units , cities, etc.
1371 **************************************************************************/
1372 void popdown_advanced_terrain_dialog(void)
1374 if (pAdvanced_Terrain_Dlg
) {
1375 is_unit_move_blocked
= FALSE
;
1376 popdown_window_group_dialog(pAdvanced_Terrain_Dlg
->pBeginWidgetList
,
1377 pAdvanced_Terrain_Dlg
->pEndWidgetList
);
1379 FC_FREE(pAdvanced_Terrain_Dlg
->pScroll
);
1380 FC_FREE(pAdvanced_Terrain_Dlg
);
1384 /**************************************************************************
1385 User selected "Advanced Menu"
1386 **************************************************************************/
1387 int advanced_terrain_window_dlg_callback(struct widget
*pWindow
)
1389 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1390 move_window_group(pAdvanced_Terrain_Dlg
->pBeginWidgetList
, pWindow
);
1395 /**************************************************************************
1396 User requested closing of advanced terrain dialog.
1397 **************************************************************************/
1398 int exit_advanced_terrain_dlg_callback(struct widget
*pWidget
)
1400 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1401 popdown_advanced_terrain_dialog();
1407 /**************************************************************************
1408 User requested terrain info.
1409 **************************************************************************/
1410 static int terrain_info_callback(struct widget
*pWidget
)
1412 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1413 int x
= pWidget
->data
.cont
->id0
;
1414 int y
= pWidget
->data
.cont
->id1
;
1416 popdown_advanced_terrain_dialog();
1418 popup_terrain_info_dialog(NULL
, map_pos_to_tile(x
, y
));
1423 /**************************************************************************
1424 User requested zoom to city.
1425 **************************************************************************/
1426 static int zoom_to_city_callback(struct widget
*pWidget
)
1428 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1429 struct city
*pCity
= pWidget
->data
.city
;
1431 popdown_advanced_terrain_dialog();
1433 popup_city_dialog(pCity
);
1438 /**************************************************************************
1439 User requested production change.
1440 **************************************************************************/
1441 static int change_production_callback(struct widget
*pWidget
)
1443 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1444 struct city
*pCity
= pWidget
->data
.city
;
1445 popdown_advanced_terrain_dialog();
1446 popup_worklist_editor(pCity
, NULL
);
1451 /**************************************************************************
1452 User requested hurry production.
1453 **************************************************************************/
1454 static int hurry_production_callback(struct widget
*pWidget
)
1456 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1457 struct city
*pCity
= pWidget
->data
.city
;
1459 popdown_advanced_terrain_dialog();
1461 popup_hurry_production_dialog(pCity
, NULL
);
1466 /**************************************************************************
1467 User requested opening of cma settings.
1468 **************************************************************************/
1469 static int cma_callback(struct widget
*pWidget
)
1471 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1472 struct city
*pCity
= pWidget
->data
.city
;
1473 popdown_advanced_terrain_dialog();
1474 popup_city_cma_dialog(pCity
);
1479 /**************************************************************************
1481 **************************************************************************/
1482 static int adv_unit_select_callback(struct widget
*pWidget
)
1484 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1485 struct unit
*pUnit
= pWidget
->data
.unit
;
1487 popdown_advanced_terrain_dialog();
1490 request_new_unit_activity(pUnit
, ACTIVITY_IDLE
);
1491 unit_focus_set(pUnit
);
1497 /**************************************************************************
1498 User selected all units from tile.
1499 **************************************************************************/
1500 static int adv_unit_select_all_callback(struct widget
*pWidget
)
1502 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1503 struct unit
*pUnit
= pWidget
->data
.unit
;
1505 popdown_advanced_terrain_dialog();
1508 activate_all_units(unit_tile(pUnit
));
1514 /**************************************************************************
1515 Sentry unit widget contains.
1516 **************************************************************************/
1517 static int adv_unit_sentry_idle_callback(struct widget
*pWidget
)
1519 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1520 struct unit
*pUnit
= pWidget
->data
.unit
;
1522 popdown_advanced_terrain_dialog();
1525 struct tile
*ptile
= unit_tile(pUnit
);
1526 unit_list_iterate(ptile
->units
, punit
) {
1527 if (unit_owner(punit
) == client
.conn
.playing
1528 && ACTIVITY_IDLE
== punit
->activity
1529 && !punit
->ai_controlled
1530 && can_unit_do_activity(punit
, ACTIVITY_SENTRY
)) {
1531 request_new_unit_activity(punit
, ACTIVITY_SENTRY
);
1533 } unit_list_iterate_end
;
1539 /**************************************************************************
1540 Initiate goto to selected tile.
1541 **************************************************************************/
1542 static int goto_here_callback(struct widget
*pWidget
)
1544 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1545 int x
= pWidget
->data
.cont
->id0
;
1546 int y
= pWidget
->data
.cont
->id1
;
1548 popdown_advanced_terrain_dialog();
1551 send_goto_tile(head_of_units_in_focus(), map_pos_to_tile(x
, y
));
1556 /**************************************************************************
1557 Initiate patrol to selected tile.
1558 **************************************************************************/
1559 static int patrol_here_callback(struct widget
*pWidget
)
1561 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1565 int x
= pWidget
->data
.cont
->id0
;
1566 int y
= pWidget
->data
.cont
->id1
;
1567 struct unit
*pUnit
= head_of_units_in_focus();
1570 popdown_advanced_terrain_dialog();
1574 enter_goto_state(pUnit
);
1576 do_unit_patrol_to(pUnit
, map_pos_to_tile(x
, y
));
1584 /**************************************************************************
1585 Initiate paradrop to selected tile.
1586 **************************************************************************/
1587 static int paradrop_here_callback(struct widget
*pWidget
)
1589 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1592 int x
= pWidget
->data
.cont
->id0
;
1593 int y
= pWidget
->data
.cont
->id1
;
1596 popdown_advanced_terrain_dialog();
1600 do_unit_paradrop_to(get_unit_in_focus(), map_pos_to_tile(x
, y
));
1606 /**************************************************************************
1607 Show help about unit type.
1608 **************************************************************************/
1609 static int unit_help_callback(struct widget
*pWidget
)
1611 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1612 Unit_type_id unit_id
= MAX_ID
- pWidget
->ID
;
1614 popdown_advanced_terrain_dialog();
1615 popup_unit_info(unit_id
);
1620 /**************************************************************************
1621 Popup a generic dialog to display some generic information about
1622 terrain : tile, units , cities, etc.
1623 **************************************************************************/
1624 void popup_advanced_terrain_dialog(struct tile
*ptile
, Uint16 pos_x
, Uint16 pos_y
)
1626 struct widget
*pWindow
= NULL
, *pBuf
= NULL
;
1628 struct unit
*pFocus_Unit
;
1631 struct CONTAINER
*pCont
;
1633 int n
, w
= 0, h
, units_h
= 0;
1636 if (pAdvanced_Terrain_Dlg
) {
1640 pCity
= tile_city(ptile
);
1641 n
= unit_list_size(ptile
->units
);
1642 pFocus_Unit
= head_of_units_in_focus();
1644 if (!n
&& !pCity
&& !pFocus_Unit
)
1646 popup_terrain_info_dialog(NULL
, ptile
);
1650 area
.h
= adj_size(2);
1651 is_unit_move_blocked
= TRUE
;
1653 pAdvanced_Terrain_Dlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
1655 pCont
= fc_calloc(1, sizeof(struct CONTAINER
));
1656 pCont
->id0
= index_to_map_pos_x(tile_index(ptile
));
1657 pCont
->id1
= index_to_map_pos_y(tile_index(ptile
));
1659 pStr
= create_str16_from_char(_("Advanced Menu") , adj_font(12));
1660 pStr
->style
|= TTF_STYLE_BOLD
;
1662 pWindow
= create_window_skeleton(NULL
, pStr
, 0);
1664 pWindow
->action
= advanced_terrain_window_dlg_callback
;
1665 set_wstate(pWindow
, FC_WS_NORMAL
);
1667 add_to_gui_list(ID_TERRAIN_ADV_DLG_WINDOW
, pWindow
);
1668 pAdvanced_Terrain_Dlg
->pEndWidgetList
= pWindow
;
1670 area
= pWindow
->area
;
1674 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
1675 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
1676 pBuf
->info_label
= create_str16_from_char(_("Close Dialog (Esc)"),
1678 area
.w
+= pBuf
->size
.w
+ adj_size(10);
1679 pBuf
->action
= exit_advanced_terrain_dlg_callback
;
1680 set_wstate(pBuf
, FC_WS_NORMAL
);
1681 pBuf
->key
= SDLK_ESCAPE
;
1683 add_to_gui_list(ID_TERRAIN_ADV_DLG_EXIT_BUTTON
, pBuf
);
1686 pStr
= create_str16_from_char(_("Terrain Info") , adj_font(10));
1687 pStr
->style
|= TTF_STYLE_BOLD
;
1689 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pStr
,
1690 (WF_RESTORE_BACKGROUND
|WF_DRAW_TEXT_LABEL_WITH_SPACE
|WF_FREE_DATA
));
1692 pBuf
->string16
->bgcol
= (SDL_Color
) {0, 0, 0, 0};
1694 pBuf
->data
.cont
= pCont
;
1696 pBuf
->action
= terrain_info_callback
;
1697 set_wstate(pBuf
, FC_WS_NORMAL
);
1699 add_to_gui_list(ID_LABEL
, pBuf
);
1701 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1702 area
.h
+= pBuf
->size
.h
;
1705 if (pCity
&& city_owner(pCity
) == client
.conn
.playing
)
1708 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
1710 add_to_gui_list(ID_SEPARATOR
, pBuf
);
1711 area
.h
+= pBuf
->next
->size
.h
;
1712 /* ------------------ */
1714 fc_snprintf(cBuf
, sizeof(cBuf
), _("Zoom to : %s"), city_name_get(pCity
));
1716 create_active_iconlabel(pBuf
, pWindow
->dst
,
1717 pStr
, cBuf
, zoom_to_city_callback
);
1718 pBuf
->data
.city
= pCity
;
1719 set_wstate(pBuf
, FC_WS_NORMAL
);
1721 add_to_gui_list(ID_LABEL
, pBuf
);
1723 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1724 area
.h
+= pBuf
->size
.h
;
1727 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
,
1728 _("Change Production"), change_production_callback
);
1730 pBuf
->data
.city
= pCity
;
1731 set_wstate(pBuf
, FC_WS_NORMAL
);
1733 add_to_gui_list(ID_LABEL
, pBuf
);
1735 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1736 area
.h
+= pBuf
->size
.h
;
1737 /* -------------- */
1739 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
,
1740 _("Hurry production"), hurry_production_callback
);
1742 pBuf
->data
.city
= pCity
;
1743 set_wstate(pBuf
, FC_WS_NORMAL
);
1745 add_to_gui_list(ID_LABEL
, pBuf
);
1747 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1748 area
.h
+= pBuf
->size
.h
;
1751 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
,
1752 _("Change City Governor settings"), cma_callback
);
1754 pBuf
->data
.city
= pCity
;
1755 set_wstate(pBuf
, FC_WS_NORMAL
);
1757 add_to_gui_list(ID_LABEL
, pBuf
);
1759 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1760 area
.h
+= pBuf
->size
.h
;
1766 && (tile_index(unit_tile(pFocus_Unit
)) != tile_index(ptile
))) {
1768 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
1770 add_to_gui_list(ID_SEPARATOR
, pBuf
);
1771 area
.h
+= pBuf
->next
->size
.h
;
1772 /* ------------------ */
1774 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
, _("Goto here"),
1775 goto_here_callback
);
1776 pBuf
->data
.cont
= pCont
;
1777 set_wstate(pBuf
, FC_WS_NORMAL
);
1779 add_to_gui_list(MAX_ID
- 1000 - pFocus_Unit
->id
, pBuf
);
1781 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1782 area
.h
+= pBuf
->size
.h
;
1785 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
, _("Patrol here"),
1786 patrol_here_callback
);
1787 pBuf
->data
.cont
= pCont
;
1788 set_wstate(pBuf
, FC_WS_NORMAL
);
1790 add_to_gui_list(MAX_ID
- 1000 - pFocus_Unit
->id
, pBuf
);
1792 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1793 area
.h
+= pBuf
->size
.h
;
1796 #if 0 /* FIXME: specific connect buttons */
1797 if(unit_has_type_flag(pFocus_Unit
, F_SETTLERS
)) {
1798 create_active_iconlabel(pBuf
, pWindow
->dst
->surface
, pStr
, _("Connect here"),
1799 connect_here_callback
);
1800 pBuf
->data
.cont
= pCont
;
1801 set_wstate(pBuf
, FC_WS_NORMAL
);
1803 add_to_gui_list(ID_LABEL
, pBuf
);
1805 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1806 area
.h
+= pBuf
->size
.h
;
1811 /* FIXME: This logic seems to try to mirror do_paradrop() why? */
1812 if(can_unit_paradrop(pFocus_Unit
) && client_tile_get_known(ptile
) &&
1813 !(((pCity
&& pplayers_non_attack(client
.conn
.playing
, city_owner(pCity
)))
1814 || is_non_attack_unit_tile(ptile
, client
.conn
.playing
))) &&
1815 (unit_type_get(pFocus_Unit
)->paratroopers_range
>=
1816 real_map_distance(unit_tile(pFocus_Unit
), ptile
))) {
1818 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
, _("Paradrop here"),
1819 paradrop_here_callback
);
1820 pBuf
->data
.cont
= pCont
;
1821 set_wstate(pBuf
, FC_WS_NORMAL
);
1823 add_to_gui_list(ID_LABEL
, pBuf
);
1825 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1826 area
.h
+= pBuf
->size
.h
;
1831 pAdvanced_Terrain_Dlg
->pBeginWidgetList
= pBuf
;
1838 struct unit_type
*pUnitType
= NULL
;
1841 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
1843 add_to_gui_list(ID_SEPARATOR
, pBuf
);
1844 area
.h
+= pBuf
->next
->size
.h
;
1848 struct unit
*pDefender
, *pAttacker
;
1849 struct widget
*pLast
= pBuf
;
1852 const char *vetname
;
1854 #define ADV_NUM_SEEN 15
1856 pDefender
= (pFocus_Unit
? get_defender(pFocus_Unit
, ptile
) : NULL
);
1857 pAttacker
= (pFocus_Unit
? get_attacker(pFocus_Unit
, ptile
) : NULL
);
1858 for (i
= 0; i
< n
; i
++) {
1859 pUnit
= unit_list_get(ptile
->units
, i
);
1860 if (pUnit
== pFocus_Unit
) {
1863 pUnitType
= unit_type_get(pUnit
);
1864 vetname
= utype_veteran_name_translation(pUnitType
, pUnit
->veteran
);
1866 if (unit_owner(pUnit
) == client
.conn
.playing
) {
1867 fc_snprintf(cBuf
, sizeof(cBuf
),
1868 _("Activate %s (%d / %d) %s (%d,%d,%s) %s"),
1869 (vetname
!= NULL
? vetname
: ""),
1870 pUnit
->hp
, pUnitType
->hp
,
1871 utype_name_translation(pUnitType
),
1872 pUnitType
->attack_strength
,
1873 pUnitType
->defense_strength
,
1874 move_points_text(pUnitType
->move_rate
, FALSE
),
1875 unit_activity_text(pUnit
));
1877 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
,
1878 cBuf
, adv_unit_select_callback
);
1879 pBuf
->data
.unit
= pUnit
;
1880 set_wstate(pBuf
, FC_WS_NORMAL
);
1881 add_to_gui_list(ID_LABEL
, pBuf
);
1884 int att_chance
, def_chance
;
1886 fc_snprintf(cBuf
, sizeof(cBuf
), _("%s %s %s (A:%d D:%d M:%s FP:%d) HP:%d%%"),
1887 nation_adjective_for_player(unit_owner(pUnit
)),
1888 (vetname
!= NULL
? vetname
: ""),
1889 utype_name_translation(pUnitType
),
1890 pUnitType
->attack_strength
,
1891 pUnitType
->defense_strength
,
1892 move_points_text(pUnitType
->move_rate
, FALSE
),
1893 pUnitType
->firepower
,
1894 ((pUnit
->hp
* 100) / pUnitType
->hp
));
1896 /* calculate chance to win */
1897 if (sdl_get_chance_to_win(&att_chance
, &def_chance
, pUnit
, pFocus_Unit
)) {
1898 /* TRANS: "CtW" = "Chance to Win" */
1899 cat_snprintf(cBuf
, sizeof(cBuf
), _(" CtW: Att:%d%% Def:%d%%"),
1900 att_chance
, def_chance
);
1903 if (pAttacker
&& pAttacker
== pUnit
) {
1904 pStr
->fgcol
= *(get_game_color(COLOR_OVERVIEW_ENEMY_UNIT
));
1907 if (pDefender
&& pDefender
== pUnit
) {
1908 pStr
->fgcol
= *(get_game_color(COLOR_OVERVIEW_MY_UNIT
));
1913 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
, cBuf
, NULL
);
1916 pStr
->fgcol
= *get_theme_color(COLOR_THEME_ADVANCEDTERRAINDLG_TEXT
);
1920 add_to_gui_list(ID_LABEL
, pBuf
);
1923 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
1924 units_h
+= pBuf
->size
.h
;
1926 if (i
> ADV_NUM_SEEN
- 1)
1928 set_wflag(pBuf
, WF_HIDDEN
);
1933 pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
= pLast
->prev
;
1934 pAdvanced_Terrain_Dlg
->pActiveWidgetList
= pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
;
1935 pAdvanced_Terrain_Dlg
->pBeginWidgetList
= pBuf
;
1936 pAdvanced_Terrain_Dlg
->pBeginActiveWidgetList
= pAdvanced_Terrain_Dlg
->pBeginWidgetList
;
1938 if(n
> ADV_NUM_SEEN
)
1940 units_h
= ADV_NUM_SEEN
* pBuf
->size
.h
;
1941 n
= create_vertical_scrollbar(pAdvanced_Terrain_Dlg
,
1942 1, ADV_NUM_SEEN
, TRUE
, TRUE
);
1948 fc_snprintf(cBuf
, sizeof(cBuf
), "%s (%d)", _("Ready all"), my_units
);
1949 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
,
1950 cBuf
, adv_unit_select_all_callback
);
1951 pBuf
->data
.unit
= pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
->data
.unit
;
1952 set_wstate(pBuf
, FC_WS_NORMAL
);
1953 pBuf
->ID
= ID_LABEL
;
1954 DownAdd(pBuf
, pLast
);
1955 area
.h
+= pBuf
->size
.h
;
1957 fc_snprintf(cBuf
, sizeof(cBuf
), "%s (%d)", _("Sentry idle"), my_units
);
1958 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
,
1959 cBuf
, adv_unit_sentry_idle_callback
);
1960 pBuf
->data
.unit
= pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
->data
.unit
;
1961 set_wstate(pBuf
, FC_WS_NORMAL
);
1962 pBuf
->ID
= ID_LABEL
;
1963 DownAdd(pBuf
, pLast
->prev
);
1964 area
.h
+= pBuf
->size
.h
;
1967 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
1968 pBuf
->ID
= ID_SEPARATOR
;
1969 DownAdd(pBuf
, pLast
->prev
->prev
);
1970 area
.h
+= pBuf
->next
->size
.h
;
1977 /* one unit - give orders */
1978 pUnit
= unit_list_get(ptile
->units
, 0);
1979 pUnitType
= unit_type_get(pUnit
);
1980 if (pUnit
!= pFocus_Unit
) {
1981 const char *vetname
;
1983 vetname
= utype_veteran_name_translation(pUnitType
, pUnit
->veteran
);
1984 if ((pCity
&& city_owner(pCity
) == client
.conn
.playing
)
1985 || (unit_owner(pUnit
) == client
.conn
.playing
)) {
1986 fc_snprintf(cBuf
, sizeof(cBuf
),
1987 _("Activate %s (%d / %d) %s (%d,%d,%s) %s"),
1988 (vetname
!= NULL
? vetname
: ""),
1989 pUnit
->hp
, pUnitType
->hp
,
1990 utype_name_translation(pUnitType
),
1991 pUnitType
->attack_strength
,
1992 pUnitType
->defense_strength
,
1993 move_points_text(pUnitType
->move_rate
, FALSE
),
1994 unit_activity_text(pUnit
));
1996 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
,
1997 cBuf
, adv_unit_select_callback
);
1998 pBuf
->data
.unit
= pUnit
;
1999 set_wstate(pBuf
, FC_WS_NORMAL
);
2001 add_to_gui_list(ID_LABEL
, pBuf
);
2003 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
2004 units_h
+= pBuf
->size
.h
;
2005 /* ---------------- */
2007 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
2009 add_to_gui_list(ID_SEPARATOR
, pBuf
);
2010 area
.h
+= pBuf
->next
->size
.h
;
2012 int att_chance
, def_chance
;
2014 fc_snprintf(cBuf
, sizeof(cBuf
), _("%s %s %s (A:%d D:%d M:%s FP:%d) HP:%d%%"),
2015 nation_adjective_for_player(unit_owner(pUnit
)),
2016 (vetname
!= NULL
? vetname
: ""),
2017 utype_name_translation(pUnitType
),
2018 pUnitType
->attack_strength
,
2019 pUnitType
->defense_strength
,
2020 move_points_text(pUnitType
->move_rate
, FALSE
),
2021 pUnitType
->firepower
,
2022 ((pUnit
->hp
* 100) / pUnitType
->hp
));
2024 /* calculate chance to win */
2025 if (sdl_get_chance_to_win(&att_chance
, &def_chance
, pUnit
, pFocus_Unit
)) {
2026 cat_snprintf(cBuf
, sizeof(cBuf
), _(" CtW: Att:%d%% Def:%d%%"),
2027 att_chance
, def_chance
);
2029 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
, cBuf
, NULL
);
2030 add_to_gui_list(ID_LABEL
, pBuf
);
2031 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
2032 units_h
+= pBuf
->size
.h
;
2033 /* ---------------- */
2036 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, NULL
, WF_FREE_THEME
);
2038 add_to_gui_list(ID_SEPARATOR
, pBuf
);
2039 area
.h
+= pBuf
->next
->size
.h
;
2043 /* ---------------- */
2044 fc_snprintf(cBuf
, sizeof(cBuf
),
2045 _("Look up \"%s\" in the Help Browser"),
2046 utype_name_translation(pUnitType
));
2047 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
,
2048 cBuf
, unit_help_callback
);
2049 set_wstate(pBuf
, FC_WS_NORMAL
);
2050 add_to_gui_list(MAX_ID
- utype_number(pUnitType
), pBuf
);
2052 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
2053 units_h
+= pBuf
->size
.h
;
2054 /* ---------------- */
2055 pAdvanced_Terrain_Dlg
->pBeginWidgetList
= pBuf
;
2061 area
.w
+= adj_size(2);
2064 resize_window(pWindow
, NULL
, NULL
,
2065 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
2066 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
2068 area
= pWindow
->area
;
2070 widget_set_position(pWindow
, pos_x
, pos_y
);
2072 w
= area
.w
- adj_size(2);
2074 if (pAdvanced_Terrain_Dlg
->pScroll
) {
2081 pBuf
= pWindow
->prev
;
2083 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
2084 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
2089 pBuf
->size
.x
= area
.x
+ 1;
2090 pBuf
->size
.y
= area
.y
+ 1;
2094 area2
.x
= adj_size(10);
2095 area2
.h
= adj_size(2);
2101 if (pBuf
== pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
)
2107 pBuf
->size
.x
= pBuf
->next
->size
.x
;
2108 pBuf
->size
.y
= pBuf
->next
->size
.y
+ pBuf
->next
->size
.h
;
2110 if (pBuf
->ID
== ID_SEPARATOR
)
2112 FREESURFACE(pBuf
->theme
);
2114 pBuf
->theme
= create_surf_alpha(w
, h
, SDL_SWSURFACE
);
2116 area2
.y
= pBuf
->size
.h
/ 2 - 1;
2117 area2
.w
= pBuf
->size
.w
- adj_size(20);
2119 SDL_FillRect(pBuf
->theme
, &area2
, map_rgba(pBuf
->theme
->format
,
2120 *get_theme_color(COLOR_THEME_ADVANCEDTERRAINDLG_TEXT
)));
2123 if(pBuf
== pAdvanced_Terrain_Dlg
->pBeginWidgetList
||
2124 pBuf
== pAdvanced_Terrain_Dlg
->pBeginActiveWidgetList
) {
2130 if (pAdvanced_Terrain_Dlg
->pScroll
)
2132 setup_vertical_scrollbar_area(pAdvanced_Terrain_Dlg
->pScroll
,
2134 pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
->size
.y
,
2135 area
.y
- pAdvanced_Terrain_Dlg
->pEndActiveWidgetList
->size
.y
+ area
.h
,
2139 /* -------------------- */
2141 redraw_group(pAdvanced_Terrain_Dlg
->pBeginWidgetList
, pWindow
, 0);
2143 widget_flush(pWindow
);
2146 /* ====================================================================== */
2147 /* ============================ PILLAGE DIALOG ========================== */
2148 /* ====================================================================== */
2149 static struct SMALL_DLG
*pPillage_Dlg
= NULL
;
2151 /**************************************************************************
2152 User interacted with pillage dialog.
2153 **************************************************************************/
2154 static int pillage_window_callback(struct widget
*pWindow
)
2156 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2157 move_window_group(pPillage_Dlg
->pBeginWidgetList
, pWindow
);
2162 /**************************************************************************
2163 User selected what to pillage.
2164 **************************************************************************/
2165 static int pillage_callback(struct widget
*pWidget
)
2167 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2168 struct unit
*pUnit
= pWidget
->data
.unit
;
2169 int what
= MAX_ID
- pWidget
->ID
;
2171 popdown_pillage_dialog();
2175 struct extra_type
*target
= extra_by_number(what
);
2177 request_new_unit_activity_targeted(pUnit
, ACTIVITY_PILLAGE
, target
);
2183 /**************************************************************************
2184 User requested closing of pillage dialog.
2185 **************************************************************************/
2186 static int exit_pillage_dlg_callback(struct widget
*pWidget
)
2188 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2189 popdown_pillage_dialog();
2194 /**************************************************************************
2195 Popdown a dialog asking the unit which improvement they would like to
2197 **************************************************************************/
2198 static void popdown_pillage_dialog(void)
2201 is_unit_move_blocked
= FALSE
;
2202 popdown_window_group_dialog(pPillage_Dlg
->pBeginWidgetList
,
2203 pPillage_Dlg
->pEndWidgetList
);
2204 FC_FREE(pPillage_Dlg
);
2209 /**************************************************************************
2210 Popup a dialog asking the unit which improvement they would like to
2212 **************************************************************************/
2213 void popup_pillage_dialog(struct unit
*pUnit
, bv_extras extras
)
2215 struct widget
*pWindow
= NULL
, *pBuf
= NULL
;
2218 struct extra_type
*tgt
;
2224 is_unit_move_blocked
= TRUE
;
2225 pPillage_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
2228 pStr
= create_str16_from_char(_("What To Pillage") , adj_font(12));
2229 pStr
->style
|= TTF_STYLE_BOLD
;
2231 pWindow
= create_window_skeleton(NULL
, pStr
, 0);
2233 pWindow
->action
= pillage_window_callback
;
2234 set_wstate(pWindow
, FC_WS_NORMAL
);
2236 add_to_gui_list(ID_PILLAGE_DLG_WINDOW
, pWindow
);
2237 pPillage_Dlg
->pEndWidgetList
= pWindow
;
2239 area
= pWindow
->area
;
2241 area
.h
= MAX(area
.h
, adj_size(2));
2245 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
2246 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
2247 pBuf
->info_label
= create_str16_from_char(_("Close Dialog (Esc)"),
2249 area
.w
+= pBuf
->size
.w
+ adj_size(10);
2250 pBuf
->action
= exit_pillage_dlg_callback
;
2251 set_wstate(pBuf
, FC_WS_NORMAL
);
2252 pBuf
->key
= SDLK_ESCAPE
;
2254 add_to_gui_list(ID_PILLAGE_DLG_EXIT_BUTTON
, pBuf
);
2257 while ((tgt
= get_preferred_pillage(extras
))) {
2258 const char *name
= NULL
;
2261 BV_CLR(extras
, extra_index(tgt
));
2262 name
= extra_name_translation(tgt
);
2263 what
= extra_index(tgt
);
2265 fc_assert(name
!= NULL
);
2267 create_active_iconlabel(pBuf
, pWindow
->dst
, pStr
,
2268 (char *) name
, pillage_callback
);
2270 pBuf
->data
.unit
= pUnit
;
2271 set_wstate(pBuf
, FC_WS_NORMAL
);
2273 add_to_gui_list(MAX_ID
- what
, pBuf
);
2275 area
.w
= MAX(area
.w
, pBuf
->size
.w
);
2276 area
.h
+= pBuf
->size
.h
;
2278 pPillage_Dlg
->pBeginWidgetList
= pBuf
;
2280 /* setup window size and start position */
2282 resize_window(pWindow
, NULL
, NULL
,
2283 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
2284 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
2286 area
= pWindow
->area
;
2288 put_window_near_map_tile(pWindow
, pWindow
->size
.w
, pWindow
->size
.h
,
2291 /* setup widget size and start position */
2294 pBuf
= pWindow
->prev
;
2295 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
2296 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
2298 /* first special to pillage */
2300 setup_vertical_widgets_position(1,
2301 area
.x
, area
.y
+ 1, area
.w
, 0,
2302 pPillage_Dlg
->pBeginWidgetList
, pBuf
);
2304 /* --------------------- */
2306 redraw_group(pPillage_Dlg
->pBeginWidgetList
, pWindow
, 0);
2308 widget_flush(pWindow
);
2311 /* ======================================================================= */
2312 /* =========================== CONNECT DIALOG ============================ */
2313 /* ======================================================================= */
2314 static struct SMALL_DLG
*pConnect_Dlg
= NULL
;
2316 /**************************************************************************
2317 Popdown a dialog asking the unit how they want to "connect" their
2318 location to the destination.
2319 **************************************************************************/
2320 static void popdown_connect_dialog(void)
2323 is_unit_move_blocked
= FALSE
;
2324 popdown_window_group_dialog(pConnect_Dlg
->pBeginWidgetList
,
2325 pConnect_Dlg
->pEndWidgetList
);
2326 FC_FREE(pConnect_Dlg
);
2330 /**************************************************************************
2332 **************************************************************************/
2333 static struct SMALL_DLG
*pRevolutionDlg
= NULL
;
2335 /**************************************************************************
2336 User confirmed revolution.
2337 **************************************************************************/
2338 static int revolution_dlg_ok_callback(struct widget
*pButton
)
2340 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2343 popdown_revolution_dialog();
2350 /**************************************************************************
2351 User cancelled revolution.
2352 **************************************************************************/
2353 static int revolution_dlg_cancel_callback(struct widget
*pCancel_Button
)
2355 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2356 popdown_revolution_dialog();
2362 /**************************************************************************
2363 User requested move of revolution dialog.
2364 **************************************************************************/
2365 static int move_revolution_dlg_callback(struct widget
*pWindow
)
2367 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2368 move_window_group(pRevolutionDlg
->pBeginWidgetList
, pWindow
);
2373 /**************************************************************************
2374 Close the revolution dialog.
2375 **************************************************************************/
2376 static void popdown_revolution_dialog(void)
2378 if(pRevolutionDlg
) {
2379 popdown_window_group_dialog(pRevolutionDlg
->pBeginWidgetList
,
2380 pRevolutionDlg
->pEndWidgetList
);
2381 FC_FREE(pRevolutionDlg
);
2382 enable_and_redraw_revolution_button();
2386 /* ==================== Public ========================= */
2388 /**************************************************************************
2389 Sellect Goverment Type
2390 **************************************************************************/
2391 static struct SMALL_DLG
*pGov_Dlg
= NULL
;
2393 /**************************************************************************
2394 Close the government dialog.
2395 **************************************************************************/
2396 static void popdown_government_dialog(void)
2399 popdown_window_group_dialog(pGov_Dlg
->pBeginWidgetList
,
2400 pGov_Dlg
->pEndWidgetList
);
2402 enable_and_redraw_revolution_button();
2406 /**************************************************************************
2407 User selected government button.
2408 **************************************************************************/
2409 static int government_dlg_callback(struct widget
*pGov_Button
)
2411 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2412 set_government_choice(government_by_number(MAX_ID
- pGov_Button
->ID
));
2414 popdown_government_dialog();
2419 /**************************************************************************
2420 User requested move of government dialog.
2421 **************************************************************************/
2422 static int move_government_dlg_callback(struct widget
*pWindow
)
2424 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2425 move_window_group(pGov_Dlg
->pBeginWidgetList
, pWindow
);
2430 /**************************************************************************
2433 Popup a dialog asking the player what government to switch to (this
2434 happens after a revolution completes).
2435 **************************************************************************/
2436 static void popup_government_dialog(void)
2438 SDL_Surface
*pLogo
= NULL
;
2439 struct SDL_String16
*pStr
= NULL
;
2440 struct widget
*pGov_Button
= NULL
;
2441 struct widget
*pWindow
= NULL
;
2443 Uint16 max_w
= 0, max_h
= 0;
2450 pGov_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
2453 pStr
= create_str16_from_char(_("Choose Your New Government"), adj_font(12));
2454 pStr
->style
|= TTF_STYLE_BOLD
;
2455 /* this win. size is temp. */
2456 pWindow
= create_window_skeleton(NULL
, pStr
, 0);
2457 pWindow
->action
= move_government_dlg_callback
;
2458 add_to_gui_list(ID_GOVERNMENT_DLG_WINDOW
, pWindow
);
2460 pGov_Dlg
->pEndWidgetList
= pWindow
;
2462 area
= pWindow
->area
;
2464 /* create gov. buttons */
2466 governments_iterate(pGov
) {
2468 if (pGov
== game
.government_during_revolution
) {
2472 if (can_change_to_government(client
.conn
.playing
, pGov
)) {
2474 pStr
= create_str16_from_char(government_name_translation(pGov
), adj_font(12));
2476 create_icon_button(get_government_surface(pGov
), pWindow
->dst
, pStr
, 0);
2477 pGov_Button
->action
= government_dlg_callback
;
2479 max_w
= MAX(max_w
, pGov_Button
->size
.w
);
2480 max_h
= MAX(max_h
, pGov_Button
->size
.h
);
2483 add_to_gui_list((MAX_ID
- government_number(pGov
)), pGov_Button
);
2487 } governments_iterate_end
;
2489 pGov_Dlg
->pBeginWidgetList
= pGov_Button
;
2491 max_w
+= adj_size(10);
2492 max_h
+= adj_size(4);
2494 area
.w
= MAX(area
.w
, max_w
+ adj_size(20));
2495 area
.h
= MAX(area
.h
, j
* (max_h
+ adj_size(10)) + adj_size(5));
2497 /* create window background */
2498 pLogo
= theme_get_background(theme
, BACKGROUND_CHOOSEGOVERNMENTDLG
);
2499 if (resize_window(pWindow
, pLogo
, NULL
,
2500 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
2501 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
)) {
2505 area
= pWindow
->area
;
2507 /* set window start positions */
2508 widget_set_position(pWindow
,
2509 (Main
.screen
->w
- pWindow
->size
.w
) / 2,
2510 (Main
.screen
->h
- pWindow
->size
.h
) / 2);
2512 /* set buttons start positions and size */
2514 while (pGov_Button
!= pGov_Dlg
->pEndWidgetList
) {
2515 pGov_Button
->size
.w
= max_w
;
2516 pGov_Button
->size
.h
= max_h
;
2517 pGov_Button
->size
.x
= area
.x
+ adj_size(10);
2518 pGov_Button
->size
.y
= area
.y
+ area
.h
- (j
++) * (max_h
+ adj_size(10));
2519 set_wstate(pGov_Button
, FC_WS_NORMAL
);
2521 pGov_Button
= pGov_Button
->next
;
2524 set_wstate(pWindow
, FC_WS_NORMAL
);
2527 redraw_group(pGov_Dlg
->pBeginWidgetList
, pWindow
, 0);
2529 widget_flush(pWindow
);
2532 /**************************************************************************
2533 Popup a dialog asking if the player wants to start a revolution.
2534 **************************************************************************/
2535 void popup_revolution_dialog(void)
2538 struct SDL_String16
*pStr
= NULL
;
2539 struct widget
*pLabel
= NULL
;
2540 struct widget
*pWindow
= NULL
;
2541 struct widget
*pCancel_Button
= NULL
;
2542 struct widget
*pOK_Button
= NULL
;
2545 if(pRevolutionDlg
) {
2549 if (0 <= client
.conn
.playing
->revolution_finishes
) {
2550 popup_government_dialog();
2554 pRevolutionDlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
2556 pStr
= create_str16_from_char(_("REVOLUTION!"), adj_font(12));
2557 pStr
->style
|= TTF_STYLE_BOLD
;
2559 pWindow
= create_window_skeleton(NULL
, pStr
, 0);
2560 pWindow
->action
= move_revolution_dlg_callback
;
2561 set_wstate(pWindow
, FC_WS_NORMAL
);
2562 add_to_gui_list(ID_REVOLUTION_DLG_WINDOW
, pWindow
);
2563 pRevolutionDlg
->pEndWidgetList
= pWindow
;
2565 area
= pWindow
->area
;
2567 /* create text label */
2568 pStr
= create_str16_from_char(_("You say you wanna revolution?"), adj_font(10));
2569 pStr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
2570 pStr
->fgcol
= *get_theme_color(COLOR_THEME_REVOLUTIONDLG_TEXT
);
2571 pLabel
= create_iconlabel(NULL
, pWindow
->dst
, pStr
, 0);
2572 add_to_gui_list(ID_REVOLUTION_DLG_LABEL
, pLabel
);
2575 /* create cancel button */
2577 create_themeicon_button_from_chars(current_theme
->Small_CANCEL_Icon
,
2578 pWindow
->dst
, _("Cancel"), adj_font(10), 0);
2579 pCancel_Button
->action
= revolution_dlg_cancel_callback
;
2580 pCancel_Button
->size
.w
+= adj_size(6);
2581 set_wstate(pCancel_Button
, FC_WS_NORMAL
);
2582 add_to_gui_list(ID_REVOLUTION_DLG_CANCEL_BUTTON
, pCancel_Button
);
2584 /* create ok button */
2586 create_themeicon_button_from_chars(current_theme
->Small_OK_Icon
,
2587 pWindow
->dst
, _("Revolution!"),
2589 pOK_Button
->action
= revolution_dlg_ok_callback
;
2590 pOK_Button
->key
= SDLK_RETURN
;
2591 set_wstate(pOK_Button
, FC_WS_NORMAL
);
2592 add_to_gui_list(ID_REVOLUTION_DLG_OK_BUTTON
, pOK_Button
);
2594 pRevolutionDlg
->pBeginWidgetList
= pOK_Button
;
2596 if ((pOK_Button
->size
.w
+ pCancel_Button
->size
.w
+ adj_size(30)) >
2597 pLabel
->size
.w
+ adj_size(20)) {
2598 area
.w
= MAX(area
.w
, pOK_Button
->size
.w
+ pCancel_Button
->size
.w
+ adj_size(30));
2600 area
.w
= MAX(area
.w
, pLabel
->size
.w
+ adj_size(20));
2603 area
.h
= MAX(area
.h
, pOK_Button
->size
.h
+ pLabel
->size
.h
+ adj_size(24));
2605 /* create window background */
2606 pLogo
= theme_get_background(theme
, BACKGROUND_REVOLUTIONDLG
);
2607 if (resize_window(pWindow
, pLogo
, NULL
,
2608 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
2609 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
)) {
2613 area
= pWindow
->area
;
2615 /* set start positions */
2616 widget_set_position(pWindow
,
2617 (Main
.screen
->w
- pWindow
->size
.w
) / 2,
2618 (Main
.screen
->h
- pWindow
->size
.h
) / 2);
2620 pOK_Button
->size
.x
= area
.x
+ adj_size(10);
2621 pOK_Button
->size
.y
= area
.y
+ area
.h
- pOK_Button
->size
.h
- adj_size(10);
2623 pCancel_Button
->size
.y
= pOK_Button
->size
.y
;
2624 pCancel_Button
->size
.x
= area
.x
+ area
.w
- pCancel_Button
->size
.w
- adj_size(10);
2626 pLabel
->size
.x
= area
.x
;
2627 pLabel
->size
.y
= area
.y
+ adj_size(4);
2628 pLabel
->size
.w
= area
.w
;
2631 redraw_group(pOK_Button
, pWindow
, 0);
2632 widget_mark_dirty(pWindow
);
2636 /**************************************************************************
2638 **************************************************************************/
2639 static struct ADVANCED_DLG
*pNationDlg
= NULL
;
2640 static struct SMALL_DLG
*pHelpDlg
= NULL
;
2643 unsigned char nation_style
; /* selected style */
2644 unsigned char selected_leader
; /* if not unique -> selected leader */
2645 Nation_type_id nation
; /* selected nation */
2646 bool leader_sex
; /* selected leader sex */
2647 struct nation_set
*set
;
2648 struct widget
*pChange_Sex
;
2649 struct widget
*pName_Edit
;
2650 struct widget
*pName_Next
;
2651 struct widget
*pName_Prev
;
2652 struct widget
*pset_name
;
2653 struct widget
*pset_next
;
2654 struct widget
*pset_prev
;
2657 static int next_set_callback(struct widget
*next_button
);
2658 static int prev_set_callback(struct widget
*prev_button
);
2659 static int nations_dialog_callback(struct widget
*pWindow
);
2660 static int nation_button_callback(struct widget
*pNation
);
2661 static int races_dialog_ok_callback(struct widget
*pStart_Button
);
2662 static int races_dialog_cancel_callback(struct widget
*pButton
);
2663 static int next_name_callback(struct widget
*pNext_Button
);
2664 static int prev_name_callback(struct widget
*pPrev_Button
);
2665 static int change_sex_callback(struct widget
*pSex
);
2666 static void select_random_leader(Nation_type_id nation
);
2667 static void change_nation_label(void);
2669 /**************************************************************************
2670 User interaceted with nations dialog.
2671 **************************************************************************/
2672 static int nations_dialog_callback(struct widget
*pWindow
)
2674 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2675 if(sellect_window_group_dialog(pNationDlg
->pBeginWidgetList
, pWindow
)) {
2676 widget_flush(pWindow
);
2682 /**************************************************************************
2683 User accepted nation.
2684 **************************************************************************/
2685 static int races_dialog_ok_callback(struct widget
*pStart_Button
)
2687 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2688 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2689 char *pStr
= convert_to_chars(pSetup
->pName_Edit
->string16
->text
);
2691 /* perform a minimum of sanity test on the name */
2692 if (strlen(pStr
) == 0) {
2693 output_window_append(ftc_client
, _("You must type a legal name."));
2694 pSellected_Widget
= pStart_Button
;
2695 set_wstate(pStart_Button
, FC_WS_SELLECTED
);
2696 widget_redraw(pStart_Button
);
2697 widget_flush(pStart_Button
);
2701 dsend_packet_nation_select_req(&client
.conn
, player_number(races_player
),
2703 pSetup
->leader_sex
, pStr
,
2704 pSetup
->nation_style
);
2707 popdown_races_dialog();
2713 /**************************************************************************
2714 User requested leader gender change.
2715 **************************************************************************/
2716 static int change_sex_callback(struct widget
*pSex
)
2718 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2719 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2721 if (pSetup
->leader_sex
) {
2722 copy_chars_to_string16(pSetup
->pChange_Sex
->string16
, _("Female"));
2724 copy_chars_to_string16(pSetup
->pChange_Sex
->string16
, _("Male"));
2726 pSetup
->leader_sex
= !pSetup
->leader_sex
;
2729 pSellected_Widget
= pSex
;
2730 set_wstate(pSex
, FC_WS_SELLECTED
);
2732 widget_redraw(pSex
);
2739 /**************************************************************************
2740 User requested next leader name.
2741 **************************************************************************/
2742 static int next_name_callback(struct widget
*pNext
)
2744 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2745 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2746 const struct nation_leader_list
*leaders
=
2747 nation_leaders(nation_by_number(pSetup
->nation
));
2748 const struct nation_leader
*pleader
;
2750 pSetup
->selected_leader
++;
2751 pleader
= nation_leader_list_get(leaders
, pSetup
->selected_leader
);
2753 /* change leadaer sex */
2754 if (pSetup
->leader_sex
!= nation_leader_is_male(pleader
)) {
2755 change_sex_callback(NULL
);
2758 /* change leadaer name */
2759 copy_chars_to_string16(pSetup
->pName_Edit
->string16
,
2760 nation_leader_name(pleader
));
2762 FC_FREE(pLeaderName
);
2763 pLeaderName
= fc_strdup(nation_leader_name(pleader
));
2765 if (nation_leader_list_size(leaders
) - 1 == pSetup
->selected_leader
) {
2766 set_wstate(pSetup
->pName_Next
, FC_WS_DISABLED
);
2769 if (get_wstate(pSetup
->pName_Prev
) == FC_WS_DISABLED
) {
2770 set_wstate(pSetup
->pName_Prev
, FC_WS_NORMAL
);
2773 if (!(get_wstate(pSetup
->pName_Next
) == FC_WS_DISABLED
)) {
2774 pSellected_Widget
= pSetup
->pName_Next
;
2775 set_wstate(pSetup
->pName_Next
, FC_WS_SELLECTED
);
2778 widget_redraw(pSetup
->pName_Edit
);
2779 widget_redraw(pSetup
->pName_Prev
);
2780 widget_redraw(pSetup
->pName_Next
);
2781 widget_mark_dirty(pSetup
->pName_Edit
);
2782 widget_mark_dirty(pSetup
->pName_Prev
);
2783 widget_mark_dirty(pSetup
->pName_Next
);
2785 widget_redraw(pSetup
->pChange_Sex
);
2786 widget_mark_dirty(pSetup
->pChange_Sex
);
2793 /**************************************************************************
2794 User requested previous leader name.
2795 **************************************************************************/
2796 static int prev_name_callback(struct widget
*pPrev
)
2798 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2799 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2800 const struct nation_leader_list
*leaders
=
2801 nation_leaders(nation_by_number(pSetup
->nation
));
2802 const struct nation_leader
*pleader
;
2804 pSetup
->selected_leader
--;
2805 pleader
= nation_leader_list_get(leaders
, pSetup
->selected_leader
);
2807 /* change leadaer sex */
2808 if (pSetup
->leader_sex
!= nation_leader_is_male(pleader
)) {
2809 change_sex_callback(NULL
);
2812 /* change leadaer name */
2813 copy_chars_to_string16(pSetup
->pName_Edit
->string16
,
2814 nation_leader_name(pleader
));
2816 FC_FREE(pLeaderName
);
2817 pLeaderName
= fc_strdup(nation_leader_name(pleader
));
2819 if (!pSetup
->selected_leader
) {
2820 set_wstate(pSetup
->pName_Prev
, FC_WS_DISABLED
);
2823 if (get_wstate(pSetup
->pName_Next
) == FC_WS_DISABLED
) {
2824 set_wstate(pSetup
->pName_Next
, FC_WS_NORMAL
);
2827 if (!(get_wstate(pSetup
->pName_Prev
) == FC_WS_DISABLED
)) {
2828 pSellected_Widget
= pSetup
->pName_Prev
;
2829 set_wstate(pSetup
->pName_Prev
, FC_WS_SELLECTED
);
2832 widget_redraw(pSetup
->pName_Edit
);
2833 widget_redraw(pSetup
->pName_Prev
);
2834 widget_redraw(pSetup
->pName_Next
);
2835 widget_mark_dirty(pSetup
->pName_Edit
);
2836 widget_mark_dirty(pSetup
->pName_Prev
);
2837 widget_mark_dirty(pSetup
->pName_Next
);
2839 widget_redraw(pSetup
->pChange_Sex
);
2840 widget_mark_dirty(pSetup
->pChange_Sex
);
2847 /**************************************************************************
2848 User requested next nationset
2849 **************************************************************************/
2850 static int next_set_callback(struct widget
*next_button
)
2852 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2853 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2854 struct option
*poption
= optset_option_by_name(server_optset
, "nationset");
2856 fc_assert(pSetup
->set
!= NULL
2857 && nation_set_index(pSetup
->set
) < nation_set_count() - 1);
2859 pSetup
->set
= nation_set_by_number(nation_set_index(pSetup
->set
) + 1);
2861 option_str_set(poption
, nation_set_rule_name(pSetup
->set
));
2867 /**************************************************************************
2868 User requested prev nationset
2869 **************************************************************************/
2870 static int prev_set_callback(struct widget
*prev_button
)
2872 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2873 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2874 struct option
*poption
= optset_option_by_name(server_optset
, "nationset");
2876 fc_assert(pSetup
->set
!= NULL
&& nation_set_index(pSetup
->set
) > 0);
2878 pSetup
->set
= nation_set_by_number(nation_set_index(pSetup
->set
) - 1);
2880 option_str_set(poption
, nation_set_rule_name(pSetup
->set
));
2886 /**************************************************************************
2887 User cancelled nations dialog.
2888 **************************************************************************/
2889 static int races_dialog_cancel_callback(struct widget
*pButton
)
2891 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2892 popdown_races_dialog();
2898 /**************************************************************************
2899 User interacted with style widget.
2900 **************************************************************************/
2901 static int style_callback(struct widget
*pWidget
)
2903 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2904 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2905 struct widget
*pGUI
= get_widget_pointer_form_main_list(MAX_ID
- 1000 -
2906 pSetup
->nation_style
);
2908 set_wstate(pGUI
, FC_WS_NORMAL
);
2909 widget_redraw(pGUI
);
2910 widget_mark_dirty(pGUI
);
2912 set_wstate(pWidget
, FC_WS_DISABLED
);
2913 widget_redraw(pWidget
);
2914 widget_mark_dirty(pWidget
);
2916 pSetup
->nation_style
= MAX_ID
- 1000 - pWidget
->ID
;
2919 pSellected_Widget
= NULL
;
2924 /**************************************************************************
2925 User interacted with help dialog.
2926 **************************************************************************/
2927 static int help_dlg_callback(struct widget
*pWindow
)
2932 /**************************************************************************
2933 User requested closing of help dialog.
2934 **************************************************************************/
2935 static int cancel_help_dlg_callback(struct widget
*pWidget
)
2937 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2939 popdown_window_group_dialog(pHelpDlg
->pBeginWidgetList
,
2940 pHelpDlg
->pEndWidgetList
);
2950 /**************************************************************************
2951 User selected nation.
2952 **************************************************************************/
2953 static int nation_button_callback(struct widget
*pNationButton
)
2955 set_wstate(pNationButton
, FC_WS_SELLECTED
);
2956 pSellected_Widget
= pNationButton
;
2958 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2959 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
2961 if (pSetup
->nation
== MAX_ID
- pNationButton
->ID
) {
2962 widget_redraw(pNationButton
);
2963 widget_flush(pNationButton
);
2967 pSetup
->nation
= MAX_ID
- pNationButton
->ID
;
2969 change_nation_label();
2971 enable(MAX_ID
- 1000 - pSetup
->nation_style
);
2972 pSetup
->nation_style
= style_number(style_of_nation(nation_by_number(pSetup
->nation
)));
2973 disable(MAX_ID
- 1000 - pSetup
->nation_style
);
2975 select_random_leader(pSetup
->nation
);
2977 redraw_group(pNationDlg
->pBeginWidgetList
, pNationDlg
->pEndWidgetList
, 0);
2978 widget_flush(pNationDlg
->pEndWidgetList
);
2980 /* pop up nation description */
2981 struct widget
*pWindow
, *pOK_Button
;
2984 SDL_Rect area
, area2
;
2985 struct nation_type
*pNation
= nation_by_number(MAX_ID
- pNationButton
->ID
);
2987 widget_redraw(pNationButton
);
2988 widget_mark_dirty(pNationButton
);
2992 pHelpDlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
2994 pStr
= create_str16_from_char(nation_plural_translation(pNation
),
2996 pStr
->style
|= TTF_STYLE_BOLD
;
2998 pWindow
= create_window_skeleton(NULL
, pStr
, 0);
2999 pWindow
->action
= help_dlg_callback
;
3001 set_wstate(pWindow
, FC_WS_NORMAL
);
3003 pHelpDlg
->pEndWidgetList
= pWindow
;
3004 add_to_gui_list(ID_WINDOW
, pWindow
);
3006 pOK_Button
= create_themeicon_button_from_chars(current_theme
->OK_Icon
,
3007 pWindow
->dst
, _("OK"),
3009 pOK_Button
->action
= cancel_help_dlg_callback
;
3010 set_wstate(pOK_Button
, FC_WS_NORMAL
);
3011 pOK_Button
->key
= SDLK_ESCAPE
;
3012 add_to_gui_list(ID_BUTTON
, pOK_Button
);
3013 pHelpDlg
->pBeginWidgetList
= pOK_Button
;
3015 pWindow
= pHelpDlg
->pEndWidgetList
;
3016 pOK_Button
= pHelpDlg
->pBeginWidgetList
;
3018 widget_undraw(pWindow
);
3019 widget_mark_dirty(pWindow
);
3022 area
= pWindow
->area
;
3026 helptext_nation(info
, sizeof(info
), pNation
, NULL
);
3027 pStr
= create_str16_from_char(info
, adj_font(12));
3030 pStr
->fgcol
= *get_theme_color(COLOR_THEME_NATIONDLG_LEGEND
);
3031 pText
= create_text_surf_smaller_that_w(pStr
, Main
.screen
->w
- adj_size(20));
3035 /* create window background */
3036 area
.w
= MAX(area
.w
, pText
->w
+ adj_size(20));
3037 area
.w
= MAX(area
.w
, pOK_Button
->size
.w
+ adj_size(20));
3038 area
.h
= MAX(area
.h
, adj_size(9) + pText
->h
3039 + adj_size(10) + pOK_Button
->size
.h
+ adj_size(10));
3041 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
3042 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
3043 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
3045 widget_set_position(pWindow
,
3046 (Main
.screen
->w
- pWindow
->size
.w
) / 2,
3047 (Main
.screen
->h
- pWindow
->size
.h
) / 2);
3049 area2
.x
= area
.x
+ adj_size(7);
3050 area2
.y
= area
.y
+ adj_size(6);
3051 alphablit(pText
, NULL
, pWindow
->theme
, &area2
);
3054 pOK_Button
->size
.x
= area
.x
+ (area
.w
- pOK_Button
->size
.w
) / 2;
3055 pOK_Button
->size
.y
= area
.y
+ area
.h
- pOK_Button
->size
.h
- adj_size(10);
3058 redraw_group(pOK_Button
, pWindow
, 0);
3060 widget_mark_dirty(pWindow
);
3068 /**************************************************************************
3069 User interacted with leader name edit widget.
3070 **************************************************************************/
3071 static int leader_name_edit_callback(struct widget
*pEdit
)
3073 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
3074 char *name
= convert_to_chars(pEdit
->string16
->text
);
3079 /* empty input -> restore previous content */
3080 copy_chars_to_string16(pEdit
->string16
, pLeaderName
);
3081 widget_redraw(pEdit
);
3082 widget_mark_dirty(pEdit
);
3088 /* =========================================================== */
3090 /**************************************************************************
3091 Update nation label.
3092 **************************************************************************/
3093 static void change_nation_label(void)
3095 SDL_Surface
*pTmp_Surf
, *pTmp_Surf_zoomed
;
3096 struct widget
*pWindow
= pNationDlg
->pEndWidgetList
;
3097 struct NAT
*pSetup
= (struct NAT
*)(pWindow
->data
.ptr
);
3098 struct widget
*pLabel
= pSetup
->pName_Edit
->next
;
3099 struct nation_type
*pNation
= nation_by_number(pSetup
->nation
);
3101 pTmp_Surf
= get_nation_flag_surface(pNation
);
3102 pTmp_Surf_zoomed
= zoomSurface(pTmp_Surf
, DEFAULT_ZOOM
* 1.0, DEFAULT_ZOOM
* 1.0, 1);
3104 FREESURFACE(pLabel
->theme
);
3105 pLabel
->theme
= pTmp_Surf_zoomed
;
3107 copy_chars_to_string16(pLabel
->string16
, nation_plural_translation(pNation
));
3109 remake_label_size(pLabel
);
3111 pLabel
->size
.x
= pWindow
->size
.x
+ pWindow
->size
.w
/ 2 +
3112 (pWindow
->size
.w
/2 - pLabel
->size
.w
) / 2;
3116 /**************************************************************************
3117 Selectes a leader and the appropriate sex. Updates the gui elements
3118 and the selected_* variables.
3119 **************************************************************************/
3120 static void select_random_leader(Nation_type_id nation
)
3122 struct NAT
*pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
3123 const struct nation_leader_list
*leaders
=
3124 nation_leaders(nation_by_number(pSetup
->nation
));
3125 const struct nation_leader
*pleader
;
3127 pSetup
->selected_leader
= fc_rand(nation_leader_list_size(leaders
));
3128 pleader
= nation_leader_list_get(leaders
, pSetup
->selected_leader
);
3129 copy_chars_to_string16(pSetup
->pName_Edit
->string16
,
3130 nation_leader_name(pleader
));
3132 FC_FREE(pLeaderName
);
3133 pLeaderName
= fc_strdup(nation_leader_name(pleader
));
3135 /* initialize leader sex */
3136 pSetup
->leader_sex
= nation_leader_is_male(pleader
);
3138 if (pSetup
->leader_sex
) {
3139 copy_chars_to_string16(pSetup
->pChange_Sex
->string16
, _("Male"));
3141 copy_chars_to_string16(pSetup
->pChange_Sex
->string16
, _("Female"));
3144 /* disable navigation buttons */
3145 set_wstate(pSetup
->pName_Prev
, FC_WS_DISABLED
);
3146 set_wstate(pSetup
->pName_Next
, FC_WS_DISABLED
);
3148 if (1 < nation_leader_list_size(leaders
)) {
3149 /* if selected leader is not the first leader, enable "previous leader" button */
3150 if (pSetup
->selected_leader
> 0) {
3151 set_wstate(pSetup
->pName_Prev
, FC_WS_NORMAL
);
3154 /* if selected leader is not the last leader, enable "next leader" button */
3155 if (pSetup
->selected_leader
< (nation_leader_list_size(leaders
) - 1)) {
3156 set_wstate(pSetup
->pName_Next
, FC_WS_NORMAL
);
3162 /**************************************************************************
3163 Count available playable nations.
3164 **************************************************************************/
3165 static int get_playable_nation_count(void)
3167 int playable_nation_count
= 0;
3169 nations_iterate(pnation
) {
3170 if (is_nation_playable(pnation
) && !pnation
->player
3171 && is_nation_pickable(pnation
))
3172 ++playable_nation_count
;
3173 } nations_iterate_end
;
3175 return playable_nation_count
;
3179 /**************************************************************************
3180 Popup the nation selection dialog.
3181 **************************************************************************/
3182 void popup_races_dialog(struct player
*pplayer
)
3184 SDL_Color bg_color
= {255,255,255,128};
3186 struct widget
*pWindow
, *pWidget
= NULL
, *pBuf
, *pLast_City_Style
;
3189 int w
= adj_size(10), h
= adj_size(10);
3190 SDL_Surface
*pTmp_Surf
, *pTmp_Surf_zoomed
= NULL
;
3191 SDL_Surface
*pMain_Bg
, *pText_Name
, *pText_Class
;
3197 struct nation_type
*pnat
;
3198 struct widget
*nationsets
= NULL
;
3199 int natinfo_y
, natinfo_h
;
3201 #define TARGETS_ROW 5
3202 #define TARGETS_COL 1
3208 races_player
= pplayer
;
3210 pNationDlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
3212 /* create window widget */
3213 pStr
= create_str16_from_char(_("What nation will you be?"), adj_font(12));
3214 pStr
->style
|= TTF_STYLE_BOLD
;
3216 pWindow
= create_window(NULL
, pStr
, w
, h
, WF_FREE_DATA
);
3217 pWindow
->action
= nations_dialog_callback
;
3218 set_wstate(pWindow
, FC_WS_NORMAL
);
3219 pSetup
= fc_calloc(1, sizeof(struct NAT
));
3220 pWindow
->data
.ptr
= (void *)pSetup
;
3222 pNationDlg
->pEndWidgetList
= pWindow
;
3223 add_to_gui_list(ID_NATION_WIZARD_WINDOW
, pWindow
);
3224 /* --------------------------------------------------------- */
3225 /* create nations list */
3227 /* Create Imprv Background Icon */
3228 pMain_Bg
= create_surf_alpha(adj_size(96*2), adj_size(64), SDL_SWSURFACE
);
3230 SDL_FillRect(pMain_Bg
, NULL
, map_rgba(pMain_Bg
->format
, bg_color
));
3232 0, 0, pMain_Bg
->w
- 1, pMain_Bg
->h
- 1,
3233 get_theme_color(COLOR_THEME_NATIONDLG_FRAME
));
3235 pStr
= create_string16(NULL
, 0, adj_font(12));
3236 pStr
->style
|= (SF_CENTER
|TTF_STYLE_BOLD
);
3237 pStr
->bgcol
= (SDL_Color
) {0, 0, 0, 0};
3242 nations_iterate(pNation
) {
3244 if (!is_nation_playable(pNation
) || !is_nation_pickable(pNation
)) {
3248 pTmp_Surf_zoomed
= adj_surf(get_nation_flag_surface(pNation
));
3250 pTmp_Surf
= crop_rect_from_surface(pMain_Bg
, NULL
);
3252 copy_chars_to_string16(pStr
, nation_plural_translation(pNation
));
3253 change_ptsize16(pStr
, adj_font(12));
3254 pText_Name
= create_text_surf_smaller_that_w(pStr
, pTmp_Surf
->w
- adj_size(4));
3257 if (pNation
->legend
&& *(pNation
->legend
) != '\0') {
3258 copy_chars_to_string16(pStr
, pNation
->legend
);
3259 change_ptsize16(pStr
, adj_font(10));
3260 pText_Class
= create_text_surf_smaller_that_w(pStr
, pTmp_Surf
->w
- adj_size(4));
3264 dst
.x
= (pTmp_Surf
->w
- pTmp_Surf_zoomed
->w
) / 2;
3265 len
= pTmp_Surf_zoomed
->h
+
3266 adj_size(10) + pText_Name
->h
+ (pText_Class
? pText_Class
->h
: 0);
3267 dst
.y
= (pTmp_Surf
->h
- len
) / 2;
3268 alphablit(pTmp_Surf_zoomed
, NULL
, pTmp_Surf
, &dst
);
3269 dst
.y
+= (pTmp_Surf_zoomed
->h
+ adj_size(10));
3271 dst
.x
= (pTmp_Surf
->w
- pText_Name
->w
) / 2;
3272 alphablit(pText_Name
, NULL
, pTmp_Surf
, &dst
);
3273 dst
.y
+= pText_Name
->h
;
3274 FREESURFACE(pText_Name
);
3277 dst
.x
= (pTmp_Surf
->w
- pText_Class
->w
) / 2;
3278 alphablit(pText_Class
, NULL
, pTmp_Surf
, &dst
);
3279 FREESURFACE(pText_Class
);
3282 pWidget
= create_icon2(pTmp_Surf
, pWindow
->dst
,
3283 (WF_RESTORE_BACKGROUND
|WF_FREE_THEME
));
3285 set_wstate(pWidget
, FC_WS_NORMAL
);
3287 pWidget
->action
= nation_button_callback
;
3289 w
= MAX(w
, pWidget
->size
.w
);
3290 h
= MAX(h
, pWidget
->size
.h
);
3292 add_to_gui_list(MAX_ID
- nation_index(pNation
), pWidget
);
3294 if (nation_index(pNation
) > (TARGETS_ROW
* TARGETS_COL
- 1)) {
3295 set_wflag(pWidget
, WF_HIDDEN
);
3298 } nations_iterate_end
;
3300 FREESURFACE(pMain_Bg
);
3302 pNationDlg
->pEndActiveWidgetList
= pWindow
->prev
;
3303 pNationDlg
->pBeginWidgetList
= pWidget
;
3304 pNationDlg
->pBeginActiveWidgetList
= pNationDlg
->pBeginWidgetList
;
3306 if(get_playable_nation_count() > TARGETS_ROW
* TARGETS_COL
) {
3307 pNationDlg
->pActiveWidgetList
= pNationDlg
->pEndActiveWidgetList
;
3308 create_vertical_scrollbar(pNationDlg
,
3309 TARGETS_COL
, TARGETS_ROW
, TRUE
, TRUE
);
3312 /* ----------------------------------------------------------------- */
3314 /* nation set selection */
3315 if (nation_set_count() > 1) {
3316 SDL_String16
*natset_str
;
3317 struct option
*poption
;
3319 natset_str
= create_str16_from_char(_("Nation set"), adj_font(12));
3320 change_ptsize16(natset_str
, adj_font(24));
3321 nationsets
= create_iconlabel(NULL
, pWindow
->dst
, natset_str
, 0);
3322 add_to_gui_list(ID_LABEL
, nationsets
);
3324 /* create nation set name label */
3325 poption
= optset_option_by_name(server_optset
, "nationset");
3326 pSetup
->set
= nation_set_by_setting_value(option_str_get(poption
));
3328 natset_str
= create_str16_from_char(nation_set_name_translation(pSetup
->set
),
3330 change_ptsize16(natset_str
, adj_font(24));
3332 pWidget
= create_iconlabel(NULL
, pWindow
->dst
, natset_str
, 0);
3334 add_to_gui_list(ID_LABEL
, pWidget
);
3335 pSetup
->pset_name
= pWidget
;
3337 /* create next nationset button */
3338 pWidget
= create_themeicon_button(current_theme
->R_ARROW_Icon
,
3339 pWindow
->dst
, NULL
, 0);
3340 pWidget
->action
= next_set_callback
;
3341 if (nation_set_index(pSetup
->set
) < nation_set_count() - 1) {
3342 set_wstate(pWidget
, FC_WS_NORMAL
);
3344 add_to_gui_list(ID_NATION_NEXT_NATIONSET_BUTTON
, pWidget
);
3345 pWidget
->size
.h
= pWidget
->next
->size
.h
;
3346 pSetup
->pset_next
= pWidget
;
3348 /* create prev nationset button */
3349 pWidget
= create_themeicon_button(current_theme
->L_ARROW_Icon
,
3350 pWindow
->dst
, NULL
, 0);
3351 pWidget
->action
= prev_set_callback
;
3352 if (nation_set_index(pSetup
->set
) > 0) {
3353 set_wstate(pWidget
, FC_WS_NORMAL
);
3355 add_to_gui_list(ID_NATION_PREV_NATIONSET_BUTTON
, pWidget
);
3356 pWidget
->size
.h
= pWidget
->next
->size
.h
;
3357 pSetup
->pset_prev
= pWidget
;
3361 pSetup
->nation
= fc_rand(get_playable_nation_count());
3362 pnat
= nation_by_number(pSetup
->nation
);
3363 pSetup
->nation_style
= style_number(style_of_nation(pnat
));
3365 copy_chars_to_string16(pStr
, nation_plural_translation(pnat
));
3366 change_ptsize16(pStr
, adj_font(24));
3368 pStr
->fgcol
= *get_theme_color(COLOR_THEME_NATIONDLG_TEXT
);
3370 pTmp_Surf_zoomed
= adj_surf(get_nation_flag_surface(pnat
));
3372 pWidget
= create_iconlabel(pTmp_Surf_zoomed
, pWindow
->dst
, pStr
,
3373 (WF_ICON_ABOVE_TEXT
|WF_ICON_CENTER
|WF_FREE_GFX
));
3374 if (nationsets
== NULL
) {
3380 add_to_gui_list(ID_LABEL
, pWidget
);
3382 /* create leader name edit */
3383 pWidget
= create_edit_from_unichars(NULL
, pWindow
->dst
,
3384 NULL
, 0, adj_font(16), adj_size(200), 0);
3385 pWidget
->size
.h
= adj_size(24);
3387 set_wstate(pWidget
, FC_WS_NORMAL
);
3388 pWidget
->action
= leader_name_edit_callback
;
3389 add_to_gui_list(ID_NATION_WIZARD_LEADER_NAME_EDIT
, pWidget
);
3390 pSetup
->pName_Edit
= pWidget
;
3392 /* create next leader name button */
3393 pWidget
= create_themeicon_button(current_theme
->R_ARROW_Icon
,
3394 pWindow
->dst
, NULL
, 0);
3395 pWidget
->action
= next_name_callback
;
3396 add_to_gui_list(ID_NATION_WIZARD_NEXT_LEADER_NAME_BUTTON
, pWidget
);
3397 pWidget
->size
.h
= pWidget
->next
->size
.h
;
3398 pSetup
->pName_Next
= pWidget
;
3400 /* create prev leader name button */
3401 pWidget
= create_themeicon_button(current_theme
->L_ARROW_Icon
,
3402 pWindow
->dst
, NULL
, 0);
3403 pWidget
->action
= prev_name_callback
;
3404 add_to_gui_list(ID_NATION_WIZARD_PREV_LEADER_NAME_BUTTON
, pWidget
);
3405 pWidget
->size
.h
= pWidget
->next
->size
.h
;
3406 pSetup
->pName_Prev
= pWidget
;
3408 /* change sex button */
3409 pWidget
= create_icon_button_from_chars(NULL
, pWindow
->dst
, _("Male"), adj_font(14), 0);
3410 pWidget
->action
= change_sex_callback
;
3411 pWidget
->size
.w
= adj_size(100);
3412 pWidget
->size
.h
= adj_size(22);
3413 set_wstate(pWidget
, FC_WS_NORMAL
);
3414 pSetup
->pChange_Sex
= pWidget
;
3416 /* add to main widget list */
3417 add_to_gui_list(ID_NATION_WIZARD_CHANGE_SEX_BUTTON
, pWidget
);
3419 /* ---------------------------------------------------------- */
3421 zoom
= DEFAULT_ZOOM
* 1.0;
3424 styles_iterate(pstyle
) {
3425 i
= basic_city_style_for_style(pstyle
);
3427 pTmp_Surf
= get_sample_city_surface(i
);
3429 if (pTmp_Surf
->w
> 48) {
3430 zoom
= DEFAULT_ZOOM
* (48.0 / pTmp_Surf
->w
);
3433 pTmp_Surf_zoomed
= zoomSurface(get_sample_city_surface(i
), zoom
, zoom
, 0);
3435 pWidget
= create_icon2(pTmp_Surf_zoomed
, pWindow
->dst
, WF_RESTORE_BACKGROUND
);
3436 pWidget
->action
= style_callback
;
3437 if (i
!= pSetup
->nation_style
) {
3438 set_wstate(pWidget
, FC_WS_NORMAL
);
3440 len
+= pWidget
->size
.w
;
3441 add_to_gui_list(MAX_ID
- 1000 - i
, pWidget
);
3442 } styles_iterate_end
;
3444 pLast_City_Style
= pWidget
;
3445 /* ---------------------------------------------------------- */
3447 /* create Cancel button */
3448 pWidget
= create_themeicon_button_from_chars(current_theme
->CANCEL_Icon
,
3449 pWindow
->dst
, _("Cancel"),
3451 pWidget
->action
= races_dialog_cancel_callback
;
3452 set_wstate(pWidget
, FC_WS_NORMAL
);
3454 add_to_gui_list(ID_NATION_WIZARD_DISCONNECT_BUTTON
, pWidget
);
3456 /* create OK button */
3458 create_themeicon_button_from_chars(current_theme
->OK_Icon
, pWindow
->dst
,
3459 _("OK"), adj_font(12), 0);
3460 pWidget
->action
= races_dialog_ok_callback
;
3462 set_wstate(pWidget
, FC_WS_NORMAL
);
3463 add_to_gui_list(ID_NATION_WIZARD_START_BUTTON
, pWidget
);
3464 pWidget
->size
.w
= MAX(pWidget
->size
.w
, pWidget
->next
->size
.w
);
3465 pWidget
->next
->size
.w
= pWidget
->size
.w
;
3467 pNationDlg
->pBeginWidgetList
= pWidget
;
3468 /* ---------------------------------------------------------- */
3470 pMain_Bg
= theme_get_background(theme
, BACKGROUND_NATIONDLG
);
3471 if(resize_window(pWindow
, pMain_Bg
, NULL
, adj_size(640), adj_size(480))) {
3472 FREESURFACE(pMain_Bg
);
3475 area
= pWindow
->area
;
3477 widget_set_position(pWindow
,
3478 (Main
.screen
->w
- pWindow
->size
.w
) / 2,
3479 (Main
.screen
->h
- pWindow
->size
.h
) / 2);
3483 h
= pNationDlg
->pEndActiveWidgetList
->size
.h
* TARGETS_ROW
;
3484 i
= (area
.h
- adj_size(43) - h
) / 2;
3485 setup_vertical_widgets_position(TARGETS_COL
,
3486 area
.x
+ adj_size(10),
3487 area
.y
+ i
- adj_size(4),
3488 0, 0, pNationDlg
->pBeginActiveWidgetList
,
3489 pNationDlg
->pEndActiveWidgetList
);
3491 if(pNationDlg
->pScroll
) {
3494 w
= pNationDlg
->pEndActiveWidgetList
->size
.w
* TARGETS_COL
;
3495 setup_vertical_scrollbar_area(pNationDlg
->pScroll
,
3496 area
.x
+ w
+ adj_size(12),
3497 area
.y
+ i
- adj_size(4), h
, FALSE
);
3499 area2
.x
= area
.x
+ w
+ adj_size(11);
3500 area2
.y
= area
.y
+ i
- adj_size(4);
3501 area2
.w
= pNationDlg
->pScroll
->pUp_Left_Button
->size
.w
+ adj_size(2);
3503 SDL_FillRectAlpha(pWindow
->theme
, &area2
, &bg_color
);
3504 putframe(pWindow
->theme
,
3505 area2
.x
, area2
.y
- 1, area2
.x
+ area2
.w
, area2
.y
+ area2
.h
,
3506 get_theme_color(COLOR_THEME_NATIONDLG_FRAME
));
3509 if (nationsets
!= NULL
) {
3510 /* Nationsets header */
3511 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/ 2 - pBuf
->size
.w
) / 2;
3512 pBuf
->size
.y
= area
.y
+ adj_size(46);
3514 natinfo_y
= pBuf
->size
.y
;
3515 natinfo_h
= area
.h
-= pBuf
->size
.y
;
3517 /* Nationset name */
3519 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/ 2 - pBuf
->size
.w
) / 2;
3520 pBuf
->size
.y
= natinfo_y
+ adj_size(46);
3522 natinfo_y
+= adj_size(46);
3523 natinfo_h
-= adj_size(46);
3525 /* Next Nationset Button */
3527 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
;
3528 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3530 /* Prev Nationset Button */
3532 pBuf
->size
.x
= pBuf
->next
->next
->size
.x
- pBuf
->size
.w
;
3533 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3541 /* Selected Nation Name */
3542 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/ 2 - pBuf
->size
.w
) / 2;
3543 pBuf
->size
.y
= natinfo_y
+ adj_size(46);
3545 /* Leader Name Edit */
3547 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/2 - pBuf
->size
.w
) / 2;
3548 pBuf
->size
.y
= natinfo_y
+ (natinfo_h
- pBuf
->size
.h
) / 2 - adj_size(30);
3550 /* Next Leader Name Button */
3552 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
;
3553 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3555 /* Prev Leader Name Button */
3557 pBuf
->size
.x
= pBuf
->next
->next
->size
.x
- pBuf
->size
.w
;
3558 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3560 /* Change Leader Sex Button */
3562 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/2 - pBuf
->size
.w
) / 2;
3563 pBuf
->size
.y
= pBuf
->next
->size
.y
+ pBuf
->next
->size
.h
+ adj_size(20);
3565 /* First Style Button */
3567 pBuf
->size
.x
= area
.x
+ area
.w
/ 2 + (area
.w
/2 - len
) / 2 - adj_size(20);
3568 pBuf
->size
.y
= pBuf
->next
->size
.y
+ pBuf
->next
->size
.h
+ adj_size(20);
3570 /* Rest Style Buttons */
3571 while (pBuf
!= pLast_City_Style
) {
3573 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(3);
3574 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3577 putline(pWindow
->theme
,
3579 natinfo_y
+ natinfo_h
- adj_size(7) - pBuf
->prev
->size
.h
- adj_size(10),
3581 natinfo_y
+ natinfo_h
- adj_size(7) - pBuf
->prev
->size
.h
- adj_size(10),
3582 get_theme_color(COLOR_THEME_NATIONDLG_FRAME
));
3584 /* Disconnect Button */
3586 pBuf
->size
.x
= area
.x
+ adj_size(10);
3587 pBuf
->size
.y
= natinfo_y
+ natinfo_h
- adj_size(7) - pBuf
->size
.h
;
3591 pBuf
->size
.x
= area
.w
- adj_size(10) - pBuf
->size
.w
;
3592 pBuf
->size
.y
= pBuf
->next
->size
.y
;
3594 /* -------------------------------------------------------------------- */
3596 select_random_leader(pSetup
->nation
);
3598 redraw_group(pNationDlg
->pBeginWidgetList
, pWindow
, 0);
3600 widget_flush(pWindow
);
3603 /**************************************************************************
3604 Close the nation selection dialog. This should allow the user to
3605 (at least) select a unit to activate.
3606 **************************************************************************/
3607 void popdown_races_dialog(void)
3610 popdown_window_group_dialog(pNationDlg
->pBeginWidgetList
,
3611 pNationDlg
->pEndWidgetList
);
3613 cancel_help_dlg_callback(NULL
);
3615 FC_FREE(pLeaderName
);
3617 FC_FREE(pNationDlg
->pScroll
);
3618 FC_FREE(pNationDlg
);
3622 /**************************************************************************
3623 The server has changed the set of selectable nations.
3624 **************************************************************************/
3625 void races_update_pickable(bool nationset_change
)
3627 /* If this is because of nationset change, update will take
3628 * place later when the new option value is received */
3629 if (pNationDlg
!= NULL
&& !nationset_change
) {
3630 popdown_races_dialog();
3631 popup_races_dialog(client
.conn
.playing
);
3635 /**************************************************************************
3636 Nationset selection update
3637 **************************************************************************/
3638 void nationset_changed(void)
3640 if (pNationDlg
!= NULL
) {
3641 popdown_races_dialog();
3642 popup_races_dialog(client
.conn
.playing
);
3646 /**************************************************************************
3647 In the nation selection dialog, make already-taken nations unavailable.
3648 This information is contained in the packet_nations_used packet.
3649 **************************************************************************/
3650 void races_toggles_set_sensitive()
3653 bool change
= FALSE
;
3654 struct widget
*pNat
;
3660 pSetup
= (struct NAT
*)(pNationDlg
->pEndWidgetList
->data
.ptr
);
3662 nations_iterate(nation
) {
3664 if (!is_nation_pickable(nation
) || nation
->player
) {
3665 log_debug(" [%d]: %d = %s", nation_index(nation
),
3666 (!is_nation_pickable(nation
) || nation
->player
),
3667 nation_rule_name(nation
));
3669 pNat
= get_widget_pointer_form_main_list(MAX_ID
- nation_index(nation
));
3670 set_wstate(pNat
, FC_WS_DISABLED
);
3672 if (nation_index(nation
) == pSetup
->nation
) {
3676 } nations_iterate_end
;
3680 pSetup
->nation
= fc_rand(get_playable_nation_count());
3681 pNat
= get_widget_pointer_form_main_list(MAX_ID
- pSetup
->nation
);
3682 } while(get_wstate(pNat
) == FC_WS_DISABLED
);
3683 if (get_wstate(pSetup
->pName_Edit
) == FC_WS_PRESSED
) {
3684 force_exit_from_event_loop();
3685 set_wstate(pSetup
->pName_Edit
, FC_WS_NORMAL
);
3687 change_nation_label();
3688 enable(MAX_ID
- 1000 - pSetup
->nation_style
);
3689 pSetup
->nation_style
= style_number(style_of_nation(nation_by_number(pSetup
->nation
)));
3690 disable(MAX_ID
- 1000 - pSetup
->nation_style
);
3691 select_random_leader(pSetup
->nation
);
3693 redraw_group(pNationDlg
->pBeginWidgetList
, pNationDlg
->pEndWidgetList
, 0);
3694 widget_flush(pNationDlg
->pEndWidgetList
);
3697 /**************************************************************************
3698 Ruleset (modpack) has suggested loading certain tileset. Confirm from
3700 **************************************************************************/
3701 void popup_tileset_suggestion_dialog(void)
3705 /****************************************************************
3706 Ruleset (modpack) has suggested loading certain soundset. Confirm from
3708 *****************************************************************/
3709 void popup_soundset_suggestion_dialog(void)
3713 /****************************************************************
3714 Ruleset (modpack) has suggested loading certain muicset. Confirm from
3716 *****************************************************************/
3717 void popup_musicset_suggestion_dialog(void)
3721 /**************************************************************************
3722 Tileset (modpack) has suggested loading certain theme. Confirm from
3724 **************************************************************************/
3725 bool popup_theme_suggestion_dialog(const char *theme_name
)
3731 /****************************************************************
3732 Player has gained a new tech.
3733 *****************************************************************/
3734 void show_tech_gained_dialog(Tech_type_id tech
)
3739 /****************************************************************
3740 Show tileset error dialog.
3741 *****************************************************************/
3742 void show_tileset_error(const char *msg
)
3747 /****************************************************************
3748 Give a warning when user is about to edit scenario with manually
3750 *****************************************************************/
3751 bool handmade_scenario_warning(void)
3753 /* Just tell the client common code to handle this. */
3757 /****************************************************************
3758 Update multipliers (policies) dialog.
3759 *****************************************************************/
3760 void real_multipliers_dialog_update(void)
3765 /****************************************************************
3766 Unit wants to get into some transport on given tile.
3767 *****************************************************************/
3768 bool request_transport(struct unit
*pcargo
, struct tile
*ptile
)
3770 return FALSE
; /* Unit was not handled here. */