Freeciv-3.1: /fast/freeciv/nightly/S3_1/client/gui-sdl2/citydlg.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
citydlg.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14/***********************************************************************
15 citydlg.c - description
16 -------------------
17 begin : Wed Sep 04 2002
18 copyright : (C) 2002 by Rafał Bursig
19 email : Rafał Bursig <bursig@poczta.fm>
20***********************************************************************/
21
22#ifdef HAVE_CONFIG_H
23#include <fc_config.h>
24#endif
25
26/* SDL2 */
27#ifdef SDL2_PLAIN_INCLUDE
28#include <SDL.h>
29#else /* SDL2_PLAIN_INCLUDE */
30#include <SDL2/SDL.h>
31#endif /* SDL2_PLAIN_INCLUDE */
32
33/* utility */
34#include "astring.h"
35#include "bitvector.h"
36#include "fcintl.h"
37#include "log.h"
38
39/* common */
40#include "game.h"
41#include "movement.h"
42#include "specialist.h"
43#include "unitlist.h"
44
45/* client */
46#include "client_main.h"
47#include "climisc.h"
48#include "control.h"
49#include "text.h"
50
51/* gui-sdl2 */
52#include "cityrep.h"
53#include "cma_fe.h"
54#include "colors.h"
55#include "dialogs.h"
56#include "graphics.h"
57#include "gui_id.h"
58#include "gui_main.h"
59#include "gui_tilespec.h"
60#include "mapview.h"
61#include "menu.h"
62#include "sprite.h"
63#include "themespec.h"
64#include "widget.h"
65#include "wldlg.h"
66
67#include "citydlg.h"
68
69/* ============================================================= */
70
71static struct city_dialog {
72 struct city *pcity;
73
74 enum {
75 INFO_PAGE = 0,
76 HAPPINESS_PAGE = 1,
77 ARMY_PAGE,
78 SUPPORTED_UNITS_PAGE,
79 MISC_PAGE
80 } page;
81
82 /* main window group list */
83 struct widget *begin_city_widget_list;
84 struct widget *end_city_widget_list;
85
86 /* Imprvm. vscrollbar */
87 struct advanced_dialog *imprv;
88
89 /* Penel group list */
90 struct advanced_dialog *panel;
91
92 /* Menu imprv. dlg. */
93 struct widget *begin_city_menu_widget_list;
94 struct widget *end_city_menu_widget_list;
95
96 /* shortcuts */
97 struct widget *add_point;
98 struct widget *buy_button;
99 struct widget *resource_map;
100 struct widget *city_name_edit;
101
102 int citizen_step;
103
104 SDL_Rect spec_area;
105
106 bool lock;
107} *pcity_dlg = NULL;
108
109 enum specialist_type {
110 SP_ELVIS, SP_SCIENTIST, SP_TAXMAN, SP_LAST
111};
112
113 static float city_map_zoom = 1;
114
115 static struct small_dialog *hurry_prog_dlg = NULL;
116
117static void popdown_hurry_production_dialog(void);
118static void disable_city_dlg_widgets(void);
119static void redraw_city_dialog(struct city *pcity);
120static void rebuild_imprm_list(struct city *pcity);
121static void rebuild_citydlg_title_str(struct widget *pwindow, struct city *pcity);
122
123/* ======================================================================= */
124
125/**********************************************************************/
132 struct impr_type *get_building_for_effect(enum effect_type effect_type)
133{
134 improvement_iterate(pimprove) {
135 if (building_has_effect(pimprove, effect_type)) {
136 return pimprove;
137 }
138 } improvement_iterate_end;
139
140 return NULL;
141}
142
143/**********************************************************************/
146 static void popdown_city_menu_dlg(bool enable_city_dialog_widgets)
147{
148 if (pcity_dlg->end_city_menu_widget_list) {
149 popdown_window_group_dialog(pcity_dlg->begin_city_menu_widget_list,
150 pcity_dlg->end_city_menu_widget_list);
151 pcity_dlg->end_city_menu_widget_list = NULL;
152 }
153 if (enable_city_dialog_widgets) {
154 /* enable city dlg */
155 enable_city_dlg_widgets();
156 }
157}
158
159/**********************************************************************/
162 static void del_city_dialog(void)
163{
164 if (pcity_dlg) {
165 if (pcity_dlg->imprv->end_widget_list) {
166 del_group_of_widgets_from_gui_list(pcity_dlg->imprv->begin_widget_list,
167 pcity_dlg->imprv->end_widget_list);
168 }
169 FC_FREE(pcity_dlg->imprv->scroll);
170 FC_FREE(pcity_dlg->imprv);
171
172 if (pcity_dlg->panel) {
173 del_group_of_widgets_from_gui_list(pcity_dlg->panel->begin_widget_list,
174 pcity_dlg->panel->end_widget_list);
175 FC_FREE(pcity_dlg->panel->scroll);
176 FC_FREE(pcity_dlg->panel);
177 }
178
179 if (hurry_prog_dlg) {
180 del_group_of_widgets_from_gui_list(hurry_prog_dlg->begin_widget_list,
181 hurry_prog_dlg->end_widget_list);
182
183 FC_FREE(hurry_prog_dlg);
184 }
185
186 free_city_units_lists();
187 popdown_city_menu_dlg(FALSE);
188
189 popdown_window_group_dialog(pcity_dlg->begin_city_widget_list,
190 pcity_dlg->end_city_widget_list);
191 FC_FREE(pcity_dlg);
192 }
193}
194
195/**********************************************************************/
199 static int city_dlg_callback(struct widget *pwindow)
200{
201 if (PRESSED_EVENT(main_data.event)) {
202 if (!cma_is_city_under_agent(pcity_dlg->pcity, NULL)
203 && city_owner(pcity_dlg->pcity) == client.conn.playing) {
204
205 if (is_in_rect_area(main_data.event.motion.x, main_data.event.motion.y,
206 pcity_dlg->spec_area)) {
207 city_rotate_specialist(pcity_dlg->pcity,
208 (main_data.event.motion.x - pcity_dlg->spec_area.x)
209 / pcity_dlg->citizen_step);
210
211 return -1;
212 }
213 }
214
215 if (!pcity_dlg->lock) {
216 if (pcity_dlg->panel) {
217 select_window_group_dialog(pcity_dlg->begin_city_widget_list, pwindow);
218 select_window_group_dialog(pcity_dlg->panel->begin_widget_list,
219 pcity_dlg->panel->end_widget_list);
220 widget_flush(pwindow);
221 } else {
222 if (select_window_group_dialog(pcity_dlg->begin_city_widget_list, pwindow)) {
223 widget_flush(pwindow);
224 }
225 }
226 }
227 }
228
229 return -1;
230}
231
232/* ===================================================================== */
233/* ========================== Units Orders Menu ======================== */
234/* ===================================================================== */
235
236/**********************************************************************/
239 static int cancel_units_orders_city_dlg_callback(struct widget *button)
240{
241 if (PRESSED_EVENT(main_data.event)) {
242 popdown_window_group_dialog(pcity_dlg->begin_city_menu_widget_list,
243 pcity_dlg->end_city_menu_widget_list);
244 pcity_dlg->end_city_menu_widget_list = NULL;
245
246 /* Enable city dlg */
247 enable_city_dlg_widgets();
248 flush_dirty();
249 }
250
251 return -1;
252}
253
254/**********************************************************************/
257 static int activate_units_orders_city_dlg_callback(struct widget *button)
258{
259 if (PRESSED_EVENT(main_data.event)) {
260 struct unit *punit = button->data.unit;
261
262 popdown_city_menu_dlg(TRUE);
263 if (punit) {
264 unit_focus_set(punit);
265 }
266 }
267
268 return -1;
269}
270
271/**********************************************************************/
274 static int activate_and_exit_units_orders_city_dlg_callback(struct widget *button)
275{
276 if (PRESSED_EVENT(main_data.event)) {
277 struct unit *punit = button->data.unit;
278
279 if (punit) {
280 popdown_window_group_dialog(pcity_dlg->begin_city_menu_widget_list,
281 pcity_dlg->end_city_menu_widget_list);
282 pcity_dlg->end_city_menu_widget_list = NULL;
283
284 popdown_city_dialog(pcity_dlg->pcity);
285
286 center_tile_mapcanvas(unit_tile(punit));
287 unit_focus_set(punit);
288 }
289 }
290
291 return -1;
292}
293
294/**********************************************************************/
297 static int sentry_units_orders_city_dlg_callback(struct widget *button)
298{
299 if (PRESSED_EVENT(main_data.event)) {
300 struct unit *punit = button->data.unit;
301
302 popdown_city_menu_dlg(TRUE);
303 if (punit) {
304 request_unit_sentry(punit);
305 }
306 }
307
308 return -1;
309}
310
311/**********************************************************************/
314 static int fortify_units_orders_city_dlg_callback(struct widget *button)
315{
316 if (PRESSED_EVENT(main_data.event)) {
317 struct unit *punit = button->data.unit;
318
319 popdown_city_menu_dlg(TRUE);
320 if (punit) {
321 request_unit_fortify(punit);
322 }
323 }
324
325 return -1;
326}
327
328/**********************************************************************/
331 static int disband_units_orders_city_dlg_callback(struct widget *button)
332{
333 if (PRESSED_EVENT(main_data.event)) {
334 struct unit *punit = button->data.unit;
335
336 popdown_city_menu_dlg(TRUE);
337 popup_unit_disband_dlg(punit, TRUE);
338 }
339
340 return -1;
341}
342
343/**********************************************************************/
346 static int homecity_units_orders_city_dlg_callback(struct widget *button)
347{
348 if (PRESSED_EVENT(main_data.event)) {
349 struct unit *punit = button->data.unit;
350
351 popdown_city_menu_dlg(TRUE);
352 if (punit) {
353 request_unit_change_homecity(punit);
354 }
355 }
356
357 return -1;
358}
359
360/**********************************************************************/
363 static int upgrade_units_orders_city_dlg_callback(struct widget *button)
364{
365 if (PRESSED_EVENT(main_data.event)) {
366 struct unit *punit = button->data.unit;
367
368 popdown_city_menu_dlg(TRUE);
369 popup_unit_upgrade_dlg(punit, TRUE);
370 }
371
372 return -1;
373}
374
375/**********************************************************************/
378 static int units_orders_dlg_callback(struct widget *button)
379{
380 return -1;
381}
382
383/**********************************************************************/
386 static int units_orders_city_dlg_callback(struct widget *button)
387{
388 bool right_button = (main_data.event.type == SDL_MOUSEBUTTONDOWN
389 && main_data.event.button.button == SDL_BUTTON_RIGHT);
390
391 if (PRESSED_EVENT(main_data.event) || right_button) {
392 utf8_str *pstr;
393 char cbuf[80];
394 struct widget *buf, *pwindow;
395 struct unit *punit;
396 const struct unit_type *putype;
397 Uint16 i = 0, hh = 0;
398 SDL_Rect area;
399
400 punit = player_unit_by_number(client_player(), MAX_ID - button->id);
401
402 if (punit == NULL || !can_client_issue_orders()) {
403 return -1;
404 }
405
406 if (right_button) {
407 popdown_city_dialog(pcity_dlg->pcity);
408 center_tile_mapcanvas(unit_tile(punit));
409 unit_focus_set(punit);
410
411 return -1;
412 }
413
414 /* Disable city dlg */
415 unselect_widget_action();
416 disable_city_dlg_widgets();
417
418 putype = unit_type_get(punit);
419
420 /* Window */
421 fc_snprintf(cbuf, sizeof(cbuf), "%s:", _("Unit commands"));
422 pstr = create_utf8_from_char_fonto(cbuf, FONTO_ATTENTION);
423 pstr->style |= TTF_STYLE_BOLD;
424 pwindow = create_window_skeleton(NULL, pstr, 0);
425
426 pwindow->action = units_orders_dlg_callback;
427 set_wstate(pwindow, FC_WS_NORMAL);
428 add_to_gui_list(ID_REVOLUTION_DLG_WINDOW, pwindow);
429 pcity_dlg->end_city_menu_widget_list = pwindow;
430
431 area = pwindow->area;
432
433 /* Unit description */
434 fc_snprintf(cbuf, sizeof(cbuf), "%s", unit_description(punit));
435 pstr = create_utf8_from_char_fonto(cbuf, FONTO_ATTENTION);
436 pstr->style |= (TTF_STYLE_BOLD|SF_CENTER);
437 buf = create_iconlabel(adj_surf(get_unittype_surface(putype, punit->facing)),
438 pwindow->dst, pstr, WF_FREE_THEME);
439 area.w = MAX(area.w, buf->size.w);
440 add_to_gui_list(ID_LABEL, buf);
441
442 /* Activate unit */
443 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
444 _("Activate unit"),
445 FONTO_ATTENTION, 0);
446 i++;
447 area.w = MAX(area.w, buf->size.w);
448 hh = MAX(hh, buf->size.h);
449 buf->action = activate_units_orders_city_dlg_callback;
450 buf->data = button->data;
451 set_wstate(buf, FC_WS_NORMAL);
452 add_to_gui_list(button->id, buf);
453
454 /* Activate unit, close dlg. */
455 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
456 _("Activate unit, close dialog"),
457 FONTO_ATTENTION, 0);
458 i++;
459 area.w = MAX(area.w, buf->size.w);
460 hh = MAX(hh, buf->size.h);
461 buf->action = activate_and_exit_units_orders_city_dlg_callback;
462 buf->data = button->data;
463 set_wstate(buf, FC_WS_NORMAL);
464 add_to_gui_list(button->id, buf);
465 /* ----- */
466
467 if (pcity_dlg->page == ARMY_PAGE) {
468 /* Sentry unit */
469 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
470 _("Sentry unit"),
471 FONTO_ATTENTION, 0);
472 i++;
473 area.w = MAX(area.w, buf->size.w);
474 hh = MAX(hh, buf->size.h);
475 buf->data = button->data;
476 buf->action = sentry_units_orders_city_dlg_callback;
477 if (punit->activity != ACTIVITY_SENTRY
478 && can_unit_do_activity_client(punit, ACTIVITY_SENTRY)) {
479 set_wstate(buf, FC_WS_NORMAL);
480 }
481 add_to_gui_list(button->id, buf);
482 /* ----- */
483
484 /* Fortify unit */
485 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
486 _("Fortify unit"),
487 FONTO_ATTENTION, 0);
488 i++;
489 area.w = MAX(area.w, buf->size.w);
490 hh = MAX(hh, buf->size.h);
491 buf->data = button->data;
492 buf->action = fortify_units_orders_city_dlg_callback;
493 if (punit->activity != ACTIVITY_FORTIFYING
494 && can_unit_do_activity_client(punit, ACTIVITY_FORTIFYING)) {
495 set_wstate(buf, FC_WS_NORMAL);
496 }
497 add_to_gui_list(button->id, buf);
498 }
499 /* ----- */
500
501 /* Disband unit */
502 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
503 _("Disband unit"),
504 FONTO_ATTENTION, 0);
505 i++;
506 area.w = MAX(area.w, buf->size.w);
507 hh = MAX(hh, buf->size.h);
508 buf->data = button->data;
509 buf->action = disband_units_orders_city_dlg_callback;
510 set_wstate(buf, FC_WS_NORMAL);
511 add_to_gui_list(button->id, buf);
512 /* ----- */
513
514 if (pcity_dlg->page == ARMY_PAGE) {
515 if (punit->homecity != pcity_dlg->pcity->id) {
516 /* Make new Homecity */
517 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
518 action_id_name_translation(ACTION_HOME_CITY),
519 FONTO_ATTENTION, 0);
520 i++;
521 area.w = MAX(area.w, buf->size.w);
522 hh = MAX(hh, buf->size.h);
523 buf->data = button->data;
524 buf->action = homecity_units_orders_city_dlg_callback;
525 set_wstate(buf, FC_WS_NORMAL);
526 add_to_gui_list(button->id, buf);
527 }
528 /* ----- */
529
530 if (can_upgrade_unittype(client.conn.playing, putype)) {
531 /* Upgrade unit */
532 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
533 _("Upgrade unit"),
534 FONTO_ATTENTION, 0);
535 i++;
536 area.w = MAX(area.w, buf->size.w);
537 hh = MAX(hh, buf->size.h);
538 buf->data = button->data;
539 buf->action = upgrade_units_orders_city_dlg_callback;
540 set_wstate(buf, FC_WS_NORMAL);
541 add_to_gui_list(button->id, buf);
542 }
543 }
544
545 /* ----- */
546 /* Cancel */
547 buf = create_icon_button_from_chars_fonto(NULL, pwindow->dst,
548 _("Cancel"),
549 FONTO_ATTENTION, 0);
550 i++;
551 area.w = MAX(area.w, buf->size.w);
552 hh = MAX(hh, buf->size.h);
553 buf->key = SDLK_ESCAPE;
554 buf->action = cancel_units_orders_city_dlg_callback;
555 set_wstate(buf, FC_WS_NORMAL);
556 add_to_gui_list(button->id, buf);
557 pcity_dlg->begin_city_menu_widget_list = buf;
558
559 /* ================================================== */
560 unselect_widget_action();
561 /* ================================================== */
562
563 area.w += adj_size(10);
564 hh += adj_size(4);
565
566 /* Create window background */
567 resize_window(pwindow, NULL, get_theme_color(COLOR_THEME_BACKGROUND),
568 (pwindow->size.w - pwindow->area.w) + area.w,
569 (pwindow->size.h - pwindow->area.h) + pwindow->prev->size.h +
570 (i * hh) + adj_size(5));
571
572 area = pwindow->area;
573
574 widget_set_position(pwindow,
575 button->size.x + adj_size(2),
576 pwindow->area.y + button->size.y + 1);
577
578 /* Label */
579 buf = pwindow->prev;
580 buf->size.w = area.w;
581 buf->size.x = area.x;
582 buf->size.y = area.y + 1;
583 buf = buf->prev;
584
585 /* First button */
586 buf->size.w = area.w;
587 buf->size.h = hh;
588 buf->size.x = area.x;
589 buf->size.y = buf->next->size.y + buf->next->size.h + adj_size(5);
590 buf = buf->prev;
591
592 while (buf != NULL) {
593 buf->size.w = area.w;
594 buf->size.h = hh;
595 buf->size.x = buf->next->size.x;
596 buf->size.y = buf->next->size.y + buf->next->size.h;
597 if (buf == pcity_dlg->begin_city_menu_widget_list) {
598 break;
599 }
600 buf = buf->prev;
601 }
602
603 /* ================================================== */
604 /* Redraw */
605 redraw_group(pcity_dlg->begin_city_menu_widget_list, pwindow, 0);
606 widget_flush(pwindow);
607 }
608
609 return -1;
610}
611
612/* ======================================================================= */
613/* ======================= City Dlg. Panels ============================== */
614/* ======================================================================= */
615
616/**********************************************************************/
619 static SDL_Surface *create_unit_surface(struct unit *punit, bool support,
620 int w, int h)
621{
622 SDL_Rect src_rect;
623 SDL_Surface *psurf;
624 struct canvas *destcanvas;
625
626 destcanvas = canvas_create(tileset_full_tile_width(tileset),
627 tileset_unit_with_small_upkeep_height(tileset));
628
629 put_unit(punit, destcanvas, 1.0, 0, 0);
630
631 /* Get unit sprite width, and crop top. Bottom might get restored in 'support'
632 * case below. */
633 src_rect = get_smaller_surface_rect(destcanvas->surf);
634
635 if (support) {
636 int i, step;
637 int free_unhappy;
638 int happy_cost;
639 SDL_Rect dest;
640 int offset = tileset_unit_layout_small_offset_y(tileset);
641
642 /* Support also layouts placing support icons higher than unit. */
643 src_rect.y = MIN(src_rect.y, offset);
644 /* Restore bottom space when needed for support icons. */
645 src_rect.h = destcanvas->surf->h - src_rect.y;
646
647 free_unhappy = get_city_bonus(pcity_dlg->pcity, EFT_MAKE_CONTENT_MIL);
648 happy_cost = city_unit_unhappiness(punit, &free_unhappy);
649
650 i = punit->upkeep[O_SHIELD] + punit->upkeep[O_FOOD] +
651 punit->upkeep[O_GOLD] + happy_cost;
652
653 if (i * icons->food->w > src_rect.w / 2) {
654 step = (src_rect.w / 2 - icons->food->w) / (i - 1);
655 } else {
656 step = icons->food->w;
657 }
658
659 dest.y = tileset_unit_layout_small_offset_y(tileset);
660 dest.x = src_rect.x + src_rect.w / 8;
661
662 for (i = 0; i < punit->upkeep[O_SHIELD]; i++) {
663 alphablit(icons->shield, NULL, destcanvas->surf, &dest, 255);
664 dest.x += step;
665 }
666
667 for (i = 0; i < punit->upkeep[O_FOOD]; i++) {
668 alphablit(icons->food, NULL, destcanvas->surf, &dest, 255);
669 dest.x += step;
670 }
671
672 for (i = 0; i < punit->upkeep[O_GOLD]; i++) {
673 alphablit(icons->coint, NULL, destcanvas->surf, &dest, 255);
674 dest.x += step;
675 }
676
677 for (i = 0; i < happy_cost; i++) {
678 alphablit(icons->face, NULL, destcanvas->surf, &dest, 255);
679 dest.x += step;
680 }
681
682 }
683
684 psurf = create_surf(src_rect.w, src_rect.h, SDL_SWSURFACE);
685 alphablit(destcanvas->surf, &src_rect, psurf, NULL, 255);
686
687 canvas_free(destcanvas);
688
689 if (w != src_rect.w || h != src_rect.h) {
690 SDL_Surface *pzoomed;
691
692 pzoomed = resize_surface_box(psurf, w, h, 1, TRUE, TRUE);
693 FREESURFACE(psurf);
694 psurf = pzoomed;
695 }
696
697 return psurf;
698}
699
700/**********************************************************************/
705 static void create_present_supported_units_widget_list(struct unit_list *units)
706{
707 int i;
708 struct widget *buf = NULL;
709 struct widget *end = NULL;
710 struct widget *pwindow = pcity_dlg->end_city_widget_list;
711 struct city *home_city;
712 const struct unit_type *putype;
713 SDL_Surface *surf;
714 utf8_str *pstr;
715 char cbuf[256];
716 int num_x, num_y, w, h;
717
718 i = 0;
719
720 num_x = (adj_size(160) / (tileset_full_tile_width(tileset) + adj_size(4)));
721 if (num_x < 4) {
722 num_x = 4;
723 w = adj_size(160 - 4*4) / 4;
724 } else {
725 w = tileset_full_tile_width(tileset) + (adj_size(160) % (tileset_full_tile_width(tileset) + 4)) / num_x;
726 }
727
728 num_y = (adj_size(151) / (tileset_full_tile_height(tileset)+4));
729 if (num_y < 4) {
730 num_y = 4;
731 h = adj_size(151 - 4*4) / 4;
732 } else {
733 h = tileset_full_tile_height(tileset) + (adj_size(151) % (tileset_full_tile_height(tileset)+4)) / num_y;
734 }
735
736 unit_list_iterate(units, punit) {
737 const char *vetname;
738 struct astring addition = ASTRING_INIT;
739
740 putype = unit_type_get(punit);
741 vetname = utype_veteran_name_translation(putype, punit->veteran);
742 home_city = game_city_by_number(punit->homecity);
743 unit_activity_astr(punit, &addition);
744 fc_snprintf(cbuf, sizeof(cbuf), "%s (%d,%d,%s)%s%s\n%s\n(%d/%d)\n%s",
745 utype_name_translation(putype),
746 putype->attack_strength,
747 putype->defense_strength,
748 move_points_text(putype->move_rate, FALSE),
749 (vetname != NULL ? "\n" : ""),
750 (vetname != NULL ? vetname : ""),
751 astr_str(&addition),
752 punit->hp, putype->hp,
753 home_city ? home_city->name : Q_("?homecity:None"));
754 astr_free(&addition);
755
756 if (pcity_dlg->page == SUPPORTED_UNITS_PAGE) {
757 int city_near_dist;
758 struct city *near_city = get_nearest_city(punit, &city_near_dist);
759
760 sz_strlcat(cbuf, "\n");
761 sz_strlcat(cbuf, get_nearest_city_text(near_city, city_near_dist));
762 surf = adj_surf(create_unit_surface(punit, TRUE, w, h));
763 } else {
764 surf = adj_surf(create_unit_surface(punit, FALSE, w, h));
765 }
766
767 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
768 pstr->style |= SF_CENTER;
769
770 buf = create_icon2(surf, pwindow->dst, WF_FREE_THEME
771 | WF_RESTORE_BACKGROUND | WF_WIDGET_HAS_INFO_LABEL);
772 buf->info_label = pstr;
773 buf->data.unit = punit;
774 add_to_gui_list(MAX_ID - punit->id, buf);
775
776 if (!end) {
777 end = buf;
778 }
779
780 if (++i > num_x * num_y) {
781 set_wflag(buf, WF_HIDDEN);
782 }
783
784 if (city_owner(pcity_dlg->pcity) == client.conn.playing) {
785 set_wstate(buf, FC_WS_NORMAL);
786 }
787
788 buf->action = units_orders_city_dlg_callback;
789 } unit_list_iterate_end;
790
791 pcity_dlg->panel = fc_calloc(1, sizeof(struct advanced_dialog));
792 pcity_dlg->panel->end_widget_list = end;
793 pcity_dlg->panel->begin_widget_list = buf;
794 pcity_dlg->panel->end_active_widget_list = pcity_dlg->panel->end_widget_list;
795 pcity_dlg->panel->begin_active_widget_list = pcity_dlg->panel->begin_widget_list;
796 pcity_dlg->panel->active_widget_list = pcity_dlg->panel->end_active_widget_list;
797
798 setup_vertical_widgets_position(num_x,
799 pwindow->area.x + adj_size(5),
800 pwindow->area.y + adj_size(44),
801 0, 0, pcity_dlg->panel->begin_active_widget_list,
802 pcity_dlg->panel->end_active_widget_list);
803
804 if (i > num_x * num_y) {
805 create_vertical_scrollbar(pcity_dlg->panel,
806 num_x, num_y, TRUE, TRUE);
807
808 setup_vertical_scrollbar_area(pcity_dlg->panel->scroll,
809 pwindow->area.x + adj_size(185),
810 pwindow->area.y + adj_size(45),
811 adj_size(150), TRUE);
812 }
813}
814
815/**********************************************************************/
818 void free_city_units_lists(void)
819{
820 if (pcity_dlg && pcity_dlg->panel) {
821 del_group_of_widgets_from_gui_list(pcity_dlg->panel->begin_widget_list,
822 pcity_dlg->panel->end_widget_list);
823 FC_FREE(pcity_dlg->panel->scroll);
824 FC_FREE(pcity_dlg->panel);
825 }
826}
827
828/**********************************************************************/
831 static int army_city_dlg_callback(struct widget *button)
832{
833 if (PRESSED_EVENT(main_data.event)) {
834 if (pcity_dlg->page != ARMY_PAGE) {
835 free_city_units_lists();
836 pcity_dlg->page = ARMY_PAGE;
837 redraw_city_dialog(pcity_dlg->pcity);
838 flush_dirty();
839 } else {
840 widget_redraw(button);
841 widget_flush(button);
842 }
843 }
844
845 return -1;
846}
847
848/**********************************************************************/
851 static int supported_unit_city_dlg_callback(struct widget *button)
852{
853 if (PRESSED_EVENT(main_data.event)) {
854 if (pcity_dlg->page != SUPPORTED_UNITS_PAGE) {
855 free_city_units_lists();
856 pcity_dlg->page = SUPPORTED_UNITS_PAGE;
857 redraw_city_dialog(pcity_dlg->pcity);
858 flush_dirty();
859 } else {
860 widget_redraw(button);
861 widget_flush(button);
862 }
863 }
864
865 return -1;
866}
867
868/* ---------------------- */
869
870/**********************************************************************/
873 static int info_city_dlg_callback(struct widget *button)
874{
875 if (PRESSED_EVENT(main_data.event)) {
876 if (pcity_dlg->page != INFO_PAGE) {
877 free_city_units_lists();
878 pcity_dlg->page = INFO_PAGE;
879 redraw_city_dialog(pcity_dlg->pcity);
880 flush_dirty();
881 } else {
882 widget_redraw(button);
883 widget_flush(button);
884 }
885 }
886
887 return -1;
888}
889
890/* ---------------------- */
891/**********************************************************************/
894 static int happy_city_dlg_callback(struct widget *button)
895{
896 if (PRESSED_EVENT(main_data.event)) {
897 if (pcity_dlg->page != HAPPINESS_PAGE) {
898 free_city_units_lists();
899 pcity_dlg->page = HAPPINESS_PAGE;
900 redraw_city_dialog(pcity_dlg->pcity);
901 flush_dirty();
902 } else {
903 widget_redraw(button);
904 widget_flush(button);
905 }
906 }
907
908 return -1;
909}
910
911/**********************************************************************/
914 static int misc_panel_city_dlg_callback(struct widget *pwidget)
915{
916 if (PRESSED_EVENT(main_data.event)) {
917 bv_city_options new_options = pcity_dlg->pcity->city_options;
918
919 switch (MAX_ID - pwidget->id) {
920 case 0x10:
921 if (BV_ISSET(new_options, CITYO_DISBAND)) {
922 BV_CLR(new_options, CITYO_DISBAND);
923 } else {
924 BV_SET(new_options, CITYO_DISBAND);
925 }
926 break;
927 case 0x20:
928 if (BV_ISSET(new_options, CITYO_SCIENCE_SPECIALISTS)) {
929 BV_CLR(new_options, CITYO_SCIENCE_SPECIALISTS);
930 } else {
931 BV_SET(new_options, CITYO_SCIENCE_SPECIALISTS);
932 }
933 if (BV_ISSET(new_options, CITYO_GOLD_SPECIALISTS)) {
934 BV_CLR(new_options, CITYO_GOLD_SPECIALISTS);
935 } else {
936 BV_SET(new_options, CITYO_GOLD_SPECIALISTS);
937 }
938
939 pwidget->theme2 = get_tax_surface(O_GOLD);
940 pwidget->id = MAX_ID - 0x40;
941 widget_redraw(pwidget);
942 widget_flush(pwidget);
943 break;
944 case 0x40:
945 BV_CLR(new_options, CITYO_SCIENCE_SPECIALISTS);
946 BV_CLR(new_options, CITYO_GOLD_SPECIALISTS);
947 pwidget->theme2 = get_tax_surface(O_LUXURY);
948 pwidget->id = MAX_ID - 0x60;
949 widget_redraw(pwidget);
950 widget_flush(pwidget);
951 break;
952 case 0x60:
953 if (BV_ISSET(new_options, CITYO_SCIENCE_SPECIALISTS)) {
954 BV_CLR(new_options, CITYO_SCIENCE_SPECIALISTS);
955 } else {
956 BV_SET(new_options, CITYO_SCIENCE_SPECIALISTS);
957 }
958
959 pwidget->theme2 = get_tax_surface(O_SCIENCE);
960 pwidget->id = MAX_ID - 0x20;
961 widget_redraw(pwidget);
962 widget_flush(pwidget);
963 break;
964 }
965
966 dsend_packet_city_options_req(&client.conn,
967 pcity_dlg->pcity->id, pcity_dlg->pcity->id,
968 new_options);
969 }
970
971 return -1;
972}
973
974/**********************************************************************/
977 static void create_city_options_widget_list(struct city *pcity)
978{
979 struct widget *buf, *pwindow = pcity_dlg->end_city_widget_list;
980 SDL_Surface *surf;
981 utf8_str *pstr;
982 char cbuf[80];
983
984 fc_snprintf(cbuf, sizeof(cbuf),
985 _("Allow unit production\nto disband city"));
986 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
987 pstr->style |= TTF_STYLE_BOLD;
988 pstr->fgcol = *get_theme_color(COLOR_THEME_CHECKBOX_LABEL_TEXT);
989
990 buf =
991 create_textcheckbox(pwindow->dst, BV_ISSET(pcity->city_options, CITYO_DISBAND), pstr,
992 WF_RESTORE_BACKGROUND);
993 set_wstate(buf, FC_WS_NORMAL);
994 buf->action = misc_panel_city_dlg_callback;
995 add_to_gui_list(MAX_ID - 0x10, buf);
996 buf->size.x = pwindow->area.x + adj_size(7);
997 buf->size.y = pwindow->area.y + adj_size(45);
998
999 /* ----- */
1000
1001 pcity_dlg->panel = fc_calloc(1, sizeof(struct advanced_dialog));
1002 pcity_dlg->panel->end_widget_list = buf;
1003
1004 /* ----- */
1005
1006 fc_snprintf(cbuf, sizeof(cbuf), "%s:", _("New citizens produce"));
1007 pstr = create_utf8_from_char_fonto(cbuf, FONTO_SLIGHTLY_BIGGER);
1008 pstr->style |= SF_CENTER;
1009
1010 if (BV_ISSET(pcity->city_options, CITYO_SCIENCE_SPECIALISTS)) {
1011 surf = get_tax_surface(O_SCIENCE);
1012 buf = create_icon_button(surf, pwindow->dst, pstr,
1013 WF_ICON_CENTER_RIGHT | WF_FREE_THEME2);
1014 add_to_gui_list(MAX_ID - 0x20, buf);
1015 } else {
1016 if (BV_ISSET(pcity->city_options, CITYO_GOLD_SPECIALISTS)) {
1017 surf = get_tax_surface(O_GOLD);
1018 buf = create_icon_button(surf, pwindow->dst,
1019 pstr, WF_ICON_CENTER_RIGHT | WF_FREE_THEME2);
1020 add_to_gui_list(MAX_ID - 0x40, buf);
1021 } else {
1022 surf = get_tax_surface(O_LUXURY);
1023 buf = create_icon_button(surf, pwindow->dst,
1024 pstr, WF_ICON_CENTER_RIGHT | WF_FREE_THEME2);
1025 add_to_gui_list(MAX_ID - 0x60, buf);
1026 }
1027 }
1028
1029 buf->size.w = adj_size(177);
1030 buf->action = misc_panel_city_dlg_callback;
1031 set_wstate(buf, FC_WS_NORMAL);
1032
1033 buf->size.x = buf->next->size.x;
1034 buf->size.y = buf->next->size.y + buf->next->size.h + adj_size(5);
1035 pcity_dlg->panel->begin_widget_list = buf;
1036}
1037
1038/**********************************************************************/
1041 static int options_city_dlg_callback(struct widget *button)
1042{
1043 if (PRESSED_EVENT(main_data.event)) {
1044 if (pcity_dlg->page != MISC_PAGE) {
1045 free_city_units_lists();
1046 pcity_dlg->page = MISC_PAGE;
1047 redraw_city_dialog(pcity_dlg->pcity);
1048 flush_dirty();
1049 } else {
1050 widget_redraw(button);
1051 widget_flush(button);
1052 }
1053 }
1054
1055 return -1;
1056}
1057
1058/* ======================================================================= */
1059
1060/**********************************************************************/
1063 static int cma_city_dlg_callback(struct widget *button)
1064{
1065 if (PRESSED_EVENT(main_data.event)) {
1066 disable_city_dlg_widgets();
1067 popup_city_cma_dialog(pcity_dlg->pcity);
1068 }
1069
1070 return -1;
1071}
1072
1073/**********************************************************************/
1076 static int exit_city_dlg_callback(struct widget *button)
1077{
1078 if (PRESSED_EVENT(main_data.event)) {
1079 popdown_city_dialog(pcity_dlg->pcity);
1080 }
1081
1082 return -1;
1083}
1084
1085/* ======================================================================= */
1086/* ======================== Buy Production Dlg. ========================== */
1087/* ======================================================================= */
1088
1089/**********************************************************************/
1092 static int cancel_buy_prod_city_dlg_callback(struct widget *button)
1093{
1094 if (PRESSED_EVENT(main_data.event)) {
1095 popdown_hurry_production_dialog();
1096
1097 if (pcity_dlg) {
1098 /* enable city dlg */
1099 enable_city_dlg_widgets();
1100 }
1101 }
1102
1103 return -1;
1104}
1105
1106/**********************************************************************/
1109 static int ok_buy_prod_city_dlg_callback(struct widget *button)
1110{
1111 if (PRESSED_EVENT(main_data.event)) {
1112 struct city *pcity = button->data.city; /* Save it. */
1113
1114 popdown_hurry_production_dialog();
1115 city_buy_production(pcity);
1116
1117 if (pcity_dlg) {
1118 /* enable city dlg */
1119 enable_city_dlg_widgets();
1120
1121 /* disable buy button */
1122 set_wstate(pcity_dlg->buy_button, FC_WS_DISABLED);
1123 widget_redraw(pcity_dlg->buy_button);
1124 widget_mark_dirty(pcity_dlg->buy_button);
1125 flush_dirty();
1126 }
1127 }
1128
1129 return -1;
1130}
1131
1132/**********************************************************************/
1135 static int buy_prod_city_dlg_callback(struct widget *button)
1136{
1137 if (PRESSED_EVENT(main_data.event)) {
1138 widget_redraw(button);
1139 widget_flush(button);
1140 disable_city_dlg_widgets();
1141 popup_hurry_production_dialog(pcity_dlg->pcity, button->dst->surface);
1142 }
1143
1144 return -1;
1145}
1146
1147/**********************************************************************/
1150 static void popdown_hurry_production_dialog(void)
1151{
1152 if (hurry_prog_dlg) {
1153 popdown_window_group_dialog(hurry_prog_dlg->begin_widget_list,
1154 hurry_prog_dlg->end_widget_list);
1155 FC_FREE(hurry_prog_dlg);
1156 flush_dirty();
1157 }
1158}
1159
1160/**********************************************************************/
1163 static int hurry_production_window_callback(struct widget *pwindow)
1164{
1165 if (PRESSED_EVENT(main_data.event)) {
1166 move_window_group(hurry_prog_dlg->begin_widget_list, pwindow);
1167 }
1168
1169 return -1;
1170}
1171
1172/**********************************************************************/
1175 void popup_hurry_production_dialog(struct city *pcity, SDL_Surface *pdest)
1176{
1177 char tbuf[512], cbuf[512];
1178 struct widget *buf = NULL, *pwindow;
1179 utf8_str *pstr;
1180 SDL_Surface *text;
1181 SDL_Rect dst;
1182 int window_x = 0, window_y = 0;
1183 SDL_Rect area;
1184 const char *name = city_production_name_translation(pcity);
1185 int value = pcity->client.buy_cost;
1186
1187 if (hurry_prog_dlg) {
1188 return;
1189 }
1190
1191 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
1192 "Treasury contains %d gold.",
1193 client_player()->economic.gold),
1194 client_player()->economic.gold);
1195
1196 hurry_prog_dlg = fc_calloc(1, sizeof(struct small_dialog));
1197
1198 if (city_can_buy(pcity)) {
1199 if (value <= client_player()->economic.gold) {
1200 fc_snprintf(cbuf, sizeof(cbuf),
1201 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
1202 PL_("Buy %s for %d gold?\n%s",
1203 "Buy %s for %d gold?\n%s", value),
1204 name, value, tbuf);
1205 } else {
1206 fc_snprintf(cbuf, sizeof(cbuf),
1207 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
1208 PL_("%s costs %d gold.\n%s",
1209 "%s costs %d gold.\n%s", value),
1210 name, value, tbuf);
1211 }
1212 } else {
1213 if (pcity->did_buy) {
1214 fc_snprintf(cbuf, sizeof(cbuf),
1215 _("Sorry, you have already bought here in this turn."));
1216 } else {
1217 fc_snprintf(cbuf, sizeof(cbuf),
1218 _("Sorry, you can't buy here in this turn."));
1219 }
1220 }
1221
1222 pstr = create_utf8_from_char_fonto(_("Buy it?"), FONTO_ATTENTION);
1223 pstr->style |= TTF_STYLE_BOLD;
1224 pwindow = create_window_skeleton(NULL, pstr, 0);
1225 pwindow->action = hurry_production_window_callback;
1226 set_wstate(pwindow, FC_WS_NORMAL);
1227 add_to_gui_list(ID_WINDOW, pwindow);
1228
1229 hurry_prog_dlg->end_widget_list = pwindow;
1230
1231 area = pwindow->area;
1232
1233 area.h += 1;
1234
1235 /* ============================================================= */
1236
1237 /* Label */
1238 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1239 pstr->style |= (TTF_STYLE_BOLD|SF_CENTER);
1240 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_BUY);
1241
1242 text = create_text_surf_from_utf8(pstr);
1243 FREEUTF8STR(pstr);
1244 area.w = MAX(area.w , text->w);
1245 area.h += text->h + adj_size(5);
1246
1247 buf = create_themeicon_button_from_chars_fonto(current_theme->cancel_icon,
1248 pwindow->dst, _("No"),
1249 FONTO_ATTENTION, 0);
1250
1251 buf->action = cancel_buy_prod_city_dlg_callback;
1252 set_wstate(buf, FC_WS_NORMAL);
1253 buf->key = SDLK_ESCAPE;
1254 area.h += buf->size.h;
1255
1256 add_to_gui_list(ID_BUTTON, buf);
1257
1258 if (city_can_buy(pcity) && (value <= client.conn.playing->economic.gold)) {
1259 buf = create_themeicon_button_from_chars_fonto(current_theme->ok_icon,
1260 pwindow->dst,
1261 _("Yes"),
1262 FONTO_ATTENTION, 0);
1263
1264 buf->action = ok_buy_prod_city_dlg_callback;
1265 set_wstate(buf, FC_WS_NORMAL);
1266 buf->data.city = pcity;
1267 buf->key = SDLK_RETURN;
1268 add_to_gui_list(ID_BUTTON, buf);
1269 buf->size.w = MAX(buf->next->size.w, buf->size.w);
1270 buf->next->size.w = buf->size.w;
1271 area.w = MAX(area.w , 2 * buf->size.w + adj_size(20));
1272 }
1273
1274 hurry_prog_dlg->begin_widget_list = buf;
1275
1276 /* Setup window size and start position */
1277 area.w += adj_size(10);
1278 area.h += adj_size(5);
1279
1280 resize_window(pwindow, NULL, get_theme_color(COLOR_THEME_BACKGROUND),
1281 (pwindow->size.w - pwindow->area.w) + area.w,
1282 (pwindow->size.h - pwindow->area.h) + area.h);
1283
1284 area = pwindow->area;
1285
1286 if (city_dialog_is_open(pcity)) {
1287 window_x = pcity_dlg->buy_button->size.x;
1288 window_y = pcity_dlg->buy_button->size.y - pwindow->size.h;
1289 } else if (is_city_report_open()) {
1290 fc_assert(selected_widget != NULL);
1291
1292 if (selected_widget->size.x + tileset_tile_width(tileset)
1293 + pwindow->size.w > main_window_width()) {
1294 window_x = selected_widget->size.x - pwindow->size.w;
1295 } else {
1296 window_x = selected_widget->size.x + tileset_tile_width(tileset);
1297 }
1298
1299 window_y = selected_widget->size.y
1300 + (selected_widget->size.h - pwindow->size.h) / 2;
1301
1302 if (window_y + pwindow->size.h > main_window_height()) {
1303 window_y = main_window_height() - pwindow->size.h - 1;
1304 } else if (window_y < 0) {
1305 window_y = 0;
1306 }
1307 } else {
1308 put_window_near_map_tile(pwindow, pwindow->size.w, pwindow->size.h, pcity->tile);
1309 }
1310
1311 widget_set_position(pwindow, window_x, window_y);
1312
1313 /* Setup rest of widgets */
1314 /* Label */
1315 dst.x = area.x + (area.w - text->w) / 2;
1316 dst.y = area.y + 1;
1317 alphablit(text, NULL, pwindow->theme, &dst, 255);
1318 dst.y += text->h + adj_size(5);
1319 FREESURFACE(text);
1320
1321 /* No */
1322 buf = pwindow->prev;
1323 buf->size.y = dst.y;
1324
1325 if (city_can_buy(pcity) && value <= client.conn.playing->economic.gold) {
1326 /* Yes */
1327 buf = buf->prev;
1328 buf->size.x = area.x + (area.w - (2 * buf->size.w + adj_size(20))) / 2;
1329 buf->size.y = dst.y;
1330
1331 /* No */
1332 buf->next->size.x = buf->size.x + buf->size.w + adj_size(20);
1333 } else {
1334 /* No */
1335 buf->size.x = area.x + area.w - buf->size.w - adj_size(10);
1336 }
1337
1338 /* ================================================== */
1339 /* Redraw */
1340 redraw_group(hurry_prog_dlg->begin_widget_list, pwindow, 0);
1341 widget_mark_dirty(pwindow);
1342 flush_dirty();
1343}
1344
1345/* =======================================================================*/
1346/* ========================== CHANGE PRODUCTION ==========================*/
1347/* =======================================================================*/
1348
1349/**********************************************************************/
1352 static int change_prod_dlg_callback(struct widget *button)
1353{
1354 if (PRESSED_EVENT(main_data.event)) {
1355 widget_redraw(button);
1356 widget_flush(button);
1357
1358 disable_city_dlg_widgets();
1359 popup_worklist_editor(pcity_dlg->pcity, NULL);
1360 }
1361
1362 return -1;
1363}
1364
1365/* =======================================================================*/
1366/* ========================== SELL IMPROVEMENTS ==========================*/
1367/* =======================================================================*/
1368
1369/**********************************************************************/
1372 static int sell_imprvm_dlg_cancel_callback(struct widget *cancel_button)
1373{
1374 if (PRESSED_EVENT(main_data.event)) {
1375 popdown_window_group_dialog(pcity_dlg->begin_city_menu_widget_list,
1376 pcity_dlg->end_city_menu_widget_list);
1377 pcity_dlg->end_city_menu_widget_list = NULL;
1378 enable_city_dlg_widgets();
1379 redraw_city_dialog(pcity_dlg->pcity);
1380 flush_dirty();
1381 }
1382
1383 return -1;
1384}
1385
1386/**********************************************************************/
1389 static int sell_imprvm_dlg_ok_callback(struct widget *ok_button)
1390{
1391 if (PRESSED_EVENT(main_data.event)) {
1392 struct widget *tmp = (struct widget *)ok_button->data.ptr;
1393
1394 city_sell_improvement(pcity_dlg->pcity, MAX_ID - 3000 - tmp->id);
1395
1396 /* popdown, we don't redraw and flush because this is made by redraw city dlg.
1397 when response from server comes */
1398 popdown_window_group_dialog(pcity_dlg->begin_city_menu_widget_list,
1399 pcity_dlg->end_city_menu_widget_list);
1400
1401 pcity_dlg->end_city_menu_widget_list = NULL;
1402
1403 /* del imprv from widget list */
1404 del_widget_from_vertical_scroll_widget_list(pcity_dlg->imprv, tmp);
1405
1406 enable_city_dlg_widgets();
1407
1408 if (pcity_dlg->imprv->end_widget_list) {
1409 set_group_state(pcity_dlg->imprv->begin_active_widget_list,
1410 pcity_dlg->imprv->end_active_widget_list, FC_WS_DISABLED);
1411 }
1412
1413 redraw_city_dialog(pcity_dlg->pcity);
1414 flush_dirty();
1415 }
1416
1417 return -1;
1418}
1419
1420/**********************************************************************/
1423 static int sell_imprvm_dlg_callback(struct widget *impr)
1424{
1425 if (PRESSED_EVENT(main_data.event)) {
1426 utf8_str *pstr = NULL;
1427 struct widget *label = NULL;
1428 struct widget *pwindow = NULL;
1429 struct widget *cancel_button = NULL;
1430 struct widget *ok_button = NULL;
1431 char cbuf[80];
1432 int id;
1433 SDL_Rect area;
1434 int price;
1435
1436 unselect_widget_action();
1437 disable_city_dlg_widgets();
1438
1439 pstr = create_utf8_from_char_fonto(_("Sell it?"), FONTO_ATTENTION);
1440 pstr->style |= TTF_STYLE_BOLD;
1441 pwindow = create_window_skeleton(NULL, pstr, 0);
1442 /*pwindow->action = move_sell_imprvm_dlg_callback; */
1443 /*set_wstate(pwindow, FC_WS_NORMAL); */
1444 add_to_gui_list(ID_WINDOW, pwindow);
1445 pcity_dlg->end_city_menu_widget_list = pwindow;
1446
1447 area = pwindow->area;
1448
1449 /* Create text label */
1450 id = MAX_ID - 3000 - impr->id;
1451
1452 price = impr_sell_gold(improvement_by_number(id));
1453 fc_snprintf(cbuf, sizeof(cbuf), PL_("Sell %s for %d gold?",
1454 "Sell %s for %d gold?", price),
1455 city_improvement_name_translation(pcity_dlg->pcity,
1456 improvement_by_number(id)),
1457 price);
1458 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1459 pstr->style |= (TTF_STYLE_BOLD|SF_CENTER);
1460 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_SELL);
1461 label = create_iconlabel(NULL, pwindow->dst, pstr, 0);
1462 add_to_gui_list(ID_LABEL, label);
1463
1464 /* Create cancel button */
1465 cancel_button =
1466 create_themeicon_button_from_chars_fonto(current_theme->small_cancel_icon,
1467 pwindow->dst, _("Cancel"),
1468 FONTO_DEFAULT, 0);
1469 cancel_button->action = sell_imprvm_dlg_cancel_callback;
1470 cancel_button->key = SDLK_ESCAPE;
1471 set_wstate(cancel_button, FC_WS_NORMAL);
1472 add_to_gui_list(ID_BUTTON, cancel_button);
1473
1474 /* create ok button */
1475 ok_button = create_themeicon_button_from_chars_fonto(current_theme->small_ok_icon,
1476 pwindow->dst, _("Sell"),
1477 FONTO_DEFAULT, 0);
1478 ok_button->data.ptr = (void *)impr;
1479 ok_button->size.w = cancel_button->size.w;
1480 ok_button->action = sell_imprvm_dlg_ok_callback;
1481 ok_button->key = SDLK_RETURN;
1482 set_wstate(ok_button, FC_WS_NORMAL);
1483 add_to_gui_list(ID_BUTTON, ok_button);
1484
1485 pcity_dlg->begin_city_menu_widget_list = ok_button;
1486
1487 /* correct sizes */
1488 if ((ok_button->size.w + cancel_button->size.w + adj_size(30)) >
1489 label->size.w + adj_size(20)) {
1490 area.w = MAX(area.w, ok_button->size.w + cancel_button->size.w + adj_size(30));
1491 } else {
1492 area.w = MAX(area.w, label->size.w + adj_size(20));
1493 }
1494
1495 area.h = MAX(area.h, ok_button->size.h + label->size.h + adj_size(25));
1496
1497 /* create window background */
1498 resize_window(pwindow, NULL, get_theme_color(COLOR_THEME_BACKGROUND),
1499 (pwindow->size.w - pwindow->area.w) + area.w,
1500 (pwindow->size.h - pwindow->area.h) + area.h);
1501
1502 area = pwindow->area;
1503
1504 /* set start positions */
1505 widget_set_position(pwindow,
1506 (main_window_width() - pwindow->size.w) / 2,
1507 (main_window_height() - pwindow->size.h) / 2 + adj_size(10));
1508
1509 ok_button->size.x = area.x + adj_size(10);
1510 ok_button->size.y = area.y + area.h - ok_button->size.h - adj_size(10);
1511
1512 cancel_button->size.y = ok_button->size.y;
1513 cancel_button->size.x = area.x + area.w - cancel_button->size.w - adj_size(10);
1514
1515 label->size.x = area.x;
1516 label->size.y = area.y + adj_size(4);
1517 label->size.w = area.w;
1518
1519 /* redraw */
1520 redraw_group(pcity_dlg->begin_city_menu_widget_list,
1521 pcity_dlg->end_city_menu_widget_list, 0);
1522
1523 widget_mark_dirty(pwindow);
1524 flush_dirty();
1525 }
1526
1527 return -1;
1528}
1529/* ====================================================================== */
1530
1531/**********************************************************************/
1534 void enable_city_dlg_widgets(void)
1535{
1536 if (pcity_dlg) {
1537 set_group_state(pcity_dlg->begin_city_widget_list,
1538 pcity_dlg->end_city_widget_list->prev, FC_WS_NORMAL);
1539
1540 if (pcity_dlg->imprv->end_active_widget_list) {
1541 if (pcity_dlg->imprv->scroll) {
1542 set_wstate(pcity_dlg->imprv->scroll->pscroll_bar, FC_WS_NORMAL); /* vscroll */
1543 set_wstate(pcity_dlg->imprv->scroll->up_left_button, FC_WS_NORMAL); /* up */
1544 set_wstate(pcity_dlg->imprv->scroll->down_right_button, FC_WS_NORMAL); /* down */
1545 }
1546
1547 /* There is common function test_player_sell_building_now(),
1548 * but we are not using it here, since we want to use set_group_state()
1549 * when possible */
1550 if (pcity_dlg->pcity->did_sell
1551 || pcity_dlg->pcity->owner != client.conn.playing) {
1552 set_group_state(pcity_dlg->imprv->begin_active_widget_list,
1553 pcity_dlg->imprv->end_active_widget_list, FC_WS_DISABLED);
1554 } else {
1555 struct widget *tmp_widget = pcity_dlg->imprv->end_active_widget_list;
1556
1557 while (TRUE) {
1558 struct impr_type *pimpr = improvement_by_number(MAX_ID - 3000 -
1559 tmp_widget->id);
1560
1561 if (!can_city_sell_building(pcity_dlg->pcity, pimpr)) {
1562 set_wstate(tmp_widget, FC_WS_DISABLED);
1563 } else {
1564 set_wstate(tmp_widget, FC_WS_NORMAL);
1565 }
1566
1567 if (tmp_widget == pcity_dlg->imprv->begin_active_widget_list) {
1568 break;
1569 }
1570
1571 tmp_widget = tmp_widget->prev;
1572
1573 } /* while */
1574 }
1575 }
1576
1577 if (!city_can_buy(pcity_dlg->pcity) && pcity_dlg->buy_button) {
1578 set_wstate(pcity_dlg->buy_button, FC_WS_DISABLED);
1579 }
1580
1581 if (pcity_dlg->panel) {
1582 set_group_state(pcity_dlg->panel->begin_widget_list,
1583 pcity_dlg->panel->end_widget_list, FC_WS_NORMAL);
1584 }
1585
1586 if (cma_is_city_under_agent(pcity_dlg->pcity, NULL)) {
1587 set_wstate(pcity_dlg->resource_map, FC_WS_DISABLED);
1588 }
1589
1590 pcity_dlg->lock = FALSE;
1591 }
1592}
1593
1594/**********************************************************************/
1597 static void disable_city_dlg_widgets(void)
1598{
1599 if (pcity_dlg->panel) {
1600 set_group_state(pcity_dlg->panel->begin_widget_list,
1601 pcity_dlg->panel->end_widget_list, FC_WS_DISABLED);
1602 }
1603
1604 if (pcity_dlg->imprv->end_widget_list) {
1605 set_group_state(pcity_dlg->imprv->begin_widget_list,
1606 pcity_dlg->imprv->end_widget_list, FC_WS_DISABLED);
1607 }
1608
1609 set_group_state(pcity_dlg->begin_city_widget_list,
1610 pcity_dlg->end_city_widget_list->prev, FC_WS_DISABLED);
1611 pcity_dlg->lock = TRUE;
1612}
1613
1614/* ======================================================================== */
1615
1616/**********************************************************************/
1619SDL_Surface *get_scaled_city_map(struct city *pcity)
1620{
1621 SDL_Surface *buf = create_city_map(pcity);
1622
1623 city_map_zoom = ((buf->w * 159 > buf->h * 249) ?
1624 (float)adj_size(249) / buf->w
1625 : (float)adj_size(159) / buf->h);
1626
1627 return zoomSurface(buf, city_map_zoom, city_map_zoom, 1);
1628}
1629
1630/**********************************************************************/
1633 static int resource_map_city_dlg_callback(struct widget *map)
1634{
1635 if (PRESSED_EVENT(main_data.event)) {
1636 int col, row;
1637
1638 if (canvas_to_city_pos(&col, &row,
1639 city_map_radius_sq_get(pcity_dlg->pcity),
1640 1 / city_map_zoom * (main_data.event.motion.x - map->dst->dest_rect.x
1641 - map->size.x),
1642 1 / city_map_zoom * (main_data.event.motion.y - map->dst->dest_rect.y
1643 - map->size.y))) {
1644
1645 city_toggle_worker(pcity_dlg->pcity, col, row);
1646 }
1647 }
1648
1649 return -1;
1650}
1651
1652/* ====================================================================== */
1653
1654/**********************************************************************/
1657 static int city_comp_by_turn_founded(const void *a, const void *b)
1658{
1659 struct city *pcity1 = *((struct city **) a);
1660 struct city *pcity2 = *((struct city **) b);
1661
1662 return pcity1->turn_founded - pcity2->turn_founded;
1663}
1664
1665/**********************************************************************/
1668 static int next_prev_city_dlg_callback(struct widget *button)
1669{
1670 if (PRESSED_EVENT(main_data.event)) {
1671 struct city **array;
1672 int i, dir, non_open_size;
1673 int size = city_list_size(client.conn.playing->cities);
1674
1675 fc_assert_ret_val(size >= 1, -1);
1676 fc_assert_ret_val(city_owner(pcity_dlg->pcity)
1677 == client.conn.playing, -1);
1678
1679 if (size == 1) {
1680 return -1;
1681 }
1682
1683 /* dir = 1 will advance to the city, dir = -1 will get previous */
1684 if (button->id == ID_CITY_DLG_NEXT_BUTTON) {
1685 dir = 1;
1686 } else {
1687 if (button->id == ID_CITY_DLG_PREV_BUTTON) {
1688 dir = -1;
1689 } else {
1690 /* Always fails. */
1691 fc_assert_ret_val(button->id == ID_CITY_DLG_NEXT_BUTTON
1692 || button->id != ID_CITY_DLG_PREV_BUTTON, -1);
1693 dir = 1;
1694 }
1695 }
1696
1697 array = fc_calloc(1, size * sizeof(struct city *));
1698
1699 non_open_size = 0;
1700 for (i = 0; i < size; i++) {
1701 array[non_open_size++] = city_list_get(client.conn.playing->cities, i);
1702 }
1703
1704 fc_assert_ret_val(non_open_size > 0, -1);
1705
1706 if (non_open_size <= 1) {
1707 FC_FREE(array);
1708 return -1;
1709 }
1710
1711 qsort(array, non_open_size, sizeof(struct city *),
1712 city_comp_by_turn_founded);
1713
1714 for (i = 0; i < non_open_size; i++) {
1715 if (pcity_dlg->pcity == array[i]) {
1716 break;
1717 }
1718 }
1719
1720 fc_assert_ret_val(i < non_open_size, -1);
1721 pcity_dlg->pcity = array[(i + dir + non_open_size) % non_open_size];
1722 FC_FREE(array);
1723
1724 /* free panel widgets */
1725 free_city_units_lists();
1726 /* refresh resource map */
1727 FREESURFACE(pcity_dlg->resource_map->theme);
1728 pcity_dlg->resource_map->theme = get_scaled_city_map(pcity_dlg->pcity);
1729 rebuild_imprm_list(pcity_dlg->pcity);
1730
1731 /* redraw */
1732 redraw_city_dialog(pcity_dlg->pcity);
1733 flush_dirty();
1734 }
1735
1736 return -1;
1737}
1738
1739/**********************************************************************/
1742 static int new_name_city_dlg_callback(struct widget *pedit)
1743{
1744 if (pedit->string_utf8->text != NULL) {
1745 if (strcmp(pedit->string_utf8->text, city_name_get(pcity_dlg->pcity))) {
1746 sdl2_client_flags |= CF_CHANGED_CITY_NAME;
1747 city_rename(pcity_dlg->pcity, pedit->string_utf8->text);
1748 }
1749 } else {
1750 /* Empty input -> restore previous content */
1751 copy_chars_to_utf8_str(pedit->string_utf8, city_name_get(pcity_dlg->pcity));
1752 widget_redraw(pedit);
1753 widget_mark_dirty(pedit);
1754 flush_dirty();
1755 }
1756
1757 return -1;
1758}
1759
1760/* ======================================================================= */
1761/* ======================== Redrawing City Dlg. ========================== */
1762/* ======================================================================= */
1763
1764/**********************************************************************/
1767 static void refresh_city_names(struct city *pcity)
1768{
1769 if (pcity_dlg->city_name_edit) {
1770 char name[MAX_LEN_NAME];
1771
1772 fc_snprintf(name, MAX_LEN_NAME, "%s", pcity_dlg->city_name_edit->string_utf8->text);
1773 if ((strcmp(city_name_get(pcity), name) != 0)
1774 || (sdl2_client_flags & CF_CHANGED_CITY_NAME)) {
1775 copy_chars_to_utf8_str(pcity_dlg->city_name_edit->string_utf8,
1776 city_name_get(pcity));
1777 rebuild_citydlg_title_str(pcity_dlg->end_city_widget_list, pcity);
1778 sdl2_client_flags &= ~CF_CHANGED_CITY_NAME;
1779 }
1780 }
1781}
1782
1783/**********************************************************************/
1787 static void redraw_misc_city_dialog(struct widget *city_window,
1788 struct city *pcity)
1789{
1790 char cbuf[60];
1791 utf8_str *pstr;
1792 SDL_Surface *surf;
1793 SDL_Rect dest;
1794
1795 fc_snprintf(cbuf, sizeof(cbuf), _("City options"));
1796
1797 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1798 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PANEL);
1799 pstr->style |= TTF_STYLE_BOLD;
1800
1801 surf = create_text_surf_from_utf8(pstr);
1802
1803 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1804 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
1805
1806 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1807
1808 FREESURFACE(surf);
1809 FREEUTF8STR(pstr);
1810
1811 if (!pcity_dlg->panel) {
1812 create_city_options_widget_list(pcity);
1813 }
1814 redraw_group(pcity_dlg->panel->begin_widget_list,
1815 pcity_dlg->panel->end_widget_list, 0);
1816}
1817
1818/**********************************************************************/
1822 static void redraw_supported_units_city_dialog(struct widget *city_window,
1823 struct city *pcity)
1824{
1825 char cbuf[60];
1826 utf8_str *pstr;
1827 SDL_Surface *surf;
1828 SDL_Rect dest;
1829 struct unit_list *units;
1830 int size;
1831
1832 if (city_owner(pcity_dlg->pcity) != client.conn.playing) {
1833 units = (pcity_dlg->pcity->client.info_units_supported);
1834 } else {
1835 units = (pcity_dlg->pcity->units_supported);
1836 }
1837
1838 size = unit_list_size(units);
1839
1840 fc_snprintf(cbuf, sizeof(cbuf), _("Supported units: %d"), size);
1841
1842 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1843 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PANEL);
1844 pstr->style |= TTF_STYLE_BOLD;
1845
1846 surf = create_text_surf_from_utf8(pstr);
1847
1848 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1849 dest.y = city_window->area.y + + adj_size(4) + current_theme->info_icon->h;
1850
1851 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1852
1853 FREESURFACE(surf);
1854 FREEUTF8STR(pstr);
1855
1856 if (pcity_dlg->panel) {
1857 if (size > 0) {
1858 redraw_group(pcity_dlg->panel->begin_widget_list,
1859 pcity_dlg->panel->end_widget_list, 0);
1860 } else {
1861 del_group_of_widgets_from_gui_list(pcity_dlg->panel->begin_widget_list,
1862 pcity_dlg->panel->end_widget_list);
1863 FC_FREE(pcity_dlg->panel->scroll);
1864 FC_FREE(pcity_dlg->panel);
1865 }
1866 } else {
1867 if (size > 0) {
1868 create_present_supported_units_widget_list(units);
1869 redraw_group(pcity_dlg->panel->begin_widget_list,
1870 pcity_dlg->panel->end_widget_list, 0);
1871 }
1872 }
1873}
1874
1875/**********************************************************************/
1879 static void redraw_army_city_dialog(struct widget *city_window,
1880 struct city *pcity)
1881{
1882 char cbuf[60];
1883 utf8_str *pstr;
1884 SDL_Surface *surf;
1885 SDL_Rect dest;
1886 struct unit_list *units;
1887 int size;
1888
1889 if (city_owner(pcity_dlg->pcity) != client.conn.playing) {
1890 units = pcity_dlg->pcity->client.info_units_present;
1891 } else {
1892 units = pcity_dlg->pcity->tile->units;
1893 }
1894
1895 size = unit_list_size(units);
1896
1897 fc_snprintf(cbuf, sizeof(cbuf), _("Present units: %d"), size);
1898
1899 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1900 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PANEL);
1901 pstr->style |= TTF_STYLE_BOLD;
1902
1903 surf = create_text_surf_from_utf8(pstr);
1904
1905 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1906 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
1907
1908 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1909
1910 FREESURFACE(surf);
1911 FREEUTF8STR(pstr);
1912
1913 if (pcity_dlg->panel) {
1914 if (size) {
1915 redraw_group(pcity_dlg->panel->begin_widget_list,
1916 pcity_dlg->panel->end_widget_list, 0);
1917 } else {
1918 del_group_of_widgets_from_gui_list(pcity_dlg->panel->begin_widget_list,
1919 pcity_dlg->panel->end_widget_list);
1920 FC_FREE(pcity_dlg->panel->scroll);
1921 FC_FREE(pcity_dlg->panel);
1922 }
1923 } else {
1924 if (size) {
1925 create_present_supported_units_widget_list(units);
1926 redraw_group(pcity_dlg->panel->begin_widget_list,
1927 pcity_dlg->panel->end_widget_list, 0);
1928 }
1929 }
1930}
1931
1932/**********************************************************************/
1936 static void redraw_info_city_dialog(struct widget *city_window,
1937 struct city *pcity)
1938{
1939 char cbuf[30];
1940 struct city *trade_city = NULL;
1941 int step, i, xx;
1942 utf8_str *pstr = NULL;
1943 SDL_Surface *surf = NULL;
1944 SDL_Rect dest;
1945
1946 fc_snprintf(cbuf, sizeof(cbuf), _("City info"));
1947 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1948 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PANEL);
1949 pstr->style |= TTF_STYLE_BOLD;
1950
1951 surf = create_text_surf_from_utf8(pstr);
1952
1953 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1954 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
1955
1956 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1957
1958 dest.x = city_window->size.x + adj_size(10);
1959 dest.y += surf->h + 1;
1960
1961 FREESURFACE(surf);
1962
1963 change_fonto_utf8(pstr, FONTO_SLIGHTLY_BIGGER);
1964 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_INFOPANEL);
1965
1966 if (pcity->pollution) {
1967 fc_snprintf(cbuf, sizeof(cbuf), _("Pollution: %d"),
1968 pcity->pollution);
1969
1970 copy_chars_to_utf8_str(pstr, cbuf);
1971
1972 surf = create_text_surf_from_utf8(pstr);
1973
1974 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1975
1976 dest.y += surf->h + adj_size(3);
1977
1978 FREESURFACE(surf);
1979
1980 if (((icons->pollution->w + 1) * pcity->pollution) > adj_size(187)) {
1981 step = (adj_size(187) - icons->pollution->w) / (pcity->pollution - 1);
1982 } else {
1983 step = icons->pollution->w + 1;
1984 }
1985
1986 for (i = 0; i < pcity->pollution; i++) {
1987 alphablit(icons->pollution, NULL, city_window->dst->surface, &dest, 255);
1988 dest.x += step;
1989 }
1990
1991 dest.x = city_window->size.x + adj_size(10);
1992 dest.y += icons->pollution->h + adj_size(3);
1993
1994 } else {
1995 fc_snprintf(cbuf, sizeof(cbuf), _("Pollution: none"));
1996
1997 copy_chars_to_utf8_str(pstr, cbuf);
1998
1999 surf = create_text_surf_from_utf8(pstr);
2000
2001 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2002
2003 dest.y += surf->h + adj_size(3);
2004
2005 FREESURFACE(surf);
2006 }
2007
2008 if (game.info.illness_on) {
2009 int risk_pml = city_illness_calc(pcity, NULL, NULL, NULL, NULL);
2010
2011 fc_snprintf(cbuf, sizeof(cbuf), _("Plague risk: %.1f%%"),
2012 (double)risk_pml / 10.0);
2013 } else {
2014 fc_snprintf(cbuf, sizeof(cbuf), _("Plague risk: none"));
2015 }
2016
2017 copy_chars_to_utf8_str(pstr, cbuf);
2018 surf = create_text_surf_from_utf8(pstr);
2019 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2020 dest.y += surf->h + adj_size(3);
2021 FREESURFACE(surf);
2022
2023 fc_snprintf(cbuf, sizeof(cbuf), _("Trade routes: "));
2024
2025 copy_chars_to_utf8_str(pstr, cbuf);
2026
2027 surf = create_text_surf_from_utf8(pstr);
2028
2029 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2030
2031 xx = dest.x + surf->w;
2032 dest.y += surf->h + adj_size(3);
2033
2034 FREESURFACE(surf);
2035
2036 step = 0;
2037 dest.x = city_window->size.x + adj_size(10);
2038
2039 trade_routes_iterate(pcity, proute) {
2040 step += proute->value;
2041
2042 if ((trade_city = game_city_by_number(proute->partner))) {
2043 fc_snprintf(cbuf, sizeof(cbuf), "%s: +%d", city_name_get(trade_city),
2044 proute->value);
2045 } else {
2046 fc_snprintf(cbuf, sizeof(cbuf), "%s: +%d", _("Unknown"),
2047 proute->value);
2048 }
2049
2050 copy_chars_to_utf8_str(pstr, cbuf);
2051
2052 surf = create_text_surf_from_utf8(pstr);
2053
2054 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2055
2056 /* Blit trade icon */
2057 dest.x += surf->w + adj_size(3);
2058 dest.y += adj_size(4);
2059 alphablit(icons->trade, NULL, city_window->dst->surface, &dest, 255);
2060 dest.x = city_window->size.x + adj_size(10);
2061 dest.y -= adj_size(4);
2062
2063 dest.y += surf->h;
2064
2065 FREESURFACE(surf);
2066 } trade_routes_iterate_end;
2067
2068 if (step > 0) {
2069 fc_snprintf(cbuf, sizeof(cbuf), _("Trade: +%d"), step);
2070
2071 copy_chars_to_utf8_str(pstr, cbuf);
2072 surf = create_text_surf_from_utf8(pstr);
2073 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2074
2075 dest.x += surf->w + adj_size(3);
2076 dest.y += adj_size(4);
2077 alphablit(icons->trade, NULL, city_window->dst->surface, &dest, 255);
2078
2079 FREESURFACE(surf);
2080 } else {
2081 fc_snprintf(cbuf, sizeof(cbuf), Q_("?trade:None"));
2082
2083 copy_chars_to_utf8_str(pstr, cbuf);
2084
2085 surf = create_text_surf_from_utf8(pstr);
2086
2087 dest.x = xx;
2088 dest.y -= surf->h + adj_size(3);
2089 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2090
2091 FREESURFACE(surf);
2092 }
2093
2094 FREEUTF8STR(pstr);
2095}
2096
2097/**********************************************************************/
2102 static void redraw_happiness_city_dialog(const struct widget *city_window,
2103 struct city *pcity)
2104{
2105 char cbuf[30];
2106 int step, i, j, count;
2107 SDL_Surface *tmp;
2108 utf8_str *pstr = NULL;
2109 SDL_Surface *surf = NULL;
2110 SDL_Rect dest = {0, 0, 0, 0};
2111 struct effect_list *sources = effect_list_new();
2112
2113 fc_snprintf(cbuf, sizeof(cbuf), _("Happiness"));
2114
2115 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
2116 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PANEL);
2117 pstr->style |= TTF_STYLE_BOLD;
2118
2119 surf = create_text_surf_from_utf8(pstr);
2120
2121 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
2122 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
2123 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2124
2125 dest.x = city_window->size.x + adj_size(10);
2126 dest.y += surf->h + 1;
2127
2128 FREESURFACE(surf);
2129 FREEUTF8STR(pstr);
2130
2131 count = (pcity->feel[CITIZEN_HAPPY][FEELING_FINAL] + pcity->feel[CITIZEN_CONTENT][FEELING_FINAL]
2132 + pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL] + pcity->feel[CITIZEN_ANGRY][FEELING_FINAL]
2133 + city_specialists(pcity));
2134
2135 if (count * icons->male_happy->w > adj_size(166)) {
2136 step = (adj_size(166) - icons->male_happy->w) / (count - 1);
2137 } else {
2138 step = icons->male_happy->w;
2139 }
2140
2141 for (j = 0; j < FEELING_LAST; j++) {
2142 if (j == 0 || pcity->feel[CITIZEN_HAPPY][j - 1] != pcity->feel[CITIZEN_HAPPY][j]
2143 || pcity->feel[CITIZEN_CONTENT][j - 1] != pcity->feel[CITIZEN_CONTENT][j]
2144 || pcity->feel[CITIZEN_UNHAPPY][j - 1] != pcity->feel[CITIZEN_UNHAPPY][j]
2145 || pcity->feel[CITIZEN_ANGRY][j - 1] != pcity->feel[CITIZEN_ANGRY][j]) {
2146 int spe, spe_max;
2147
2148 if (j != 0) {
2149 create_line(city_window->dst->surface,
2150 dest.x, dest.y, dest.x + adj_size(176), dest.y,
2151 get_theme_color(COLOR_THEME_CITYDLG_FRAME));
2152 dest.y += adj_size(5);
2153 }
2154
2155 if (pcity->feel[CITIZEN_HAPPY][j]) {
2156 surf = icons->male_happy;
2157 for (i = 0; i < pcity->feel[CITIZEN_HAPPY][j]; i++) {
2158 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2159 dest.x += step;
2160 if (surf == icons->male_happy) {
2161 surf = icons->female_happy;
2162 } else {
2163 surf = icons->male_happy;
2164 }
2165 }
2166 }
2167
2168 if (pcity->feel[CITIZEN_CONTENT][j]) {
2169 surf = icons->male_content;
2170 for (i = 0; i < pcity->feel[CITIZEN_CONTENT][j]; i++) {
2171 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2172 dest.x += step;
2173 if (surf == icons->male_content) {
2174 surf = icons->female_content;
2175 } else {
2176 surf = icons->male_content;
2177 }
2178 }
2179 }
2180
2181 if (pcity->feel[CITIZEN_UNHAPPY][j]) {
2182 surf = icons->male_unhappy;
2183 for (i = 0; i < pcity->feel[CITIZEN_UNHAPPY][j]; i++) {
2184 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2185 dest.x += step;
2186 if (surf == icons->male_unhappy) {
2187 surf = icons->female_unhappy;
2188 } else {
2189 surf = icons->male_unhappy;
2190 }
2191 }
2192 }
2193
2194 if (pcity->feel[CITIZEN_ANGRY][j]) {
2195 surf = icons->male_angry;
2196 for (i = 0; i < pcity->feel[CITIZEN_ANGRY][j]; i++) {
2197 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2198 dest.x += step;
2199 if (surf == icons->male_angry) {
2200 surf = icons->female_angry;
2201 } else {
2202 surf = icons->male_angry;
2203 }
2204 }
2205 }
2206
2207 spe_max = specialist_count();
2208 for (spe = 0 ; spe < spe_max; spe++) {
2209 if (pcity->specialists[spe]) {
2210 for (i = 0; i < pcity->specialists[spe]; i++) {
2211 alphablit(icons->specialists[spe], NULL, city_window->dst->surface,
2212 &dest, 255);
2213 dest.x += step;
2214 }
2215 }
2216 }
2217
2218 if (j == 1) { /* Luxury effect */
2219 dest.x =
2220 city_window->size.x + adj_size(187) - icons->big_luxury->w - adj_size(2);
2221 count = dest.y;
2222 dest.y += (icons->male_happy->h -
2223 icons->big_luxury->h) / 2;
2224 alphablit(icons->big_luxury, NULL, city_window->dst->surface, &dest, 255);
2225 dest.y = count;
2226 }
2227
2228 if (j == 2) { /* Improvements effects */
2229 int w = -1;
2230 count = 0;
2231
2232 get_city_bonus_effects(sources, pcity, NULL, EFT_MAKE_CONTENT);
2233
2234 effect_list_iterate(sources, psource) {
2235 requirement_vector_iterate(&(psource->reqs), preq) {
2236 if (preq->source.kind == VUT_IMPROVEMENT) {
2237 tmp = get_building_surface(preq->source.value.building);
2238 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2239 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2240
2241 count += (tmp->h + 1);
2242
2243 if (w < 0) {
2244 w = tmp->w;
2245 }
2246
2247 FREESURFACE(tmp);
2248 }
2249 } requirement_vector_iterate_end;
2250 } effect_list_iterate_end;
2251
2252 if (w >= 0) {
2253 dest.x = city_window->size.x + adj_size(187) - w - adj_size(2);
2254 i = dest.y;
2255 dest.y += (icons->male_happy->h - count) / 2;
2256
2257 effect_list_iterate(sources, psource) {
2258 requirement_vector_iterate(&(psource->reqs), preq) {
2259 if (preq->source.kind == VUT_IMPROVEMENT) {
2260 tmp = get_building_surface(preq->source.value.building);
2261 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2262 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2263
2264 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2265 dest.y += (tmp->h + 1);
2266
2267 FREESURFACE(tmp);
2268 }
2269 } requirement_vector_iterate_end;
2270 } effect_list_iterate_end;
2271
2272 dest.y = i;
2273 }
2274
2275 effect_list_clear(sources);
2276 }
2277
2278 if (j == 3) { /* police effect */
2279 dest.x = city_window->size.x + adj_size(187) - icons->police->w - adj_size(5);
2280 i = dest.y;
2281 dest.y +=
2282 (icons->male_happy->h - icons->police->h) / 2;
2283 alphablit(icons->police, NULL, city_window->dst->surface, &dest, 255);
2284 dest.y = i;
2285 }
2286
2287 if (j == 4) { /* Wonders effect */
2288 int w = -1;
2289 count = 0;
2290
2291 get_city_bonus_effects(sources, pcity, NULL, EFT_MAKE_HAPPY);
2292 effect_list_iterate(sources, psource) {
2293 requirement_vector_iterate(&(psource->reqs), preq) {
2294 if (preq->source.kind == VUT_IMPROVEMENT) {
2295 tmp = get_building_surface(preq->source.value.building);
2296 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2297 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2298
2299 count += (tmp->h + 1);
2300
2301 if (w < 0) {
2302 w = tmp->w;
2303 }
2304
2305 FREESURFACE(tmp);
2306 }
2307 } requirement_vector_iterate_end;
2308 } effect_list_iterate_end;
2309
2310 effect_list_clear(sources);
2311
2312 get_city_bonus_effects(sources, pcity, NULL, EFT_FORCE_CONTENT);
2313
2314 effect_list_iterate(sources, psource) {
2315 requirement_vector_iterate(&(psource->reqs), preq) {
2316 if (preq->source.kind == VUT_IMPROVEMENT) {
2317 tmp = get_building_surface(preq->source.value.building);
2318 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2319 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2320 count += (tmp->h + 1);
2321
2322 if (w < 0) {
2323 w = tmp->w;
2324 }
2325
2326 FREESURFACE(tmp);
2327 }
2328 } requirement_vector_iterate_end;
2329 } effect_list_iterate_end;
2330
2331 effect_list_clear(sources);
2332
2333 get_city_bonus_effects(sources, pcity, NULL, EFT_NO_UNHAPPY);
2334
2335 effect_list_iterate(sources, psource) {
2336 requirement_vector_iterate(&(psource->reqs), preq) {
2337 if (preq->source.kind == VUT_IMPROVEMENT) {
2338 tmp = get_building_surface(preq->source.value.building);
2339 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2340 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2341
2342 count += (tmp->h + 1);
2343
2344 if (w < 0) {
2345 w = tmp->w;
2346 }
2347
2348 FREESURFACE(tmp);
2349 }
2350 } requirement_vector_iterate_end;
2351 } effect_list_iterate_end;
2352
2353 effect_list_clear(sources);
2354
2355 if (w >= 0) {
2356 dest.x = city_window->size.x + adj_size(187) - surf->w - adj_size(2);
2357 i = dest.y;
2358 dest.y += (icons->male_happy->h - count) / 2;
2359
2360 get_city_bonus_effects(sources, pcity, NULL, EFT_MAKE_HAPPY);
2361
2362 effect_list_iterate(sources, psource) {
2363 requirement_vector_iterate(&(psource->reqs), preq) {
2364 if (preq->source.kind == VUT_IMPROVEMENT) {
2365 tmp = get_building_surface(preq->source.value.building);
2366 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2367 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2368
2369 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2370 dest.y += (tmp->h + 1);
2371
2372 FREESURFACE(tmp);
2373 }
2374 } requirement_vector_iterate_end;
2375 } effect_list_iterate_end;
2376
2377 effect_list_clear(sources);
2378
2379 get_city_bonus_effects(sources, pcity, NULL, EFT_FORCE_CONTENT);
2380
2381 effect_list_iterate(sources, psource) {
2382 requirement_vector_iterate(&(psource->reqs), preq) {
2383 if (preq->source.kind == VUT_IMPROVEMENT) {
2384 tmp = get_building_surface(preq->source.value.building);
2385 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2386 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2387
2388 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2389 dest.y += (tmp->h + 1);
2390
2391 FREESURFACE(tmp);
2392 }
2393 } requirement_vector_iterate_end;
2394 } effect_list_iterate_end;
2395
2396 effect_list_clear(sources);
2397
2398 get_city_bonus_effects(sources, pcity, NULL, EFT_NO_UNHAPPY);
2399
2400 effect_list_iterate(sources, psource) {
2401 requirement_vector_iterate(&(psource->reqs), preq) {
2402 if (preq->source.kind == VUT_IMPROVEMENT) {
2403 tmp = get_building_surface(preq->source.value.building);
2404 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2405 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2406
2407 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2408 dest.y += (tmp->h + 1);
2409
2410 FREESURFACE(tmp);
2411 }
2412 } requirement_vector_iterate_end;
2413 } effect_list_iterate_end;
2414
2415 effect_list_clear(sources);
2416
2417 dest.y = i;
2418 }
2419 }
2420
2421 dest.x = city_window->size.x + adj_size(10);
2422 dest.y += icons->male_happy->h + adj_size(5);
2423
2424 }
2425 }
2426
2427 effect_list_destroy(sources);
2428}
2429
2430/**********************************************************************/
2433 static void redraw_city_dialog(struct city *pcity)
2434{
2435 char cbuf[40];
2436 int i, step, count, limit;
2437 int cost = 0;
2438 SDL_Rect dest;
2439 struct widget *pwindow = pcity_dlg->end_city_widget_list;
2440 SDL_Surface *buf = NULL, *buf2 = NULL;
2441 utf8_str *pstr = NULL;
2442 int spe, spe_max;
2443
2444 refresh_city_names(pcity);
2445
2446 if ((city_unhappy(pcity) || city_celebrating(pcity) || city_happy(pcity)
2447 || cma_is_city_under_agent(pcity, NULL))
2448 ^ ((sdl2_client_flags & CF_CITY_STATUS_SPECIAL) == CF_CITY_STATUS_SPECIAL)) {
2449 /* City status was changed : NORMAL <-> DISORDER, HAPPY, CELEBR. */
2450
2451 sdl2_client_flags ^= CF_CITY_STATUS_SPECIAL;
2452
2453#if 0
2454 /* Upd. resource map */
2455 FREESURFACE(pcity_dlg->resource_map->theme);
2456 pcity_dlg->resource_map->theme = get_scaled_city_map(pcity);
2457#endif
2458
2459 /* Upd. window title */
2460 rebuild_citydlg_title_str(pcity_dlg->end_city_widget_list, pcity);
2461 }
2462
2463 /* Update resource map */
2464 FREESURFACE(pcity_dlg->resource_map->theme);
2465 pcity_dlg->resource_map->theme = get_scaled_city_map(pcity);
2466
2467 /* Redraw city dlg */
2468 redraw_group(pcity_dlg->begin_city_widget_list,
2469 pcity_dlg->end_city_widget_list, 0);
2470
2471 /* ================================================================= */
2472 fc_snprintf(cbuf, sizeof(cbuf), _("City map"));
2473
2474 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
2475 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_GOLD);
2476 pstr->style |= TTF_STYLE_BOLD;
2477
2478 buf = create_text_surf_from_utf8(pstr);
2479
2480 dest.x = pwindow->size.x + adj_size(196) + (adj_size(132) - buf->w) / 2;
2481 dest.y = pwindow->size.y + adj_size(49) + (adj_size(13) - buf->h) / 2;
2482
2483 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2484
2485 FREESURFACE(buf);
2486
2487 fc_snprintf(cbuf, sizeof(cbuf), _("Citizens"));
2488
2489 copy_chars_to_utf8_str(pstr, cbuf);
2490 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_LUX);
2491
2492 buf = create_text_surf_from_utf8(pstr);
2493
2494 dest.x = pwindow->size.x + adj_size(344) + (adj_size(146) - buf->w) / 2;
2495 dest.y = pwindow->size.y + adj_size(47) + (adj_size(13) - buf->h) / 2;
2496
2497 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2498
2499 FREESURFACE(buf);
2500
2501 fc_snprintf(cbuf, sizeof(cbuf), _("City improvements"));
2502
2503 copy_chars_to_utf8_str(pstr, cbuf);
2504 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_GOLD);
2505
2506 buf = create_text_surf_from_utf8(pstr);
2507
2508 dest.x = pwindow->size.x + adj_size(504) + (adj_size(132) - buf->w) / 2;
2509 dest.y = pwindow->size.y + adj_size(49) + (adj_size(13) - buf->h) / 2;
2510
2511 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2512
2513 FREESURFACE(buf);
2514
2515 /* ================================================================= */
2516 /* Food label */
2517 fc_snprintf(cbuf, sizeof(cbuf), _("Food: %d per turn"),
2518 pcity->prod[O_FOOD]);
2519
2520 copy_chars_to_utf8_str(pstr, cbuf);
2521
2522 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_FOODPERTURN);
2523
2524 buf = create_text_surf_from_utf8(pstr);
2525
2526 dest.x = pwindow->size.x + adj_size(200);
2527 dest.y = pwindow->size.y + adj_size(228) + (adj_size(16) - buf->h) / 2;
2528
2529 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2530
2531 FREESURFACE(buf);
2532
2533 /* Draw food income */
2534 dest.y = pwindow->size.y + adj_size(246) + (adj_size(16) - icons->big_food->h) / 2;
2535 dest.x = pwindow->size.x + adj_size(203);
2536
2537 if (pcity->surplus[O_FOOD] >= 0) {
2538 count = pcity->prod[O_FOOD] - pcity->surplus[O_FOOD];
2539 } else {
2540 count = pcity->prod[O_FOOD];
2541 }
2542
2543 if (((icons->big_food->w + 1) * count) > adj_size(200)) {
2544 step = (adj_size(200) - icons->big_food->w) / (count - 1);
2545 } else {
2546 step = icons->big_food->w + 1;
2547 }
2548
2549 for (i = 0; i < count; i++) {
2550 alphablit(icons->big_food, NULL, pwindow->dst->surface, &dest, 255);
2551 dest.x += step;
2552 }
2553
2554 fc_snprintf(cbuf, sizeof(cbuf), Q_("?food:Surplus: %d"),
2555 pcity->surplus[O_FOOD]);
2556
2557 copy_chars_to_utf8_str(pstr, cbuf);
2558 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_FOOD_SURPLUS);
2559
2560 buf = create_text_surf_from_utf8(pstr);
2561
2562 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2563 dest.y = pwindow->size.y + adj_size(228) + (adj_size(16) - buf->h) / 2;
2564
2565 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2566
2567 FREESURFACE(buf);
2568
2569 /* Draw surplus of food */
2570 if (pcity->surplus[O_FOOD]) {
2571 if (pcity->surplus[O_FOOD] > 0) {
2572 count = pcity->surplus[O_FOOD];
2573 buf = icons->big_food;
2574 } else {
2575 count = -1 * pcity->surplus[O_FOOD];
2576 buf = icons->big_food_corr;
2577 }
2578
2579 dest.x = pwindow->size.x + adj_size(423);
2580 dest.y = pwindow->size.y + adj_size(246) + (adj_size(16) - buf->h) / 2;
2581
2582 if (count > 2) {
2583 if (count < 18) {
2584 step = (adj_size(30) - buf->w) / (count - 1);
2585 } else {
2586 step = 1;
2587 count = 17;
2588 }
2589 } else {
2590 step = buf->w + 1;
2591 }
2592
2593 for (i = 0; i < count; i++) {
2594 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2595 dest.x -= step;
2596 }
2597 }
2598
2599 /* ================================================================= */
2600 /* Productions label */
2601 fc_snprintf(cbuf, sizeof(cbuf), _("Production: %d (%d) per turn"),
2602 pcity->surplus[O_SHIELD],
2603 pcity->prod[O_SHIELD] + pcity->waste[O_SHIELD]);
2604
2605 copy_chars_to_utf8_str(pstr, cbuf);
2606 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PROD);
2607
2608 buf = create_text_surf_from_utf8(pstr);
2609
2610 dest.x = pwindow->size.x + adj_size(200);
2611 dest.y = pwindow->size.y + adj_size(263) + (adj_size(15) - buf->h) / 2;
2612
2613 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2614
2615 FREESURFACE(buf);
2616
2617 /* Draw productions shields */
2618 if (pcity->surplus[O_SHIELD]) {
2619
2620 if (pcity->surplus[O_SHIELD] > 0) {
2621 count = pcity->surplus[O_SHIELD] + pcity->waste[O_SHIELD];
2622 buf = icons->big_shield;
2623 } else {
2624 count = -1 * pcity->surplus[O_SHIELD];
2625 buf = icons->big_shield_corr;
2626 }
2627
2628 dest.y = pwindow->size.y + adj_size(281) + (adj_size(16) - buf->h) / 2;
2629 dest.x = pwindow->size.x + adj_size(203);
2630
2631 if ((buf->w * count) > adj_size(200)) {
2632 step = (adj_size(200) - buf->w) / (count - 1);
2633 } else {
2634 step = buf->w;
2635 }
2636
2637 for (i = 0; i < count; i++) {
2638 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2639 dest.x += step;
2640 if (i > pcity->surplus[O_SHIELD]) {
2641 buf = icons->big_shield_corr;
2642 }
2643 }
2644 }
2645
2646 /* Support shields label */
2647 fc_snprintf(cbuf, sizeof(cbuf), Q_("?production:Support: %d"),
2648 pcity->prod[O_SHIELD] + pcity->waste[O_SHIELD] -
2649 pcity->surplus[O_SHIELD]);
2650
2651 copy_chars_to_utf8_str(pstr, cbuf);
2652 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_SUPPORT);
2653
2654 buf = create_text_surf_from_utf8(pstr);
2655
2656 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2657 dest.y = pwindow->size.y + adj_size(263) + (adj_size(15) - buf->h) / 2;
2658
2659 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2660
2661 FREESURFACE(buf);
2662
2663 /* Draw support shields */
2664 if (pcity->prod[O_SHIELD] - pcity->surplus[O_SHIELD]) {
2665 dest.x = pwindow->size.x + adj_size(423);
2666 dest.y =
2667 pwindow->size.y + adj_size(281) + (adj_size(16) - icons->big_shield->h) / 2;
2668
2669 if ((icons->big_shield->w + 1) * (pcity->prod[O_SHIELD] -
2670 pcity->surplus[O_SHIELD]) > adj_size(30)) {
2671 step =
2672 (adj_size(30) - icons->big_food->w) / (pcity->prod[O_SHIELD] -
2673 pcity->surplus[O_SHIELD] - 1);
2674 } else {
2675 step = icons->big_shield->w + 1;
2676 }
2677
2678 for (i = 0; i < (pcity->prod[O_SHIELD] - pcity->surplus[O_SHIELD]); i++) {
2679 alphablit(icons->big_shield, NULL, pwindow->dst->surface, &dest, 255);
2680 dest.x -= step;
2681 }
2682 }
2683
2684 /* ================================================================= */
2685 /* Trade label */
2686 fc_snprintf(cbuf, sizeof(cbuf), _("Trade: %d per turn"),
2687 pcity->surplus[O_TRADE]);
2688
2689 copy_chars_to_utf8_str(pstr, cbuf);
2690 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_TRADE);
2691
2692 buf = create_text_surf_from_utf8(pstr);
2693
2694 dest.x = pwindow->size.x + adj_size(200);
2695 dest.y = pwindow->size.y + adj_size(298) + (adj_size(15) - buf->h) / 2;
2696
2697 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2698
2699 FREESURFACE(buf);
2700
2701 /* Draw total (trade - corruption) */
2702 if (pcity->surplus[O_TRADE]) {
2703 dest.y =
2704 pwindow->size.y + adj_size(316) + (adj_size(16) - icons->big_trade->h) / 2;
2705 dest.x = pwindow->size.x + adj_size(203);
2706
2707 if (((icons->big_trade->w + 1) * pcity->surplus[O_TRADE]) > adj_size(200)) {
2708 step = (adj_size(200) - icons->big_trade->w) / (pcity->surplus[O_TRADE] - 1);
2709 } else {
2710 step = icons->big_trade->w + 1;
2711 }
2712
2713 for (i = 0; i < pcity->surplus[O_TRADE]; i++) {
2714 alphablit(icons->big_trade, NULL, pwindow->dst->surface, &dest, 255);
2715 dest.x += step;
2716 }
2717 }
2718
2719 /* Corruption label */
2720 fc_snprintf(cbuf, sizeof(cbuf), _("Corruption: %d"),
2721 pcity->waste[O_TRADE]);
2722
2723 copy_chars_to_utf8_str(pstr, cbuf);
2724 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_CORRUPTION);
2725
2726 buf = create_text_surf_from_utf8(pstr);
2727
2728 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2729 dest.y = pwindow->size.y + adj_size(298) + (adj_size(15) - buf->h) / 2;
2730
2731 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2732
2733 FREESURFACE(buf);
2734
2735 /* Draw corruption */
2736 if (pcity->waste[O_TRADE] > 0) {
2737 dest.x = pwindow->size.x + adj_size(423);
2738 dest.y =
2739 pwindow->size.y + adj_size(316) + (adj_size(16) - icons->big_trade->h) / 2;
2740
2741 if (((icons->big_trade_corr->w + 1) * pcity->waste[O_TRADE]) > adj_size(30)) {
2742 step =
2743 (adj_size(30) - icons->big_trade_corr->w) / (pcity->waste[O_TRADE] - 1);
2744 } else {
2745 step = icons->big_trade_corr->w + 1;
2746 }
2747
2748 for (i = 0; i < pcity->waste[O_TRADE]; i++) {
2749 alphablit(icons->big_trade_corr, NULL, pwindow->dst->surface,
2750 &dest, 255);
2751 dest.x -= step;
2752 }
2753 }
2754
2755 /* ================================================================= */
2756 /* Gold label */
2757 fc_snprintf(cbuf, sizeof(cbuf), _("Gold: %d (%d) per turn"),
2758 pcity->surplus[O_GOLD], pcity->prod[O_GOLD]);
2759
2760 copy_chars_to_utf8_str(pstr, cbuf);
2761 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_GOLD);
2762
2763 buf = create_text_surf_from_utf8(pstr);
2764
2765 dest.x = pwindow->size.x + adj_size(200);
2766 dest.y = pwindow->size.y + adj_size(342) + (adj_size(15) - buf->h) / 2;
2767
2768 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2769
2770 FREESURFACE(buf);
2771
2772 /* Draw coins */
2773 count = pcity->surplus[O_GOLD];
2774 if (count) {
2775
2776 if (count > 0) {
2777 buf = icons->big_coin;
2778 } else {
2779 count *= -1;
2780 buf = icons->big_coin_corr;
2781 }
2782
2783 dest.y = pwindow->size.y + adj_size(359) + (adj_size(16) - buf->h) / 2;
2784 dest.x = pwindow->size.x + adj_size(203);
2785
2786 if ((buf->w * count) > adj_size(110)) {
2787 step = (adj_size(110) - buf->w) / (count - 1);
2788 if (!step) {
2789 step = 1;
2790 count = 97;
2791 }
2792 } else {
2793 step = buf->w;
2794 }
2795
2796 for (i = 0; i < count; i++) {
2797 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2798 dest.x += step;
2799 }
2800
2801 }
2802
2803 /* Upkeep label */
2804 fc_snprintf(cbuf, sizeof(cbuf), _("Upkeep: %d"),
2805 pcity->prod[O_GOLD] - pcity->surplus[O_GOLD]);
2806
2807 copy_chars_to_utf8_str(pstr, cbuf);
2808 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_UPKEEP);
2809
2810 buf = create_text_surf_from_utf8(pstr);
2811
2812 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2813 dest.y = pwindow->size.y + adj_size(342) + (adj_size(15) - buf->h) / 2;
2814
2815 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2816
2817 FREESURFACE(buf);
2818
2819 /* Draw upkeep */
2820 count = pcity->surplus[O_GOLD];
2821 if (pcity->prod[O_GOLD] - count) {
2822
2823 dest.x = pwindow->size.x + adj_size(423);
2824 dest.y = pwindow->size.y + adj_size(359)
2825 + (adj_size(16) - icons->big_coin_upkeep->h) / 2;
2826
2827 if (((icons->big_coin_upkeep->w + 1) *
2828 (pcity->prod[O_GOLD] - count)) > adj_size(110)) {
2829 step = (adj_size(110) - icons->big_coin_upkeep->w) /
2830 (pcity->prod[O_GOLD] - count - 1);
2831 } else {
2832 step = icons->big_coin_upkeep->w + 1;
2833 }
2834
2835 for (i = 0; i < (pcity->prod[O_GOLD] - count); i++) {
2836 alphablit(icons->big_coin_upkeep, NULL, pwindow->dst->surface,
2837 &dest, 255);
2838 dest.x -= step;
2839 }
2840 }
2841
2842 /* ================================================================= */
2843 /* Science label */
2844 fc_snprintf(cbuf, sizeof(cbuf), _("Science: %d per turn"),
2845 pcity->prod[O_SCIENCE]);
2846
2847 copy_chars_to_utf8_str(pstr, cbuf);
2848 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_SCIENCE);
2849
2850 buf = create_text_surf_from_utf8(pstr);
2851
2852 dest.x = pwindow->size.x + adj_size(200);
2853 dest.y = pwindow->size.y + adj_size(376) + (adj_size(15) - buf->h) / 2;
2854
2855 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2856
2857 FREESURFACE(buf);
2858
2859 /* Draw colb */
2860 count = pcity->prod[O_SCIENCE];
2861 if (count) {
2862
2863 dest.y =
2864 pwindow->size.y + adj_size(394) + (adj_size(16) - icons->big_colb->h) / 2;
2865 dest.x = pwindow->size.x + adj_size(203);
2866
2867 if ((icons->big_colb->w * count) > adj_size(235)) {
2868 step = (adj_size(235) - icons->big_colb->w) / (count - 1);
2869 if (!step) {
2870 step = 1;
2871 count = 222;
2872 }
2873 } else {
2874 step = icons->big_colb->w;
2875 }
2876
2877 for (i = 0; i < count; i++) {
2878 alphablit(icons->big_colb, NULL, pwindow->dst->surface, &dest, 255);
2879 dest.x += step;
2880 }
2881 }
2882
2883 /* ================================================================= */
2884 /* Luxury label */
2885 fc_snprintf(cbuf, sizeof(cbuf), _("Luxury: %d per turn"),
2886 pcity->prod[O_LUXURY]);
2887
2888 copy_chars_to_utf8_str(pstr, cbuf);
2889 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_LUX);
2890
2891 buf = create_text_surf_from_utf8(pstr);
2892
2893 dest.x = pwindow->size.x + adj_size(200);
2894 dest.y = pwindow->size.y + adj_size(412) + (adj_size(15) - buf->h) / 2;
2895
2896 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2897
2898 FREESURFACE(buf);
2899
2900 /* Draw luxury */
2901 if (pcity->prod[O_LUXURY]) {
2902
2903 dest.y =
2904 pwindow->size.y + adj_size(429) + (adj_size(16) - icons->big_luxury->h) / 2;
2905 dest.x = pwindow->size.x + adj_size(203);
2906
2907 if ((icons->big_luxury->w * pcity->prod[O_LUXURY]) > adj_size(235)) {
2908 step =
2909 (adj_size(235) - icons->big_luxury->w) / (pcity->prod[O_LUXURY] - 1);
2910 } else {
2911 step = icons->big_luxury->w;
2912 }
2913
2914 for (i = 0; i < pcity->prod[O_LUXURY]; i++) {
2915 alphablit(icons->big_luxury, NULL, pwindow->dst->surface, &dest, 255);
2916 dest.x += step;
2917 }
2918 }
2919
2920 /* ================================================================= */
2921 /* Turns to grow label */
2922 count = city_turns_to_grow(pcity);
2923 if (count == 0) {
2924 fc_snprintf(cbuf, sizeof(cbuf), _("City growth: blocked"));
2925 } else if (count == FC_INFINITY) {
2926 fc_snprintf(cbuf, sizeof(cbuf), _("City growth: never"));
2927 } else if (count < 0) {
2928 /* Turns until famine */
2929 fc_snprintf(cbuf, sizeof(cbuf),
2930 _("City shrinks: %d %s"), abs(count),
2931 PL_("turn", "turns", abs(count)));
2932 } else {
2933 fc_snprintf(cbuf, sizeof(cbuf),
2934 _("City growth: %d %s"), count,
2935 PL_("turn", "turns", count));
2936 }
2937
2938 copy_chars_to_utf8_str(pstr, cbuf);
2939
2940 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_GROWTH);
2941
2942 buf = create_text_surf_from_utf8(pstr);
2943
2944 dest.x = pwindow->size.x + adj_size(445) + (adj_size(192) - buf->w) / 2;
2945 dest.y = pwindow->size.y + adj_size(227);
2946
2947 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2948
2949 FREESURFACE(buf);
2950
2951 count = (city_granary_size(city_size_get(pcity))) / 10;
2952
2953 if (count > 12) {
2954 step = (adj_size(168) - icons->big_food->h) / adj_size((11 + count - 12));
2955 i = (count - 1) * step + 14;
2956 } else {
2957 step = icons->big_food->h;
2958 i = count * step;
2959 }
2960
2961 /* food stock */
2962
2963 if (get_city_bonus(pcity, EFT_GROWTH_FOOD) > 0) {
2964 /* with granary */
2965 /* stocks label */
2966 copy_chars_to_utf8_str(pstr, _("Stock"));
2967 buf = create_text_surf_from_utf8(pstr);
2968
2969 dest.x = pwindow->size.x + adj_size(461) + (adj_size(76) - buf->w) / 2;
2970 dest.y = pwindow->size.y + adj_size(258) - buf->h - 1;
2971
2972 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2973
2974 FREESURFACE(buf);
2975
2976 /* granary label */
2977 copy_chars_to_utf8_str(pstr, _("Granary"));
2978 buf = create_text_surf_from_utf8(pstr);
2979
2980 dest.x = pwindow->size.x + adj_size(549) + (adj_size(76) - buf->w) / 2;
2981 dest.y = pwindow->size.y + adj_size(258) - buf->h - 1;
2982
2983 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2984
2985 FREESURFACE(buf);
2986
2987 /* draw bcgd granary */
2988 dest.x = pwindow->size.x + adj_size(462);
2989 dest.y = pwindow->size.y + adj_size(260);
2990 dest.w = 70 + 4;
2991 dest.h = i + 4;
2992
2993 fill_rect_alpha(pwindow->dst->surface, &dest,
2994 get_theme_color(COLOR_THEME_CITYDLG_GRANARY));
2995
2996 create_frame(pwindow->dst->surface,
2997 dest.x - 1, dest.y - 1, dest.w, dest.h,
2998 get_theme_color(COLOR_THEME_CITYDLG_FRAME));
2999
3000 /* draw bcgd stocks*/
3001 dest.x = pwindow->size.x + adj_size(550);
3002 dest.y = pwindow->size.y + adj_size(260);
3003
3004 fill_rect_alpha(pwindow->dst->surface, &dest,
3005 get_theme_color(COLOR_THEME_CITYDLG_STOCKS));
3006
3007 create_frame(pwindow->dst->surface,
3008 dest.x - 1, dest.y - 1, dest.w, dest.h,
3009 get_theme_color(COLOR_THEME_CITYDLG_FRAME));
3010
3011 /* draw stocks icons */
3012 cost = city_granary_size(city_size_get(pcity));
3013 if (pcity->food_stock + pcity->surplus[O_FOOD] > cost) {
3014 count = cost;
3015 } else {
3016 if (pcity->surplus[O_FOOD] < 0) {
3017 count = pcity->food_stock;
3018 } else {
3019 count = pcity->food_stock + pcity->surplus[O_FOOD];
3020 }
3021 }
3022 cost /= 2;
3023
3024 if (pcity->surplus[O_FOOD] < 0) {
3025 limit = pcity->food_stock + pcity->surplus[O_FOOD];
3026 if (limit < 0) {
3027 limit = 0;
3028 }
3029 } else {
3030 limit = 0xffff;
3031 }
3032
3033 dest.x += 2;
3034 dest.y += 2;
3035 i = 0;
3036 buf = icons->big_food;
3037 while (count && cost) {
3038 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3039 dest.x += buf->w;
3040 count--;
3041 cost--;
3042 i++;
3043 if (dest.x > pwindow->size.x + adj_size(620)) {
3044 dest.x = pwindow->size.x + adj_size(552);
3045 dest.y += step;
3046 }
3047 if (i > limit - 1) {
3048 buf = icons->big_food_corr;
3049 } else {
3050 if (i > pcity->food_stock - 1) {
3051 buf = icons->big_food_surplus;
3052 }
3053 }
3054 }
3055 /* draw granary icons */
3056 dest.x = pwindow->size.x + adj_size(462) + adj_size(2);
3057 dest.y = pwindow->size.y + adj_size(260) + adj_size(2);
3058
3059 while (count) {
3060 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3061 dest.x += buf->w;
3062 count--;
3063 i++;
3064 if (dest.x > pwindow->size.x + adj_size(532)) {
3065 dest.x = pwindow->size.x + adj_size(464);
3066 dest.y += step;
3067 }
3068 if (i > limit - 1) {
3069 buf = icons->big_food_corr;
3070 } else {
3071 if (i > pcity->food_stock - 1) {
3072 buf = icons->big_food_surplus;
3073 }
3074 }
3075 }
3076
3077 } else {
3078 /* without granary */
3079 /* stocks label */
3080 copy_chars_to_utf8_str(pstr, _("Stock"));
3081 buf = create_text_surf_from_utf8(pstr);
3082
3083 dest.x = pwindow->size.x + adj_size(461) + (adj_size(144) - buf->w) / 2;
3084 dest.y = pwindow->size.y + adj_size(258) - buf->h - 1;
3085
3086 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3087 FREESURFACE(buf);
3088
3089 /* food stock */
3090
3091 /* draw bcgd */
3092 dest.x = pwindow->size.x + adj_size(462);
3093 dest.y = pwindow->size.y + adj_size(260);
3094 dest.w = adj_size(144);
3095 dest.h = i + adj_size(4);
3096
3097 fill_rect_alpha(pwindow->dst->surface, &dest,
3098 get_theme_color(COLOR_THEME_CITYDLG_FOODSTOCK));
3099
3100 create_frame(pwindow->dst->surface,
3101 dest.x - 1, dest.y - 1, dest.w, dest.h,
3102 get_theme_color(COLOR_THEME_CITYDLG_FRAME));
3103
3104 /* draw icons */
3105 cost = city_granary_size(city_size_get(pcity));
3106 if (pcity->food_stock + pcity->surplus[O_FOOD] > cost) {
3107 count = cost;
3108 } else {
3109 if (pcity->surplus[O_FOOD] < 0) {
3110 count = pcity->food_stock;
3111 } else {
3112 count = pcity->food_stock + pcity->surplus[O_FOOD];
3113 }
3114 }
3115
3116 if (pcity->surplus[O_FOOD] < 0) {
3117 limit = pcity->food_stock + pcity->surplus[O_FOOD];
3118 if (limit < 0) {
3119 limit = 0;
3120 }
3121 } else {
3122 limit = 0xffff;
3123 }
3124
3125 dest.x += adj_size(2);
3126 dest.y += adj_size(2);
3127 i = 0;
3128 buf = icons->big_food;
3129 while (count) {
3130 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3131 dest.x += buf->w;
3132 count--;
3133 i++;
3134 if (dest.x > pwindow->size.x + adj_size(602)) {
3135 dest.x = pwindow->size.x + adj_size(464);
3136 dest.y += step;
3137 }
3138 if (i > limit - 1) {
3139 buf = icons->big_food_corr;
3140 } else {
3141 if (i > pcity->food_stock - 1) {
3142 buf = icons->big_food_surplus;
3143 }
3144 }
3145 }
3146 }
3147 /* ================================================================= */
3148
3149 /* draw productions shields progress */
3150 if (VUT_UTYPE == pcity->production.kind) {
3151 const struct unit_type *punittype = pcity->production.value.utype;
3152
3153 cost = utype_build_shield_cost(pcity, NULL, punittype);
3154 count = cost / 10;
3155
3156 copy_chars_to_utf8_str(pstr, utype_name_translation(punittype));
3157 buf = create_text_surf_from_utf8(pstr);
3158
3159 buf2 = get_unittype_surface(punittype, direction8_invalid());
3160 buf2 = zoomSurface(buf2, DEFAULT_ZOOM * ((float)32 / buf2->h),
3161 DEFAULT_ZOOM * ((float)32 / buf2->h), 1);
3162
3163 /* blit unit icon */
3164 dest.x = pwindow->size.x + adj_size(6) + (adj_size(185) - (buf->w + buf2->w + adj_size(5))) / 2;
3165 dest.y = pwindow->size.y + adj_size(233);
3166
3167 alphablit(buf2, NULL, pwindow->dst->surface, &dest, 255);
3168
3169 dest.y += (buf2->h - buf->h) / 2;
3170 dest.x += buf2->w + adj_size(5);
3171
3172 } else {
3173 const struct impr_type *pimprove = pcity->production.value.building;
3174
3175 if (improvement_has_flag(pimprove, IF_GOLD)) {
3176
3177 if (pcity_dlg->buy_button
3178 && get_wstate(pcity_dlg->buy_button) != FC_WS_DISABLED) {
3179 set_wstate(pcity_dlg->buy_button, FC_WS_DISABLED);
3180 widget_redraw(pcity_dlg->buy_button);
3181 }
3182
3183 /* You can't see capitalization progress */
3184 count = 0;
3185
3186 } else {
3187
3188 if (city_can_buy(pcity) && pcity_dlg->buy_button
3189 && (get_wstate(pcity_dlg->buy_button) == FC_WS_DISABLED)) {
3190 set_wstate(pcity_dlg->buy_button, FC_WS_NORMAL);
3191 widget_redraw(pcity_dlg->buy_button);
3192 }
3193
3194 cost = impr_build_shield_cost(pcity, pimprove);
3195 count = cost / 10;
3196 }
3197
3198 copy_chars_to_utf8_str(pstr, improvement_name_translation(pimprove));
3199 buf = create_text_surf_from_utf8(pstr);
3200
3201 buf2 = get_building_surface(pcity->production.value.building);
3202 buf2 = zoomSurface(buf2, DEFAULT_ZOOM * ((float)32 / buf2->h),
3203 DEFAULT_ZOOM * ((float)32 / buf2->h), 1);
3204
3205 /* blit impr icon */
3206 dest.x = pwindow->size.x + adj_size(6) + (adj_size(185) - (buf->w + buf2->w + adj_size(5))) / 2;
3207 dest.y = pwindow->size.y + adj_size(233);
3208
3209 alphablit(buf2, NULL, pwindow->dst->surface, &dest, 255);
3210
3211 dest.y += (buf2->h - buf->h) / 2;
3212 dest.x += buf2->w + adj_size(5);
3213 }
3214
3215 /* blit unit/impr name */
3216 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3217
3218 FREESURFACE(buf);
3219 FREESURFACE(buf2);
3220
3221 if (count) {
3222 if (count > 11) {
3223 step = (adj_size(154) - icons->big_shield->h) / adj_size((10 + count - 11));
3224
3225 if (!step) {
3226 step = 1;
3227 }
3228
3229 i = (step * (count - 1)) + icons->big_shield->h;
3230 } else {
3231 step = icons->big_shield->h;
3232 i = count * step;
3233 }
3234
3235 /* draw shield stock background */
3236 dest.x = pwindow->size.x + adj_size(28);
3237 dest.y = pwindow->size.y + adj_size(270);
3238 dest.w = adj_size(144);
3239 dest.h = i + adj_size(4);
3240
3241 fill_rect_alpha(pwindow->dst->surface, &dest,
3242 get_theme_color(COLOR_THEME_CITYDLG_SHIELDSTOCK));
3243
3244 create_frame(pwindow->dst->surface,
3245 dest.x - 1, dest.y - 1, dest.w, dest.h,
3246 get_theme_color(COLOR_THEME_CITYDLG_FRAME));
3247
3248 /* draw production progress text */
3249 dest.y = pwindow->size.y + adj_size(270) + dest.h + 1;
3250
3251 if (pcity->shield_stock < cost) {
3252 count = city_production_turns_to_build(pcity, TRUE);
3253 if (count == 999) {
3254 fc_snprintf(cbuf, sizeof(cbuf), "(%d/%d) %s!",
3255 pcity->shield_stock, cost, _("blocked"));
3256 } else {
3257 fc_snprintf(cbuf, sizeof(cbuf), "(%d/%d) %d %s",
3258 pcity->shield_stock, cost, count, PL_("turn", "turns", count));
3259 }
3260 } else {
3261 fc_snprintf(cbuf, sizeof(cbuf), "(%d/%d) %s!",
3262 pcity->shield_stock, cost, _("finished"));
3263 }
3264
3265 copy_chars_to_utf8_str(pstr, cbuf);
3266 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_LUX);
3267
3268 buf = create_text_surf_from_utf8(pstr);
3269
3270 dest.x = pwindow->size.x + adj_size(6) + (adj_size(185) - buf->w) / 2;
3271
3272 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3273
3274 FREEUTF8STR(pstr);
3275 FREESURFACE(buf);
3276
3277 /* draw shield stock */
3278 if (pcity->shield_stock + pcity->surplus[O_SHIELD] <= cost) {
3279 count = pcity->shield_stock + pcity->surplus[O_SHIELD];
3280 } else {
3281 count = cost;
3282 }
3283 dest.x = pwindow->size.x + adj_size(29) + adj_size(2);
3284 dest.y = pwindow->size.y + adj_size(270) + adj_size(2);
3285 i = 0;
3286
3287 buf = icons->big_shield;
3288 while (count > 0) {
3289 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3290 dest.x += buf->w;
3291 count--;
3292 if (dest.x > pwindow->size.x + adj_size(170)) {
3293 dest.x = pwindow->size.x + adj_size(31);
3294 dest.y += step;
3295 }
3296 i++;
3297 if (i > pcity->shield_stock - 1) {
3298 buf = icons->big_shield_surplus;
3299 }
3300 }
3301 }
3302
3303 /* count != 0 */
3304 /* ==================================================== */
3305 /* Draw Citizens */
3306 count = (pcity->feel[CITIZEN_HAPPY][FEELING_FINAL] + pcity->feel[CITIZEN_CONTENT][FEELING_FINAL]
3307 + pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL] + pcity->feel[CITIZEN_ANGRY][FEELING_FINAL]
3308 + city_specialists(pcity));
3309
3310 buf = get_citizen_surface(CITIZEN_HAPPY, 0);
3311
3312 if (count > 13) {
3313 step = (adj_size(440) - buf->w) / (adj_size(12 + count - 13));
3314 } else {
3315 step = buf->w;
3316 }
3317
3318 pcity_dlg->citizen_step = step;
3319
3320 dest.x = pwindow->size.x + adj_size(198);
3321 dest.y = pwindow->size.y + pwindow->area.y + adj_size(1) + (adj_size(22) - buf->h) / 2;
3322 pcity_dlg->spec_area.x = pwindow->dst->dest_rect.x + dest.x;
3323 pcity_dlg->spec_area.y = pwindow->dst->dest_rect.y + dest.y;
3324 pcity_dlg->spec_area.w = count * step;
3325 pcity_dlg->spec_area.h = buf->h;
3326
3327 if (pcity->feel[CITIZEN_HAPPY][FEELING_FINAL]) {
3328 for (i = 0; i < pcity->feel[CITIZEN_HAPPY][FEELING_FINAL]; i++) {
3329 buf = adj_surf(get_citizen_surface(CITIZEN_HAPPY, i));
3330
3331 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3332 dest.x += step;
3333 FREESURFACE(buf);
3334 }
3335 }
3336
3337 if (pcity->feel[CITIZEN_CONTENT][FEELING_FINAL]) {
3338 for (i = 0; i < pcity->feel[CITIZEN_CONTENT][FEELING_FINAL]; i++) {
3339 buf = adj_surf(get_citizen_surface(CITIZEN_CONTENT, i));
3340
3341 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3342 dest.x += step;
3343 FREESURFACE(buf);
3344 }
3345 }
3346
3347 if (pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL]) {
3348 for (i = 0; i < pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL]; i++) {
3349 buf = adj_surf(get_citizen_surface(CITIZEN_UNHAPPY, i));
3350
3351 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3352 dest.x += step;
3353 FREESURFACE(buf);
3354 }
3355 }
3356
3357 if (pcity->feel[CITIZEN_ANGRY][FEELING_FINAL]) {
3358 for (i = 0; i < pcity->feel[CITIZEN_ANGRY][FEELING_FINAL]; i++) {
3359 buf = adj_surf(get_citizen_surface(CITIZEN_ANGRY, i));
3360
3361 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3362 dest.x += step;
3363 FREESURFACE(buf);
3364 }
3365 }
3366
3367 spe_max = specialist_count();
3368 for (spe = 0; spe < spe_max; spe++) {
3369 if (pcity->specialists[spe] > 0) {
3370 buf = adj_surf(get_citizen_surface(CITIZEN_SPECIALIST + spe, i));
3371
3372 for (i = 0; i < pcity->specialists[spe]; i++) {
3373 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3374 dest.x += step;
3375 }
3376 FREESURFACE(buf);
3377 }
3378 }
3379
3380 /* ==================================================== */
3381
3382
3383 switch (pcity_dlg->page) {
3384 case INFO_PAGE:
3385 redraw_info_city_dialog(pwindow, pcity);
3386 break;
3387
3388 case HAPPINESS_PAGE:
3389 redraw_happiness_city_dialog(pwindow, pcity);
3390 break;
3391
3392 case ARMY_PAGE:
3393 redraw_army_city_dialog(pwindow, pcity);
3394 break;
3395
3396 case SUPPORTED_UNITS_PAGE:
3397 redraw_supported_units_city_dialog(pwindow, pcity);
3398 break;
3399
3400 case MISC_PAGE:
3401 redraw_misc_city_dialog(pwindow, pcity);
3402 break;
3403
3404 default:
3405 break;
3406
3407 }
3408
3409 /* redraw "sell improvement" dialog */
3410 redraw_group(pcity_dlg->begin_city_menu_widget_list,
3411 pcity_dlg->end_city_menu_widget_list, 0);
3412
3413 widget_mark_dirty(pwindow);
3414}
3415
3416/* ============================================================== */
3417
3418/**********************************************************************/
3421 static void rebuild_imprm_list(struct city *pcity)
3422{
3423 int count = 0;
3424 struct widget *pwindow = pcity_dlg->end_city_widget_list;
3425 struct widget *add_dock, *buf, *last;
3426 SDL_Surface *logo = NULL;
3427 utf8_str *pstr = NULL;
3428 struct player *owner = city_owner(pcity);
3429 int prev_y = 0;
3430
3431 if (!pcity_dlg->imprv) {
3432 pcity_dlg->imprv = fc_calloc(1, sizeof(struct advanced_dialog));
3433 }
3434
3435 /* free old list */
3436 if (pcity_dlg->imprv->end_widget_list) {
3437 del_group_of_widgets_from_gui_list(pcity_dlg->imprv->begin_widget_list,
3438 pcity_dlg->imprv->end_widget_list);
3439 pcity_dlg->imprv->end_widget_list = NULL;
3440 pcity_dlg->imprv->begin_widget_list = NULL;
3441 pcity_dlg->imprv->end_active_widget_list = NULL;
3442 pcity_dlg->imprv->begin_active_widget_list = NULL;
3443 pcity_dlg->imprv->active_widget_list = NULL;
3444 FC_FREE(pcity_dlg->imprv->scroll);
3445 }
3446
3447 add_dock = pcity_dlg->add_point;
3448 buf = last = add_dock;
3449
3450 /* Alloc new */
3451 city_built_iterate(pcity, pimprove) {
3452 pstr = create_utf8_from_char_fonto(
3453 city_improvement_name_translation(pcity, pimprove),
3454 FONTO_DEFAULT);
3455 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_IMPR);
3456
3457 pstr->style |= TTF_STYLE_BOLD;
3458
3459 logo = get_building_surface(pimprove);
3460 logo = resize_surface_box(logo, adj_size(22), adj_size(22), 1, TRUE, TRUE);
3461
3462 buf = create_iconlabel(logo, pwindow->dst, pstr,
3463 (WF_FREE_THEME | WF_RESTORE_BACKGROUND));
3464
3465 buf->size.x = pwindow->size.x + adj_size(450);
3466 buf->size.y = pwindow->size.y + adj_size(66) + prev_y;
3467
3468 prev_y += buf->size.h;
3469
3470 buf->size.w = adj_size(165);
3471 buf->action = sell_imprvm_dlg_callback;
3472
3473 if (!pcity_dlg->pcity->did_sell
3474 && !is_wonder(pimprove) && (owner == client.conn.playing)) {
3475 set_wstate(buf, FC_WS_NORMAL);
3476 }
3477
3478 buf->id = MAX_ID - improvement_number(pimprove) - 3000;
3479 widget_add_as_prev(buf, add_dock);
3480 add_dock = buf;
3481
3482 count++;
3483
3484 if (count > 7) {
3485 set_wflag(buf, WF_HIDDEN);
3486 }
3487
3488 } city_built_iterate_end;
3489
3490 if (count) {
3491 pcity_dlg->imprv->end_widget_list = last->prev;
3492 pcity_dlg->imprv->end_active_widget_list = pcity_dlg->imprv->end_widget_list;
3493 pcity_dlg->imprv->begin_widget_list = buf;
3494 pcity_dlg->imprv->begin_active_widget_list = pcity_dlg->imprv->begin_widget_list;
3495
3496 if (count > 7) {
3497 pcity_dlg->imprv->active_widget_list = pcity_dlg->imprv->end_active_widget_list;
3498
3499 create_vertical_scrollbar(pcity_dlg->imprv, 1, 7, TRUE, TRUE);
3500
3501 setup_vertical_scrollbar_area(pcity_dlg->imprv->scroll,
3502 pwindow->size.x + adj_size(635),
3503 pwindow->size.y + adj_size(66),
3504 adj_size(155), TRUE);
3505 }
3506 }
3507}
3508
3509/**********************************************************************/
3512 static void rebuild_citydlg_title_str(struct widget *pwindow,
3513 struct city *pcity)
3514{
3515 char cbuf[512];
3516
3517 fc_snprintf(cbuf, sizeof(cbuf),
3518 _("City of %s (Population %s citizens)"),
3519 city_name_get(pcity),
3520 population_to_text(city_population(pcity)));
3521
3522 if (city_unhappy(pcity)) {
3523 /* TRANS: preserve leading space */
3524 fc_strlcat(cbuf, _(" - DISORDER"), sizeof(cbuf));
3525 } else {
3526 if (city_celebrating(pcity)) {
3527 /* TRANS: preserve leading space */
3528 fc_strlcat(cbuf, _(" - celebrating"), sizeof(cbuf));
3529 } else {
3530 if (city_happy(pcity)) {
3531 /* TRANS: preserve leading space */
3532 fc_strlcat(cbuf, _(" - happy"), sizeof(cbuf));
3533 }
3534 }
3535 }
3536
3537 if (cma_is_city_under_agent(pcity, NULL)) {
3538 /* TRANS: preserve leading space */
3539 fc_strlcat(cbuf, _(" - under Citizen Governor control."), sizeof(cbuf));
3540 }
3541
3542 copy_chars_to_utf8_str(pwindow->string_utf8, cbuf);
3543}
3544
3545
3546/* ========================= Public ================================== */
3547
3548/**********************************************************************/
3552 void real_city_dialog_popup(struct city *pcity)
3553{
3554 struct widget *pwindow = NULL, *buf = NULL;
3555 SDL_Surface *logo = NULL;
3556 utf8_str *pstr = NULL;
3557 int cs;
3558 struct player *owner = city_owner(pcity);
3559 SDL_Rect area;
3560
3561 if (pcity_dlg) {
3562 return;
3563 }
3564
3565 menus_update();
3566
3567 pcity_dlg = fc_calloc(1, sizeof(struct city_dialog));
3568 pcity_dlg->pcity = pcity;
3569 pcity_dlg->page = ARMY_PAGE;
3570
3571 pstr = create_utf8_str_fonto(NULL, 0, FONTO_ATTENTION);
3572 pstr->style |= TTF_STYLE_BOLD;
3573 pwindow = create_window(NULL, pstr, adj_size(640), adj_size(480), 0);
3574
3575 rebuild_citydlg_title_str(pwindow, pcity);
3576
3577 pwindow->action = city_dlg_callback;
3578 set_wstate(pwindow, FC_WS_NORMAL);
3579
3580 add_to_gui_list(ID_CITY_DLG_WINDOW, pwindow);
3581
3582 pcity_dlg->end_city_widget_list = pwindow;
3583
3584 /* create window background */
3585 logo = theme_get_background(active_theme, BACKGROUND_CITYDLG);
3586 if (resize_window(pwindow, logo, NULL, adj_size(640), adj_size(480))) {
3587 FREESURFACE(logo);
3588 }
3589
3590 logo = get_city_gfx();
3591 alphablit(logo, NULL, pwindow->theme, NULL, 255);
3592
3593 area = pwindow->area;
3594
3595 widget_set_position(pwindow,
3596 (main_window_width() - pwindow->size.w) / 2,
3597 (main_window_height() - pwindow->size.h) / 2);
3598
3599 /* ============================================================= */
3600
3601 /* Close dialog button */
3602 buf = create_themeicon(current_theme->small_cancel_icon, pwindow->dst,
3603 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3604 buf->info_label = create_utf8_from_char_fonto(_("Close Dialog (Esc)"),
3605 FONTO_ATTENTION);
3606 buf->action = exit_city_dlg_callback;
3607 buf->size.x = area.x + area.w - buf->size.w;
3608 buf->size.y = pwindow->size.y + adj_size(2);
3609 buf->key = SDLK_ESCAPE;
3610 set_wstate(buf, FC_WS_NORMAL);
3611 add_to_gui_list(ID_CITY_DLG_EXIT_BUTTON, buf);
3612
3613 /* -------- */
3614
3615 buf = create_themeicon(current_theme->army_icon, pwindow->dst,
3616 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3617 buf->info_label = create_utf8_from_char_fonto(_("Present units"),
3618 FONTO_ATTENTION);
3619 buf->action = army_city_dlg_callback;
3620 buf->size.x = area.x + adj_size(2) + ((adj_size(183) - 5 * buf->size.w) / 6);
3621 buf->size.y = area.y + adj_size(2);
3622 set_wstate(buf, FC_WS_NORMAL);
3623 add_to_gui_list(ID_CITY_DLG_ARMY_BUTTON, buf);
3624 /* -------- */
3625
3626 buf = create_themeicon(current_theme->support_icon, pwindow->dst,
3627 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3628 buf->info_label = create_utf8_from_char_fonto(_("Supported units"),
3629 FONTO_ATTENTION);
3630 buf->action = supported_unit_city_dlg_callback;
3631 buf->size.x =
3632 area.x + adj_size(2) + 2 * ((adj_size(183) - 5 * buf->size.w) / 6) + buf->size.w;
3633 buf->size.y = area.y + adj_size(2);
3634
3635 set_wstate(buf, FC_WS_NORMAL);
3636 add_to_gui_list(ID_CITY_DLG_SUPPORT_BUTTON, buf);
3637 /* -------- */
3638
3639 buf = create_themeicon(current_theme->happy_icon, pwindow->dst,
3640 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3641 buf->info_label = create_utf8_from_char_fonto(_("Happiness"),
3642 FONTO_ATTENTION);
3643 buf->action = happy_city_dlg_callback;
3644 buf->size.x
3645 = area.x + adj_size(2) + 3 * ((adj_size(183) - 5 * buf->size.w) / 6) + 2 * buf->size.w;
3646 buf->size.y = area.y + adj_size(2);
3647 set_wstate(buf, FC_WS_NORMAL);
3648 add_to_gui_list(ID_CITY_DLG_HAPPY_BUTTON, buf);
3649 /* -------- */
3650
3651 buf = create_themeicon(current_theme->info_icon, pwindow->dst,
3652 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3653 buf->info_label = create_utf8_from_char_fonto(_("City info"),
3654 FONTO_ATTENTION);
3655 buf->action = info_city_dlg_callback;
3656 buf->size.x
3657 = area.x + adj_size(4) + 4 * ((adj_size(183) - 5 * buf->size.w) / 6) + 3 * buf->size.w;
3658 buf->size.y = area.y + adj_size(2);
3659 set_wstate(buf, FC_WS_NORMAL);
3660 add_to_gui_list(ID_CITY_DLG_INFO_BUTTON, buf);
3661
3662 pcity_dlg->add_point = buf;
3663 pcity_dlg->begin_city_widget_list = buf;
3664 /* ===================================================== */
3665 rebuild_imprm_list(pcity);
3666 /* ===================================================== */
3667
3668 logo = get_scaled_city_map(pcity);
3669
3670 buf = create_themelabel(logo, pwindow->dst, NULL,
3671 logo->w, logo->h, WF_SELECT_WITHOUT_BAR);
3672
3673 pcity_dlg->resource_map = buf;
3674
3675 buf->action = resource_map_city_dlg_callback;
3676 if (!cma_is_city_under_agent(pcity, NULL) && (owner == client.conn.playing)) {
3677 set_wstate(buf, FC_WS_NORMAL);
3678 }
3679 buf->size.x = area.x + adj_size(193) + (adj_size(249) - buf->size.w) / 2;
3680 buf->size.y = area.y + adj_size(41) + (adj_size(158) - buf->size.h) / 2;
3681 add_to_gui_list(ID_CITY_DLG_RESOURCE_MAP, buf);
3682 /* -------- */
3683
3684 buf = create_themeicon(current_theme->options_icon, pwindow->dst,
3685 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3686 buf->info_label = create_utf8_from_char_fonto(_("City options"),
3687 FONTO_ATTENTION);
3688 buf->action = options_city_dlg_callback;
3689 buf->size.x
3690 = area.x + adj_size(4) + 5 * ((adj_size(183) - 5 * buf->size.w) / 6) + 4 * buf->size.w;
3691 buf->size.y = area.y + adj_size(2);
3692 if (owner == client.conn.playing) {
3693 set_wstate(buf, FC_WS_NORMAL);
3694 }
3695 add_to_gui_list(ID_CITY_DLG_OPTIONS_BUTTON, buf);
3696 /* -------- */
3697
3698 buf = create_themeicon(current_theme->prod_icon, pwindow->dst,
3699 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3700 buf->info_label = create_utf8_from_char_fonto(_("Change production"),
3701 FONTO_ATTENTION);
3702 buf->action = change_prod_dlg_callback;
3703 buf->size.x = area.x + adj_size(7);
3704 buf->size.y = area.y + area.h - buf->size.h - adj_size(5);
3705 if (owner == client.conn.playing) {
3706 set_wstate(buf, FC_WS_NORMAL);
3707 }
3708 buf->key = SDLK_c;
3709 add_to_gui_list(ID_CITY_DLG_CHANGE_PROD_BUTTON, buf);
3710 /* -------- */
3711
3712 buf = create_themeicon(current_theme->buy_prod_icon, pwindow->dst,
3713 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3714 buf->info_label = create_utf8_from_char_fonto(_("Hurry production"),
3715 FONTO_ATTENTION);
3716 buf->action = buy_prod_city_dlg_callback;
3717 buf->size.x = area.x + adj_size(7) + (buf->size.w + adj_size(2));
3718 buf->size.y = area.y + area.h - buf->size.h - adj_size(5);
3719 pcity_dlg->buy_button = buf;
3720 buf->key = SDLK_h;
3721 if (city_can_buy(pcity)) {
3722 set_wstate(buf, FC_WS_NORMAL);
3723 }
3724 add_to_gui_list(ID_CITY_DLG_PROD_BUY_BUTTON, buf);
3725 /* -------- */
3726
3727 buf = create_themeicon(current_theme->cma_icon, pwindow->dst,
3728 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3729 buf->info_label = create_utf8_from_char_fonto(_("Citizen Governor"),
3730 FONTO_ATTENTION);
3731 buf->action = cma_city_dlg_callback;
3732 buf->key = SDLK_a;
3733 buf->size.x = area.x + adj_size(7) + (buf->size.w + adj_size(2)) * 2;
3734 buf->size.y = area.y + area.h - buf->size.h - adj_size(5);
3735 if (owner == client.conn.playing) {
3736 set_wstate(buf, FC_WS_NORMAL);
3737 }
3738 add_to_gui_list(ID_CITY_DLG_CMA_BUTTON, buf);
3739
3740
3741 /* -------- */
3742 buf = create_themeicon(current_theme->l_arrow_icon, pwindow->dst,
3743 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3744 buf->info_label = create_utf8_from_char_fonto(_("Previous city"),
3745 FONTO_ATTENTION);
3746 buf->action = next_prev_city_dlg_callback;
3747 buf->size.x = area.x + adj_size(220) - buf->size.w - adj_size(8);
3748 buf->size.y = area.y + area.h - buf->size.h;
3749 if (owner == client.conn.playing) {
3750 set_wstate(buf, FC_WS_NORMAL);
3751 }
3752 buf->key = SDLK_LEFT;
3753 buf->mod = KMOD_LSHIFT;
3754 add_to_gui_list(ID_CITY_DLG_PREV_BUTTON, buf);
3755 /* -------- */
3756
3757 buf = create_themeicon(current_theme->r_arrow_icon, pwindow->dst,
3758 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3759 buf->info_label = create_utf8_from_char_fonto(_("Next city"),
3760 FONTO_ATTENTION);
3761 buf->action = next_prev_city_dlg_callback;
3762 buf->size.x = area.x + adj_size(420) + adj_size(2);
3763 buf->size.y = area.y + area.h - buf->size.h;
3764 if (owner == client.conn.playing) {
3765 set_wstate(buf, FC_WS_NORMAL);
3766 }
3767 buf->key = SDLK_RIGHT;
3768 buf->mod = KMOD_LSHIFT;
3769 add_to_gui_list(ID_CITY_DLG_NEXT_BUTTON, buf);
3770 /* -------- */
3771
3772 buf = create_edit_from_chars_fonto(NULL, pwindow->dst, city_name_get(pcity),
3773 FONTO_DEFAULT, adj_size(200),
3774 WF_RESTORE_BACKGROUND);
3775 buf->action = new_name_city_dlg_callback;
3776 buf->size.x = area.x + (area.w - buf->size.w) / 2;
3777 buf->size.y = area.y + area.h - buf->size.h - adj_size(2);
3778 if (owner == client.conn.playing) {
3779 set_wstate(buf, FC_WS_NORMAL);
3780 }
3781
3782 pcity_dlg->city_name_edit = buf;
3783 add_to_gui_list(ID_CITY_DLG_NAME_EDIT, buf);
3784
3785 pcity_dlg->begin_city_widget_list = buf;
3786
3787 /* check if Citizen Icons style was loaded */
3788 cs = style_of_city(pcity);
3789
3790 if (cs != icons->style) {
3791 reload_citizens_icons(cs);
3792 }
3793
3794 /* ===================================================== */
3795 if ((city_unhappy(pcity) || city_celebrating(pcity)
3796 || city_happy(pcity))) {
3797 sdl2_client_flags |= CF_CITY_STATUS_SPECIAL;
3798 }
3799 /* ===================================================== */
3800
3801 redraw_city_dialog(pcity);
3802 flush_dirty();
3803}
3804
3805/**********************************************************************/
3808 void popdown_city_dialog(struct city *pcity)
3809{
3810 if (city_dialog_is_open(pcity)) {
3811 del_city_dialog();
3812
3813 flush_dirty();
3814
3815 sdl2_client_flags &= ~CF_CITY_STATUS_SPECIAL;
3816 menus_update();
3817 }
3818}
3819
3820/**********************************************************************/
3823 void popdown_all_city_dialogs(void)
3824{
3825 if (pcity_dlg) {
3826 popdown_city_dialog(pcity_dlg->pcity);
3827 }
3828}
3829
3830/**********************************************************************/
3833 void real_city_dialog_refresh(struct city *pcity)
3834{
3835 if (city_dialog_is_open(pcity)) {
3836 redraw_city_dialog(pcity_dlg->pcity);
3837 flush_dirty();
3838 }
3839}
3840
3841/**********************************************************************/
3846 void refresh_unit_city_dialogs(struct unit *punit)
3847{
3848 struct city *city_sup = game_city_by_number(punit->homecity);
3849 struct city *city_pre = tile_city(unit_tile(punit));
3850
3851 if (pcity_dlg && ((pcity_dlg->pcity == city_sup)
3852 || (pcity_dlg->pcity == city_pre))) {
3853 free_city_units_lists();
3854 redraw_city_dialog(pcity_dlg->pcity);
3855 flush_dirty();
3856 }
3857}
3858
3859/**********************************************************************/
3862 bool city_dialog_is_open(struct city *pcity)
3863{
3864 return (pcity_dlg && (pcity_dlg->pcity == pcity));
3865}
action_id_name_translation
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1910
astr_free
void astr_free(struct astring *astr)
Definition astring.c:153
astring.h
astr_str
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
Definition astring.h:93
ASTRING_INIT
#define ASTRING_INIT
Definition astring.h:44
bitvector.h
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
BV_CLR
#define BV_CLR(bv, bit)
Definition bitvector.h:86
city_improvement_name_translation
const char * city_improvement_name_translation(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:658
city_granary_size
int city_granary_size(int city_size)
Definition city.c:2101
city_unit_unhappiness
int city_unit_unhappiness(struct unit *punit, int *free_unhappy)
Definition city.c:2940
city_name_get
const char * city_name_get(const struct city *pcity)
Definition city.c:1111
city_population
int city_population(const struct city *pcity)
Definition city.c:1165
city_production_turns_to_build
int city_production_turns_to_build(const struct city *pcity, bool include_shield_stock)
Definition city.c:805
city_unhappy
bool city_unhappy(const struct city *pcity)
Definition city.c:1595
city_celebrating
bool city_celebrating(const struct city *pcity)
Definition city.c:1614
city_illness_calc
int city_illness_calc(const struct city *pcity, int *ill_base, int *ill_size, int *ill_trade, int *ill_pollution)
Definition city.c:2769
city_happy
bool city_happy(const struct city *pcity)
Definition city.c:1583
city_map_radius_sq_get
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:132
city_specialists
citizens city_specialists(const struct city *pcity)
Definition city.c:3226
city_turns_to_grow
int city_turns_to_grow(const struct city *pcity)
Definition city.c:1965
city_production_name_translation
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:695
city_size_get
static citizens city_size_get(const struct city *pcity)
Definition city.h:549
CITIZEN_SPECIALIST
@ CITIZEN_SPECIALIST
Definition city.h:265
CITIZEN_ANGRY
@ CITIZEN_ANGRY
Definition city.h:263
CITIZEN_HAPPY
@ CITIZEN_HAPPY
Definition city.h:260
CITIZEN_CONTENT
@ CITIZEN_CONTENT
Definition city.h:261
CITIZEN_UNHAPPY
@ CITIZEN_UNHAPPY
Definition city.h:262
city_owner
#define city_owner(_pcity_)
Definition city.h:543
FEELING_FINAL
@ FEELING_FINAL
Definition city.h:276
FEELING_LAST
@ FEELING_LAST
Definition city.h:277
city_built_iterate
#define city_built_iterate(_pcity, _p)
Definition city.h:801
city_built_iterate_end
#define city_built_iterate_end
Definition city.h:807
city_rename
int city_rename(struct city *pcity, const char *name)
Definition citydlg_common.c:1577
city_buy_production
int city_buy_production(struct city *pcity)
Definition citydlg_common.c:1525
city_toggle_worker
int city_toggle_worker(struct city *pcity, int city_x, int city_y)
Definition citydlg_common.c:1545
city_rotate_specialist
void city_rotate_specialist(struct city *pcity, int citizen_index)
Definition citydlg_common.c:1212
canvas_to_city_pos
bool canvas_to_city_pos(int *city_x, int *city_y, int city_radius_sq, int canvas_x, int canvas_y)
Definition citydlg_common.c:115
city_sell_improvement
int city_sell_improvement(struct city *pcity, Impr_type_id sell_id)
Definition citydlg_common.c:1517
city_can_buy
bool city_can_buy(const struct city *pcity)
Definition citydlg_common.c:1497
trade_city
Definition menu.h:138
client
struct civclient client
Definition client_main.c:149
can_client_issue_orders
bool can_client_issue_orders(void)
Definition client_main.c:1265
client_main.h
client_player
#define client_player()
Definition client_main.h:106
get_nearest_city
struct city * get_nearest_city(const struct unit *punit, int *sq_dist)
Definition climisc.c:1101
climisc.h
cma_is_city_under_agent
bool cma_is_city_under_agent(const struct city *pcity, struct cm_parameter *parameter)
Definition cma_core.c:550
request_unit_fortify
void request_unit_fortify(struct unit *punit)
Definition control.c:2213
unit_focus_set
void unit_focus_set(struct unit *punit)
Definition control.c:502
request_unit_change_homecity
void request_unit_change_homecity(struct unit *punit)
Definition control.c:1994
request_unit_sentry
void request_unit_sentry(struct unit *punit)
Definition control.c:2202
control.h
can_unit_do_activity_client
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:40
punit
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:73
cost
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:73
id
int int id
Definition editgui_g.h:28
get_city_bonus
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:789
get_city_bonus_effects
int get_city_bonus_effects(struct effect_list *plist, const struct city *pcity, const struct output_type *poutput, enum effect_type effect_type)
Definition effects.c:1075
building_has_effect
bool building_has_effect(const struct impr_type *pimprove, enum effect_type effect_type)
Definition effects.c:587
effect_list_iterate_end
#define effect_list_iterate_end
Definition effects.h:375
effect_list_iterate
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:373
current_theme
QString current_theme
Definition fc_client.cpp:65
MAX_LEN_NAME
#define MAX_LEN_NAME
Definition fc_types.h:66
O_SHIELD
@ O_SHIELD
Definition fc_types.h:91
O_FOOD
@ O_FOOD
Definition fc_types.h:91
O_TRADE
@ O_TRADE
Definition fc_types.h:91
O_SCIENCE
@ O_SCIENCE
Definition fc_types.h:91
O_LUXURY
@ O_LUXURY
Definition fc_types.h:91
O_GOLD
@ O_GOLD
Definition fc_types.h:91
fcintl.h
Q_
#define Q_(String)
Definition fcintl.h:70
PL_
#define PL_(String1, String2, n)
Definition fcintl.h:71
_
#define _(String)
Definition fcintl.h:67
population_to_text
const char * population_to_text(int thousand_citizen)
Definition game.c:714
game
struct civ_game game
Definition game.c:57
game_city_by_number
struct city * game_city_by_number(int id)
Definition game.c:102
game.h
canvas_free
void canvas_free(struct canvas *store)
Definition canvas.c:44
canvas_create
struct canvas * canvas_create(int width, int height)
Definition canvas.c:28
real_city_dialog_popup
void real_city_dialog_popup(struct city *pcity)
Definition citydlg.c:558
city_dialog_is_open
bool city_dialog_is_open(struct city *pcity)
Definition citydlg.c:579
real_city_dialog_refresh
void real_city_dialog_refresh(struct city *pcity)
Definition citydlg.c:481
popdown_all_city_dialogs
void popdown_all_city_dialogs(void)
Definition citydlg.c:599
refresh_unit_city_dialogs
void refresh_unit_city_dialogs(struct unit *punit)
Definition citydlg.c:538
owner
struct city * owner
Definition citydlg.c:219
HAPPINESS_PAGE
@ HAPPINESS_PAGE
Definition citydlg.c:111
popdown_city_dialog
void popdown_city_dialog(struct city *pcity)
Definition citydlg.c:587
flush_dirty
void flush_dirty(void)
Definition mapview.c:450
units_orders_city_dlg_callback
static int units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:386
redraw_supported_units_city_dialog
static void redraw_supported_units_city_dialog(struct widget *city_window, struct city *pcity)
Definition citydlg.c:1822
activate_and_exit_units_orders_city_dlg_callback
static int activate_and_exit_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:274
cancel_buy_prod_city_dlg_callback
static int cancel_buy_prod_city_dlg_callback(struct widget *button)
Definition citydlg.c:1092
units_orders_dlg_callback
static int units_orders_dlg_callback(struct widget *button)
Definition citydlg.c:378
options_city_dlg_callback
static int options_city_dlg_callback(struct widget *button)
Definition citydlg.c:1041
redraw_city_dialog
static void redraw_city_dialog(struct city *pcity)
Definition citydlg.c:2433
army_city_dlg_callback
static int army_city_dlg_callback(struct widget *button)
Definition citydlg.c:831
rebuild_imprm_list
static void rebuild_imprm_list(struct city *pcity)
Definition citydlg.c:3421
redraw_happiness_city_dialog
static void redraw_happiness_city_dialog(const struct widget *city_window, struct city *pcity)
Definition citydlg.c:2102
redraw_misc_city_dialog
static void redraw_misc_city_dialog(struct widget *city_window, struct city *pcity)
Definition citydlg.c:1787
redraw_info_city_dialog
static void redraw_info_city_dialog(struct widget *city_window, struct city *pcity)
Definition citydlg.c:1936
new_name_city_dlg_callback
static int new_name_city_dlg_callback(struct widget *pedit)
Definition citydlg.c:1742
sell_imprvm_dlg_cancel_callback
static int sell_imprvm_dlg_cancel_callback(struct widget *cancel_button)
Definition citydlg.c:1372
next_prev_city_dlg_callback
static int next_prev_city_dlg_callback(struct widget *button)
Definition citydlg.c:1668
disable_city_dlg_widgets
static void disable_city_dlg_widgets(void)
Definition citydlg.c:1597
sell_imprvm_dlg_ok_callback
static int sell_imprvm_dlg_ok_callback(struct widget *ok_button)
Definition citydlg.c:1389
create_unit_surface
static SDL_Surface * create_unit_surface(struct unit *punit, bool support, int w, int h)
Definition citydlg.c:619
resource_map_city_dlg_callback
static int resource_map_city_dlg_callback(struct widget *map)
Definition citydlg.c:1633
refresh_city_names
static void refresh_city_names(struct city *pcity)
Definition citydlg.c:1767
enable_city_dlg_widgets
void enable_city_dlg_widgets(void)
Definition citydlg.c:1534
buy_prod_city_dlg_callback
static int buy_prod_city_dlg_callback(struct widget *button)
Definition citydlg.c:1135
upgrade_units_orders_city_dlg_callback
static int upgrade_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:363
fortify_units_orders_city_dlg_callback
static int fortify_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:314
redraw_army_city_dialog
static void redraw_army_city_dialog(struct widget *city_window, struct city *pcity)
Definition citydlg.c:1879
popdown_hurry_production_dialog
static void popdown_hurry_production_dialog(void)
Definition citydlg.c:1150
change_prod_dlg_callback
static int change_prod_dlg_callback(struct widget *button)
Definition citydlg.c:1352
specialist_type
specialist_type
Definition citydlg.c:109
SP_SCIENTIST
@ SP_SCIENTIST
Definition citydlg.c:110
SP_LAST
@ SP_LAST
Definition citydlg.c:110
SP_ELVIS
@ SP_ELVIS
Definition citydlg.c:110
SP_TAXMAN
@ SP_TAXMAN
Definition citydlg.c:110
get_building_for_effect
struct impr_type * get_building_for_effect(enum effect_type effect_type)
Definition citydlg.c:132
popup_hurry_production_dialog
void popup_hurry_production_dialog(struct city *pcity, SDL_Surface *pdest)
Definition citydlg.c:1175
create_city_options_widget_list
static void create_city_options_widget_list(struct city *pcity)
Definition citydlg.c:977
supported_unit_city_dlg_callback
static int supported_unit_city_dlg_callback(struct widget *button)
Definition citydlg.c:851
city_comp_by_turn_founded
static int city_comp_by_turn_founded(const void *a, const void *b)
Definition citydlg.c:1657
activate_units_orders_city_dlg_callback
static int activate_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:257
popdown_city_menu_dlg
static void popdown_city_menu_dlg(bool enable_city_dialog_widgets)
Definition citydlg.c:146
hurry_prog_dlg
static struct small_dialog * hurry_prog_dlg
Definition citydlg.c:115
hurry_production_window_callback
static int hurry_production_window_callback(struct widget *pwindow)
Definition citydlg.c:1163
del_city_dialog
static void del_city_dialog(void)
Definition citydlg.c:162
ok_buy_prod_city_dlg_callback
static int ok_buy_prod_city_dlg_callback(struct widget *button)
Definition citydlg.c:1109
cancel_units_orders_city_dlg_callback
static int cancel_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:239
rebuild_citydlg_title_str
static void rebuild_citydlg_title_str(struct widget *pwindow, struct city *pcity)
Definition citydlg.c:3512
cma_city_dlg_callback
static int cma_city_dlg_callback(struct widget *button)
Definition citydlg.c:1063
homecity_units_orders_city_dlg_callback
static int homecity_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:346
sentry_units_orders_city_dlg_callback
static int sentry_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:297
pcity_dlg
static struct city_dialog * pcity_dlg
exit_city_dlg_callback
static int exit_city_dlg_callback(struct widget *button)
Definition citydlg.c:1076
sell_imprvm_dlg_callback
static int sell_imprvm_dlg_callback(struct widget *impr)
Definition citydlg.c:1423
info_city_dlg_callback
static int info_city_dlg_callback(struct widget *button)
Definition citydlg.c:873
disband_units_orders_city_dlg_callback
static int disband_units_orders_city_dlg_callback(struct widget *button)
Definition citydlg.c:331
happy_city_dlg_callback
static int happy_city_dlg_callback(struct widget *button)
Definition citydlg.c:894
city_dlg_callback
static int city_dlg_callback(struct widget *pwindow)
Definition citydlg.c:199
city_map_zoom
static float city_map_zoom
Definition citydlg.c:113
get_scaled_city_map
SDL_Surface * get_scaled_city_map(struct city *pcity)
Definition citydlg.c:1619
misc_panel_city_dlg_callback
static int misc_panel_city_dlg_callback(struct widget *pwidget)
Definition citydlg.c:914
free_city_units_lists
void free_city_units_lists(void)
Definition citydlg.c:818
create_present_supported_units_widget_list
static void create_present_supported_units_widget_list(struct unit_list *units)
Definition citydlg.c:705
is_city_report_open
bool is_city_report_open(void)
Definition cityrep.c:1130
popup_city_cma_dialog
void popup_city_cma_dialog(struct city *pcity)
Definition cma_fe.c:891
cma_fe.h
get_theme_color
SDL_Color * get_theme_color(enum theme_color themecolor)
Definition colors.c:44
put_window_near_map_tile
void put_window_near_map_tile(struct widget *pwindow, int window_width, int window_height, struct tile *ptile)
Definition dialogs.c:108
popup_unit_disband_dlg
void popup_unit_disband_dlg(struct unit *punit, bool city)
Definition dialogs.c:875
popup_unit_upgrade_dlg
void popup_unit_upgrade_dlg(struct unit *punit, bool city)
Definition dialogs.c:680
get_smaller_surface_rect
SDL_Rect get_smaller_surface_rect(SDL_Surface *surf)
Definition graphics.c:936
is_in_rect_area
bool is_in_rect_area(int x, int y, SDL_Rect rect)
Definition graphics.c:925
main_window_width
int main_window_width(void)
Definition graphics.c:685
fill_rect_alpha
int fill_rect_alpha(SDL_Surface *surf, SDL_Rect *prect, SDL_Color *pcolor)
Definition graphics.c:865
create_line
void create_line(SDL_Surface *dest, Sint16 x0, Sint16 y0, Sint16 x1, Sint16 y1, SDL_Color *pcolor)
Definition graphics.c:1378
alphablit
int alphablit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:199
main_data
struct sdl2_data main_data
Definition graphics.c:57
create_surf
SDL_Surface * create_surf(int width, int height, Uint32 flags)
Definition graphics.c:351
create_frame
void create_frame(SDL_Surface *dest, Sint16 left, Sint16 top, Sint16 width, Sint16 height, SDL_Color *pcolor)
Definition graphics.c:1347
main_window_height
int main_window_height(void)
Definition graphics.c:693
resize_surface_box
SDL_Surface * resize_surface_box(const SDL_Surface *psrc, Uint16 new_width, Uint16 new_height, int smooth, bool scale_up, bool absolute_dimensions)
Definition graphics.c:1256
DEFAULT_ZOOM
#define DEFAULT_ZOOM
Definition graphics.h:198
FREESURFACE
#define FREESURFACE(ptr)
Definition graphics.h:322
adj_surf
#define adj_surf(surf)
Definition graphics.h:200
sdl2_client_flags
Uint32 sdl2_client_flags
Definition gui_main.c:97
CF_CHANGED_CITY_NAME
#define CF_CHANGED_CITY_NAME
Definition gui_main.h:50
selected_widget
struct widget * selected_widget
Definition widget.c:48
CF_CITY_STATUS_SPECIAL
#define CF_CITY_STATUS_SPECIAL
Definition gui_main.h:51
adj_size
#define adj_size(size)
Definition gui_main.h:138
PRESSED_EVENT
#define PRESSED_EVENT(event)
Definition gui_main.h:68
create_city_map
SDL_Surface * create_city_map(struct city *pcity)
Definition mapview.c:1196
popup_worklist_editor
void popup_worklist_editor(struct city *pcity, struct global_worklist *gwl)
Definition wldlg.c:1050
citydlg.h
cityrep.h
colors.h
dialogs.h
graphics.h
gui_main.h
mapview.h
menu.h
sprite.h
wldlg.h
gui_id.h
ID_CITY_DLG_HAPPY_BUTTON
@ ID_CITY_DLG_HAPPY_BUTTON
Definition gui_id.h:151
ID_CITY_DLG_CHANGE_PROD_BUTTON
@ ID_CITY_DLG_CHANGE_PROD_BUTTON
Definition gui_id.h:160
ID_CITY_DLG_PROD_BUY_BUTTON
@ ID_CITY_DLG_PROD_BUY_BUTTON
Definition gui_id.h:162
ID_CITY_DLG_WINDOW
@ ID_CITY_DLG_WINDOW
Definition gui_id.h:146
ID_CITY_DLG_RESOURCE_MAP
@ ID_CITY_DLG_RESOURCE_MAP
Definition gui_id.h:159
ID_CITY_DLG_CMA_BUTTON
@ ID_CITY_DLG_CMA_BUTTON
Definition gui_id.h:163
ID_CITY_DLG_NEXT_BUTTON
@ ID_CITY_DLG_NEXT_BUTTON
Definition gui_id.h:165
ID_BUTTON
@ ID_BUTTON
Definition gui_id.h:29
ID_CITY_DLG_OPTIONS_BUTTON
@ ID_CITY_DLG_OPTIONS_BUTTON
Definition gui_id.h:167
ID_CITY_DLG_NAME_EDIT
@ ID_CITY_DLG_NAME_EDIT
Definition gui_id.h:166
ID_CITY_DLG_SUPPORT_BUTTON
@ ID_CITY_DLG_SUPPORT_BUTTON
Definition gui_id.h:153
ID_LABEL
@ ID_LABEL
Definition gui_id.h:27
ID_CITY_DLG_ARMY_BUTTON
@ ID_CITY_DLG_ARMY_BUTTON
Definition gui_id.h:152
ID_WINDOW
@ ID_WINDOW
Definition gui_id.h:30
ID_REVOLUTION_DLG_WINDOW
@ ID_REVOLUTION_DLG_WINDOW
Definition gui_id.h:141
ID_CITY_DLG_EXIT_BUTTON
@ ID_CITY_DLG_EXIT_BUTTON
Definition gui_id.h:147
ID_CITY_DLG_INFO_BUTTON
@ ID_CITY_DLG_INFO_BUTTON
Definition gui_id.h:150
ID_CITY_DLG_PREV_BUTTON
@ ID_CITY_DLG_PREV_BUTTON
Definition gui_id.h:164
copy_chars_to_utf8_str
utf8_str * copy_chars_to_utf8_str(utf8_str *pstr, const char *pchars)
Definition gui_string.c:251
create_text_surf_from_utf8
SDL_Surface * create_text_surf_from_utf8(utf8_str *pstr)
Definition gui_string.c:425
change_fonto_utf8
void change_fonto_utf8(utf8_str *pstr, enum font_origin origin)
Definition gui_string.c:584
create_utf8_str_fonto
utf8_str * create_utf8_str_fonto(char *in_text, size_t n_alloc, enum font_origin origin)
Definition gui_string.c:241
FREEUTF8STR
#define FREEUTF8STR(pstr)
Definition gui_string.h:92
SF_CENTER
#define SF_CENTER
Definition gui_string.h:40
FONTO_DEFAULT
@ FONTO_DEFAULT
Definition gui_string.h:64
FONTO_SLIGHTLY_BIGGER
@ FONTO_SLIGHTLY_BIGGER
Definition gui_string.h:65
FONTO_ATTENTION
@ FONTO_ATTENTION
Definition gui_string.h:66
create_utf8_from_char_fonto
#define create_utf8_from_char_fonto(string_in, fonto)
Definition gui_string.h:107
icons
struct city_icon * icons
Definition gui_tilespec.c:55
reload_citizens_icons
void reload_citizens_icons(int style)
Definition gui_tilespec.c:126
get_city_gfx
SDL_Surface * get_city_gfx(void)
Definition gui_tilespec.c:477
gui_tilespec.h
get_building_surface
static SDL_Surface * get_building_surface(const struct impr_type *pimprove)
Definition gui_tilespec.h:252
get_citizen_surface
static SDL_Surface * get_citizen_surface(enum citizen_category type, int citizen_index)
Definition gui_tilespec.h:219
get_tax_surface
static SDL_Surface * get_tax_surface(Output_type_id otype)
Definition gui_tilespec.h:269
get_unittype_surface
static SDL_Surface * get_unittype_surface(const struct unit_type *punittype, enum direction8 facing)
Definition gui_tilespec.h:260
improvement_by_number
struct impr_type * improvement_by_number(const Impr_type_id id)
Definition improvement.c:192
impr_sell_gold
int impr_sell_gold(const struct impr_type *pimprove)
Definition improvement.c:332
can_city_sell_building
bool can_city_sell_building(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:1072
improvement_number
Impr_type_id improvement_number(const struct impr_type *pimprove)
Definition improvement.c:182
impr_build_shield_cost
int impr_build_shield_cost(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:292
is_wonder
bool is_wonder(const struct impr_type *pimprove)
Definition improvement.c:341
improvement_has_flag
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
Definition improvement.c:381
improvement_name_translation
const char * improvement_name_translation(const struct impr_type *pimprove)
Definition improvement.c:241
improvement_iterate_end
#define improvement_iterate_end
Definition improvement.h:211
improvement_iterate
#define improvement_iterate(_p)
Definition improvement.h:205
name
const char * name
Definition inputfile.c:127
log.h
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
put_unit
void put_unit(const struct unit *punit, struct canvas *pcanvas, float zoom, int canvas_x, int canvas_y)
Definition mapview_common.c:1374
center_tile_mapcanvas
void center_tile_mapcanvas(const struct tile *ptile)
Definition mapview_common.c:1222
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
menus_update
void menus_update(void)
Definition update_queue.c:562
move_points_text
const char * move_points_text(int mp, bool reduce)
Definition movement.c:973
movement.h
dsend_packet_city_options_req
int dsend_packet_city_options_req(struct connection *pc, int city_id16, int city_id32, bv_city_options options)
Definition packets_gen.c:29671
player_unit_by_number
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1205
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:93
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:91
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
MIN
#define MIN(x, y)
Definition shared.h:55
FC_INFINITY
#define FC_INFINITY
Definition shared.h:36
MAX
#define MAX(x, y)
Definition shared.h:54
specialist_count
Specialist_type_id specialist_count(void)
Definition specialist.c:71
specialist.h
step
int step
Definition specpq.h:92
size
size_t size
Definition specvec.h:72
advanced_dialog
Definition widget.h:180
advanced_dialog::active_widget_list
struct widget * active_widget_list
Definition widget.h:186
advanced_dialog::end_widget_list
struct widget * end_widget_list
Definition widget.h:182
advanced_dialog::begin_widget_list
struct widget * begin_widget_list
Definition widget.h:181
advanced_dialog::begin_active_widget_list
struct widget * begin_active_widget_list
Definition widget.h:184
advanced_dialog::end_active_widget_list
struct widget * end_active_widget_list
Definition widget.h:185
advanced_dialog::scroll
struct scroll_bar * scroll
Definition widget.h:187
astring
Definition astring.h:36
canvas
Definition canvas.h:21
canvas::surf
SDL_Surface * surf
Definition canvas.h:27
city_dialog
Definition citydlg.c:136
city_dialog::resource_map
struct widget * resource_map
Definition citydlg.c:99
city_dialog::city_name_edit
struct widget * city_name_edit
Definition citydlg.c:100
city_dialog::add_point
struct widget * add_point
Definition citydlg.c:97
city_dialog::citizen_step
int citizen_step
Definition citydlg.c:102
city_dialog::page
enum city_dialog::@211 page
city_dialog::lock
bool lock
Definition citydlg.c:106
city_dialog::pcity
struct city * pcity
Definition citydlg.c:137
city_dialog::spec_area
SDL_Rect spec_area
Definition citydlg.c:104
city_dialog::begin_city_widget_list
struct widget * begin_city_widget_list
Definition citydlg.c:83
city_dialog::buy_button
struct widget * buy_button
Definition citydlg.c:98
city_dialog::buy_button
QPushButton * buy_button
Definition citydlg.h:477
city_dialog::panel
struct advanced_dialog * panel
Definition citydlg.c:90
city_dialog::end_city_menu_widget_list
struct widget * end_city_menu_widget_list
Definition citydlg.c:94
city_dialog::imprv
struct advanced_dialog * imprv
Definition citydlg.c:87
city_dialog::begin_city_menu_widget_list
struct widget * begin_city_menu_widget_list
Definition citydlg.c:93
city_dialog::HAPPINESS_PAGE
@ HAPPINESS_PAGE
Definition citydlg.c:76
city_dialog::ARMY_PAGE
@ ARMY_PAGE
Definition citydlg.c:77
city_dialog::SUPPORTED_UNITS_PAGE
@ SUPPORTED_UNITS_PAGE
Definition citydlg.c:78
city_dialog::INFO_PAGE
@ INFO_PAGE
Definition citydlg.c:75
city_dialog::MISC_PAGE
@ MISC_PAGE
Definition citydlg.c:79
city_dialog::end_city_widget_list
struct widget * end_city_widget_list
Definition citydlg.c:84
city_icon::coint
SDL_Surface * coint
Definition gui_tilespec.h:171
city_icon::police
SDL_Surface * police
Definition gui_tilespec.h:177
city_icon::shield
SDL_Surface * shield
Definition gui_tilespec.h:168
city_icon::male_angry
SDL_Surface * male_angry
Definition gui_tilespec.h:187
city_icon::big_colb
SDL_Surface * big_colb
Definition gui_tilespec.h:160
city_icon::big_coin
SDL_Surface * big_coin
Definition gui_tilespec.h:159
city_icon::female_angry
SDL_Surface * female_angry
Definition gui_tilespec.h:188
city_icon::big_food_corr
SDL_Surface * big_food_corr
Definition gui_tilespec.h:152
city_icon::big_shield_corr
SDL_Surface * big_shield_corr
Definition gui_tilespec.h:153
city_icon::big_coin_corr
SDL_Surface * big_coin_corr
Definition gui_tilespec.h:162
city_icon::specialists
SDL_Surface * specialists[SP_MAX]
Definition gui_tilespec.h:190
city_icon::big_food_surplus
SDL_Surface * big_food_surplus
Definition gui_tilespec.h:165
city_icon::female_happy
SDL_Surface * female_happy
Definition gui_tilespec.h:182
city_icon::big_trade
SDL_Surface * big_trade
Definition gui_tilespec.h:157
city_icon::female_content
SDL_Surface * female_content
Definition gui_tilespec.h:184
city_icon::big_coin_upkeep
SDL_Surface * big_coin_upkeep
Definition gui_tilespec.h:163
city_icon::trade
SDL_Surface * trade
Definition gui_tilespec.h:169
city_icon::big_luxury
SDL_Surface * big_luxury
Definition gui_tilespec.h:158
city_icon::food
SDL_Surface * food
Definition gui_tilespec.h:167
city_icon::style
int style
Definition gui_tilespec.h:150
city_icon::female_unhappy
SDL_Surface * female_unhappy
Definition gui_tilespec.h:186
city_icon::male_content
SDL_Surface * male_content
Definition gui_tilespec.h:183
city_icon::face
SDL_Surface * face
Definition gui_tilespec.h:173
city_icon::male_happy
SDL_Surface * male_happy
Definition gui_tilespec.h:181
city_icon::big_shield
SDL_Surface * big_shield
Definition gui_tilespec.h:156
city_icon::big_shield_surplus
SDL_Surface * big_shield_surplus
Definition gui_tilespec.h:164
city_icon::male_unhappy
SDL_Surface * male_unhappy
Definition gui_tilespec.h:185
city_icon::big_trade_corr
SDL_Surface * big_trade_corr
Definition gui_tilespec.h:154
city_icon::big_food
SDL_Surface * big_food
Definition gui_tilespec.h:155
city_icon::pollution
SDL_Surface * pollution
Definition gui_tilespec.h:176
city
Definition city.h:309
city::surplus
int surplus[O_LAST]
Definition city.h:343
city::food_stock
int food_stock
Definition city.h:354
city::pollution
int pollution
Definition city.h:356
city::did_sell
bool did_sell
Definition city.h:367
city::id
int id
Definition city.h:315
city::waste
int waste[O_LAST]
Definition city.h:344
city::info_units_present
struct unit_list * info_units_present
Definition city.h:457
city::city_options
bv_city_options city_options
Definition city.h:389
city::owner
struct player * owner
Definition city.h:312
city::turn_founded
int turn_founded
Definition city.h:372
city::did_buy
bool did_buy
Definition city.h:366
city::info_units_supported
struct unit_list * info_units_supported
Definition city.h:456
city::name
char * name
Definition city.h:310
city::production
struct universal production
Definition city.h:382
city::buy_cost
int buy_cost
Definition city.h:449
city::feel
citizens feel[CITIZEN_LAST][FEELING_LAST]
Definition city.h:321
city::specialists
citizens specialists[SP_MAX]
Definition city.h:324
city::tile
struct tile * tile
Definition city.h:311
city::shield_stock
int shield_stock
Definition city.h:355
city::prod
int prod[O_LAST]
Definition city.h:346
city::units_supported
struct unit_list * units_supported
Definition city.h:391
city::client
struct city::@17::@20 client
civ_game::info
struct packet_game_info info
Definition game.h:89
civclient::conn
struct connection conn
Definition client_main.h:96
connection::playing
struct player * playing
Definition connection.h:156
gui_layer::surface
SDL_Surface * surface
Definition graphics.h:229
gui_layer::dest_rect
SDL_Rect dest_rect
Definition graphics.h:228
impr_type
Definition improvement.h:68
packet_game_info::illness_on
bool illness_on
Definition packets_gen.h:181
player
Definition player.h:249
player::cities
struct city_list * cities
Definition player.h:281
scroll_bar::up_left_button
struct widget * up_left_button
Definition widget_scrollbar.h:21
scroll_bar::pscroll_bar
struct widget * pscroll_bar
Definition widget_scrollbar.h:22
scroll_bar::down_right_button
struct widget * down_right_button
Definition widget_scrollbar.h:23
sdl2_data::event
SDL_Event event
Definition graphics.h:217
small_dialog
Definition widget.h:174
small_dialog::begin_widget_list
struct widget * begin_widget_list
Definition widget.h:175
small_dialog::end_widget_list
struct widget * end_widget_list
Definition widget.h:176
tile::units
struct unit_list * units
Definition tile.h:57
tileset
Definition tilespec.c:459
unit_type
Definition unittype.h:481
unit_type::defense_strength
int defense_strength
Definition unittype.h:496
unit_type::move_rate
int move_rate
Definition unittype.h:497
unit_type::hp
int hp
Definition unittype.h:505
unit_type::attack_strength
int attack_strength
Definition unittype.h:495
unit
Definition unit.h:138
unit::upkeep
int upkeep[O_LAST]
Definition unit.h:148
unit::activity
enum unit_activity activity
Definition unit.h:157
unit::id
int id
Definition unit.h:145
unit::hp
int hp
Definition unit.h:151
unit::facing
enum direction8 facing
Definition unit.h:142
unit::homecity
int homecity
Definition unit.h:146
unit::veteran
int veteran
Definition unit.h:152
universal::kind
enum universals_n kind
Definition fc_types.h:758
universal::value
universals_u value
Definition fc_types.h:757
utf8_str
Definition gui_string.h:52
utf8_str::style
Uint8 style
Definition gui_string.h:53
utf8_str::fgcol
SDL_Color fgcol
Definition gui_string.h:57
utf8_str::text
char * text
Definition gui_string.h:60
widget
Definition widget.h:112
widget::next
struct widget * next
Definition widget.h:113
widget::ptr
void * ptr
Definition widget.h:133
widget::info_label
utf8_str * info_label
Definition widget.h:122
widget::key
SDL_Keycode key
Definition widget.h:153
widget::data
union widget::@214 data
widget::dst
struct gui_layer * dst
Definition widget.h:116
widget::prev
struct widget * prev
Definition widget.h:114
widget::action
int(* action)(struct widget *)
Definition widget.h:157
widget::unit
struct unit * unit
Definition widget.h:129
widget::city
struct city * city
Definition widget.h:128
widget::cont
struct container * cont
Definition widget.h:127
widget::theme
SDL_Surface * theme
Definition widget.h:118
widget::string_utf8
utf8_str * string_utf8
Definition widget.h:121
widget::area
SDL_Rect area
Definition widget.h:149
widget::id
Uint16 id
Definition widget.h:155
widget::size
SDL_Rect size
Definition widget.h:145
widget::theme2
SDL_Surface * theme2
Definition widget.h:119
style_of_city
int style_of_city(const struct city *pcity)
Definition style.c:202
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
fc_strlcat
size_t fc_strlcat(char *dest, const char *src, size_t n)
Definition support.c:832
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
sz_strlcat
#define sz_strlcat(dest, src)
Definition support.h:162
get_nearest_city_text
const char * get_nearest_city_text(struct city *pcity, int sq_dist)
Definition text.c:474
unit_description
const char * unit_description(struct unit *punit)
Definition text.c:508
text.h
theme_get_background
SDL_Surface * theme_get_background(const struct theme *t, enum theme_background background)
Definition themebackgrounds.c:94
BACKGROUND_CITYDLG
@ BACKGROUND_CITYDLG
Definition themebackgrounds.h:30
COLOR_THEME_BACKGROUND
@ COLOR_THEME_BACKGROUND
Definition themecolors.h:23
COLOR_THEME_CITYDLG_INFOPANEL
@ COLOR_THEME_CITYDLG_INFOPANEL
Definition themecolors.h:58
COLOR_THEME_CITYDLG_SELL
@ COLOR_THEME_CITYDLG_SELL
Definition themecolors.h:63
COLOR_THEME_CITYDLG_FOODPERTURN
@ COLOR_THEME_CITYDLG_FOODPERTURN
Definition themecolors.h:49
COLOR_THEME_CITYDLG_IMPR
@ COLOR_THEME_CITYDLG_IMPR
Definition themecolors.h:57
COLOR_THEME_CITYDLG_BUY
@ COLOR_THEME_CITYDLG_BUY
Definition themecolors.h:46
COLOR_THEME_CITYDLG_SHIELDSTOCK
@ COLOR_THEME_CITYDLG_SHIELDSTOCK
Definition themecolors.h:64
COLOR_THEME_CITYDLG_LUX
@ COLOR_THEME_CITYDLG_LUX
Definition themecolors.h:59
COLOR_THEME_CITYDLG_TRADE
@ COLOR_THEME_CITYDLG_TRADE
Definition themecolors.h:67
COLOR_THEME_CITYDLG_PROD
@ COLOR_THEME_CITYDLG_PROD
Definition themecolors.h:61
COLOR_THEME_CITYDLG_GROWTH
@ COLOR_THEME_CITYDLG_GROWTH
Definition themecolors.h:55
COLOR_THEME_CITYDLG_SUPPORT
@ COLOR_THEME_CITYDLG_SUPPORT
Definition themecolors.h:66
COLOR_THEME_CITYDLG_GRANARY
@ COLOR_THEME_CITYDLG_GRANARY
Definition themecolors.h:54
COLOR_THEME_CITYDLG_SCIENCE
@ COLOR_THEME_CITYDLG_SCIENCE
Definition themecolors.h:62
COLOR_THEME_CITYDLG_CORRUPTION
@ COLOR_THEME_CITYDLG_CORRUPTION
Definition themecolors.h:48
COLOR_THEME_CITYDLG_FOODSTOCK
@ COLOR_THEME_CITYDLG_FOODSTOCK
Definition themecolors.h:50
COLOR_THEME_CITYDLG_GOLD
@ COLOR_THEME_CITYDLG_GOLD
Definition themecolors.h:53
COLOR_THEME_CITYDLG_STOCKS
@ COLOR_THEME_CITYDLG_STOCKS
Definition themecolors.h:65
COLOR_THEME_CITYDLG_UPKEEP
@ COLOR_THEME_CITYDLG_UPKEEP
Definition themecolors.h:68
COLOR_THEME_CITYDLG_FRAME
@ COLOR_THEME_CITYDLG_FRAME
Definition themecolors.h:52
COLOR_THEME_CITYDLG_FOOD_SURPLUS
@ COLOR_THEME_CITYDLG_FOOD_SURPLUS
Definition themecolors.h:51
COLOR_THEME_CITYDLG_PANEL
@ COLOR_THEME_CITYDLG_PANEL
Definition themecolors.h:60
COLOR_THEME_CHECKBOX_LABEL_TEXT
@ COLOR_THEME_CHECKBOX_LABEL_TEXT
Definition themecolors.h:24
active_theme
struct theme * active_theme
Definition themespec.c:154
themespec.h
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tileset_full_tile_height
int tileset_full_tile_height(const struct tileset *t)
Definition tilespec.c:752
tileset_unit_with_small_upkeep_height
int tileset_unit_with_small_upkeep_height(const struct tileset *t)
Definition tilespec.c:834
tileset_unit_layout_small_offset_y
int tileset_unit_layout_small_offset_y(const struct tileset *t)
Definition tilespec.c:854
tileset_full_tile_width
int tileset_full_tile_width(const struct tileset *t)
Definition tilespec.c:739
tileset_tile_width
int tileset_tile_width(const struct tileset *t)
Definition tilespec.c:716
trade_routes_iterate_end
#define trade_routes_iterate_end
Definition traderoutes.h:133
trade_routes_iterate
#define trade_routes_iterate(c, proute)
Definition traderoutes.h:129
universals_u::utype
const struct unit_type * utype
Definition fc_types.h:604
universals_u::building
const struct impr_type * building
Definition fc_types.h:598
unit_activity_astr
void unit_activity_astr(const struct unit *punit, struct astring *astr)
Definition unit.c:1175
unit_tile
#define unit_tile(_pu)
Definition unit.h:388
unitlist.h
unit_list_iterate
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
unit_list_iterate_end
#define unit_list_iterate_end
Definition unitlist.h:33
utype_veteran_name_translation
const char * utype_veteran_name_translation(const struct unit_type *punittype, int level)
Definition unittype.c:2646
unit_type_get
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
can_upgrade_unittype
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1755
utype_build_shield_cost
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1490
utype_name_translation
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612
set_group_state
void set_group_state(struct widget *begin_group_widget_list, struct widget *end_group_widget_list, enum widget_state state)
Definition widget.c:897
add_to_gui_list
void add_to_gui_list(Uint16 id, struct widget *gui)
Definition widget.c:585
del_group_of_widgets_from_gui_list
void del_group_of_widgets_from_gui_list(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:862
unselect_widget_action
void unselect_widget_action(void)
Definition widget.c:417
widget_add_as_prev
void widget_add_as_prev(struct widget *new_widget, struct widget *add_dock)
Definition widget.c:601
select_window_group_dialog
bool select_window_group_dialog(struct widget *begin_widget_list, struct widget *pwindow)
Definition widget.c:997
setup_vertical_widgets_position
int setup_vertical_widgets_position(int step, Sint16 start_x, Sint16 start_y, Uint16 w, Uint16 h, struct widget *begin, struct widget *end)
Definition widget.c:1050
redraw_group
Uint16 redraw_group(const struct widget *begin_group_widget_list, const struct widget *end_group_widget_list, int add_to_update)
Definition widget.c:719
popdown_window_group_dialog
void popdown_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:982
move_window_group
void move_window_group(struct widget *begin_widget_list, struct widget *pwindow)
Definition widget.c:1038
widget.h
widget_set_position
static void widget_set_position(struct widget *pwidget, int x, int y)
Definition widget.h:266
MAX_ID
#define MAX_ID
Definition widget.h:38
FC_WS_DISABLED
@ FC_WS_DISABLED
Definition widget.h:99
FC_WS_NORMAL
@ FC_WS_NORMAL
Definition widget.h:96
del_widget_from_vertical_scroll_widget_list
bool del_widget_from_vertical_scroll_widget_list(struct advanced_dialog *dlg, struct widget *pwidget) fc__attribute((nonnull(2)))
Definition widget_scrollbar.c:1349
widget_mark_dirty
static void widget_mark_dirty(struct widget *pwidget)
Definition widget.h:286
widget_flush
static void widget_flush(struct widget *pwidget)
Definition widget.h:291
set_wstate
void set_wstate(struct widget *pwidget, enum widget_state state)
Definition widget_core.c:36
get_wstate
enum widget_state get_wstate(const struct widget *pwidget)
Definition widget_core.c:70
WF_WIDGET_HAS_INFO_LABEL
@ WF_WIDGET_HAS_INFO_LABEL
Definition widget.h:88
WF_ICON_CENTER_RIGHT
@ WF_ICON_CENTER_RIGHT
Definition widget.h:84
WF_FREE_THEME2
@ WF_FREE_THEME2
Definition widget.h:74
WF_SELECT_WITHOUT_BAR
@ WF_SELECT_WITHOUT_BAR
Definition widget.h:89
WF_RESTORE_BACKGROUND
@ WF_RESTORE_BACKGROUND
Definition widget.h:85
WF_HIDDEN
@ WF_HIDDEN
Definition widget.h:68
WF_FREE_THEME
@ WF_FREE_THEME
Definition widget.h:72
widget_redraw
static int widget_redraw(struct widget *pwidget)
Definition widget.h:276
set_wflag
void set_wflag(struct widget *pwidget, enum widget_flag flag)
Definition widget_core.c:54
create_icon_button
struct widget * create_icon_button(SDL_Surface *icon, struct gui_layer *pdest, utf8_str *pstr, Uint32 flags)
Definition widget_button.c:265
create_icon_button_from_chars_fonto
#define create_icon_button_from_chars_fonto(icon, pdest, char_string, fonto, flags)
Definition widget_button.h:23
create_themeicon_button_from_chars_fonto
#define create_themeicon_button_from_chars_fonto(icon_theme, pdest, char_string, fonto, flags)
Definition widget_button.h:36
create_textcheckbox
struct widget * create_textcheckbox(struct gui_layer *pdest, bool state, utf8_str *pstr, Uint32 flags)
Definition widget_checkbox.c:149
create_edit_from_chars_fonto
#define create_edit_from_chars_fonto(background, pdest, char_string, fonto, length, flags)
Definition widget_edit.h:29
create_themeicon
struct widget * create_themeicon(SDL_Surface *icon_theme, struct gui_layer *pdest, Uint32 flags)
Definition widget_icon.c:208
create_icon2
struct widget * create_icon2(SDL_Surface *icon, struct gui_layer *pdest, Uint32 flags)
Definition widget_icon.c:333
create_themelabel
struct widget * create_themelabel(SDL_Surface *icon, struct gui_layer *pdest, utf8_str *pstr, Uint16 w, Uint16 h, Uint32 flags)
Definition widget_label.c:180
create_iconlabel
struct widget * create_iconlabel(SDL_Surface *icon, struct gui_layer *pdest, utf8_str *pstr, Uint32 flags)
Definition widget_label.c:215
setup_vertical_scrollbar_area
void setup_vertical_scrollbar_area(struct scroll_bar *scroll, Sint16 start_x, Sint16 start_y, Uint16 height, bool swap_start_x)
Definition widget_scrollbar.c:572
create_vertical_scrollbar
Uint32 create_vertical_scrollbar(struct advanced_dialog *dlg, Uint8 step, Uint8 active, bool create_scrollbar, bool create_buttons)
Definition widget_scrollbar.c:491
resize_window
int resize_window(struct widget *pwindow, SDL_Surface *bcgd, SDL_Color *pcolor, Uint16 new_w, Uint16 new_h)
Definition widget_window.c:255
create_window_skeleton
struct widget * create_window_skeleton(struct gui_layer *pdest, utf8_str *title, Uint32 flags)
Definition widget_window.c:180
create_window
struct widget * create_window(struct gui_layer *pdest, utf8_str *title, Uint16 w, Uint16 h, Uint32 flags)
Definition widget_window.c:231