Freeciv-3.2: /fast/freeciv/nightly/S3_2/client/gui-sdl3/citydlg.c Source File

Freeciv-3.2

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