Freeciv-3.3: /fast/freeciv/nightly/main/client/gui-sdl2/citydlg.c Source File

Freeciv-3.3

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 get_smaller_surface_rect(destcanvas->surf, &src_rect);
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, pcity_dlg->pcity->id, new_options);
967 }
968
969 return -1;
970}
971
972/**********************************************************************/
975 static void create_city_options_widget_list(struct city *pcity)
976{
977 struct widget *buf, *pwindow = pcity_dlg->end_city_widget_list;
978 SDL_Surface *surf;
979 utf8_str *pstr;
980 char cbuf[80];
981
982 fc_snprintf(cbuf, sizeof(cbuf),
983 _("Allow unit production\nto disband city"));
984 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
985 pstr->style |= TTF_STYLE_BOLD;
986 pstr->fgcol = *get_theme_color(COLOR_THEME_CHECKBOX_LABEL_TEXT);
987
988 buf =
989 create_textcheckbox(pwindow->dst, BV_ISSET(pcity->city_options, CITYO_DISBAND), pstr,
990 WF_RESTORE_BACKGROUND);
991 set_wstate(buf, FC_WS_NORMAL);
992 buf->action = misc_panel_city_dlg_callback;
993 add_to_gui_list(MAX_ID - 0x10, buf);
994 buf->size.x = pwindow->area.x + adj_size(7);
995 buf->size.y = pwindow->area.y + adj_size(45);
996
997 /* ----- */
998
999 pcity_dlg->panel = fc_calloc(1, sizeof(struct advanced_dialog));
1000 pcity_dlg->panel->end_widget_list = buf;
1001
1002 /* ----- */
1003
1004 fc_snprintf(cbuf, sizeof(cbuf), "%s:", _("New citizens produce"));
1005 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT_PLUS);
1006 pstr->style |= SF_CENTER;
1007
1008 if (BV_ISSET(pcity->city_options, CITYO_SCIENCE_SPECIALISTS)) {
1009 surf = get_tax_surface(O_SCIENCE);
1010 buf = create_icon_button(surf, pwindow->dst, pstr,
1011 WF_ICON_CENTER_RIGHT | WF_FREE_THEME2);
1012 add_to_gui_list(MAX_ID - 0x20, buf);
1013 } else {
1014 if (BV_ISSET(pcity->city_options, CITYO_GOLD_SPECIALISTS)) {
1015 surf = get_tax_surface(O_GOLD);
1016 buf = create_icon_button(surf, pwindow->dst,
1017 pstr, WF_ICON_CENTER_RIGHT | WF_FREE_THEME2);
1018 add_to_gui_list(MAX_ID - 0x40, buf);
1019 } else {
1020 surf = get_tax_surface(O_LUXURY);
1021 buf = create_icon_button(surf, pwindow->dst,
1022 pstr, WF_ICON_CENTER_RIGHT | WF_FREE_THEME2);
1023 add_to_gui_list(MAX_ID - 0x60, buf);
1024 }
1025 }
1026
1027 buf->size.w = adj_size(177);
1028 buf->action = misc_panel_city_dlg_callback;
1029 set_wstate(buf, FC_WS_NORMAL);
1030
1031 buf->size.x = buf->next->size.x;
1032 buf->size.y = buf->next->size.y + buf->next->size.h + adj_size(5);
1033 pcity_dlg->panel->begin_widget_list = buf;
1034}
1035
1036/**********************************************************************/
1039 static int options_city_dlg_callback(struct widget *button)
1040{
1041 if (PRESSED_EVENT(main_data.event)) {
1042 if (pcity_dlg->page != MISC_PAGE) {
1043 free_city_units_lists();
1044 pcity_dlg->page = MISC_PAGE;
1045 redraw_city_dialog(pcity_dlg->pcity);
1046 flush_dirty();
1047 } else {
1048 widget_redraw(button);
1049 widget_flush(button);
1050 }
1051 }
1052
1053 return -1;
1054}
1055
1056/* ======================================================================= */
1057
1058/**********************************************************************/
1061 static int cma_city_dlg_callback(struct widget *button)
1062{
1063 if (PRESSED_EVENT(main_data.event)) {
1064 disable_city_dlg_widgets();
1065 popup_city_cma_dialog(pcity_dlg->pcity);
1066 }
1067
1068 return -1;
1069}
1070
1071/**********************************************************************/
1074 static int exit_city_dlg_callback(struct widget *button)
1075{
1076 if (PRESSED_EVENT(main_data.event)) {
1077 popdown_city_dialog(pcity_dlg->pcity);
1078 }
1079
1080 return -1;
1081}
1082
1083/* ======================================================================= */
1084/* ======================== Buy Production Dlg. ========================== */
1085/* ======================================================================= */
1086
1087/**********************************************************************/
1090 static int cancel_buy_prod_city_dlg_callback(struct widget *button)
1091{
1092 if (PRESSED_EVENT(main_data.event)) {
1093 popdown_hurry_production_dialog();
1094
1095 if (pcity_dlg) {
1096 /* enable city dlg */
1097 enable_city_dlg_widgets();
1098 }
1099 }
1100
1101 return -1;
1102}
1103
1104/**********************************************************************/
1107 static int ok_buy_prod_city_dlg_callback(struct widget *button)
1108{
1109 if (PRESSED_EVENT(main_data.event)) {
1110 struct city *pcity = button->data.city; /* Save it. */
1111
1112 popdown_hurry_production_dialog();
1113 city_buy_production(pcity);
1114
1115 if (pcity_dlg) {
1116 /* enable city dlg */
1117 enable_city_dlg_widgets();
1118
1119 /* disable buy button */
1120 set_wstate(pcity_dlg->buy_button, FC_WS_DISABLED);
1121 widget_redraw(pcity_dlg->buy_button);
1122 widget_mark_dirty(pcity_dlg->buy_button);
1123 flush_dirty();
1124 }
1125 }
1126
1127 return -1;
1128}
1129
1130/**********************************************************************/
1133 static int buy_prod_city_dlg_callback(struct widget *button)
1134{
1135 if (PRESSED_EVENT(main_data.event)) {
1136 widget_redraw(button);
1137 widget_flush(button);
1138 disable_city_dlg_widgets();
1139 popup_hurry_production_dialog(pcity_dlg->pcity, button->dst->surface);
1140 }
1141
1142 return -1;
1143}
1144
1145/**********************************************************************/
1148 static void popdown_hurry_production_dialog(void)
1149{
1150 if (hurry_prog_dlg) {
1151 popdown_window_group_dialog(hurry_prog_dlg->begin_widget_list,
1152 hurry_prog_dlg->end_widget_list);
1153 FC_FREE(hurry_prog_dlg);
1154 flush_dirty();
1155 }
1156}
1157
1158/**********************************************************************/
1161 static int hurry_production_window_callback(struct widget *pwindow)
1162{
1163 if (PRESSED_EVENT(main_data.event)) {
1164 move_window_group(hurry_prog_dlg->begin_widget_list, pwindow);
1165 }
1166
1167 return -1;
1168}
1169
1170/**********************************************************************/
1173 void popup_hurry_production_dialog(struct city *pcity, SDL_Surface *pdest)
1174{
1175 char tbuf[512], cbuf[512];
1176 struct widget *buf = NULL, *pwindow;
1177 utf8_str *pstr;
1178 SDL_Surface *text;
1179 SDL_Rect dst;
1180 int window_x = 0, window_y = 0;
1181 SDL_Rect area;
1182 const char *name = city_production_name_translation(pcity);
1183 int value = pcity->client.buy_cost;
1184
1185 if (hurry_prog_dlg) {
1186 return;
1187 }
1188
1189 fc_snprintf(tbuf, ARRAY_SIZE(tbuf), PL_("Treasury contains %d gold.",
1190 "Treasury contains %d gold.",
1191 client_player()->economic.gold),
1192 client_player()->economic.gold);
1193
1194 hurry_prog_dlg = fc_calloc(1, sizeof(struct small_dialog));
1195
1196 if (city_can_buy(pcity)) {
1197 if (value <= client_player()->economic.gold) {
1198 fc_snprintf(cbuf, sizeof(cbuf),
1199 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
1200 PL_("Buy %s for %d gold?\n%s",
1201 "Buy %s for %d gold?\n%s", value),
1202 name, value, tbuf);
1203 } else {
1204 fc_snprintf(cbuf, sizeof(cbuf),
1205 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
1206 PL_("%s costs %d gold.\n%s",
1207 "%s costs %d gold.\n%s", value),
1208 name, value, tbuf);
1209 }
1210 } else {
1211 if (pcity->did_buy) {
1212 fc_snprintf(cbuf, sizeof(cbuf),
1213 _("Sorry, you have already bought here in this turn."));
1214 } else {
1215 fc_snprintf(cbuf, sizeof(cbuf),
1216 _("Sorry, you can't buy here in this turn."));
1217 }
1218 }
1219
1220 pstr = create_utf8_from_char_fonto(_("Buy it?"), FONTO_ATTENTION);
1221 pstr->style |= TTF_STYLE_BOLD;
1222 pwindow = create_window_skeleton(NULL, pstr, 0);
1223 pwindow->action = hurry_production_window_callback;
1224 set_wstate(pwindow, FC_WS_NORMAL);
1225 add_to_gui_list(ID_WINDOW, pwindow);
1226
1227 hurry_prog_dlg->end_widget_list = pwindow;
1228
1229 area = pwindow->area;
1230
1231 area.h += 1;
1232
1233 /* ============================================================= */
1234
1235 /* Label */
1236 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1237 pstr->style |= (TTF_STYLE_BOLD|SF_CENTER);
1238 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_BUY);
1239
1240 text = create_text_surf_from_utf8(pstr);
1241 FREEUTF8STR(pstr);
1242 area.w = MAX(area.w , text->w);
1243 area.h += text->h + adj_size(5);
1244
1245 buf = create_themeicon_button_from_chars_fonto(current_theme->cancel_icon,
1246 pwindow->dst, _("No"),
1247 FONTO_ATTENTION, 0);
1248
1249 buf->action = cancel_buy_prod_city_dlg_callback;
1250 set_wstate(buf, FC_WS_NORMAL);
1251 buf->key = SDLK_ESCAPE;
1252 area.h += buf->size.h;
1253
1254 add_to_gui_list(ID_BUTTON, buf);
1255
1256 if (city_can_buy(pcity) && (value <= client.conn.playing->economic.gold)) {
1257 buf = create_themeicon_button_from_chars_fonto(current_theme->ok_icon,
1258 pwindow->dst,
1259 _("Yes"),
1260 FONTO_ATTENTION, 0);
1261
1262 buf->action = ok_buy_prod_city_dlg_callback;
1263 set_wstate(buf, FC_WS_NORMAL);
1264 buf->data.city = pcity;
1265 buf->key = SDLK_RETURN;
1266 add_to_gui_list(ID_BUTTON, buf);
1267 buf->size.w = MAX(buf->next->size.w, buf->size.w);
1268 buf->next->size.w = buf->size.w;
1269 area.w = MAX(area.w , 2 * buf->size.w + adj_size(20));
1270 }
1271
1272 hurry_prog_dlg->begin_widget_list = buf;
1273
1274 /* Setup window size and start position */
1275 area.w += adj_size(10);
1276 area.h += adj_size(5);
1277
1278 resize_window(pwindow, NULL, get_theme_color(COLOR_THEME_BACKGROUND),
1279 (pwindow->size.w - pwindow->area.w) + area.w,
1280 (pwindow->size.h - pwindow->area.h) + area.h);
1281
1282 area = pwindow->area;
1283
1284 if (city_dialog_is_open(pcity)) {
1285 window_x = pcity_dlg->buy_button->size.x;
1286 window_y = pcity_dlg->buy_button->size.y - pwindow->size.h;
1287 } else if (is_city_report_open()) {
1288 fc_assert(selected_widget != NULL);
1289
1290 if (selected_widget->size.x + tileset_tile_width(tileset)
1291 + pwindow->size.w > main_window_width()) {
1292 window_x = selected_widget->size.x - pwindow->size.w;
1293 } else {
1294 window_x = selected_widget->size.x + tileset_tile_width(tileset);
1295 }
1296
1297 window_y = selected_widget->size.y
1298 + (selected_widget->size.h - pwindow->size.h) / 2;
1299
1300 if (window_y + pwindow->size.h > main_window_height()) {
1301 window_y = main_window_height() - pwindow->size.h - 1;
1302 } else if (window_y < 0) {
1303 window_y = 0;
1304 }
1305 } else {
1306 put_window_near_map_tile(pwindow, pwindow->size.w, pwindow->size.h, pcity->tile);
1307 }
1308
1309 widget_set_position(pwindow, window_x, window_y);
1310
1311 /* Setup rest of widgets */
1312 /* Label */
1313 dst.x = area.x + (area.w - text->w) / 2;
1314 dst.y = area.y + 1;
1315 alphablit(text, NULL, pwindow->theme, &dst, 255);
1316 dst.y += text->h + adj_size(5);
1317 FREESURFACE(text);
1318
1319 /* No */
1320 buf = pwindow->prev;
1321 buf->size.y = dst.y;
1322
1323 if (city_can_buy(pcity) && value <= client.conn.playing->economic.gold) {
1324 /* Yes */
1325 buf = buf->prev;
1326 buf->size.x = area.x + (area.w - (2 * buf->size.w + adj_size(20))) / 2;
1327 buf->size.y = dst.y;
1328
1329 /* No */
1330 buf->next->size.x = buf->size.x + buf->size.w + adj_size(20);
1331 } else {
1332 /* No */
1333 buf->size.x = area.x + area.w - buf->size.w - adj_size(10);
1334 }
1335
1336 /* ================================================== */
1337 /* Redraw */
1338 redraw_group(hurry_prog_dlg->begin_widget_list, pwindow, 0);
1339 widget_mark_dirty(pwindow);
1340 flush_dirty();
1341}
1342
1343/* =======================================================================*/
1344/* ========================== CHANGE PRODUCTION ==========================*/
1345/* =======================================================================*/
1346
1347/**********************************************************************/
1350 static int change_prod_dlg_callback(struct widget *button)
1351{
1352 if (PRESSED_EVENT(main_data.event)) {
1353 widget_redraw(button);
1354 widget_flush(button);
1355
1356 disable_city_dlg_widgets();
1357 popup_worklist_editor(pcity_dlg->pcity, NULL);
1358 }
1359
1360 return -1;
1361}
1362
1363/* =======================================================================*/
1364/* ========================== SELL IMPROVEMENTS ==========================*/
1365/* =======================================================================*/
1366
1367/**********************************************************************/
1370 static int sell_imprvm_dlg_cancel_callback(struct widget *cancel_button)
1371{
1372 if (PRESSED_EVENT(main_data.event)) {
1373 popdown_window_group_dialog(pcity_dlg->begin_city_menu_widget_list,
1374 pcity_dlg->end_city_menu_widget_list);
1375 pcity_dlg->end_city_menu_widget_list = NULL;
1376 enable_city_dlg_widgets();
1377 redraw_city_dialog(pcity_dlg->pcity);
1378 flush_dirty();
1379 }
1380
1381 return -1;
1382}
1383
1384/**********************************************************************/
1387 static int sell_imprvm_dlg_ok_callback(struct widget *ok_button)
1388{
1389 if (PRESSED_EVENT(main_data.event)) {
1390 struct widget *tmp = (struct widget *)ok_button->data.ptr;
1391
1392 city_sell_improvement(pcity_dlg->pcity, MAX_ID - 3000 - tmp->id);
1393
1394 /* popdown, we don't redraw and flush because this is made by redraw city dlg.
1395 when response from server comes */
1396 popdown_window_group_dialog(pcity_dlg->begin_city_menu_widget_list,
1397 pcity_dlg->end_city_menu_widget_list);
1398
1399 pcity_dlg->end_city_menu_widget_list = NULL;
1400
1401 /* del imprv from widget list */
1402 del_widget_from_vertical_scroll_widget_list(pcity_dlg->imprv, tmp);
1403
1404 enable_city_dlg_widgets();
1405
1406 if (pcity_dlg->imprv->end_widget_list) {
1407 set_group_state(pcity_dlg->imprv->begin_active_widget_list,
1408 pcity_dlg->imprv->end_active_widget_list, FC_WS_DISABLED);
1409 }
1410
1411 redraw_city_dialog(pcity_dlg->pcity);
1412 flush_dirty();
1413 }
1414
1415 return -1;
1416}
1417
1418/**********************************************************************/
1421 static int sell_imprvm_dlg_callback(struct widget *impr)
1422{
1423 if (PRESSED_EVENT(main_data.event)) {
1424 utf8_str *pstr = NULL;
1425 struct widget *label = NULL;
1426 struct widget *pwindow = NULL;
1427 struct widget *cancel_button = NULL;
1428 struct widget *ok_button = NULL;
1429 char cbuf[80];
1430 int id;
1431 SDL_Rect area;
1432 int price;
1433
1434 unselect_widget_action();
1435 disable_city_dlg_widgets();
1436
1437 pstr = create_utf8_from_char_fonto(_("Sell it?"), FONTO_ATTENTION);
1438 pstr->style |= TTF_STYLE_BOLD;
1439 pwindow = create_window_skeleton(NULL, pstr, 0);
1440 /*pwindow->action = move_sell_imprvm_dlg_callback; */
1441 /*set_wstate(pwindow, FC_WS_NORMAL); */
1442 add_to_gui_list(ID_WINDOW, pwindow);
1443 pcity_dlg->end_city_menu_widget_list = pwindow;
1444
1445 area = pwindow->area;
1446
1447 /* Create text label */
1448 id = MAX_ID - 3000 - impr->id;
1449
1450 price = impr_sell_gold(improvement_by_number(id));
1451 fc_snprintf(cbuf, sizeof(cbuf), PL_("Sell %s for %d gold?",
1452 "Sell %s for %d gold?", price),
1453 city_improvement_name_translation(pcity_dlg->pcity,
1454 improvement_by_number(id)),
1455 price);
1456 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1457 pstr->style |= (TTF_STYLE_BOLD|SF_CENTER);
1458 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_SELL);
1459 label = create_iconlabel(NULL, pwindow->dst, pstr, 0);
1460 add_to_gui_list(ID_LABEL, label);
1461
1462 /* Create cancel button */
1463 cancel_button =
1464 create_themeicon_button_from_chars_fonto(current_theme->small_cancel_icon,
1465 pwindow->dst, _("Cancel"),
1466 FONTO_DEFAULT, 0);
1467 cancel_button->action = sell_imprvm_dlg_cancel_callback;
1468 cancel_button->key = SDLK_ESCAPE;
1469 set_wstate(cancel_button, FC_WS_NORMAL);
1470 add_to_gui_list(ID_BUTTON, cancel_button);
1471
1472 /* create ok button */
1473 ok_button = create_themeicon_button_from_chars_fonto(current_theme->small_ok_icon,
1474 pwindow->dst, _("Sell"),
1475 FONTO_DEFAULT, 0);
1476 ok_button->data.ptr = (void *)impr;
1477 ok_button->size.w = cancel_button->size.w;
1478 ok_button->action = sell_imprvm_dlg_ok_callback;
1479 ok_button->key = SDLK_RETURN;
1480 set_wstate(ok_button, FC_WS_NORMAL);
1481 add_to_gui_list(ID_BUTTON, ok_button);
1482
1483 pcity_dlg->begin_city_menu_widget_list = ok_button;
1484
1485 /* correct sizes */
1486 if ((ok_button->size.w + cancel_button->size.w + adj_size(30)) >
1487 label->size.w + adj_size(20)) {
1488 area.w = MAX(area.w, ok_button->size.w + cancel_button->size.w + adj_size(30));
1489 } else {
1490 area.w = MAX(area.w, label->size.w + adj_size(20));
1491 }
1492
1493 area.h = MAX(area.h, ok_button->size.h + label->size.h + adj_size(25));
1494
1495 /* create window background */
1496 resize_window(pwindow, NULL, get_theme_color(COLOR_THEME_BACKGROUND),
1497 (pwindow->size.w - pwindow->area.w) + area.w,
1498 (pwindow->size.h - pwindow->area.h) + area.h);
1499
1500 area = pwindow->area;
1501
1502 /* set start positions */
1503 widget_set_position(pwindow,
1504 (main_window_width() - pwindow->size.w) / 2,
1505 (main_window_height() - pwindow->size.h) / 2 + adj_size(10));
1506
1507 ok_button->size.x = area.x + adj_size(10);
1508 ok_button->size.y = area.y + area.h - ok_button->size.h - adj_size(10);
1509
1510 cancel_button->size.y = ok_button->size.y;
1511 cancel_button->size.x = area.x + area.w - cancel_button->size.w - adj_size(10);
1512
1513 label->size.x = area.x;
1514 label->size.y = area.y + adj_size(4);
1515 label->size.w = area.w;
1516
1517 /* redraw */
1518 redraw_group(pcity_dlg->begin_city_menu_widget_list,
1519 pcity_dlg->end_city_menu_widget_list, 0);
1520
1521 widget_mark_dirty(pwindow);
1522 flush_dirty();
1523 }
1524
1525 return -1;
1526}
1527/* ====================================================================== */
1528
1529/**********************************************************************/
1532 void enable_city_dlg_widgets(void)
1533{
1534 if (pcity_dlg) {
1535 set_group_state(pcity_dlg->begin_city_widget_list,
1536 pcity_dlg->end_city_widget_list->prev, FC_WS_NORMAL);
1537
1538 if (pcity_dlg->imprv->end_active_widget_list) {
1539 if (pcity_dlg->imprv->scroll) {
1540 set_wstate(pcity_dlg->imprv->scroll->pscroll_bar, FC_WS_NORMAL); /* vscroll */
1541 set_wstate(pcity_dlg->imprv->scroll->up_left_button, FC_WS_NORMAL); /* up */
1542 set_wstate(pcity_dlg->imprv->scroll->down_right_button, FC_WS_NORMAL); /* down */
1543 }
1544
1545 /* There is common function test_player_sell_building_now(),
1546 * but we are not using it here, since we want to use set_group_state()
1547 * when possible */
1548 if (pcity_dlg->pcity->did_sell
1549 || pcity_dlg->pcity->owner != client.conn.playing) {
1550 set_group_state(pcity_dlg->imprv->begin_active_widget_list,
1551 pcity_dlg->imprv->end_active_widget_list, FC_WS_DISABLED);
1552 } else {
1553 struct widget *tmp_widget = pcity_dlg->imprv->end_active_widget_list;
1554
1555 while (TRUE) {
1556 struct impr_type *pimpr = improvement_by_number(MAX_ID - 3000 -
1557 tmp_widget->id);
1558
1559 if (!can_city_sell_building(pcity_dlg->pcity, pimpr)) {
1560 set_wstate(tmp_widget, FC_WS_DISABLED);
1561 } else {
1562 set_wstate(tmp_widget, FC_WS_NORMAL);
1563 }
1564
1565 if (tmp_widget == pcity_dlg->imprv->begin_active_widget_list) {
1566 break;
1567 }
1568
1569 tmp_widget = tmp_widget->prev;
1570
1571 } /* while */
1572 }
1573 }
1574
1575 if (!city_can_buy(pcity_dlg->pcity) && pcity_dlg->buy_button) {
1576 set_wstate(pcity_dlg->buy_button, FC_WS_DISABLED);
1577 }
1578
1579 if (pcity_dlg->panel) {
1580 set_group_state(pcity_dlg->panel->begin_widget_list,
1581 pcity_dlg->panel->end_widget_list, FC_WS_NORMAL);
1582 }
1583
1584 if (cma_is_city_under_agent(pcity_dlg->pcity, NULL)) {
1585 set_wstate(pcity_dlg->resource_map, FC_WS_DISABLED);
1586 }
1587
1588 pcity_dlg->lock = FALSE;
1589 }
1590}
1591
1592/**********************************************************************/
1595 static void disable_city_dlg_widgets(void)
1596{
1597 if (pcity_dlg->panel) {
1598 set_group_state(pcity_dlg->panel->begin_widget_list,
1599 pcity_dlg->panel->end_widget_list, FC_WS_DISABLED);
1600 }
1601
1602 if (pcity_dlg->imprv->end_widget_list) {
1603 set_group_state(pcity_dlg->imprv->begin_widget_list,
1604 pcity_dlg->imprv->end_widget_list, FC_WS_DISABLED);
1605 }
1606
1607 set_group_state(pcity_dlg->begin_city_widget_list,
1608 pcity_dlg->end_city_widget_list->prev, FC_WS_DISABLED);
1609 pcity_dlg->lock = TRUE;
1610}
1611
1612/* ======================================================================== */
1613
1614/**********************************************************************/
1617 SDL_Surface *get_scaled_city_map(struct city *pcity)
1618{
1619 SDL_Surface *buf = create_city_map(pcity);
1620
1621 city_map_zoom = ((buf->w * 159 > buf->h * 249) ?
1622 (float)adj_size(249) / buf->w
1623 : (float)adj_size(159) / buf->h);
1624
1625 return zoomSurface(buf, city_map_zoom, city_map_zoom, 1);
1626}
1627
1628/**********************************************************************/
1631 static int resource_map_city_dlg_callback(struct widget *map)
1632{
1633 if (PRESSED_EVENT(main_data.event)) {
1634 int col, row;
1635
1636 if (canvas_to_city_pos(&col, &row,
1637 city_map_radius_sq_get(pcity_dlg->pcity),
1638 1 / city_map_zoom * (main_data.event.motion.x - map->dst->dest_rect.x
1639 - map->size.x),
1640 1 / city_map_zoom * (main_data.event.motion.y - map->dst->dest_rect.y
1641 - map->size.y))) {
1642
1643 city_toggle_worker(pcity_dlg->pcity, col, row);
1644 }
1645 }
1646
1647 return -1;
1648}
1649
1650/* ====================================================================== */
1651
1652/**********************************************************************/
1655 static int city_comp_by_turn_founded(const void *a, const void *b)
1656{
1657 struct city *pcity1 = *((struct city **) a);
1658 struct city *pcity2 = *((struct city **) b);
1659
1660 return pcity1->turn_founded - pcity2->turn_founded;
1661}
1662
1663/**********************************************************************/
1666 static int next_prev_city_dlg_callback(struct widget *button)
1667{
1668 if (PRESSED_EVENT(main_data.event)) {
1669 struct city **array;
1670 int i, dir, non_open_size;
1671 int size = city_list_size(client.conn.playing->cities);
1672
1673 fc_assert_ret_val(size >= 1, -1);
1674 fc_assert_ret_val(city_owner(pcity_dlg->pcity)
1675 == client.conn.playing, -1);
1676
1677 if (size == 1) {
1678 return -1;
1679 }
1680
1681 /* dir = 1 will advance to the city, dir = -1 will get previous */
1682 if (button->id == ID_CITY_DLG_NEXT_BUTTON) {
1683 dir = 1;
1684 } else {
1685 if (button->id == ID_CITY_DLG_PREV_BUTTON) {
1686 dir = -1;
1687 } else {
1688 /* Always fails. */
1689 fc_assert_ret_val(button->id == ID_CITY_DLG_NEXT_BUTTON
1690 || button->id != ID_CITY_DLG_PREV_BUTTON, -1);
1691 dir = 1;
1692 }
1693 }
1694
1695 array = fc_calloc(1, size * sizeof(struct city *));
1696
1697 non_open_size = 0;
1698 for (i = 0; i < size; i++) {
1699 array[non_open_size++] = city_list_get(client.conn.playing->cities, i);
1700 }
1701
1702 fc_assert_ret_val(non_open_size > 0, -1);
1703
1704 if (non_open_size <= 1) {
1705 FC_FREE(array);
1706 return -1;
1707 }
1708
1709 qsort(array, non_open_size, sizeof(struct city *),
1710 city_comp_by_turn_founded);
1711
1712 for (i = 0; i < non_open_size; i++) {
1713 if (pcity_dlg->pcity == array[i]) {
1714 break;
1715 }
1716 }
1717
1718 fc_assert_ret_val(i < non_open_size, -1);
1719 pcity_dlg->pcity = array[(i + dir + non_open_size) % non_open_size];
1720 FC_FREE(array);
1721
1722 /* free panel widgets */
1723 free_city_units_lists();
1724 /* refresh resource map */
1725 FREESURFACE(pcity_dlg->resource_map->theme);
1726 pcity_dlg->resource_map->theme = get_scaled_city_map(pcity_dlg->pcity);
1727 rebuild_imprm_list(pcity_dlg->pcity);
1728
1729 /* redraw */
1730 redraw_city_dialog(pcity_dlg->pcity);
1731 flush_dirty();
1732 }
1733
1734 return -1;
1735}
1736
1737/**********************************************************************/
1740 static int new_name_city_dlg_callback(struct widget *pedit)
1741{
1742 if (pedit->string_utf8->text != NULL) {
1743 if (strcmp(pedit->string_utf8->text, city_name_get(pcity_dlg->pcity))) {
1744 sdl2_client_flags |= CF_CHANGED_CITY_NAME;
1745 city_rename(pcity_dlg->pcity, pedit->string_utf8->text);
1746 }
1747 } else {
1748 /* Empty input -> restore previous content */
1749 copy_chars_to_utf8_str(pedit->string_utf8, city_name_get(pcity_dlg->pcity));
1750 widget_redraw(pedit);
1751 widget_mark_dirty(pedit);
1752 flush_dirty();
1753 }
1754
1755 return -1;
1756}
1757
1758/* ======================================================================= */
1759/* ======================== Redrawing City Dlg. ========================== */
1760/* ======================================================================= */
1761
1762/**********************************************************************/
1765 static void refresh_city_names(struct city *pcity)
1766{
1767 if (pcity_dlg->city_name_edit) {
1768 char name[MAX_LEN_NAME];
1769
1770 fc_snprintf(name, MAX_LEN_NAME, "%s", pcity_dlg->city_name_edit->string_utf8->text);
1771 if ((strcmp(city_name_get(pcity), name) != 0)
1772 || (sdl2_client_flags & CF_CHANGED_CITY_NAME)) {
1773 copy_chars_to_utf8_str(pcity_dlg->city_name_edit->string_utf8,
1774 city_name_get(pcity));
1775 rebuild_citydlg_title_str(pcity_dlg->end_city_widget_list, pcity);
1776 sdl2_client_flags &= ~CF_CHANGED_CITY_NAME;
1777 }
1778 }
1779}
1780
1781/**********************************************************************/
1785 static void redraw_misc_city_dialog(struct widget *city_window,
1786 struct city *pcity)
1787{
1788 char cbuf[60];
1789 utf8_str *pstr;
1790 SDL_Surface *surf;
1791 SDL_Rect dest;
1792
1793 fc_snprintf(cbuf, sizeof(cbuf), _("City options"));
1794
1795 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1796 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PANEL);
1797 pstr->style |= TTF_STYLE_BOLD;
1798
1799 surf = create_text_surf_from_utf8(pstr);
1800
1801 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1802 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
1803
1804 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1805
1806 FREESURFACE(surf);
1807 FREEUTF8STR(pstr);
1808
1809 if (!pcity_dlg->panel) {
1810 create_city_options_widget_list(pcity);
1811 }
1812 redraw_group(pcity_dlg->panel->begin_widget_list,
1813 pcity_dlg->panel->end_widget_list, 0);
1814}
1815
1816/**********************************************************************/
1820 static void redraw_supported_units_city_dialog(struct widget *city_window,
1821 struct city *pcity)
1822{
1823 char cbuf[60];
1824 utf8_str *pstr;
1825 SDL_Surface *surf;
1826 SDL_Rect dest;
1827 struct unit_list *units;
1828 int size;
1829
1830 if (city_owner(pcity_dlg->pcity) != client.conn.playing) {
1831 units = (pcity_dlg->pcity->client.info_units_supported);
1832 } else {
1833 units = (pcity_dlg->pcity->units_supported);
1834 }
1835
1836 size = unit_list_size(units);
1837
1838 fc_snprintf(cbuf, sizeof(cbuf), _("Supported units: %d"), size);
1839
1840 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1841 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PANEL);
1842 pstr->style |= TTF_STYLE_BOLD;
1843
1844 surf = create_text_surf_from_utf8(pstr);
1845
1846 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1847 dest.y = city_window->area.y + + adj_size(4) + current_theme->info_icon->h;
1848
1849 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1850
1851 FREESURFACE(surf);
1852 FREEUTF8STR(pstr);
1853
1854 if (pcity_dlg->panel) {
1855 if (size > 0) {
1856 redraw_group(pcity_dlg->panel->begin_widget_list,
1857 pcity_dlg->panel->end_widget_list, 0);
1858 } else {
1859 del_group_of_widgets_from_gui_list(pcity_dlg->panel->begin_widget_list,
1860 pcity_dlg->panel->end_widget_list);
1861 FC_FREE(pcity_dlg->panel->scroll);
1862 FC_FREE(pcity_dlg->panel);
1863 }
1864 } else {
1865 if (size > 0) {
1866 create_present_supported_units_widget_list(units);
1867 redraw_group(pcity_dlg->panel->begin_widget_list,
1868 pcity_dlg->panel->end_widget_list, 0);
1869 }
1870 }
1871}
1872
1873/**********************************************************************/
1877 static void redraw_army_city_dialog(struct widget *city_window,
1878 struct city *pcity)
1879{
1880 char cbuf[60];
1881 utf8_str *pstr;
1882 SDL_Surface *surf;
1883 SDL_Rect dest;
1884 struct unit_list *units;
1885 int size;
1886
1887 if (city_owner(pcity_dlg->pcity) != client.conn.playing) {
1888 units = pcity_dlg->pcity->client.info_units_present;
1889 } else {
1890 units = pcity_dlg->pcity->tile->units;
1891 }
1892
1893 size = unit_list_size(units);
1894
1895 fc_snprintf(cbuf, sizeof(cbuf), _("Present units: %d"), size);
1896
1897 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1898 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PANEL);
1899 pstr->style |= TTF_STYLE_BOLD;
1900
1901 surf = create_text_surf_from_utf8(pstr);
1902
1903 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1904 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
1905
1906 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1907
1908 FREESURFACE(surf);
1909 FREEUTF8STR(pstr);
1910
1911 if (pcity_dlg->panel) {
1912 if (size) {
1913 redraw_group(pcity_dlg->panel->begin_widget_list,
1914 pcity_dlg->panel->end_widget_list, 0);
1915 } else {
1916 del_group_of_widgets_from_gui_list(pcity_dlg->panel->begin_widget_list,
1917 pcity_dlg->panel->end_widget_list);
1918 FC_FREE(pcity_dlg->panel->scroll);
1919 FC_FREE(pcity_dlg->panel);
1920 }
1921 } else {
1922 if (size) {
1923 create_present_supported_units_widget_list(units);
1924 redraw_group(pcity_dlg->panel->begin_widget_list,
1925 pcity_dlg->panel->end_widget_list, 0);
1926 }
1927 }
1928}
1929
1930/**********************************************************************/
1934 static void redraw_info_city_dialog(struct widget *city_window,
1935 struct city *pcity)
1936{
1937 char cbuf[30];
1938 struct city *trade_city = NULL;
1939 int step, i, xx;
1940 utf8_str *pstr = NULL;
1941 SDL_Surface *surf = NULL;
1942 SDL_Rect dest;
1943
1944 fc_snprintf(cbuf, sizeof(cbuf), _("City info"));
1945 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
1946 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PANEL);
1947 pstr->style |= TTF_STYLE_BOLD;
1948
1949 surf = create_text_surf_from_utf8(pstr);
1950
1951 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
1952 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
1953
1954 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1955
1956 dest.x = city_window->size.x + adj_size(10);
1957 dest.y += surf->h + 1;
1958
1959 FREESURFACE(surf);
1960
1961 change_fonto_utf8(pstr, FONTO_DEFAULT_PLUS);
1962 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_INFOPANEL);
1963
1964 if (pcity->pollution) {
1965 fc_snprintf(cbuf, sizeof(cbuf), _("Pollution: %d"),
1966 pcity->pollution);
1967
1968 copy_chars_to_utf8_str(pstr, cbuf);
1969
1970 surf = create_text_surf_from_utf8(pstr);
1971
1972 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
1973
1974 dest.y += surf->h + adj_size(3);
1975
1976 FREESURFACE(surf);
1977
1978 if (((icons->pollution->w + 1) * pcity->pollution) > adj_size(187)) {
1979 step = (adj_size(187) - icons->pollution->w) / (pcity->pollution - 1);
1980 } else {
1981 step = icons->pollution->w + 1;
1982 }
1983
1984 for (i = 0; i < pcity->pollution; i++) {
1985 alphablit(icons->pollution, NULL, city_window->dst->surface, &dest, 255);
1986 dest.x += step;
1987 }
1988
1989 dest.x = city_window->size.x + adj_size(10);
1990 dest.y += icons->pollution->h + adj_size(3);
1991
1992 } else {
1993 fc_snprintf(cbuf, sizeof(cbuf), _("Pollution: none"));
1994
1995 copy_chars_to_utf8_str(pstr, cbuf);
1996
1997 surf = create_text_surf_from_utf8(pstr);
1998
1999 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2000
2001 dest.y += surf->h + adj_size(3);
2002
2003 FREESURFACE(surf);
2004 }
2005
2006 if (game.info.illness_on) {
2007 int risk_pml = city_illness_calc(pcity, NULL, NULL, NULL, NULL);
2008
2009 fc_snprintf(cbuf, sizeof(cbuf), _("Plague risk: %.1f%%"),
2010 (double)risk_pml / 10.0);
2011 } else {
2012 fc_snprintf(cbuf, sizeof(cbuf), _("Plague risk: none"));
2013 }
2014
2015 copy_chars_to_utf8_str(pstr, cbuf);
2016 surf = create_text_surf_from_utf8(pstr);
2017 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2018 dest.y += surf->h + adj_size(3);
2019 FREESURFACE(surf);
2020
2021 fc_snprintf(cbuf, sizeof(cbuf), _("Trade routes: "));
2022
2023 copy_chars_to_utf8_str(pstr, cbuf);
2024
2025 surf = create_text_surf_from_utf8(pstr);
2026
2027 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2028
2029 xx = dest.x + surf->w;
2030 dest.y += surf->h + adj_size(3);
2031
2032 FREESURFACE(surf);
2033
2034 step = 0;
2035 dest.x = city_window->size.x + adj_size(10);
2036
2037 trade_routes_iterate(pcity, proute) {
2038 step += proute->value;
2039
2040 if ((trade_city = game_city_by_number(proute->partner))) {
2041 fc_snprintf(cbuf, sizeof(cbuf), "%s: +%d", city_name_get(trade_city),
2042 proute->value);
2043 } else {
2044 fc_snprintf(cbuf, sizeof(cbuf), "%s: +%d", _("Unknown"),
2045 proute->value);
2046 }
2047
2048 copy_chars_to_utf8_str(pstr, cbuf);
2049
2050 surf = create_text_surf_from_utf8(pstr);
2051
2052 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2053
2054 /* Blit trade icon */
2055 dest.x += surf->w + adj_size(3);
2056 dest.y += adj_size(4);
2057 alphablit(icons->trade, NULL, city_window->dst->surface, &dest, 255);
2058 dest.x = city_window->size.x + adj_size(10);
2059 dest.y -= adj_size(4);
2060
2061 dest.y += surf->h;
2062
2063 FREESURFACE(surf);
2064 } trade_routes_iterate_end;
2065
2066 if (step > 0) {
2067 fc_snprintf(cbuf, sizeof(cbuf), _("Trade: +%d"), step);
2068
2069 copy_chars_to_utf8_str(pstr, cbuf);
2070 surf = create_text_surf_from_utf8(pstr);
2071 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2072
2073 dest.x += surf->w + adj_size(3);
2074 dest.y += adj_size(4);
2075 alphablit(icons->trade, NULL, city_window->dst->surface, &dest, 255);
2076
2077 FREESURFACE(surf);
2078 } else {
2079 fc_snprintf(cbuf, sizeof(cbuf), Q_("?trade:None"));
2080
2081 copy_chars_to_utf8_str(pstr, cbuf);
2082
2083 surf = create_text_surf_from_utf8(pstr);
2084
2085 dest.x = xx;
2086 dest.y -= surf->h + adj_size(3);
2087 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2088
2089 FREESURFACE(surf);
2090 }
2091
2092 FREEUTF8STR(pstr);
2093}
2094
2095/**********************************************************************/
2100 static void redraw_happiness_city_dialog(const struct widget *city_window,
2101 struct city *pcity)
2102{
2103 char cbuf[30];
2104 int step, i, j, count;
2105 SDL_Surface *tmp;
2106 utf8_str *pstr = NULL;
2107 SDL_Surface *surf = NULL;
2108 SDL_Rect dest = {0, 0, 0, 0};
2109 struct effect_list *sources = effect_list_new();
2110
2111 fc_snprintf(cbuf, sizeof(cbuf), _("Happiness"));
2112
2113 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
2114 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PANEL);
2115 pstr->style |= TTF_STYLE_BOLD;
2116
2117 surf = create_text_surf_from_utf8(pstr);
2118
2119 dest.x = city_window->area.x + adj_size(2) + (adj_size(192) - surf->w) / 2;
2120 dest.y = city_window->area.y + adj_size(4) + current_theme->info_icon->h;
2121 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2122
2123 dest.x = city_window->size.x + adj_size(10);
2124 dest.y += surf->h + 1;
2125
2126 FREESURFACE(surf);
2127 FREEUTF8STR(pstr);
2128
2129 count = (pcity->feel[CITIZEN_HAPPY][FEELING_FINAL] + pcity->feel[CITIZEN_CONTENT][FEELING_FINAL]
2130 + pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL] + pcity->feel[CITIZEN_ANGRY][FEELING_FINAL]
2131 + city_specialists(pcity));
2132
2133 if (count * icons->male_happy->w > adj_size(166)) {
2134 step = (adj_size(166) - icons->male_happy->w) / (count - 1);
2135 } else {
2136 step = icons->male_happy->w;
2137 }
2138
2139 for (j = 0; j < FEELING_LAST; j++) {
2140 if (j == 0 || pcity->feel[CITIZEN_HAPPY][j - 1] != pcity->feel[CITIZEN_HAPPY][j]
2141 || pcity->feel[CITIZEN_CONTENT][j - 1] != pcity->feel[CITIZEN_CONTENT][j]
2142 || pcity->feel[CITIZEN_UNHAPPY][j - 1] != pcity->feel[CITIZEN_UNHAPPY][j]
2143 || pcity->feel[CITIZEN_ANGRY][j - 1] != pcity->feel[CITIZEN_ANGRY][j]) {
2144 int spe, spe_max;
2145
2146 if (j != 0) {
2147 create_line(city_window->dst->surface,
2148 dest.x, dest.y, dest.x + adj_size(176), dest.y,
2149 get_theme_color(COLOR_THEME_CITYDLG_FRAME));
2150 dest.y += adj_size(5);
2151 }
2152
2153 if (pcity->feel[CITIZEN_HAPPY][j]) {
2154 surf = icons->male_happy;
2155 for (i = 0; i < pcity->feel[CITIZEN_HAPPY][j]; i++) {
2156 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2157 dest.x += step;
2158 if (surf == icons->male_happy) {
2159 surf = icons->female_happy;
2160 } else {
2161 surf = icons->male_happy;
2162 }
2163 }
2164 }
2165
2166 if (pcity->feel[CITIZEN_CONTENT][j]) {
2167 surf = icons->male_content;
2168 for (i = 0; i < pcity->feel[CITIZEN_CONTENT][j]; i++) {
2169 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2170 dest.x += step;
2171 if (surf == icons->male_content) {
2172 surf = icons->female_content;
2173 } else {
2174 surf = icons->male_content;
2175 }
2176 }
2177 }
2178
2179 if (pcity->feel[CITIZEN_UNHAPPY][j]) {
2180 surf = icons->male_unhappy;
2181 for (i = 0; i < pcity->feel[CITIZEN_UNHAPPY][j]; i++) {
2182 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2183 dest.x += step;
2184 if (surf == icons->male_unhappy) {
2185 surf = icons->female_unhappy;
2186 } else {
2187 surf = icons->male_unhappy;
2188 }
2189 }
2190 }
2191
2192 if (pcity->feel[CITIZEN_ANGRY][j]) {
2193 surf = icons->male_angry;
2194 for (i = 0; i < pcity->feel[CITIZEN_ANGRY][j]; i++) {
2195 alphablit(surf, NULL, city_window->dst->surface, &dest, 255);
2196 dest.x += step;
2197 if (surf == icons->male_angry) {
2198 surf = icons->female_angry;
2199 } else {
2200 surf = icons->male_angry;
2201 }
2202 }
2203 }
2204
2205 spe_max = specialist_count();
2206 for (spe = 0 ; spe < spe_max; spe++) {
2207 if (pcity->specialists[spe]) {
2208 for (i = 0; i < pcity->specialists[spe]; i++) {
2209 alphablit(icons->specialists[spe], NULL, city_window->dst->surface,
2210 &dest, 255);
2211 dest.x += step;
2212 }
2213 }
2214 }
2215
2216 if (j == 1) { /* Luxury effect */
2217 dest.x =
2218 city_window->size.x + adj_size(187) - icons->big_luxury->w - adj_size(2);
2219 count = dest.y;
2220 dest.y += (icons->male_happy->h -
2221 icons->big_luxury->h) / 2;
2222 alphablit(icons->big_luxury, NULL, city_window->dst->surface, &dest, 255);
2223 dest.y = count;
2224 }
2225
2226 if (j == 2) { /* Improvements effects */
2227 int w = -1;
2228 count = 0;
2229
2230 get_city_bonus_effects(sources, pcity, NULL, EFT_MAKE_CONTENT);
2231
2232 effect_list_iterate(sources, psource) {
2233 requirement_vector_iterate(&(psource->reqs), preq) {
2234 if (preq->source.kind == VUT_IMPROVEMENT) {
2235 tmp = get_building_surface(preq->source.value.building);
2236 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2237 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2238
2239 count += (tmp->h + 1);
2240
2241 if (w < 0) {
2242 w = tmp->w;
2243 }
2244
2245 FREESURFACE(tmp);
2246 }
2247 } requirement_vector_iterate_end;
2248 } effect_list_iterate_end;
2249
2250 if (w >= 0) {
2251 dest.x = city_window->size.x + adj_size(187) - w - adj_size(2);
2252 i = dest.y;
2253 dest.y += (icons->male_happy->h - count) / 2;
2254
2255 effect_list_iterate(sources, psource) {
2256 requirement_vector_iterate(&(psource->reqs), preq) {
2257 if (preq->source.kind == VUT_IMPROVEMENT) {
2258 tmp = get_building_surface(preq->source.value.building);
2259 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2260 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2261
2262 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2263 dest.y += (tmp->h + 1);
2264
2265 FREESURFACE(tmp);
2266 }
2267 } requirement_vector_iterate_end;
2268 } effect_list_iterate_end;
2269
2270 dest.y = i;
2271 }
2272
2273 effect_list_clear(sources);
2274 }
2275
2276 if (j == 3) { /* police effect */
2277 dest.x = city_window->size.x + adj_size(187) - icons->police->w - adj_size(5);
2278 i = dest.y;
2279 dest.y +=
2280 (icons->male_happy->h - icons->police->h) / 2;
2281 alphablit(icons->police, NULL, city_window->dst->surface, &dest, 255);
2282 dest.y = i;
2283 }
2284
2285 if (j == 4) { /* Wonders effect */
2286 int w = -1;
2287 count = 0;
2288
2289 get_city_bonus_effects(sources, pcity, NULL, EFT_MAKE_HAPPY);
2290 effect_list_iterate(sources, psource) {
2291 requirement_vector_iterate(&(psource->reqs), preq) {
2292 if (preq->source.kind == VUT_IMPROVEMENT) {
2293 tmp = get_building_surface(preq->source.value.building);
2294 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2295 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2296
2297 count += (tmp->h + 1);
2298
2299 if (w < 0) {
2300 w = tmp->w;
2301 }
2302
2303 FREESURFACE(tmp);
2304 }
2305 } requirement_vector_iterate_end;
2306 } effect_list_iterate_end;
2307
2308 effect_list_clear(sources);
2309
2310 get_city_bonus_effects(sources, pcity, NULL, EFT_FORCE_CONTENT);
2311
2312 effect_list_iterate(sources, psource) {
2313 requirement_vector_iterate(&(psource->reqs), preq) {
2314 if (preq->source.kind == VUT_IMPROVEMENT) {
2315 tmp = get_building_surface(preq->source.value.building);
2316 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2317 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2318 count += (tmp->h + 1);
2319
2320 if (w < 0) {
2321 w = tmp->w;
2322 }
2323
2324 FREESURFACE(tmp);
2325 }
2326 } requirement_vector_iterate_end;
2327 } effect_list_iterate_end;
2328
2329 effect_list_clear(sources);
2330
2331 get_city_bonus_effects(sources, pcity, NULL, EFT_NO_UNHAPPY);
2332
2333 effect_list_iterate(sources, psource) {
2334 requirement_vector_iterate(&(psource->reqs), preq) {
2335 if (preq->source.kind == VUT_IMPROVEMENT) {
2336 tmp = get_building_surface(preq->source.value.building);
2337 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2338 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2339
2340 count += (tmp->h + 1);
2341
2342 if (w < 0) {
2343 w = tmp->w;
2344 }
2345
2346 FREESURFACE(tmp);
2347 }
2348 } requirement_vector_iterate_end;
2349 } effect_list_iterate_end;
2350
2351 effect_list_clear(sources);
2352
2353 if (w >= 0) {
2354 dest.x = city_window->size.x + adj_size(187) - surf->w - adj_size(2);
2355 i = dest.y;
2356 dest.y += (icons->male_happy->h - count) / 2;
2357
2358 get_city_bonus_effects(sources, pcity, NULL, EFT_MAKE_HAPPY);
2359
2360 effect_list_iterate(sources, psource) {
2361 requirement_vector_iterate(&(psource->reqs), preq) {
2362 if (preq->source.kind == VUT_IMPROVEMENT) {
2363 tmp = get_building_surface(preq->source.value.building);
2364 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2365 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2366
2367 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2368 dest.y += (tmp->h + 1);
2369
2370 FREESURFACE(tmp);
2371 }
2372 } requirement_vector_iterate_end;
2373 } effect_list_iterate_end;
2374
2375 effect_list_clear(sources);
2376
2377 get_city_bonus_effects(sources, pcity, NULL, EFT_FORCE_CONTENT);
2378
2379 effect_list_iterate(sources, psource) {
2380 requirement_vector_iterate(&(psource->reqs), preq) {
2381 if (preq->source.kind == VUT_IMPROVEMENT) {
2382 tmp = get_building_surface(preq->source.value.building);
2383 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2384 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2385
2386 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2387 dest.y += (tmp->h + 1);
2388
2389 FREESURFACE(tmp);
2390 }
2391 } requirement_vector_iterate_end;
2392 } effect_list_iterate_end;
2393
2394 effect_list_clear(sources);
2395
2396 get_city_bonus_effects(sources, pcity, NULL, EFT_NO_UNHAPPY);
2397
2398 effect_list_iterate(sources, psource) {
2399 requirement_vector_iterate(&(psource->reqs), preq) {
2400 if (preq->source.kind == VUT_IMPROVEMENT) {
2401 tmp = get_building_surface(preq->source.value.building);
2402 tmp = zoomSurface(tmp, DEFAULT_ZOOM * ((float)18 / tmp->w),
2403 DEFAULT_ZOOM * ((float)18 / tmp->w), 1);
2404
2405 alphablit(tmp, NULL, city_window->dst->surface, &dest, 255);
2406 dest.y += (tmp->h + 1);
2407
2408 FREESURFACE(tmp);
2409 }
2410 } requirement_vector_iterate_end;
2411 } effect_list_iterate_end;
2412
2413 effect_list_clear(sources);
2414
2415 dest.y = i;
2416 }
2417 }
2418
2419 dest.x = city_window->size.x + adj_size(10);
2420 dest.y += icons->male_happy->h + adj_size(5);
2421
2422 }
2423 }
2424
2425 effect_list_destroy(sources);
2426}
2427
2428/**********************************************************************/
2431 static void redraw_city_dialog(struct city *pcity)
2432{
2433 char cbuf[40];
2434 int i, step, count, limit;
2435 int cost = 0;
2436 SDL_Rect dest;
2437 struct widget *pwindow = pcity_dlg->end_city_widget_list;
2438 SDL_Surface *buf = NULL, *buf2 = NULL;
2439 utf8_str *pstr = NULL;
2440 int spe, spe_max;
2441
2442 refresh_city_names(pcity);
2443
2444 if ((city_unhappy(pcity) || city_celebrating(pcity) || city_happy(pcity)
2445 || cma_is_city_under_agent(pcity, NULL))
2446 ^ ((sdl2_client_flags & CF_CITY_STATUS_SPECIAL) == CF_CITY_STATUS_SPECIAL)) {
2447 /* City status was changed : NORMAL <-> DISORDER, HAPPY, CELEBR. */
2448
2449 sdl2_client_flags ^= CF_CITY_STATUS_SPECIAL;
2450
2451#if 0
2452 /* Upd. resource map */
2453 FREESURFACE(pcity_dlg->resource_map->theme);
2454 pcity_dlg->resource_map->theme = get_scaled_city_map(pcity);
2455#endif
2456
2457 /* Upd. window title */
2458 rebuild_citydlg_title_str(pcity_dlg->end_city_widget_list, pcity);
2459 }
2460
2461 /* Update resource map */
2462 FREESURFACE(pcity_dlg->resource_map->theme);
2463 pcity_dlg->resource_map->theme = get_scaled_city_map(pcity);
2464
2465 /* Redraw city dlg */
2466 redraw_group(pcity_dlg->begin_city_widget_list,
2467 pcity_dlg->end_city_widget_list, 0);
2468
2469 /* ================================================================= */
2470 fc_snprintf(cbuf, sizeof(cbuf), _("City map"));
2471
2472 pstr = create_utf8_from_char_fonto(cbuf, FONTO_DEFAULT);
2473 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_GOLD);
2474 pstr->style |= TTF_STYLE_BOLD;
2475
2476 buf = create_text_surf_from_utf8(pstr);
2477
2478 dest.x = pwindow->size.x + adj_size(196) + (adj_size(132) - buf->w) / 2;
2479 dest.y = pwindow->size.y + adj_size(49) + (adj_size(13) - buf->h) / 2;
2480
2481 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2482
2483 FREESURFACE(buf);
2484
2485 fc_snprintf(cbuf, sizeof(cbuf), _("Citizens"));
2486
2487 copy_chars_to_utf8_str(pstr, cbuf);
2488 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_LUX);
2489
2490 buf = create_text_surf_from_utf8(pstr);
2491
2492 dest.x = pwindow->size.x + adj_size(344) + (adj_size(146) - buf->w) / 2;
2493 dest.y = pwindow->size.y + adj_size(47) + (adj_size(13) - buf->h) / 2;
2494
2495 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2496
2497 FREESURFACE(buf);
2498
2499 fc_snprintf(cbuf, sizeof(cbuf), _("City improvements"));
2500
2501 copy_chars_to_utf8_str(pstr, cbuf);
2502 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_GOLD);
2503
2504 buf = create_text_surf_from_utf8(pstr);
2505
2506 dest.x = pwindow->size.x + adj_size(504) + (adj_size(132) - buf->w) / 2;
2507 dest.y = pwindow->size.y + adj_size(49) + (adj_size(13) - buf->h) / 2;
2508
2509 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2510
2511 FREESURFACE(buf);
2512
2513 /* ================================================================= */
2514 /* Food label */
2515 fc_snprintf(cbuf, sizeof(cbuf), _("Food: %d per turn"),
2516 pcity->prod[O_FOOD]);
2517
2518 copy_chars_to_utf8_str(pstr, cbuf);
2519
2520 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_FOODPERTURN);
2521
2522 buf = create_text_surf_from_utf8(pstr);
2523
2524 dest.x = pwindow->size.x + adj_size(200);
2525 dest.y = pwindow->size.y + adj_size(228) + (adj_size(16) - buf->h) / 2;
2526
2527 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2528
2529 FREESURFACE(buf);
2530
2531 /* Draw food income */
2532 dest.y = pwindow->size.y + adj_size(246) + (adj_size(16) - icons->big_food->h) / 2;
2533 dest.x = pwindow->size.x + adj_size(203);
2534
2535 if (pcity->surplus[O_FOOD] >= 0) {
2536 count = pcity->prod[O_FOOD] - pcity->surplus[O_FOOD];
2537 } else {
2538 count = pcity->prod[O_FOOD];
2539 }
2540
2541 if (((icons->big_food->w + 1) * count) > adj_size(200)) {
2542 step = (adj_size(200) - icons->big_food->w) / (count - 1);
2543 } else {
2544 step = icons->big_food->w + 1;
2545 }
2546
2547 for (i = 0; i < count; i++) {
2548 alphablit(icons->big_food, NULL, pwindow->dst->surface, &dest, 255);
2549 dest.x += step;
2550 }
2551
2552 fc_snprintf(cbuf, sizeof(cbuf), Q_("?food:Surplus: %d"),
2553 pcity->surplus[O_FOOD]);
2554
2555 copy_chars_to_utf8_str(pstr, cbuf);
2556 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_FOOD_SURPLUS);
2557
2558 buf = create_text_surf_from_utf8(pstr);
2559
2560 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2561 dest.y = pwindow->size.y + adj_size(228) + (adj_size(16) - buf->h) / 2;
2562
2563 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2564
2565 FREESURFACE(buf);
2566
2567 /* Draw surplus of food */
2568 if (pcity->surplus[O_FOOD]) {
2569 if (pcity->surplus[O_FOOD] > 0) {
2570 count = pcity->surplus[O_FOOD];
2571 buf = icons->big_food;
2572 } else {
2573 count = -1 * pcity->surplus[O_FOOD];
2574 buf = icons->big_food_corr;
2575 }
2576
2577 dest.x = pwindow->size.x + adj_size(423);
2578 dest.y = pwindow->size.y + adj_size(246) + (adj_size(16) - buf->h) / 2;
2579
2580 if (count > 2) {
2581 if (count < 18) {
2582 step = (adj_size(30) - buf->w) / (count - 1);
2583 } else {
2584 step = 1;
2585 count = 17;
2586 }
2587 } else {
2588 step = buf->w + 1;
2589 }
2590
2591 for (i = 0; i < count; i++) {
2592 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2593 dest.x -= step;
2594 }
2595 }
2596
2597 /* ================================================================= */
2598 /* Productions label */
2599 fc_snprintf(cbuf, sizeof(cbuf), _("Production: %d (%d) per turn"),
2600 pcity->surplus[O_SHIELD],
2601 pcity->prod[O_SHIELD] + pcity->waste[O_SHIELD]);
2602
2603 copy_chars_to_utf8_str(pstr, cbuf);
2604 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PROD);
2605
2606 buf = create_text_surf_from_utf8(pstr);
2607
2608 dest.x = pwindow->size.x + adj_size(200);
2609 dest.y = pwindow->size.y + adj_size(263) + (adj_size(15) - buf->h) / 2;
2610
2611 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2612
2613 FREESURFACE(buf);
2614
2615 /* Draw productions shields */
2616 if (pcity->surplus[O_SHIELD]) {
2617
2618 if (pcity->surplus[O_SHIELD] > 0) {
2619 count = pcity->surplus[O_SHIELD] + pcity->waste[O_SHIELD];
2620 buf = icons->big_shield;
2621 } else {
2622 count = -1 * pcity->surplus[O_SHIELD];
2623 buf = icons->big_shield_corr;
2624 }
2625
2626 dest.y = pwindow->size.y + adj_size(281) + (adj_size(16) - buf->h) / 2;
2627 dest.x = pwindow->size.x + adj_size(203);
2628
2629 if ((buf->w * count) > adj_size(200)) {
2630 step = (adj_size(200) - buf->w) / (count - 1);
2631 } else {
2632 step = buf->w;
2633 }
2634
2635 for (i = 0; i < count; i++) {
2636 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2637 dest.x += step;
2638 if (i > pcity->surplus[O_SHIELD]) {
2639 buf = icons->big_shield_corr;
2640 }
2641 }
2642 }
2643
2644 /* Support shields label */
2645 fc_snprintf(cbuf, sizeof(cbuf), Q_("?production:Support: %d"),
2646 pcity->prod[O_SHIELD] + pcity->waste[O_SHIELD] -
2647 pcity->surplus[O_SHIELD]);
2648
2649 copy_chars_to_utf8_str(pstr, cbuf);
2650 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_SUPPORT);
2651
2652 buf = create_text_surf_from_utf8(pstr);
2653
2654 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2655 dest.y = pwindow->size.y + adj_size(263) + (adj_size(15) - buf->h) / 2;
2656
2657 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2658
2659 FREESURFACE(buf);
2660
2661 /* Draw support shields */
2662 if (pcity->prod[O_SHIELD] - pcity->surplus[O_SHIELD]) {
2663 dest.x = pwindow->size.x + adj_size(423);
2664 dest.y =
2665 pwindow->size.y + adj_size(281) + (adj_size(16) - icons->big_shield->h) / 2;
2666
2667 if ((icons->big_shield->w + 1) * (pcity->prod[O_SHIELD] -
2668 pcity->surplus[O_SHIELD]) > adj_size(30)) {
2669 step =
2670 (adj_size(30) - icons->big_food->w) / (pcity->prod[O_SHIELD] -
2671 pcity->surplus[O_SHIELD] - 1);
2672 } else {
2673 step = icons->big_shield->w + 1;
2674 }
2675
2676 for (i = 0; i < (pcity->prod[O_SHIELD] - pcity->surplus[O_SHIELD]); i++) {
2677 alphablit(icons->big_shield, NULL, pwindow->dst->surface, &dest, 255);
2678 dest.x -= step;
2679 }
2680 }
2681
2682 /* ================================================================= */
2683 /* Trade label */
2684 fc_snprintf(cbuf, sizeof(cbuf), _("Trade: %d per turn"),
2685 pcity->surplus[O_TRADE]);
2686
2687 copy_chars_to_utf8_str(pstr, cbuf);
2688 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_TRADE);
2689
2690 buf = create_text_surf_from_utf8(pstr);
2691
2692 dest.x = pwindow->size.x + adj_size(200);
2693 dest.y = pwindow->size.y + adj_size(298) + (adj_size(15) - buf->h) / 2;
2694
2695 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2696
2697 FREESURFACE(buf);
2698
2699 /* Draw total (trade - corruption) */
2700 if (pcity->surplus[O_TRADE]) {
2701 dest.y =
2702 pwindow->size.y + adj_size(316) + (adj_size(16) - icons->big_trade->h) / 2;
2703 dest.x = pwindow->size.x + adj_size(203);
2704
2705 if (((icons->big_trade->w + 1) * pcity->surplus[O_TRADE]) > adj_size(200)) {
2706 step = (adj_size(200) - icons->big_trade->w) / (pcity->surplus[O_TRADE] - 1);
2707 } else {
2708 step = icons->big_trade->w + 1;
2709 }
2710
2711 for (i = 0; i < pcity->surplus[O_TRADE]; i++) {
2712 alphablit(icons->big_trade, NULL, pwindow->dst->surface, &dest, 255);
2713 dest.x += step;
2714 }
2715 }
2716
2717 /* Corruption label */
2718 fc_snprintf(cbuf, sizeof(cbuf), _("Corruption: %d"),
2719 pcity->waste[O_TRADE]);
2720
2721 copy_chars_to_utf8_str(pstr, cbuf);
2722 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_CORRUPTION);
2723
2724 buf = create_text_surf_from_utf8(pstr);
2725
2726 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2727 dest.y = pwindow->size.y + adj_size(298) + (adj_size(15) - buf->h) / 2;
2728
2729 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2730
2731 FREESURFACE(buf);
2732
2733 /* Draw corruption */
2734 if (pcity->waste[O_TRADE] > 0) {
2735 dest.x = pwindow->size.x + adj_size(423);
2736 dest.y =
2737 pwindow->size.y + adj_size(316) + (adj_size(16) - icons->big_trade->h) / 2;
2738
2739 if (((icons->big_trade_corr->w + 1) * pcity->waste[O_TRADE]) > adj_size(30)) {
2740 step =
2741 (adj_size(30) - icons->big_trade_corr->w) / (pcity->waste[O_TRADE] - 1);
2742 } else {
2743 step = icons->big_trade_corr->w + 1;
2744 }
2745
2746 for (i = 0; i < pcity->waste[O_TRADE]; i++) {
2747 alphablit(icons->big_trade_corr, NULL, pwindow->dst->surface,
2748 &dest, 255);
2749 dest.x -= step;
2750 }
2751 }
2752
2753 /* ================================================================= */
2754 /* Gold label */
2755 fc_snprintf(cbuf, sizeof(cbuf), _("Gold: %d (%d) per turn"),
2756 pcity->surplus[O_GOLD], pcity->prod[O_GOLD]);
2757
2758 copy_chars_to_utf8_str(pstr, cbuf);
2759 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_GOLD);
2760
2761 buf = create_text_surf_from_utf8(pstr);
2762
2763 dest.x = pwindow->size.x + adj_size(200);
2764 dest.y = pwindow->size.y + adj_size(342) + (adj_size(15) - buf->h) / 2;
2765
2766 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2767
2768 FREESURFACE(buf);
2769
2770 /* Draw coins */
2771 count = pcity->surplus[O_GOLD];
2772 if (count) {
2773
2774 if (count > 0) {
2775 buf = icons->big_coin;
2776 } else {
2777 count *= -1;
2778 buf = icons->big_coin_corr;
2779 }
2780
2781 dest.y = pwindow->size.y + adj_size(359) + (adj_size(16) - buf->h) / 2;
2782 dest.x = pwindow->size.x + adj_size(203);
2783
2784 if ((buf->w * count) > adj_size(110)) {
2785 step = (adj_size(110) - buf->w) / (count - 1);
2786 if (!step) {
2787 step = 1;
2788 count = 97;
2789 }
2790 } else {
2791 step = buf->w;
2792 }
2793
2794 for (i = 0; i < count; i++) {
2795 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2796 dest.x += step;
2797 }
2798
2799 }
2800
2801 /* Upkeep label */
2802 fc_snprintf(cbuf, sizeof(cbuf), _("Upkeep: %d"),
2803 pcity->prod[O_GOLD] - pcity->surplus[O_GOLD]);
2804
2805 copy_chars_to_utf8_str(pstr, cbuf);
2806 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_UPKEEP);
2807
2808 buf = create_text_surf_from_utf8(pstr);
2809
2810 dest.x = pwindow->size.x + adj_size(440) - buf->w;
2811 dest.y = pwindow->size.y + adj_size(342) + (adj_size(15) - buf->h) / 2;
2812
2813 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2814
2815 FREESURFACE(buf);
2816
2817 /* Draw upkeep */
2818 count = pcity->surplus[O_GOLD];
2819 if (pcity->prod[O_GOLD] - count) {
2820
2821 dest.x = pwindow->size.x + adj_size(423);
2822 dest.y = pwindow->size.y + adj_size(359)
2823 + (adj_size(16) - icons->big_coin_upkeep->h) / 2;
2824
2825 if (((icons->big_coin_upkeep->w + 1) *
2826 (pcity->prod[O_GOLD] - count)) > adj_size(110)) {
2827 step = (adj_size(110) - icons->big_coin_upkeep->w) /
2828 (pcity->prod[O_GOLD] - count - 1);
2829 } else {
2830 step = icons->big_coin_upkeep->w + 1;
2831 }
2832
2833 for (i = 0; i < (pcity->prod[O_GOLD] - count); i++) {
2834 alphablit(icons->big_coin_upkeep, NULL, pwindow->dst->surface,
2835 &dest, 255);
2836 dest.x -= step;
2837 }
2838 }
2839
2840 /* ================================================================= */
2841 /* Science label */
2842 fc_snprintf(cbuf, sizeof(cbuf), _("Science: %d per turn"),
2843 pcity->prod[O_SCIENCE]);
2844
2845 copy_chars_to_utf8_str(pstr, cbuf);
2846 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_SCIENCE);
2847
2848 buf = create_text_surf_from_utf8(pstr);
2849
2850 dest.x = pwindow->size.x + adj_size(200);
2851 dest.y = pwindow->size.y + adj_size(376) + (adj_size(15) - buf->h) / 2;
2852
2853 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2854
2855 FREESURFACE(buf);
2856
2857 /* Draw colb */
2858 count = pcity->prod[O_SCIENCE];
2859 if (count) {
2860
2861 dest.y =
2862 pwindow->size.y + adj_size(394) + (adj_size(16) - icons->big_colb->h) / 2;
2863 dest.x = pwindow->size.x + adj_size(203);
2864
2865 if ((icons->big_colb->w * count) > adj_size(235)) {
2866 step = (adj_size(235) - icons->big_colb->w) / (count - 1);
2867 if (!step) {
2868 step = 1;
2869 count = 222;
2870 }
2871 } else {
2872 step = icons->big_colb->w;
2873 }
2874
2875 for (i = 0; i < count; i++) {
2876 alphablit(icons->big_colb, NULL, pwindow->dst->surface, &dest, 255);
2877 dest.x += step;
2878 }
2879 }
2880
2881 /* ================================================================= */
2882 /* Luxury label */
2883 fc_snprintf(cbuf, sizeof(cbuf), _("Luxury: %d per turn"),
2884 pcity->prod[O_LUXURY]);
2885
2886 copy_chars_to_utf8_str(pstr, cbuf);
2887 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_LUX);
2888
2889 buf = create_text_surf_from_utf8(pstr);
2890
2891 dest.x = pwindow->size.x + adj_size(200);
2892 dest.y = pwindow->size.y + adj_size(412) + (adj_size(15) - buf->h) / 2;
2893
2894 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2895
2896 FREESURFACE(buf);
2897
2898 /* Draw luxury */
2899 if (pcity->prod[O_LUXURY]) {
2900
2901 dest.y =
2902 pwindow->size.y + adj_size(429) + (adj_size(16) - icons->big_luxury->h) / 2;
2903 dest.x = pwindow->size.x + adj_size(203);
2904
2905 if ((icons->big_luxury->w * pcity->prod[O_LUXURY]) > adj_size(235)) {
2906 step =
2907 (adj_size(235) - icons->big_luxury->w) / (pcity->prod[O_LUXURY] - 1);
2908 } else {
2909 step = icons->big_luxury->w;
2910 }
2911
2912 for (i = 0; i < pcity->prod[O_LUXURY]; i++) {
2913 alphablit(icons->big_luxury, NULL, pwindow->dst->surface, &dest, 255);
2914 dest.x += step;
2915 }
2916 }
2917
2918 /* ================================================================= */
2919 /* Turns to grow label */
2920 count = city_turns_to_grow(pcity);
2921 if (count == 0) {
2922 fc_snprintf(cbuf, sizeof(cbuf), _("City growth: blocked"));
2923 } else if (count == FC_INFINITY) {
2924 fc_snprintf(cbuf, sizeof(cbuf), _("City growth: never"));
2925 } else if (count < 0) {
2926 /* Turns until famine */
2927 fc_snprintf(cbuf, sizeof(cbuf),
2928 _("City shrinks: %d %s"), abs(count),
2929 PL_("turn", "turns", abs(count)));
2930 } else {
2931 fc_snprintf(cbuf, sizeof(cbuf),
2932 _("City growth: %d %s"), count,
2933 PL_("turn", "turns", count));
2934 }
2935
2936 copy_chars_to_utf8_str(pstr, cbuf);
2937
2938 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_GROWTH);
2939
2940 buf = create_text_surf_from_utf8(pstr);
2941
2942 dest.x = pwindow->size.x + adj_size(445) + (adj_size(192) - buf->w) / 2;
2943 dest.y = pwindow->size.y + adj_size(227);
2944
2945 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2946
2947 FREESURFACE(buf);
2948
2949 count = (city_granary_size(city_size_get(pcity))) / 10;
2950
2951 if (count > 12) {
2952 step = (adj_size(168) - icons->big_food->h) / adj_size((11 + count - 12));
2953 i = (count - 1) * step + 14;
2954 } else {
2955 step = icons->big_food->h;
2956 i = count * step;
2957 }
2958
2959 /* Food stock */
2960 if (get_city_bonus(pcity, EFT_GROWTH_FOOD) > 0) {
2961 /* With granary */
2962 /* Stocks label */
2963 copy_chars_to_utf8_str(pstr, _("Stock"));
2964 buf = create_text_surf_from_utf8(pstr);
2965
2966 dest.x = pwindow->size.x + adj_size(461) + (adj_size(76) - buf->w) / 2;
2967 dest.y = pwindow->size.y + adj_size(258) - buf->h - 1;
2968
2969 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2970
2971 FREESURFACE(buf);
2972
2973 /* Granary label */
2974 copy_chars_to_utf8_str(pstr, _("Granary"));
2975 buf = create_text_surf_from_utf8(pstr);
2976
2977 dest.x = pwindow->size.x + adj_size(549) + (adj_size(76) - buf->w) / 2;
2978 dest.y = pwindow->size.y + adj_size(258) - buf->h - 1;
2979
2980 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
2981
2982 FREESURFACE(buf);
2983
2984 /* Draw bcgd granary */
2985 dest.x = pwindow->size.x + adj_size(462);
2986 dest.y = pwindow->size.y + adj_size(260);
2987 dest.w = 70 + 4;
2988 dest.h = i + 4;
2989
2990 fill_rect_alpha(pwindow->dst->surface, &dest,
2991 get_theme_color(COLOR_THEME_CITYDLG_GRANARY));
2992
2993 create_frame(pwindow->dst->surface,
2994 dest.x - 1, dest.y - 1, dest.w, dest.h,
2995 get_theme_color(COLOR_THEME_CITYDLG_FRAME));
2996
2997 /* Draw bcgd stocks*/
2998 dest.x = pwindow->size.x + adj_size(550);
2999 dest.y = pwindow->size.y + adj_size(260);
3000
3001 fill_rect_alpha(pwindow->dst->surface, &dest,
3002 get_theme_color(COLOR_THEME_CITYDLG_STOCKS));
3003
3004 create_frame(pwindow->dst->surface,
3005 dest.x - 1, dest.y - 1, dest.w, dest.h,
3006 get_theme_color(COLOR_THEME_CITYDLG_FRAME));
3007
3008 /* Draw stocks icons */
3009 cost = city_granary_size(city_size_get(pcity));
3010 if (pcity->food_stock + pcity->surplus[O_FOOD] > cost) {
3011 count = cost;
3012 } else {
3013 if (pcity->surplus[O_FOOD] < 0) {
3014 count = pcity->food_stock;
3015 } else {
3016 count = pcity->food_stock + pcity->surplus[O_FOOD];
3017 }
3018 }
3019 cost /= 2;
3020
3021 if (pcity->surplus[O_FOOD] < 0) {
3022 limit = pcity->food_stock + pcity->surplus[O_FOOD];
3023 if (limit < 0) {
3024 limit = 0;
3025 }
3026 } else {
3027 limit = 0xffff;
3028 }
3029
3030 dest.x += 2;
3031 dest.y += 2;
3032 i = 0;
3033 buf = icons->big_food;
3034 while (count && cost) {
3035 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3036 dest.x += buf->w;
3037 count--;
3038 cost--;
3039 i++;
3040 if (dest.x > pwindow->size.x + adj_size(620)) {
3041 dest.x = pwindow->size.x + adj_size(552);
3042 dest.y += step;
3043 }
3044 if (i > limit - 1) {
3045 buf = icons->big_food_corr;
3046 } else {
3047 if (i > pcity->food_stock - 1) {
3048 buf = icons->big_food_surplus;
3049 }
3050 }
3051 }
3052 /* Draw granary icons */
3053 dest.x = pwindow->size.x + adj_size(462) + adj_size(2);
3054 dest.y = pwindow->size.y + adj_size(260) + adj_size(2);
3055
3056 while (count) {
3057 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3058 dest.x += buf->w;
3059 count--;
3060 i++;
3061
3062 if (dest.x > pwindow->size.x + adj_size(532)) {
3063 dest.x = pwindow->size.x + adj_size(464);
3064 dest.y += step;
3065 }
3066
3067 if (i > limit - 1) {
3068 buf = icons->big_food_corr;
3069 } else if (i > pcity->food_stock - 1) {
3070 buf = icons->big_food_surplus;
3071 }
3072 }
3073
3074 } else {
3075 /* Without granary */
3076 /* Stocks label */
3077 copy_chars_to_utf8_str(pstr, _("Stock"));
3078 buf = create_text_surf_from_utf8(pstr);
3079
3080 dest.x = pwindow->size.x + adj_size(461) + (adj_size(144) - buf->w) / 2;
3081 dest.y = pwindow->size.y + adj_size(258) - buf->h - 1;
3082
3083 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3084 FREESURFACE(buf);
3085
3086 /* Food stock */
3087
3088 /* Draw bcgd */
3089 dest.x = pwindow->size.x + adj_size(462);
3090 dest.y = pwindow->size.y + adj_size(260);
3091 dest.w = adj_size(144);
3092 dest.h = i + adj_size(4);
3093
3094 fill_rect_alpha(pwindow->dst->surface, &dest,
3095 get_theme_color(COLOR_THEME_CITYDLG_FOODSTOCK));
3096
3097 create_frame(pwindow->dst->surface,
3098 dest.x - 1, dest.y - 1, dest.w, dest.h,
3099 get_theme_color(COLOR_THEME_CITYDLG_FRAME));
3100
3101 /* Draw icons */
3102 cost = city_granary_size(city_size_get(pcity));
3103 if (pcity->food_stock + pcity->surplus[O_FOOD] > cost) {
3104 count = cost;
3105 } else {
3106 if (pcity->surplus[O_FOOD] < 0) {
3107 count = pcity->food_stock;
3108 } else {
3109 count = pcity->food_stock + pcity->surplus[O_FOOD];
3110 }
3111 }
3112
3113 if (pcity->surplus[O_FOOD] < 0) {
3114 limit = pcity->food_stock + pcity->surplus[O_FOOD];
3115 if (limit < 0) {
3116 limit = 0;
3117 }
3118 } else {
3119 limit = 0xffff;
3120 }
3121
3122 dest.x += adj_size(2);
3123 dest.y += adj_size(2);
3124 i = 0;
3125 buf = icons->big_food;
3126 while (count) {
3127 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3128 dest.x += buf->w;
3129 count--;
3130 i++;
3131
3132 if (dest.x > pwindow->size.x + adj_size(602)) {
3133 dest.x = pwindow->size.x + adj_size(464);
3134 dest.y += step;
3135 }
3136 if (i > limit - 1) {
3137 buf = icons->big_food_corr;
3138 } else {
3139 if (i > pcity->food_stock - 1) {
3140 buf = icons->big_food_surplus;
3141 }
3142 }
3143 }
3144 }
3145 /* ================================================================= */
3146
3147 /* draw productions shields progress */
3148 if (VUT_UTYPE == pcity->production.kind) {
3149 const struct unit_type *punittype = pcity->production.value.utype;
3150
3151 cost = utype_build_shield_cost(pcity, NULL, punittype);
3152 count = cost / 10;
3153
3154 copy_chars_to_utf8_str(pstr, utype_name_translation(punittype));
3155 buf = create_text_surf_from_utf8(pstr);
3156
3157 buf2 = get_unittype_surface(punittype, direction8_invalid());
3158 buf2 = zoomSurface(buf2, DEFAULT_ZOOM * ((float)32 / buf2->h),
3159 DEFAULT_ZOOM * ((float)32 / buf2->h), 1);
3160
3161 /* blit unit icon */
3162 dest.x = pwindow->size.x + adj_size(6) + (adj_size(185) - (buf->w + buf2->w + adj_size(5))) / 2;
3163 dest.y = pwindow->size.y + adj_size(233);
3164
3165 alphablit(buf2, NULL, pwindow->dst->surface, &dest, 255);
3166
3167 dest.y += (buf2->h - buf->h) / 2;
3168 dest.x += buf2->w + adj_size(5);
3169
3170 } else {
3171 const struct impr_type *pimprove = pcity->production.value.building;
3172
3173 if (is_convert_improvement(pimprove)) {
3174
3175 if (pcity_dlg->buy_button
3176 && get_wstate(pcity_dlg->buy_button) != FC_WS_DISABLED) {
3177 set_wstate(pcity_dlg->buy_button, FC_WS_DISABLED);
3178 widget_redraw(pcity_dlg->buy_button);
3179 }
3180
3181 /* You can't see capitalization progress */
3182 count = 0;
3183
3184 } else {
3185
3186 if (city_can_buy(pcity) && pcity_dlg->buy_button
3187 && (get_wstate(pcity_dlg->buy_button) == FC_WS_DISABLED)) {
3188 set_wstate(pcity_dlg->buy_button, FC_WS_NORMAL);
3189 widget_redraw(pcity_dlg->buy_button);
3190 }
3191
3192 cost = impr_build_shield_cost(pcity, pimprove);
3193 count = cost / 10;
3194 }
3195
3196 copy_chars_to_utf8_str(pstr, improvement_name_translation(pimprove));
3197 buf = create_text_surf_from_utf8(pstr);
3198
3199 buf2 = get_building_surface(pcity->production.value.building);
3200 buf2 = zoomSurface(buf2, DEFAULT_ZOOM * ((float)32 / buf2->h),
3201 DEFAULT_ZOOM * ((float)32 / buf2->h), 1);
3202
3203 /* blit impr icon */
3204 dest.x = pwindow->size.x + adj_size(6) + (adj_size(185) - (buf->w + buf2->w + adj_size(5))) / 2;
3205 dest.y = pwindow->size.y + adj_size(233);
3206
3207 alphablit(buf2, NULL, pwindow->dst->surface, &dest, 255);
3208
3209 dest.y += (buf2->h - buf->h) / 2;
3210 dest.x += buf2->w + adj_size(5);
3211 }
3212
3213 /* blit unit/impr name */
3214 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3215
3216 FREESURFACE(buf);
3217 FREESURFACE(buf2);
3218
3219 if (count) {
3220 if (count > 11) {
3221 step = (adj_size(154) - icons->big_shield->h) / adj_size((10 + count - 11));
3222
3223 if (!step) {
3224 step = 1;
3225 }
3226
3227 i = (step * (count - 1)) + icons->big_shield->h;
3228 } else {
3229 step = icons->big_shield->h;
3230 i = count * step;
3231 }
3232
3233 /* draw shield stock background */
3234 dest.x = pwindow->size.x + adj_size(28);
3235 dest.y = pwindow->size.y + adj_size(270);
3236 dest.w = adj_size(144);
3237 dest.h = i + adj_size(4);
3238
3239 fill_rect_alpha(pwindow->dst->surface, &dest,
3240 get_theme_color(COLOR_THEME_CITYDLG_SHIELDSTOCK));
3241
3242 create_frame(pwindow->dst->surface,
3243 dest.x - 1, dest.y - 1, dest.w, dest.h,
3244 get_theme_color(COLOR_THEME_CITYDLG_FRAME));
3245
3246 /* draw production progress text */
3247 dest.y = pwindow->size.y + adj_size(270) + dest.h + 1;
3248
3249 if (pcity->shield_stock < cost) {
3250 count = city_production_turns_to_build(pcity, TRUE);
3251 if (count == 999) {
3252 fc_snprintf(cbuf, sizeof(cbuf), "(%d/%d) %s!",
3253 pcity->shield_stock, cost, _("blocked"));
3254 } else {
3255 fc_snprintf(cbuf, sizeof(cbuf), "(%d/%d) %d %s",
3256 pcity->shield_stock, cost, count, PL_("turn", "turns", count));
3257 }
3258 } else {
3259 fc_snprintf(cbuf, sizeof(cbuf), "(%d/%d) %s!",
3260 pcity->shield_stock, cost, _("finished"));
3261 }
3262
3263 copy_chars_to_utf8_str(pstr, cbuf);
3264 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_LUX);
3265
3266 buf = create_text_surf_from_utf8(pstr);
3267
3268 dest.x = pwindow->size.x + adj_size(6) + (adj_size(185) - buf->w) / 2;
3269
3270 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3271
3272 FREEUTF8STR(pstr);
3273 FREESURFACE(buf);
3274
3275 /* draw shield stock */
3276 if (pcity->shield_stock + pcity->surplus[O_SHIELD] <= cost) {
3277 count = pcity->shield_stock + pcity->surplus[O_SHIELD];
3278 } else {
3279 count = cost;
3280 }
3281 dest.x = pwindow->size.x + adj_size(29) + adj_size(2);
3282 dest.y = pwindow->size.y + adj_size(270) + adj_size(2);
3283 i = 0;
3284
3285 buf = icons->big_shield;
3286 while (count > 0) {
3287 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3288 dest.x += buf->w;
3289 count--;
3290 if (dest.x > pwindow->size.x + adj_size(170)) {
3291 dest.x = pwindow->size.x + adj_size(31);
3292 dest.y += step;
3293 }
3294 i++;
3295 if (i > pcity->shield_stock - 1) {
3296 buf = icons->big_shield_surplus;
3297 }
3298 }
3299 }
3300
3301 /* count != 0 */
3302 /* ==================================================== */
3303 /* Draw Citizens */
3304 count = (pcity->feel[CITIZEN_HAPPY][FEELING_FINAL] + pcity->feel[CITIZEN_CONTENT][FEELING_FINAL]
3305 + pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL] + pcity->feel[CITIZEN_ANGRY][FEELING_FINAL]
3306 + city_specialists(pcity));
3307
3308 buf = get_citizen_surface(CITIZEN_HAPPY, 0);
3309
3310 if (count > 13) {
3311 step = (adj_size(440) - buf->w) / (adj_size(12 + count - 13));
3312 } else {
3313 step = buf->w;
3314 }
3315
3316 pcity_dlg->citizen_step = step;
3317
3318 dest.x = pwindow->size.x + adj_size(198);
3319 dest.y = pwindow->size.y + pwindow->area.y + adj_size(1) + (adj_size(22) - buf->h) / 2;
3320 pcity_dlg->spec_area.x = pwindow->dst->dest_rect.x + dest.x;
3321 pcity_dlg->spec_area.y = pwindow->dst->dest_rect.y + dest.y;
3322 pcity_dlg->spec_area.w = count * step;
3323 pcity_dlg->spec_area.h = buf->h;
3324
3325 if (pcity->feel[CITIZEN_HAPPY][FEELING_FINAL]) {
3326 for (i = 0; i < pcity->feel[CITIZEN_HAPPY][FEELING_FINAL]; i++) {
3327 buf = adj_surf(get_citizen_surface(CITIZEN_HAPPY, i));
3328
3329 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3330 dest.x += step;
3331 FREESURFACE(buf);
3332 }
3333 }
3334
3335 if (pcity->feel[CITIZEN_CONTENT][FEELING_FINAL]) {
3336 for (i = 0; i < pcity->feel[CITIZEN_CONTENT][FEELING_FINAL]; i++) {
3337 buf = adj_surf(get_citizen_surface(CITIZEN_CONTENT, i));
3338
3339 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3340 dest.x += step;
3341 FREESURFACE(buf);
3342 }
3343 }
3344
3345 if (pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL]) {
3346 for (i = 0; i < pcity->feel[CITIZEN_UNHAPPY][FEELING_FINAL]; i++) {
3347 buf = adj_surf(get_citizen_surface(CITIZEN_UNHAPPY, i));
3348
3349 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3350 dest.x += step;
3351 FREESURFACE(buf);
3352 }
3353 }
3354
3355 if (pcity->feel[CITIZEN_ANGRY][FEELING_FINAL]) {
3356 for (i = 0; i < pcity->feel[CITIZEN_ANGRY][FEELING_FINAL]; i++) {
3357 buf = adj_surf(get_citizen_surface(CITIZEN_ANGRY, i));
3358
3359 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3360 dest.x += step;
3361 FREESURFACE(buf);
3362 }
3363 }
3364
3365 spe_max = specialist_count();
3366 for (spe = 0; spe < spe_max; spe++) {
3367 if (pcity->specialists[spe] > 0) {
3368 buf = adj_surf(get_citizen_surface(CITIZEN_SPECIALIST + spe, i));
3369
3370 for (i = 0; i < pcity->specialists[spe]; i++) {
3371 alphablit(buf, NULL, pwindow->dst->surface, &dest, 255);
3372 dest.x += step;
3373 }
3374 FREESURFACE(buf);
3375 }
3376 }
3377
3378 /* ==================================================== */
3379
3380
3381 switch (pcity_dlg->page) {
3382 case INFO_PAGE:
3383 redraw_info_city_dialog(pwindow, pcity);
3384 break;
3385
3386 case HAPPINESS_PAGE:
3387 redraw_happiness_city_dialog(pwindow, pcity);
3388 break;
3389
3390 case ARMY_PAGE:
3391 redraw_army_city_dialog(pwindow, pcity);
3392 break;
3393
3394 case SUPPORTED_UNITS_PAGE:
3395 redraw_supported_units_city_dialog(pwindow, pcity);
3396 break;
3397
3398 case MISC_PAGE:
3399 redraw_misc_city_dialog(pwindow, pcity);
3400 break;
3401
3402 default:
3403 break;
3404
3405 }
3406
3407 /* redraw "sell improvement" dialog */
3408 redraw_group(pcity_dlg->begin_city_menu_widget_list,
3409 pcity_dlg->end_city_menu_widget_list, 0);
3410
3411 widget_mark_dirty(pwindow);
3412}
3413
3414/* ============================================================== */
3415
3416/**********************************************************************/
3419 static void rebuild_imprm_list(struct city *pcity)
3420{
3421 int count = 0;
3422 struct widget *pwindow = pcity_dlg->end_city_widget_list;
3423 struct widget *add_dock, *buf, *last;
3424 SDL_Surface *logo = NULL;
3425 utf8_str *pstr = NULL;
3426 struct player *owner = city_owner(pcity);
3427 int prev_y = 0;
3428
3429 if (!pcity_dlg->imprv) {
3430 pcity_dlg->imprv = fc_calloc(1, sizeof(struct advanced_dialog));
3431 }
3432
3433 /* free old list */
3434 if (pcity_dlg->imprv->end_widget_list) {
3435 del_group_of_widgets_from_gui_list(pcity_dlg->imprv->begin_widget_list,
3436 pcity_dlg->imprv->end_widget_list);
3437 pcity_dlg->imprv->end_widget_list = NULL;
3438 pcity_dlg->imprv->begin_widget_list = NULL;
3439 pcity_dlg->imprv->end_active_widget_list = NULL;
3440 pcity_dlg->imprv->begin_active_widget_list = NULL;
3441 pcity_dlg->imprv->active_widget_list = NULL;
3442 FC_FREE(pcity_dlg->imprv->scroll);
3443 }
3444
3445 add_dock = pcity_dlg->add_point;
3446 buf = last = add_dock;
3447
3448 /* Alloc new */
3449 city_built_iterate(pcity, pimprove) {
3450 pstr = create_utf8_from_char_fonto(
3451 city_improvement_name_translation(pcity, pimprove),
3452 FONTO_DEFAULT);
3453 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_IMPR);
3454
3455 pstr->style |= TTF_STYLE_BOLD;
3456
3457 logo = get_building_surface(pimprove);
3458 logo = resize_surface_box(logo, adj_size(22), adj_size(22), 1, TRUE, TRUE);
3459
3460 buf = create_iconlabel(logo, pwindow->dst, pstr,
3461 (WF_FREE_THEME | WF_RESTORE_BACKGROUND));
3462
3463 buf->size.x = pwindow->size.x + adj_size(450);
3464 buf->size.y = pwindow->size.y + adj_size(66) + prev_y;
3465
3466 prev_y += buf->size.h;
3467
3468 buf->size.w = adj_size(165);
3469 buf->action = sell_imprvm_dlg_callback;
3470
3471 if (!pcity_dlg->pcity->did_sell
3472 && !is_wonder(pimprove) && (owner == client.conn.playing)) {
3473 set_wstate(buf, FC_WS_NORMAL);
3474 }
3475
3476 buf->id = MAX_ID - improvement_number(pimprove) - 3000;
3477 widget_add_as_prev(buf, add_dock);
3478 add_dock = buf;
3479
3480 count++;
3481
3482 if (count > 7) {
3483 set_wflag(buf, WF_HIDDEN);
3484 }
3485
3486 } city_built_iterate_end;
3487
3488 if (count) {
3489 pcity_dlg->imprv->end_widget_list = last->prev;
3490 pcity_dlg->imprv->end_active_widget_list = pcity_dlg->imprv->end_widget_list;
3491 pcity_dlg->imprv->begin_widget_list = buf;
3492 pcity_dlg->imprv->begin_active_widget_list = pcity_dlg->imprv->begin_widget_list;
3493
3494 if (count > 7) {
3495 pcity_dlg->imprv->active_widget_list = pcity_dlg->imprv->end_active_widget_list;
3496
3497 create_vertical_scrollbar(pcity_dlg->imprv, 1, 7, TRUE, TRUE);
3498
3499 setup_vertical_scrollbar_area(pcity_dlg->imprv->scroll,
3500 pwindow->size.x + adj_size(635),
3501 pwindow->size.y + adj_size(66),
3502 adj_size(155), TRUE);
3503 }
3504 }
3505}
3506
3507/**********************************************************************/
3510 static void rebuild_citydlg_title_str(struct widget *pwindow,
3511 struct city *pcity)
3512{
3513 char cbuf[512];
3514
3515 fc_snprintf(cbuf, sizeof(cbuf),
3516 _("City of %s (Population %s citizens)"),
3517 city_name_get(pcity),
3518 population_to_text(city_population(pcity)));
3519
3520 if (city_unhappy(pcity)) {
3521 /* TRANS: preserve leading space */
3522 fc_strlcat(cbuf, _(" - DISORDER"), sizeof(cbuf));
3523 } else {
3524 if (city_celebrating(pcity)) {
3525 /* TRANS: preserve leading space */
3526 fc_strlcat(cbuf, _(" - celebrating"), sizeof(cbuf));
3527 } else {
3528 if (city_happy(pcity)) {
3529 /* TRANS: preserve leading space */
3530 fc_strlcat(cbuf, _(" - happy"), sizeof(cbuf));
3531 }
3532 }
3533 }
3534
3535 if (cma_is_city_under_agent(pcity, NULL)) {
3536 /* TRANS: preserve leading space */
3537 fc_strlcat(cbuf, _(" - under Citizen Governor control."), sizeof(cbuf));
3538 }
3539
3540 copy_chars_to_utf8_str(pwindow->string_utf8, cbuf);
3541}
3542
3543
3544/* ========================= Public ================================== */
3545
3546/**********************************************************************/
3550 void real_city_dialog_popup(struct city *pcity)
3551{
3552 struct widget *pwindow = NULL, *buf = NULL;
3553 SDL_Surface *logo = NULL;
3554 utf8_str *pstr = NULL;
3555 int cs;
3556 struct player *owner = city_owner(pcity);
3557 SDL_Rect area;
3558
3559 if (pcity_dlg) {
3560 return;
3561 }
3562
3563 menus_update();
3564
3565 pcity_dlg = fc_calloc(1, sizeof(struct city_dialog));
3566 pcity_dlg->pcity = pcity;
3567 pcity_dlg->page = ARMY_PAGE;
3568
3569 pstr = create_utf8_str_fonto(NULL, 0, FONTO_ATTENTION);
3570 pstr->style |= TTF_STYLE_BOLD;
3571 pwindow = create_window(NULL, pstr, adj_size(640), adj_size(480), 0);
3572
3573 rebuild_citydlg_title_str(pwindow, pcity);
3574
3575 pwindow->action = city_dlg_callback;
3576 set_wstate(pwindow, FC_WS_NORMAL);
3577
3578 add_to_gui_list(ID_CITY_DLG_WINDOW, pwindow);
3579
3580 pcity_dlg->end_city_widget_list = pwindow;
3581
3582 /* create window background */
3583 logo = theme_get_background(active_theme, BACKGROUND_CITYDLG);
3584 if (resize_window(pwindow, logo, NULL, adj_size(640), adj_size(480))) {
3585 FREESURFACE(logo);
3586 }
3587
3588 logo = get_city_gfx();
3589 alphablit(logo, NULL, pwindow->theme, NULL, 255);
3590
3591 area = pwindow->area;
3592
3593 widget_set_position(pwindow,
3594 (main_window_width() - pwindow->size.w) / 2,
3595 (main_window_height() - pwindow->size.h) / 2);
3596
3597 /* ============================================================= */
3598
3599 /* Close dialog button */
3600 buf = create_themeicon(current_theme->small_cancel_icon, pwindow->dst,
3601 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3602 buf->info_label = create_utf8_from_char_fonto(_("Close Dialog (Esc)"),
3603 FONTO_ATTENTION);
3604 buf->action = exit_city_dlg_callback;
3605 buf->size.x = area.x + area.w - buf->size.w;
3606 buf->size.y = pwindow->size.y + adj_size(2);
3607 buf->key = SDLK_ESCAPE;
3608 set_wstate(buf, FC_WS_NORMAL);
3609 add_to_gui_list(ID_CITY_DLG_EXIT_BUTTON, buf);
3610
3611 /* -------- */
3612
3613 buf = create_themeicon(current_theme->army_icon, pwindow->dst,
3614 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3615 buf->info_label = create_utf8_from_char_fonto(_("Present units"),
3616 FONTO_ATTENTION);
3617 buf->action = army_city_dlg_callback;
3618 buf->size.x = area.x + adj_size(2) + ((adj_size(183) - 5 * buf->size.w) / 6);
3619 buf->size.y = area.y + adj_size(2);
3620 set_wstate(buf, FC_WS_NORMAL);
3621 add_to_gui_list(ID_CITY_DLG_ARMY_BUTTON, buf);
3622 /* -------- */
3623
3624 buf = create_themeicon(current_theme->support_icon, pwindow->dst,
3625 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3626 buf->info_label = create_utf8_from_char_fonto(_("Supported units"),
3627 FONTO_ATTENTION);
3628 buf->action = supported_unit_city_dlg_callback;
3629 buf->size.x =
3630 area.x + adj_size(2) + 2 * ((adj_size(183) - 5 * buf->size.w) / 6) + buf->size.w;
3631 buf->size.y = area.y + adj_size(2);
3632
3633 set_wstate(buf, FC_WS_NORMAL);
3634 add_to_gui_list(ID_CITY_DLG_SUPPORT_BUTTON, buf);
3635 /* -------- */
3636
3637 buf = create_themeicon(current_theme->happy_icon, pwindow->dst,
3638 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3639 buf->info_label = create_utf8_from_char_fonto(_("Happiness"),
3640 FONTO_ATTENTION);
3641 buf->action = happy_city_dlg_callback;
3642 buf->size.x
3643 = area.x + adj_size(2) + 3 * ((adj_size(183) - 5 * buf->size.w) / 6) + 2 * buf->size.w;
3644 buf->size.y = area.y + adj_size(2);
3645 set_wstate(buf, FC_WS_NORMAL);
3646 add_to_gui_list(ID_CITY_DLG_HAPPY_BUTTON, buf);
3647 /* -------- */
3648
3649 buf = create_themeicon(current_theme->info_icon, pwindow->dst,
3650 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3651 buf->info_label = create_utf8_from_char_fonto(_("City info"),
3652 FONTO_ATTENTION);
3653 buf->action = info_city_dlg_callback;
3654 buf->size.x
3655 = area.x + adj_size(4) + 4 * ((adj_size(183) - 5 * buf->size.w) / 6) + 3 * buf->size.w;
3656 buf->size.y = area.y + adj_size(2);
3657 set_wstate(buf, FC_WS_NORMAL);
3658 add_to_gui_list(ID_CITY_DLG_INFO_BUTTON, buf);
3659
3660 pcity_dlg->add_point = buf;
3661 pcity_dlg->begin_city_widget_list = buf;
3662 /* ===================================================== */
3663 rebuild_imprm_list(pcity);
3664 /* ===================================================== */
3665
3666 logo = get_scaled_city_map(pcity);
3667
3668 buf = create_themelabel(logo, pwindow->dst, NULL,
3669 logo->w, logo->h, WF_SELECT_WITHOUT_BAR);
3670
3671 pcity_dlg->resource_map = buf;
3672
3673 buf->action = resource_map_city_dlg_callback;
3674 if (!cma_is_city_under_agent(pcity, NULL) && (owner == client.conn.playing)) {
3675 set_wstate(buf, FC_WS_NORMAL);
3676 }
3677 buf->size.x = area.x + adj_size(193) + (adj_size(249) - buf->size.w) / 2;
3678 buf->size.y = area.y + adj_size(41) + (adj_size(158) - buf->size.h) / 2;
3679 add_to_gui_list(ID_CITY_DLG_RESOURCE_MAP, buf);
3680 /* -------- */
3681
3682 buf = create_themeicon(current_theme->options_icon, pwindow->dst,
3683 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3684 buf->info_label = create_utf8_from_char_fonto(_("City options"),
3685 FONTO_ATTENTION);
3686 buf->action = options_city_dlg_callback;
3687 buf->size.x
3688 = area.x + adj_size(4) + 5 * ((adj_size(183) - 5 * buf->size.w) / 6) + 4 * buf->size.w;
3689 buf->size.y = area.y + adj_size(2);
3690 if (owner == client.conn.playing) {
3691 set_wstate(buf, FC_WS_NORMAL);
3692 }
3693 add_to_gui_list(ID_CITY_DLG_OPTIONS_BUTTON, buf);
3694 /* -------- */
3695
3696 buf = create_themeicon(current_theme->prod_icon, pwindow->dst,
3697 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3698 buf->info_label = create_utf8_from_char_fonto(_("Change production"),
3699 FONTO_ATTENTION);
3700 buf->action = change_prod_dlg_callback;
3701 buf->size.x = area.x + adj_size(7);
3702 buf->size.y = area.y + area.h - buf->size.h - adj_size(5);
3703 if (owner == client.conn.playing) {
3704 set_wstate(buf, FC_WS_NORMAL);
3705 }
3706 buf->key = SDLK_c;
3707 add_to_gui_list(ID_CITY_DLG_CHANGE_PROD_BUTTON, buf);
3708 /* -------- */
3709
3710 buf = create_themeicon(current_theme->buy_prod_icon, pwindow->dst,
3711 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3712 buf->info_label = create_utf8_from_char_fonto(_("Hurry production"),
3713 FONTO_ATTENTION);
3714 buf->action = buy_prod_city_dlg_callback;
3715 buf->size.x = area.x + adj_size(7) + (buf->size.w + adj_size(2));
3716 buf->size.y = area.y + area.h - buf->size.h - adj_size(5);
3717 pcity_dlg->buy_button = buf;
3718 buf->key = SDLK_h;
3719 if (city_can_buy(pcity)) {
3720 set_wstate(buf, FC_WS_NORMAL);
3721 }
3722 add_to_gui_list(ID_CITY_DLG_PROD_BUY_BUTTON, buf);
3723 /* -------- */
3724
3725 buf = create_themeicon(current_theme->cma_icon, pwindow->dst,
3726 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3727 buf->info_label = create_utf8_from_char_fonto(_("Citizen Governor"),
3728 FONTO_ATTENTION);
3729 buf->action = cma_city_dlg_callback;
3730 buf->key = SDLK_a;
3731 buf->size.x = area.x + adj_size(7) + (buf->size.w + adj_size(2)) * 2;
3732 buf->size.y = area.y + area.h - buf->size.h - adj_size(5);
3733 if (owner == client.conn.playing) {
3734 set_wstate(buf, FC_WS_NORMAL);
3735 }
3736 add_to_gui_list(ID_CITY_DLG_CMA_BUTTON, buf);
3737
3738
3739 /* -------- */
3740 buf = create_themeicon(current_theme->l_arrow_icon, pwindow->dst,
3741 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3742 buf->info_label = create_utf8_from_char_fonto(_("Previous city"),
3743 FONTO_ATTENTION);
3744 buf->action = next_prev_city_dlg_callback;
3745 buf->size.x = area.x + adj_size(220) - buf->size.w - adj_size(8);
3746 buf->size.y = area.y + area.h - buf->size.h;
3747 if (owner == client.conn.playing) {
3748 set_wstate(buf, FC_WS_NORMAL);
3749 }
3750 buf->key = SDLK_LEFT;
3751 buf->mod = KMOD_LSHIFT;
3752 add_to_gui_list(ID_CITY_DLG_PREV_BUTTON, buf);
3753 /* -------- */
3754
3755 buf = create_themeicon(current_theme->r_arrow_icon, pwindow->dst,
3756 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
3757 buf->info_label = create_utf8_from_char_fonto(_("Next city"),
3758 FONTO_ATTENTION);
3759 buf->action = next_prev_city_dlg_callback;
3760 buf->size.x = area.x + adj_size(420) + adj_size(2);
3761 buf->size.y = area.y + area.h - buf->size.h;
3762 if (owner == client.conn.playing) {
3763 set_wstate(buf, FC_WS_NORMAL);
3764 }
3765 buf->key = SDLK_RIGHT;
3766 buf->mod = KMOD_LSHIFT;
3767 add_to_gui_list(ID_CITY_DLG_NEXT_BUTTON, buf);
3768 /* -------- */
3769
3770 buf = create_edit_from_chars_fonto(NULL, pwindow->dst, city_name_get(pcity),
3771 FONTO_DEFAULT, adj_size(200),
3772 WF_RESTORE_BACKGROUND);
3773 buf->action = new_name_city_dlg_callback;
3774 buf->size.x = area.x + (area.w - buf->size.w) / 2;
3775 buf->size.y = area.y + area.h - buf->size.h - adj_size(2);
3776 if (owner == client.conn.playing) {
3777 set_wstate(buf, FC_WS_NORMAL);
3778 }
3779
3780 pcity_dlg->city_name_edit = buf;
3781 add_to_gui_list(ID_CITY_DLG_NAME_EDIT, buf);
3782
3783 pcity_dlg->begin_city_widget_list = buf;
3784
3785 /* check if Citizen Icons style was loaded */
3786 cs = style_of_city(pcity);
3787
3788 if (cs != icons->style) {
3789 reload_citizens_icons(cs);
3790 }
3791
3792 /* ===================================================== */
3793 if ((city_unhappy(pcity) || city_celebrating(pcity)
3794 || city_happy(pcity))) {
3795 sdl2_client_flags |= CF_CITY_STATUS_SPECIAL;
3796 }
3797 /* ===================================================== */
3798
3799 redraw_city_dialog(pcity);
3800 flush_dirty();
3801}
3802
3803/**********************************************************************/
3806 void popdown_city_dialog(struct city *pcity)
3807{
3808 if (city_dialog_is_open(pcity)) {
3809 del_city_dialog();
3810
3811 flush_dirty();
3812
3813 sdl2_client_flags &= ~CF_CITY_STATUS_SPECIAL;
3814 menus_update();
3815 }
3816}
3817
3818/**********************************************************************/
3821 void popdown_all_city_dialogs(void)
3822{
3823 if (pcity_dlg) {
3824 popdown_city_dialog(pcity_dlg->pcity);
3825 }
3826}
3827
3828/**********************************************************************/
3831 void real_city_dialog_refresh(struct city *pcity)
3832{
3833 if (city_dialog_is_open(pcity)) {
3834 redraw_city_dialog(pcity_dlg->pcity);
3835 flush_dirty();
3836 }
3837}
3838
3839/**********************************************************************/
3844 void refresh_unit_city_dialogs(struct unit *punit)
3845{
3846 struct city *city_sup = game_city_by_number(punit->homecity);
3847 struct city *city_pre = tile_city(unit_tile(punit));
3848
3849 if (pcity_dlg && ((pcity_dlg->pcity == city_sup)
3850 || (pcity_dlg->pcity == city_pre))) {
3851 free_city_units_lists();
3852 redraw_city_dialog(pcity_dlg->pcity);
3853 flush_dirty();
3854 }
3855}
3856
3857/**********************************************************************/
3860 bool city_dialog_is_open(struct city *pcity)
3861{
3862 return (pcity_dlg && (pcity_dlg->pcity == pcity));
3863}
action_id_name_translation
const char * action_id_name_translation(action_id act_id)
Definition actions.c:1215
astr_free
void astr_free(struct astring *astr)
Definition astring.c:148
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:662
city_granary_size
int city_granary_size(int city_size)
Definition city.c:2123
city_unit_unhappiness
int city_unit_unhappiness(struct unit *punit, int *free_unhappy)
Definition city.c:3040
city_name_get
const char * city_name_get(const struct city *pcity)
Definition city.c:1128
city_population
int city_population(const struct city *pcity)
Definition city.c:1182
city_production_turns_to_build
int city_production_turns_to_build(const struct city *pcity, bool include_shield_stock)
Definition city.c:819
city_unhappy
bool city_unhappy(const struct city *pcity)
Definition city.c:1618
city_celebrating
bool city_celebrating(const struct city *pcity)
Definition city.c:1637
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:2861
city_happy
bool city_happy(const struct city *pcity)
Definition city.c:1606
city_map_radius_sq_get
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:136
city_specialists
citizens city_specialists(const struct city *pcity)
Definition city.c:3305
city_turns_to_grow
int city_turns_to_grow(const struct city *pcity)
Definition city.c:1988
city_production_name_translation
const char * city_production_name_translation(const struct city *pcity)
Definition city.c:699
city_size_get
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
CITIZEN_SPECIALIST
@ CITIZEN_SPECIALIST
Definition city.h:273
CITIZEN_ANGRY
@ CITIZEN_ANGRY
Definition city.h:271
CITIZEN_HAPPY
@ CITIZEN_HAPPY
Definition city.h:268
CITIZEN_CONTENT
@ CITIZEN_CONTENT
Definition city.h:269
CITIZEN_UNHAPPY
@ CITIZEN_UNHAPPY
Definition city.h:270
city_owner
#define city_owner(_pcity_)
Definition city.h:563
FEELING_FINAL
@ FEELING_FINAL
Definition city.h:284
FEELING_LAST
@ FEELING_LAST
Definition city.h:285
city_built_iterate
#define city_built_iterate(_pcity, _p)
Definition city.h:822
city_built_iterate_end
#define city_built_iterate_end
Definition city.h:828
city_rename
int city_rename(struct city *pcity, const char *name)
Definition citydlg_common.c:1602
city_buy_production
int city_buy_production(struct city *pcity)
Definition citydlg_common.c:1552
city_toggle_worker
int city_toggle_worker(struct city *pcity, int city_x, int city_y)
Definition citydlg_common.c:1571
city_rotate_specialist
void city_rotate_specialist(struct city *pcity, int citizen_index)
Definition citydlg_common.c:1240
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:1544
city_can_buy
bool city_can_buy(const struct city *pcity)
Definition citydlg_common.c:1524
trade_city
Definition menu.h:139
client
struct civclient client
Definition client_main.c:150
can_client_issue_orders
bool can_client_issue_orders(void)
Definition client_main.c:1264
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:1108
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:551
incite_cost
char * incite_cost
Definition comments.c:74
request_unit_fortify
void request_unit_fortify(struct unit *punit)
Definition control.c:2324
unit_focus_set
void unit_focus_set(struct unit *punit)
Definition control.c:501
request_unit_change_homecity
void request_unit_change_homecity(struct unit *punit)
Definition control.c:2065
request_unit_sentry
void request_unit_sentry(struct unit *punit)
Definition control.c:2313
control.h
can_unit_do_activity_client
#define can_unit_do_activity_client(_punit_, _act_)
Definition control.h:41
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:74
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:74
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:846
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:1153
building_has_effect
bool building_has_effect(const struct impr_type *pimprove, enum effect_type effect_type)
Definition effects.c:644
effect_list_iterate_end
#define effect_list_iterate_end
Definition effects.h:81
effect_list_iterate
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:79
current_theme
QString current_theme
Definition fc_client.cpp:64
MAX_LEN_NAME
#define MAX_LEN_NAME
Definition fc_types.h:66
O_SHIELD
@ O_SHIELD
Definition fc_types.h:101
O_FOOD
@ O_FOOD
Definition fc_types.h:101
O_TRADE
@ O_TRADE
Definition fc_types.h:101
O_SCIENCE
@ O_SCIENCE
Definition fc_types.h:101
O_LUXURY
@ O_LUXURY
Definition fc_types.h:101
O_GOLD
@ O_GOLD
Definition fc_types.h:101
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:740
game
struct civ_game game
Definition game.c:62
game_city_by_number
struct city * game_city_by_number(int id)
Definition game.c:107
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
HAPPINESS_PAGE
@ HAPPINESS_PAGE
Definition citydlg.c:111
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:480
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:220
popdown_city_dialog
void popdown_city_dialog(struct city *pcity)
Definition citydlg.c:587
flush_dirty
void flush_dirty(void)
Definition mapview.c:468
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:1820
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:1090
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:1039
redraw_city_dialog
static void redraw_city_dialog(struct city *pcity)
Definition citydlg.c:2431
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:3419
redraw_happiness_city_dialog
static void redraw_happiness_city_dialog(const struct widget *city_window, struct city *pcity)
Definition citydlg.c:2100
redraw_misc_city_dialog
static void redraw_misc_city_dialog(struct widget *city_window, struct city *pcity)
Definition citydlg.c:1785
redraw_info_city_dialog
static void redraw_info_city_dialog(struct widget *city_window, struct city *pcity)
Definition citydlg.c:1934
new_name_city_dlg_callback
static int new_name_city_dlg_callback(struct widget *pedit)
Definition citydlg.c:1740
sell_imprvm_dlg_cancel_callback
static int sell_imprvm_dlg_cancel_callback(struct widget *cancel_button)
Definition citydlg.c:1370
next_prev_city_dlg_callback
static int next_prev_city_dlg_callback(struct widget *button)
Definition citydlg.c:1666
disable_city_dlg_widgets
static void disable_city_dlg_widgets(void)
Definition citydlg.c:1595
sell_imprvm_dlg_ok_callback
static int sell_imprvm_dlg_ok_callback(struct widget *ok_button)
Definition citydlg.c:1387
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:1631
refresh_city_names
static void refresh_city_names(struct city *pcity)
Definition citydlg.c:1765
enable_city_dlg_widgets
void enable_city_dlg_widgets(void)
Definition citydlg.c:1532
buy_prod_city_dlg_callback
static int buy_prod_city_dlg_callback(struct widget *button)
Definition citydlg.c:1133
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:1877
popdown_hurry_production_dialog
static void popdown_hurry_production_dialog(void)
Definition citydlg.c:1148
change_prod_dlg_callback
static int change_prod_dlg_callback(struct widget *button)
Definition citydlg.c:1350
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:1173
create_city_options_widget_list
static void create_city_options_widget_list(struct city *pcity)
Definition citydlg.c:975
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:1655
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:1161
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:1107
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:3510
cma_city_dlg_callback
static int cma_city_dlg_callback(struct widget *button)
Definition citydlg.c:1061
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:1074
sell_imprvm_dlg_callback
static int sell_imprvm_dlg_callback(struct widget *impr)
Definition citydlg.c:1421
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:1617
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
get_theme_color
SDL_Color * get_theme_color(enum theme_color themecolor)
Definition colors.c:47
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:109
popup_unit_disband_dlg
void popup_unit_disband_dlg(struct unit *punit, bool city)
Definition dialogs.c:878
popup_unit_upgrade_dlg
void popup_unit_upgrade_dlg(struct unit *punit, bool city)
Definition dialogs.c:683
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:1381
alphablit
int alphablit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:199
is_in_rect_area
bool is_in_rect_area(int x, int y, const SDL_Rect *rect)
Definition graphics.c:925
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
get_smaller_surface_rect
void get_smaller_surface_rect(SDL_Surface *surf, SDL_Rect *rect)
Definition graphics.c:936
create_frame
void create_frame(SDL_Surface *dest, Sint16 left, Sint16 top, Sint16 width, Sint16 height, SDL_Color *pcolor)
Definition graphics.c:1350
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:1257
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
ID_CITY_DLG_HAPPY_BUTTON
@ ID_CITY_DLG_HAPPY_BUTTON
Definition gui_id.h:150
ID_CITY_DLG_CHANGE_PROD_BUTTON
@ ID_CITY_DLG_CHANGE_PROD_BUTTON
Definition gui_id.h:159
ID_CITY_DLG_PROD_BUY_BUTTON
@ ID_CITY_DLG_PROD_BUY_BUTTON
Definition gui_id.h:161
ID_CITY_DLG_WINDOW
@ ID_CITY_DLG_WINDOW
Definition gui_id.h:145
ID_CITY_DLG_RESOURCE_MAP
@ ID_CITY_DLG_RESOURCE_MAP
Definition gui_id.h:158
ID_CITY_DLG_CMA_BUTTON
@ ID_CITY_DLG_CMA_BUTTON
Definition gui_id.h:162
ID_CITY_DLG_NEXT_BUTTON
@ ID_CITY_DLG_NEXT_BUTTON
Definition gui_id.h:164
ID_BUTTON
@ ID_BUTTON
Definition gui_id.h:29
ID_CITY_DLG_OPTIONS_BUTTON
@ ID_CITY_DLG_OPTIONS_BUTTON
Definition gui_id.h:166
ID_CITY_DLG_NAME_EDIT
@ ID_CITY_DLG_NAME_EDIT
Definition gui_id.h:165
ID_CITY_DLG_SUPPORT_BUTTON
@ ID_CITY_DLG_SUPPORT_BUTTON
Definition gui_id.h:152
ID_LABEL
@ ID_LABEL
Definition gui_id.h:27
ID_CITY_DLG_ARMY_BUTTON
@ ID_CITY_DLG_ARMY_BUTTON
Definition gui_id.h:151
ID_WINDOW
@ ID_WINDOW
Definition gui_id.h:30
ID_REVOLUTION_DLG_WINDOW
@ ID_REVOLUTION_DLG_WINDOW
Definition gui_id.h:140
ID_CITY_DLG_EXIT_BUTTON
@ ID_CITY_DLG_EXIT_BUTTON
Definition gui_id.h:146
ID_CITY_DLG_INFO_BUTTON
@ ID_CITY_DLG_INFO_BUTTON
Definition gui_id.h:149
ID_CITY_DLG_PREV_BUTTON
@ ID_CITY_DLG_PREV_BUTTON
Definition gui_id.h:163
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:53
selected_widget
struct widget * selected_widget
Definition widget.c:48
CF_CITY_STATUS_SPECIAL
#define CF_CITY_STATUS_SPECIAL
Definition gui_main.h:54
adj_size
#define adj_size(size)
Definition gui_main.h:141
PRESSED_EVENT
#define PRESSED_EVENT(event)
Definition gui_main.h:71
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:93
SF_CENTER
#define SF_CENTER
Definition gui_string.h:40
FONTO_DEFAULT
@ FONTO_DEFAULT
Definition gui_string.h:65
FONTO_DEFAULT_PLUS
@ FONTO_DEFAULT_PLUS
Definition gui_string.h:66
FONTO_ATTENTION
@ FONTO_ATTENTION
Definition gui_string.h:67
create_utf8_from_char_fonto
#define create_utf8_from_char_fonto(string_in, fonto)
Definition gui_string.h:108
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:476
get_building_surface
static SDL_Surface * get_building_surface(const struct impr_type *pimprove)
Definition gui_tilespec.h:251
get_citizen_surface
static SDL_Surface * get_citizen_surface(enum citizen_category type, int citizen_index)
Definition gui_tilespec.h:218
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:259
create_city_map
SDL_Surface * create_city_map(struct city *pcity)
Definition mapview.c:1196
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:24
COLOR_THEME_CITYDLG_INFOPANEL
@ COLOR_THEME_CITYDLG_INFOPANEL
Definition themecolors.h:59
COLOR_THEME_CITYDLG_SELL
@ COLOR_THEME_CITYDLG_SELL
Definition themecolors.h:64
COLOR_THEME_CITYDLG_FOODPERTURN
@ COLOR_THEME_CITYDLG_FOODPERTURN
Definition themecolors.h:50
COLOR_THEME_CITYDLG_IMPR
@ COLOR_THEME_CITYDLG_IMPR
Definition themecolors.h:58
COLOR_THEME_CITYDLG_BUY
@ COLOR_THEME_CITYDLG_BUY
Definition themecolors.h:47
COLOR_THEME_CITYDLG_SHIELDSTOCK
@ COLOR_THEME_CITYDLG_SHIELDSTOCK
Definition themecolors.h:65
COLOR_THEME_CITYDLG_LUX
@ COLOR_THEME_CITYDLG_LUX
Definition themecolors.h:60
COLOR_THEME_CITYDLG_TRADE
@ COLOR_THEME_CITYDLG_TRADE
Definition themecolors.h:68
COLOR_THEME_CITYDLG_PROD
@ COLOR_THEME_CITYDLG_PROD
Definition themecolors.h:62
COLOR_THEME_CITYDLG_GROWTH
@ COLOR_THEME_CITYDLG_GROWTH
Definition themecolors.h:56
COLOR_THEME_CITYDLG_SUPPORT
@ COLOR_THEME_CITYDLG_SUPPORT
Definition themecolors.h:67
COLOR_THEME_CITYDLG_GRANARY
@ COLOR_THEME_CITYDLG_GRANARY
Definition themecolors.h:55
COLOR_THEME_CITYDLG_SCIENCE
@ COLOR_THEME_CITYDLG_SCIENCE
Definition themecolors.h:63
COLOR_THEME_CITYDLG_CORRUPTION
@ COLOR_THEME_CITYDLG_CORRUPTION
Definition themecolors.h:49
COLOR_THEME_CITYDLG_FOODSTOCK
@ COLOR_THEME_CITYDLG_FOODSTOCK
Definition themecolors.h:51
COLOR_THEME_CITYDLG_GOLD
@ COLOR_THEME_CITYDLG_GOLD
Definition themecolors.h:54
COLOR_THEME_CITYDLG_STOCKS
@ COLOR_THEME_CITYDLG_STOCKS
Definition themecolors.h:66
COLOR_THEME_CITYDLG_UPKEEP
@ COLOR_THEME_CITYDLG_UPKEEP
Definition themecolors.h:69
COLOR_THEME_CITYDLG_FRAME
@ COLOR_THEME_CITYDLG_FRAME
Definition themecolors.h:53
COLOR_THEME_CITYDLG_FOOD_SURPLUS
@ COLOR_THEME_CITYDLG_FOOD_SURPLUS
Definition themecolors.h:52
COLOR_THEME_CITYDLG_PANEL
@ COLOR_THEME_CITYDLG_PANEL
Definition themecolors.h:61
COLOR_THEME_CHECKBOX_LABEL_TEXT
@ COLOR_THEME_CHECKBOX_LABEL_TEXT
Definition themecolors.h:25
active_theme
struct theme * active_theme
Definition themespec.c:154
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:898
add_to_gui_list
void add_to_gui_list(Uint16 id, struct widget *gui)
Definition widget.c:586
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:863
unselect_widget_action
void unselect_widget_action(void)
Definition widget.c:418
widget_add_as_prev
void widget_add_as_prev(struct widget *new_widget, struct widget *add_dock)
Definition widget.c:602
select_window_group_dialog
bool select_window_group_dialog(struct widget *begin_widget_list, struct widget *pwindow)
Definition widget.c:998
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:1051
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:720
popdown_window_group_dialog
void popdown_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:983
move_window_group
void move_window_group(struct widget *begin_widget_list, struct widget *pwindow)
Definition widget.c:1039
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:1344
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:212
create_icon2
struct widget * create_icon2(SDL_Surface *icon, struct gui_layer *pdest, Uint32 flags)
Definition widget_icon.c:337
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:567
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:486
resize_window
bool 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
popup_worklist_editor
void popup_worklist_editor(struct city *pcity, struct global_worklist *gwl)
Definition wldlg.c:1055
cma_fe.h
gui_id.h
gui_tilespec.h
themespec.h
widget.h
citydlg.h
cityrep.h
colors.h
dialogs.h
graphics.h
gui_main.h
mapview.h
menu.h
sprite.h
wldlg.h
improvement_by_number
struct impr_type * improvement_by_number(const Impr_type_id id)
Definition improvement.c:194
impr_sell_gold
int impr_sell_gold(const struct impr_type *pimprove)
Definition improvement.c:334
can_city_sell_building
bool can_city_sell_building(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:1100
improvement_number
Impr_type_id improvement_number(const struct impr_type *pimprove)
Definition improvement.c:184
impr_build_shield_cost
int impr_build_shield_cost(const struct city *pcity, const struct impr_type *pimprove)
Definition improvement.c:294
is_wonder
bool is_wonder(const struct impr_type *pimprove)
Definition improvement.c:343
is_convert_improvement
bool is_convert_improvement(const struct impr_type *pimprove)
Definition improvement.c:811
improvement_name_translation
const char * improvement_name_translation(const struct impr_type *pimprove)
Definition improvement.c:243
improvement_iterate_end
#define improvement_iterate_end
Definition improvement.h:205
improvement_iterate
#define improvement_iterate(_p)
Definition improvement.h:199
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:1389
center_tile_mapcanvas
void center_tile_mapcanvas(const struct tile *ptile)
Definition mapview_common.c:1237
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:1016
movement.h
dsend_packet_city_options_req
int dsend_packet_city_options_req(struct connection *pc, int city_id, bv_city_options options)
Definition packets_gen.c:20503
player_unit_by_number
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1229
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:94
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:92
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::begin_active_widget_list
struct widget * begin_active_widget_list
Definition widget.h:184
advanced_dialog::end_widget_list
struct widget * end_widget_list
Definition widget.h:182
advanced_dialog::end_active_widget_list
struct widget * end_active_widget_list
Definition widget.h:185
advanced_dialog::active_widget_list
struct widget * active_widget_list
Definition widget.h:186
advanced_dialog::scroll
struct scroll_bar * scroll
Definition widget.h:187
advanced_dialog::begin_widget_list
struct widget * begin_widget_list
Definition widget.h:181
astring
Definition astring.h:36
canvas
Definition canvas.h:22
city_dialog
Definition citydlg.c:136
city_dialog::resource_map
struct widget * resource_map
Definition citydlg.c:99
city_dialog::citizen_step
int citizen_step
Definition citydlg.c:102
city_dialog::imprv
struct advanced_dialog * imprv
Definition citydlg.c:87
city_dialog::lock
bool lock
Definition citydlg.c:106
city_dialog::begin_city_menu_widget_list
struct widget * begin_city_menu_widget_list
Definition citydlg.c:93
city_dialog::end_city_widget_list
struct widget * end_city_widget_list
Definition citydlg.c:84
city_dialog::ARMY_PAGE
@ ARMY_PAGE
Definition citydlg.c:77
city_dialog::MISC_PAGE
@ MISC_PAGE
Definition citydlg.c:79
city_dialog::SUPPORTED_UNITS_PAGE
@ SUPPORTED_UNITS_PAGE
Definition citydlg.c:78
city_dialog::HAPPINESS_PAGE
@ HAPPINESS_PAGE
Definition citydlg.c:76
city_dialog::INFO_PAGE
@ INFO_PAGE
Definition citydlg.c:75
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::city_name_edit
struct widget * city_name_edit
Definition citydlg.c:100
city_dialog::page
enum city_dialog::@213 page
city_dialog::end_city_menu_widget_list
struct widget * end_city_menu_widget_list
Definition citydlg.c:94
city_dialog::buy_button
QPushButton * buy_button
Definition citydlg.h:477
city_dialog::add_point
struct widget * add_point
Definition citydlg.c:97
city_dialog::panel
struct advanced_dialog * panel
Definition citydlg.c:90
city_icon::pollution
SDL_Surface * pollution
Definition gui_tilespec.h:175
city_icon::shield
SDL_Surface * shield
Definition gui_tilespec.h:167
city_icon::coint
SDL_Surface * coint
Definition gui_tilespec.h:170
city_icon::big_trade_corr
SDL_Surface * big_trade_corr
Definition gui_tilespec.h:153
city_icon::trade
SDL_Surface * trade
Definition gui_tilespec.h:168
city_icon::big_shield_corr
SDL_Surface * big_shield_corr
Definition gui_tilespec.h:152
city_icon::big_trade
SDL_Surface * big_trade
Definition gui_tilespec.h:156
city_icon::face
SDL_Surface * face
Definition gui_tilespec.h:172
city_icon::food
SDL_Surface * food
Definition gui_tilespec.h:166
city_icon::female_angry
SDL_Surface * female_angry
Definition gui_tilespec.h:187
city_icon::big_shield
SDL_Surface * big_shield
Definition gui_tilespec.h:155
city_icon::specialists
SDL_Surface * specialists[SP_MAX]
Definition gui_tilespec.h:189
city_icon::female_happy
SDL_Surface * female_happy
Definition gui_tilespec.h:181
city_icon::big_luxury
SDL_Surface * big_luxury
Definition gui_tilespec.h:157
city_icon::female_content
SDL_Surface * female_content
Definition gui_tilespec.h:183
city_icon::police
SDL_Surface * police
Definition gui_tilespec.h:176
city_icon::style
int style
Definition gui_tilespec.h:149
city_icon::big_colb
SDL_Surface * big_colb
Definition gui_tilespec.h:159
city_icon::big_coin_upkeep
SDL_Surface * big_coin_upkeep
Definition gui_tilespec.h:162
city_icon::female_unhappy
SDL_Surface * female_unhappy
Definition gui_tilespec.h:185
city_icon::male_unhappy
SDL_Surface * male_unhappy
Definition gui_tilespec.h:184
city_icon::male_content
SDL_Surface * male_content
Definition gui_tilespec.h:182
city_icon::big_food
SDL_Surface * big_food
Definition gui_tilespec.h:154
city_icon::big_coin_corr
SDL_Surface * big_coin_corr
Definition gui_tilespec.h:161
city_icon::male_happy
SDL_Surface * male_happy
Definition gui_tilespec.h:180
city_icon::big_coin
SDL_Surface * big_coin
Definition gui_tilespec.h:158
city_icon::big_food_corr
SDL_Surface * big_food_corr
Definition gui_tilespec.h:151
city_icon::male_angry
SDL_Surface * male_angry
Definition gui_tilespec.h:186
city_icon::big_food_surplus
SDL_Surface * big_food_surplus
Definition gui_tilespec.h:164
city_icon::big_shield_surplus
SDL_Surface * big_shield_surplus
Definition gui_tilespec.h:163
city
Definition city.h:320
city::surplus
int surplus[O_LAST]
Definition city.h:355
city::food_stock
int food_stock
Definition city.h:367
city::pollution
int pollution
Definition city.h:369
city::did_sell
bool did_sell
Definition city.h:380
city::id
int id
Definition city.h:326
city::waste
int waste[O_LAST]
Definition city.h:356
city::info_units_present
struct unit_list * info_units_present
Definition city.h:474
city::city_options
bv_city_options city_options
Definition city.h:403
city::owner
struct player * owner
Definition city.h:323
city::turn_founded
int turn_founded
Definition city.h:386
city::did_buy
bool did_buy
Definition city.h:379
city::info_units_supported
struct unit_list * info_units_supported
Definition city.h:473
city::production
struct universal production
Definition city.h:396
city::buy_cost
int buy_cost
Definition city.h:466
city::feel
citizens feel[CITIZEN_LAST][FEELING_LAST]
Definition city.h:333
city::specialists
citizens specialists[SP_MAX]
Definition city.h:336
city::tile
struct tile * tile
Definition city.h:322
city::shield_stock
int shield_stock
Definition city.h:368
city::prod
int prod[O_LAST]
Definition city.h:358
city::units_supported
struct unit_list * units_supported
Definition city.h:406
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:151
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:50
packet_game_info::illness_on
bool illness_on
Definition packets_gen.h:187
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::down_right_button
struct widget * down_right_button
Definition widget_scrollbar.h:23
scroll_bar::pscroll_bar
struct widget * pscroll_bar
Definition widget_scrollbar.h:22
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:58
tileset
Definition tilespec.c:481
unit_type
Definition unittype.h:507
unit
Definition unit.h:140
unit::upkeep
int upkeep[O_LAST]
Definition unit.h:150
unit::activity
enum unit_activity activity
Definition unit.h:159
unit::id
int id
Definition unit.h:147
unit::hp
int hp
Definition unit.h:153
unit::facing
enum direction8 facing
Definition unit.h:144
unit::homecity
int homecity
Definition unit.h:148
unit::veteran
int veteran
Definition unit.h:154
universal::kind
enum universals_n kind
Definition fc_types.h:910
universal::value
universals_u value
Definition fc_types.h:909
utf8_str
Definition gui_string.h:52
utf8_str::text
char * text
Definition gui_string.h:60
widget
Definition widget.h:112
widget::data
union widget::@216 data
widget::ptr
void * ptr
Definition widget.h:133
widget::key
SDL_Keycode key
Definition widget.h:153
widget::theme
SDL_Surface * theme
Definition widget.h:118
widget::theme2
SDL_Surface * theme2
Definition widget.h:119
widget::prev
struct widget * prev
Definition widget.h:114
widget::unit
struct unit * unit
Definition widget.h:129
widget::dst
struct gui_layer * dst
Definition widget.h:116
widget::city
struct city * city
Definition widget.h:128
widget::string_utf8
utf8_str * string_utf8
Definition widget.h:121
widget::action
int(* action)(struct widget *)
Definition widget.h:157
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
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:960
fc_strlcat
size_t fc_strlcat(char *dest, const char *src, size_t n)
Definition support.c:822
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
sz_strlcat
#define sz_strlcat(dest, src)
Definition support.h:190
get_nearest_city_text
const char * get_nearest_city_text(struct city *pcity, int sq_dist)
Definition text.c:454
unit_description
const char * unit_description(struct unit *punit)
Definition text.c:488
text.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:789
tileset_unit_with_small_upkeep_height
int tileset_unit_with_small_upkeep_height(const struct tileset *t)
Definition tilespec.c:871
tileset_unit_layout_small_offset_y
int tileset_unit_layout_small_offset_y(const struct tileset *t)
Definition tilespec.c:891
tileset_full_tile_width
int tileset_full_tile_width(const struct tileset *t)
Definition tilespec.c:776
tileset_tile_width
int tileset_tile_width(const struct tileset *t)
Definition tilespec.c:753
trade_routes_iterate_end
#define trade_routes_iterate_end
Definition traderoutes.h:135
trade_routes_iterate
#define trade_routes_iterate(c, proute)
Definition traderoutes.h:131
universals_u::utype
const struct unit_type * utype
Definition fc_types.h:728
universals_u::building
const struct impr_type * building
Definition fc_types.h:721
unit_activity_astr
void unit_activity_astr(const struct unit *punit, struct astring *astr)
Definition unit.c:1181
unit_tile
#define unit_tile(_pu)
Definition unit.h:397
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:2598
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:1703
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:1438
utype_name_translation
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560