When mixer is not available, recommend SDL2_mixer instead of SDL1.2 mixer
[freeciv.git] / client / gui-sdl2 / cityrep.c
blob17b26d6ff3a99135ef8898a4c5cd8989ab9049e4
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.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* SDL2 */
19 #ifdef SDL2_PLAIN_INCLUDE
20 #include <SDL.h>
21 #else /* SDL2_PLAIN_INCLUDE */
22 #include <SDL2/SDL.h>
23 #endif /* SDL2_PLAIN_INCLUDE */
25 /* utility */
26 #include "fcintl.h"
27 #include "log.h"
29 /* common */
30 #include "game.h"
32 /* client */
33 #include "client_main.h"
35 /* gui-sdl2 */
36 #include "citydlg.h"
37 #include "cma_fe.h"
38 #include "colors.h"
39 #include "graphics.h"
40 #include "gui_id.h"
41 #include "gui_main.h"
42 #include "gui_tilespec.h"
43 #include "mapctrl.h"
44 #include "mapview.h"
45 #include "repodlgs.h"
46 #include "sprite.h"
47 #include "themespec.h"
48 #include "widget.h"
49 #include "wldlg.h"
51 #include "cityrep.h"
53 static struct ADVANCED_DLG *pCityRep = NULL;
55 static void real_info_city_report_dialog_update(void);
57 /* ==================================================================== */
59 /**************************************************************************
60 Close city report dialog.
61 **************************************************************************/
62 void city_report_dialog_popdown(void)
64 if (pCityRep) {
65 popdown_window_group_dialog(pCityRep->pBeginWidgetList,
66 pCityRep->pEndWidgetList);
67 FC_FREE(pCityRep->pScroll);
68 FC_FREE(pCityRep);
70 enable_and_redraw_find_city_button();
71 flush_dirty();
75 /**************************************************************************
76 User interacted with cityreport window.
77 **************************************************************************/
78 static int city_report_windows_callback(struct widget *pWindow)
80 if (Main.event.button.button == SDL_BUTTON_LEFT) {
81 move_window_group(pCityRep->pBeginWidgetList, pWindow);
84 return -1;
87 /**************************************************************************
88 User interacted with city report close button.
89 **************************************************************************/
90 static int exit_city_report_callback(struct widget *pWidget)
92 if (Main.event.button.button == SDL_BUTTON_LEFT) {
93 city_report_dialog_popdown();
96 return -1;
99 /**************************************************************************
100 User interacted with city button on city report.
101 **************************************************************************/
102 static int popup_citydlg_from_city_report_callback(struct widget *pWidget)
104 if (Main.event.button.button == SDL_BUTTON_LEFT) {
105 popup_city_dialog(pWidget->data.city);
108 return -1;
111 /**************************************************************************
112 User interacted with worklist button on city report.
113 **************************************************************************/
114 static int popup_worklist_from_city_report_callback(struct widget *pWidget)
116 if (Main.event.button.button == SDL_BUTTON_LEFT) {
117 popup_worklist_editor(pWidget->data.city, NULL);
120 return -1;
123 /**************************************************************************
124 User interacted with city production button on city report.
125 **************************************************************************/
126 static int popup_buy_production_from_city_report_callback(struct widget *pWidget)
128 if (Main.event.button.button == SDL_BUTTON_LEFT) {
129 popup_hurry_production_dialog(pWidget->data.city, NULL);
132 return -1;
135 /**************************************************************************
136 User interacted with cma button on city report.
137 **************************************************************************/
138 static int popup_cma_from_city_report_callback(struct widget *pWidget)
140 if (Main.event.button.button == SDL_BUTTON_LEFT) {
141 struct city *pCity = game_city_by_number(MAX_ID - pWidget->ID);
143 /* state is changed before enter this function */
144 if (!get_checkbox_state(pWidget)) {
145 cma_release_city(pCity);
146 city_report_dialog_update_city(pCity);
147 } else {
148 popup_city_cma_dialog(pCity);
152 return -1;
155 #if 0
156 /**************************************************************************
157 User interacted with information report button.
158 **************************************************************************/
159 static int info_city_report_callback(struct widget *pWidget)
161 if (Main.event.button.button == SDL_BUTTON_LEFT) {
162 set_wstate(pWidget, FC_WS_NORMAL);
163 selected_widget = NULL;
164 widget_redraw(pWidget);
165 widget_mark_dirty(pWidget);
166 real_info_city_report_dialog_update();
169 return -1;
171 #endif /* 0 */
173 #define COL 17
175 /**************************************************************************
176 Rebuild the city info report.
177 **************************************************************************/
178 static void real_info_city_report_dialog_update(void)
180 SDL_Color bg_color = {255, 255, 255, 136};
182 struct widget *pbuf = NULL;
183 struct widget *pWindow, *pLast;
184 utf8_str *pstr;
185 SDL_Surface *pText1, *pText2, *pText3, *pUnits_Icon, *pCMA_Icon, *pText4;
186 SDL_Surface *pLogo;
187 int togrow, w = 0 , count, ww = 0, hh = 0, name_w = 0, prod_w = 0, H;
188 char cbuf[128];
189 const char *pName;
190 SDL_Rect dst;
191 SDL_Rect area;
193 if (pCityRep) {
194 popdown_window_group_dialog(pCityRep->pBeginWidgetList,
195 pCityRep->pEndWidgetList);
196 } else {
197 pCityRep = fc_calloc(1, sizeof(struct ADVANCED_DLG));
200 fc_snprintf(cbuf, sizeof(cbuf), _("size"));
201 pstr = create_utf8_from_char(cbuf, adj_font(10));
202 pstr->style |= SF_CENTER;
203 pText1 = create_text_surf_from_utf8(pstr);
205 fc_snprintf(cbuf, sizeof(cbuf), _("time\nto grow"));
206 copy_chars_to_utf8_str(pstr, cbuf);
207 pText2 = create_text_surf_from_utf8(pstr);
209 fc_snprintf(cbuf, sizeof(cbuf), _("City Name"));
210 copy_chars_to_utf8_str(pstr, cbuf);
211 pText3 = create_text_surf_from_utf8(pstr);
212 name_w = pText3->w + adj_size(6);
214 fc_snprintf(cbuf, sizeof(cbuf), _("Production"));
215 copy_chars_to_utf8_str(pstr, cbuf);
216 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYREP_TEXT);
217 pText4 = create_text_surf_from_utf8(pstr);
218 prod_w = pText4->w;
219 FREEUTF8STR(pstr);
221 pUnits_Icon = create_icon_from_theme(current_theme->UNITS_Icon, 0);
222 pCMA_Icon = create_icon_from_theme(current_theme->CMA_Icon, 0);
224 /* --------------- */
225 pstr = create_utf8_from_char(_("Cities Report"), adj_font(12));
226 pstr->style |= TTF_STYLE_BOLD;
228 pWindow = create_window_skeleton(NULL, pstr, 0);
229 pCityRep->pEndWidgetList = pWindow;
230 set_wstate(pWindow, FC_WS_NORMAL);
231 pWindow->action = city_report_windows_callback;
233 add_to_gui_list(ID_WINDOW, pWindow);
235 area = pWindow->area;
237 /* ------------------------- */
238 /* exit button */
239 pbuf = create_themeicon(current_theme->Small_CANCEL_Icon, pWindow->dst,
240 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
241 pbuf->info_label = create_utf8_from_char(_("Close Dialog"), adj_font(12));
242 pbuf->action = exit_city_report_callback;
243 set_wstate(pbuf, FC_WS_NORMAL);
244 pbuf->key = SDLK_ESCAPE;
246 add_to_gui_list(ID_BUTTON, pbuf);
248 /* FIXME: not implemented yet */
249 #if 0
250 /* ------------------------- */
251 pbuf = create_themeicon(current_theme->INFO_Icon, pWindow->dst,
252 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
253 pbuf->info_label = create_str16_from_char(_("Information Report"),
254 adj_font(12));
256 pbuf->action = info_city_report_callback;
257 set_wstate(pbuf, FC_WS_NORMAL);
259 add_to_gui_list(ID_BUTTON, pbuf);
260 /* -------- */
261 pbuf = create_themeicon(current_theme->Happy_Icon, pWindow->dst,
262 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
263 pbuf->info_label = create_str16_from_char(_("Happiness Report"), adj_font(12));
265 pbuf->action = happy_city_report_callback;
266 set_wstate(pbuf, FC_WS_NORMAL);
268 add_to_gui_list(ID_BUTTON, pbuf);
269 /* -------- */
270 pbuf = create_themeicon(current_theme->Army_Icon, pWindow->dst,
271 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
273 pbuf->info_label = create_str16_from_char(_("Garrison Report"),
274 adj_font(12));
276 pbuf->action = army_city_dlg_callback;
277 set_wstate(pbuf, FC_WS_NORMAL);
279 add_to_gui_list(ID_BUTTON, pbuf);
280 /* -------- */
281 pbuf = create_themeicon(current_theme->Support_Icon, pWindow->dst,
282 WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND);
283 pbuf->info_label = create_str16_from_char(_("Maintenance Report"),
284 adj_font(12));
286 pbuf->action = supported_unit_city_dlg_callback;
287 set_wstate(pbuf, FC_WS_NORMAL);
289 add_to_gui_list(ID_BUTTON, pbuf);
290 /* ------------------------ */
291 #endif /* 0 */
293 pLast = pbuf;
294 count = 0;
295 city_list_iterate(client.conn.playing->cities, pCity) {
296 pstr = create_utf8_from_char(city_name_get(pCity), adj_font(12));
297 pstr->style |= TTF_STYLE_BOLD;
298 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
299 (WF_RESTORE_BACKGROUND | WF_SELECT_WITHOUT_BAR));
301 if (city_unhappy(pCity)) {
302 pbuf->string_utf8->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_TRADE);
303 } else {
304 if (city_celebrating(pCity)) {
305 pbuf->string_utf8->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_CELEB);
306 } else {
307 if (city_happy(pCity)) {
308 pbuf->string_utf8->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_HAPPY);
313 pbuf->action = popup_citydlg_from_city_report_callback;
314 set_wstate(pbuf, FC_WS_NORMAL);
315 pbuf->data.city = pCity;
316 if (count > 13 * COL) {
317 set_wflag(pbuf , WF_HIDDEN);
319 hh = pbuf->size.h;
320 name_w = MAX(pbuf->size.w, name_w);
321 add_to_gui_list(MAX_ID - pCity->id, pbuf);
323 /* ----------- */
324 fc_snprintf(cbuf, sizeof(cbuf), "%d", city_size_get(pCity));
325 pstr = create_utf8_from_char(cbuf, adj_font(10));
326 pstr->style |= SF_CENTER;
327 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
328 WF_RESTORE_BACKGROUND);
329 if (count > 13 * COL) {
330 set_wflag(pbuf, WF_HIDDEN);
332 hh = MAX(hh, pbuf->size.h);
333 pbuf->size.w = pText1->w + adj_size(8);
334 add_to_gui_list(MAX_ID - pCity->id, pbuf);
336 /* ----------- */
337 pbuf = create_checkbox(pWindow->dst,
338 cma_is_city_under_agent(pCity, NULL), WF_RESTORE_BACKGROUND);
339 if (count > 13 * COL) {
340 set_wflag(pbuf, WF_HIDDEN);
342 hh = MAX(hh, pbuf->size.h);
343 fc_assert(MAX_ID > pCity->id);
344 add_to_gui_list(MAX_ID - pCity->id, pbuf);
345 set_wstate(pbuf, FC_WS_NORMAL);
346 pbuf->action = popup_cma_from_city_report_callback;
348 /* ----------- */
349 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->prod[O_FOOD] - pCity->surplus[O_FOOD]);
350 pstr = create_utf8_from_char(cbuf, adj_font(10));
351 pstr->style |= SF_CENTER;
352 pstr->fgcol = *get_game_color(COLOR_OVERVIEW_LAND);
353 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
354 WF_RESTORE_BACKGROUND);
355 if (count > 13 * COL) {
356 set_wflag(pbuf, WF_HIDDEN);
358 hh = MAX(hh, pbuf->size.h);
359 pbuf->size.w = pIcons->pBIG_Food->w + adj_size(6);
360 add_to_gui_list(MAX_ID - pCity->id, pbuf);
362 /* ----------- */
363 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->surplus[O_FOOD]);
364 pstr = create_utf8_from_char(cbuf, adj_font(10));
365 pstr->style |= SF_CENTER;
366 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_FOOD_SURPLUS);
367 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
368 WF_RESTORE_BACKGROUND);
369 if (count > 13 * COL) {
370 set_wflag(pbuf, WF_HIDDEN);
372 hh = MAX(hh, pbuf->size.h);
373 pbuf->size.w = pIcons->pBIG_Food_Corr->w + adj_size(6);
374 add_to_gui_list(MAX_ID - pCity->id, pbuf);
376 /* ----------- */
377 togrow = city_turns_to_grow(pCity);
378 switch (togrow) {
379 case 0:
380 fc_snprintf(cbuf, sizeof(cbuf), "#");
381 break;
382 case FC_INFINITY:
383 fc_snprintf(cbuf, sizeof(cbuf), "--");
384 break;
385 default:
386 fc_snprintf(cbuf, sizeof(cbuf), "%d", togrow);
387 break;
390 pstr = create_utf8_from_char(cbuf, adj_font(10));
391 pstr->style |= SF_CENTER;
392 if (togrow < 0) {
393 pstr->fgcol.r = 255;
395 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
396 WF_RESTORE_BACKGROUND);
397 if (count > 13 * COL) {
398 set_wflag(pbuf, WF_HIDDEN);
400 hh = MAX(hh, pbuf->size.h);
401 pbuf->size.w = pText2->w + adj_size(6);
402 add_to_gui_list(MAX_ID - pCity->id, pbuf);
404 /* ----------- */
405 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->surplus[O_TRADE]);
406 pstr = create_utf8_from_char(cbuf, adj_font(10));
407 pstr->style |= SF_CENTER;
408 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_TRADE);
409 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
410 WF_RESTORE_BACKGROUND);
411 if (count > 13 * COL) {
412 set_wflag(pbuf, WF_HIDDEN);
414 hh = MAX(hh, pbuf->size.h);
415 pbuf->size.w = pIcons->pBIG_Trade->w + adj_size(6);
416 add_to_gui_list(MAX_ID - pCity->id, pbuf);
418 /* ----------- */
419 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->waste[O_TRADE]);
420 pstr = create_utf8_from_char(cbuf, adj_font(10));
421 pstr->style |= SF_CENTER;
422 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
423 WF_RESTORE_BACKGROUND);
424 if (count > 13 * COL) {
425 set_wflag(pbuf, WF_HIDDEN);
427 hh = MAX(hh, pbuf->size.h);
428 pbuf->size.w = pIcons->pBIG_Trade_Corr->w + adj_size(6);
429 add_to_gui_list(MAX_ID - pCity->id, pbuf);
431 /* ----------- */
432 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->surplus[O_GOLD]);
433 pstr = create_utf8_from_char(cbuf, adj_font(10));
434 pstr->style |= SF_CENTER;
435 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_GOLD);
436 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
437 WF_RESTORE_BACKGROUND);
438 if (count > 13 * COL) {
439 set_wflag(pbuf, WF_HIDDEN);
441 hh = MAX(hh, pbuf->size.h);
442 pbuf->size.w = pIcons->pBIG_Coin->w + adj_size(6);
443 add_to_gui_list(MAX_ID - pCity->id, pbuf);
445 /* ----------- */
446 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->prod[O_SCIENCE]);
447 pstr = create_utf8_from_char(cbuf, adj_font(10));
448 pstr->style |= SF_CENTER;
449 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_SCIENCE);
450 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
451 WF_RESTORE_BACKGROUND);
452 if (count > 13 * COL) {
453 set_wflag(pbuf, WF_HIDDEN);
455 hh = MAX(hh, pbuf->size.h);
456 pbuf->size.w = pIcons->pBIG_Colb->w + adj_size(6);
457 add_to_gui_list(MAX_ID - pCity->id, pbuf);
459 /* ----------- */
460 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->prod[O_LUXURY]);
461 pstr = create_utf8_from_char(cbuf, adj_font(10));
462 pstr->style |= SF_CENTER;
463 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_LUX);
464 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
465 WF_RESTORE_BACKGROUND);
466 if (count > 13 * COL) {
467 set_wflag(pbuf, WF_HIDDEN);
469 hh = MAX(hh, pbuf->size.h);
470 pbuf->size.w = pIcons->pBIG_Luxury->w + adj_size(6);
471 add_to_gui_list(MAX_ID - pCity->id, pbuf);
473 /* ----------- */
474 fc_snprintf(cbuf, sizeof(cbuf), "%d",
475 pCity->prod[O_SHIELD] + pCity->waste[O_SHIELD]);
476 pstr = create_utf8_from_char(cbuf, adj_font(10));
477 pstr->style |= SF_CENTER;
478 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_PROD);
479 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
480 WF_RESTORE_BACKGROUND);
481 if (count > 13 * COL) {
482 set_wflag(pbuf, WF_HIDDEN);
484 hh = MAX(hh, pbuf->size.h);
485 pbuf->size.w = pIcons->pBIG_Shield->w + adj_size(6);
486 add_to_gui_list(MAX_ID - pCity->id, pbuf);
488 /* ----------- */
489 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->waste[O_SHIELD]);
490 pstr = create_utf8_from_char(cbuf, adj_font(10));
491 pstr->style |= SF_CENTER;
492 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
493 WF_RESTORE_BACKGROUND);
494 if (count > 13 * COL) {
495 set_wflag(pbuf, WF_HIDDEN);
497 hh = MAX(hh, pbuf->size.h);
498 pbuf->size.w = pIcons->pBIG_Shield_Corr->w + adj_size(6);
499 add_to_gui_list(MAX_ID - pCity->id, pbuf);
501 /* ----------- */
502 fc_snprintf(cbuf, sizeof(cbuf), "%d",
503 pCity->prod[O_SHIELD] + pCity->waste[O_SHIELD] - pCity->surplus[O_SHIELD]);
504 pstr = create_utf8_from_char(cbuf, adj_font(10));
505 pstr->style |= SF_CENTER;
506 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_SUPPORT);
507 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
508 WF_RESTORE_BACKGROUND);
509 if (count > 13 * COL) {
510 set_wflag(pbuf, WF_HIDDEN);
512 hh = MAX(hh, pbuf->size.h);
513 pbuf->size.w = pUnits_Icon->w + adj_size(6);
514 add_to_gui_list(MAX_ID - pCity->id, pbuf);
516 /* ----------- */
517 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->surplus[O_SHIELD]);
518 pstr = create_utf8_from_char(cbuf, adj_font(10));
519 pstr->style |= SF_CENTER;
520 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_TRADE);
521 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
522 WF_RESTORE_BACKGROUND);
523 if (count > 13 * COL) {
524 set_wflag(pbuf, WF_HIDDEN);
526 hh = MAX(hh, pbuf->size.h);
527 pbuf->size.w = pIcons->pBIG_Shield_Surplus->w + adj_size(6);
528 add_to_gui_list(MAX_ID - pCity->id, pbuf);
530 /* ----------- */
531 if (VUT_UTYPE == pCity->production.kind) {
532 struct unit_type *pUnitType = pCity->production.value.utype;
534 pLogo = ResizeSurfaceBox(get_unittype_surface(pUnitType, direction8_invalid()),
535 adj_size(36), adj_size(24), 1,
536 TRUE, TRUE);
537 togrow = utype_build_shield_cost(pUnitType);
538 pName = utype_name_translation(pUnitType);
539 } else {
540 struct impr_type *pImprove = pCity->production.value.building;
542 pLogo = ResizeSurfaceBox(get_building_surface(pCity->production.value.building),
543 adj_size(36), adj_size(24), 1,
544 TRUE, TRUE);
545 togrow = impr_build_shield_cost(pImprove);
546 pName = improvement_name_translation(pImprove);
549 if (!worklist_is_empty(&(pCity->worklist))) {
550 dst.x = pLogo->w - pIcons->pWorklist->w;
551 dst.y = 0;
552 alphablit(pIcons->pWorklist, NULL, pLogo, &dst, 255);
553 fc_snprintf(cbuf, sizeof(cbuf), "%s\n(%d/%d)\n%s",
554 pName, pCity->shield_stock, togrow, _("worklist"));
555 } else {
556 fc_snprintf(cbuf, sizeof(cbuf), "%s\n(%d/%d)%s",
557 pName, pCity->shield_stock, togrow,
558 pCity->shield_stock > togrow ? _("\nfinished"): "" );
561 /* info string */
562 pstr = create_utf8_from_char(cbuf, adj_font(10));
563 pstr->style |= SF_CENTER;
565 togrow = city_production_turns_to_build(pCity, TRUE);
566 if (togrow == 999) {
567 fc_snprintf(cbuf, sizeof(cbuf), "%s", _("never"));
568 } else {
569 fc_snprintf(cbuf, sizeof(cbuf), "%d %s",
570 togrow, PL_("turn", "turns", togrow));
573 pbuf = create_icon2(pLogo, pWindow->dst,
574 WF_WIDGET_HAS_INFO_LABEL |WF_RESTORE_BACKGROUND
575 | WF_FREE_THEME);
576 pbuf->info_label = pstr;
577 if (count > 13 * COL) {
578 set_wflag(pbuf, WF_HIDDEN);
580 hh = MAX(hh, pbuf->size.h);
581 add_to_gui_list(MAX_ID - pCity->id, pbuf);
582 set_wstate(pbuf, FC_WS_NORMAL);
583 pbuf->action = popup_worklist_from_city_report_callback;
584 pbuf->data.city = pCity;
586 pstr = create_utf8_from_char(cbuf, adj_font(10));
587 pstr->style |= SF_CENTER;
588 pstr->fgcol = *get_theme_color(COLOR_THEME_CITYREP_TEXT);
589 pbuf = create_iconlabel(NULL, pWindow->dst, pstr,
590 (WF_SELECT_WITHOUT_BAR | WF_RESTORE_BACKGROUND));
591 if (count > 13 * COL) {
592 set_wflag(pbuf, WF_HIDDEN);
594 hh = MAX(hh, pbuf->size.h);
595 prod_w = MAX(prod_w, pbuf->size.w);
596 add_to_gui_list(MAX_ID - pCity->id, pbuf);
597 pbuf->data.city = pCity;
598 pbuf->action = popup_buy_production_from_city_report_callback;
599 if (city_can_buy(pCity)) {
600 set_wstate(pbuf, FC_WS_NORMAL);
603 count += COL;
604 } city_list_iterate_end;
606 H = hh;
607 pCityRep->pBeginWidgetList = pbuf;
608 /* setup window width */
609 area.w = name_w + adj_size(6) + pText1->w + adj_size(8) + pCMA_Icon->w
610 + (pIcons->pBIG_Food->w + adj_size(6)) * 10 + pText2->w + adj_size(6)
611 + pUnits_Icon->w + adj_size(6) + prod_w + adj_size(170);
613 if (count) {
614 pCityRep->pEndActiveWidgetList = pLast->prev;
615 pCityRep->pBeginActiveWidgetList = pCityRep->pBeginWidgetList;
616 if (count > 14 * COL) {
617 pCityRep->pActiveWidgetList = pCityRep->pEndActiveWidgetList;
618 if (pCityRep->pScroll) {
619 pCityRep->pScroll->count = count;
621 ww = create_vertical_scrollbar(pCityRep, COL, 14, TRUE, TRUE);
622 area.w += ww;
623 area.h = 14 * (hh + adj_size(2));
624 } else {
625 area.h = (count / COL) * (hh + adj_size(2));
629 area.h += pText2->h + adj_size(6);
630 area.w += adj_size(2);
632 pLogo = theme_get_background(theme, BACKGROUND_CITYREP);
633 resize_window(pWindow, pLogo, NULL,
634 (pWindow->size.w - pWindow->area.w) + area.w,
635 (pWindow->size.h - pWindow->area.h) + area.h);
636 FREESURFACE(pLogo);
638 #if 0
639 pLogo = SDL_DisplayFormat(pWindow->theme);
640 FREESURFACE(pWindow->theme);
641 pWindow->theme = pLogo;
642 pLogo = NULL;
643 #endif
645 area = pWindow->area;
647 widget_set_position(pWindow,
648 (main_window_width() - pWindow->size.w) / 2,
649 (main_window_height() - pWindow->size.h) / 2);
651 /* exit button */
652 pbuf = pWindow->prev;
653 pbuf->size.x = area.x + area.w - pbuf->size.w - 1;
654 pbuf->size.y = pWindow->size.y + adj_size(2);
656 /* FIXME: not implemented yet */
657 #if 0
658 /* info button */
659 pbuf = pbuf->prev;
660 pbuf->size.x = area.x + area.w - pbuf->size.w - adj_size(5);
661 pbuf->size.y = area.y + area.h - pbuf->size.h - adj_size(5);
663 /* happy button */
664 pbuf = pbuf->prev;
665 pbuf->size.x = pbuf->next->size.x - adj_size(5) - pbuf->size.w;
666 pbuf->size.y = pbuf->next->size.y;
668 /* army button */
669 pbuf = pbuf->prev;
670 pbuf->size.x = pbuf->next->size.x - adj_size(5) - pbuf->size.w;
671 pbuf->size.y = pbuf->next->size.y;
673 /* supported button */
674 pbuf = pbuf->prev;
675 pbuf->size.x = pbuf->next->size.x - adj_size(5) - pbuf->size.w;
676 pbuf->size.y = pbuf->next->size.y;
677 #endif /* 0 */
679 /* cities background and labels */
680 dst.x = area.x + adj_size(2);
681 dst.y = area.y + 1;
682 dst.w = (name_w + adj_size(6)) + (pText1->w + adj_size(8)) + adj_size(5);
683 dst.h = area.h - adj_size(2);
684 fill_rect_alpha(pWindow->theme, &dst, &bg_color);
686 create_frame(pWindow->theme,
687 dst.x , dst.y, dst.w, dst.h - 1,
688 get_theme_color(COLOR_THEME_CITYREP_FRAME));
690 dst.y += (pText2->h - pText3->h) / 2;
691 dst.x += ((name_w + adj_size(6)) - pText3->w) / 2;
692 alphablit(pText3, NULL, pWindow->theme, &dst, 255);
693 FREESURFACE(pText3);
695 /* city size background and label */
696 dst.x = area.x + adj_size(5) + name_w + adj_size(5 + 4);
697 alphablit(pText1, NULL, pWindow->theme, &dst, 255);
698 ww = pText1->w;
699 FREESURFACE(pText1);
701 /* cma icon */
702 dst.x += (ww + adj_size(9));
703 dst.y = area.y + 1 + (pText2->h - pCMA_Icon->h) / 2;
704 alphablit(pCMA_Icon, NULL, pWindow->theme, &dst, 255);
705 ww = pCMA_Icon->w;
706 FREESURFACE(pCMA_Icon);
708 /* -------------- */
709 /* populations food unkeep background and label */
710 dst.x += (ww + 1);
711 dst.y = area.y + 1;
712 w = dst.x + adj_size(2);
713 dst.w = (pIcons->pBIG_Food->w + adj_size(6)) + adj_size(10)
714 + (pIcons->pBIG_Food_Surplus->w + adj_size(6)) + adj_size(10)
715 + pText2->w + adj_size(6 + 2);
716 dst.h = area.h - adj_size(2);
717 fill_rect_alpha(pWindow->theme, &dst, get_theme_color(COLOR_THEME_CITYREP_FOODSTOCK));
719 create_frame(pWindow->theme,
720 dst.x, dst.y, dst.w, dst.h - 1,
721 get_theme_color(COLOR_THEME_CITYREP_FRAME));
723 dst.y = area.y + 1 + (pText2->h - pIcons->pBIG_Food->h) / 2;
724 dst.x += adj_size(5);
725 alphablit(pIcons->pBIG_Food, NULL, pWindow->theme, &dst, 255);
727 /* food surplus Icon */
728 w += (pIcons->pBIG_Food->w + adj_size(6)) + adj_size(10);
729 dst.x = w + adj_size(3);
730 alphablit(pIcons->pBIG_Food_Surplus, NULL, pWindow->theme, &dst, 255);
732 /* to grow label */
733 w += (pIcons->pBIG_Food_Surplus->w + adj_size(6)) + adj_size(10);
734 dst.x = w + adj_size(3);
735 dst.y = area.y + 1;
736 alphablit(pText2, NULL, pWindow->theme, &dst, 255);
737 hh = pText2->h;
738 ww = pText2->w;
739 FREESURFACE(pText2);
740 /* -------------- */
742 /* trade, corruptions, gold, science, luxury income background and label */
743 dst.x = w + (ww + adj_size(8));
744 dst.y = area.y + 1;
745 w = dst.x + adj_size(2);
746 dst.w = (pIcons->pBIG_Trade->w + adj_size(6)) + adj_size(10) +
747 (pIcons->pBIG_Trade_Corr->w + adj_size(6)) + adj_size(10) +
748 (pIcons->pBIG_Coin->w + adj_size(6)) + adj_size(10) +
749 (pIcons->pBIG_Colb->w + adj_size(6)) + adj_size(10) +
750 (pIcons->pBIG_Luxury->w + adj_size(6)) + adj_size(4);
751 dst.h = area.h - adj_size(2);
753 fill_rect_alpha(pWindow->theme, &dst, get_theme_color(COLOR_THEME_CITYREP_TRADE));
755 create_frame(pWindow->theme,
756 dst.x , dst.y, dst.w, dst.h - 1,
757 get_theme_color(COLOR_THEME_CITYREP_FRAME));
759 dst.y = area.y + 1 + (hh - pIcons->pBIG_Trade->h) / 2;
760 dst.x += adj_size(5);
761 alphablit(pIcons->pBIG_Trade, NULL, pWindow->theme, &dst, 255);
763 w += (pIcons->pBIG_Trade->w + adj_size(6)) + adj_size(10);
764 dst.x = w + adj_size(3);
765 alphablit(pIcons->pBIG_Trade_Corr, NULL, pWindow->theme, &dst, 255);
767 w += (pIcons->pBIG_Food_Corr->w + adj_size(6)) + adj_size(10);
768 dst.x = w + adj_size(3);
769 alphablit(pIcons->pBIG_Coin, NULL, pWindow->theme, &dst, 255);
771 w += (pIcons->pBIG_Coin->w + adj_size(6)) + adj_size(10);
772 dst.x = w + adj_size(3);
773 alphablit(pIcons->pBIG_Colb, NULL, pWindow->theme, &dst, 255);
775 w += (pIcons->pBIG_Colb->w + adj_size(6)) + adj_size(10);
776 dst.x = w + adj_size(3);
777 alphablit(pIcons->pBIG_Luxury, NULL, pWindow->theme, &dst, 255);
778 /* --------------------- */
780 /* total productions, waste, support, shields surplus background and label */
781 w += (pIcons->pBIG_Luxury->w + adj_size(6)) + adj_size(4);
782 dst.x = w;
783 w += adj_size(2);
784 dst.y = area.y + 1;
785 dst.w = (pIcons->pBIG_Shield->w + adj_size(6)) + adj_size(10) +
786 (pIcons->pBIG_Shield_Corr->w + adj_size(6)) + adj_size(10) +
787 (pUnits_Icon->w + adj_size(6)) + adj_size(10) +
788 (pIcons->pBIG_Shield_Surplus->w + adj_size(6)) + adj_size(4);
789 dst.h = area.h - adj_size(2);
791 fill_rect_alpha(pWindow->theme, &dst, get_theme_color(COLOR_THEME_CITYREP_PROD));
793 create_frame(pWindow->theme,
794 dst.x , dst.y, dst.w, dst.h - 1,
795 get_theme_color(COLOR_THEME_CITYREP_FRAME));
797 dst.y = area.y + 1 + (hh - pIcons->pBIG_Shield->h) / 2;
798 dst.x += adj_size(5);
799 alphablit(pIcons->pBIG_Shield, NULL, pWindow->theme, &dst, 255);
801 w += (pIcons->pBIG_Shield->w + adj_size(6)) + adj_size(10);
802 dst.x = w + adj_size(3);
803 alphablit(pIcons->pBIG_Shield_Corr, NULL, pWindow->theme, &dst, 255);
805 w += (pIcons->pBIG_Shield_Corr->w + adj_size(6)) + adj_size(10);
806 dst.x = w + adj_size(3);
807 dst.y = area.y + 1 + (hh - pUnits_Icon->h) / 2;
808 alphablit(pUnits_Icon, NULL, pWindow->theme, &dst, 255);
810 w += (pUnits_Icon->w + adj_size(6)) + adj_size(10);
811 FREESURFACE(pUnits_Icon);
812 dst.x = w + adj_size(3);
813 dst.y = area.y + 1 + (hh - pIcons->pBIG_Shield_Surplus->h) / 2;
814 alphablit(pIcons->pBIG_Shield_Surplus, NULL, pWindow->theme, &dst, 255);
815 /* ------------------------------- */
817 w += (pIcons->pBIG_Shield_Surplus->w + adj_size(6)) + adj_size(10);
818 dst.x = w;
819 w += adj_size(2);
820 dst.y = area.y + 1;
821 dst.w = adj_size(36) + adj_size(5) + prod_w;
822 dst.h = hh + adj_size(2);
824 fill_rect_alpha(pWindow->theme, &dst, get_theme_color(COLOR_THEME_CITYREP_PROD));
826 create_frame(pWindow->theme,
827 dst.x , dst.y, dst.w, dst.h - 1,
828 get_theme_color(COLOR_THEME_CITYREP_FRAME));
830 dst.y = area.y + 1 + (hh - pText4->h) / 2;
831 dst.x += (dst.w - pText4->w) / 2;
832 alphablit(pText4, NULL, pWindow->theme, &dst, 255);
833 FREESURFACE(pText4);
835 if (count) {
836 int start_x = area.x + adj_size(5);
837 int start_y = area.y + hh + adj_size(3);
839 H += adj_size(2);
840 pbuf = pbuf->prev;
841 while (TRUE) {
843 /* city name */
844 pbuf->size.x = start_x;
845 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
846 pbuf->size.w = name_w;
848 /* city size */
849 pbuf = pbuf->prev;
850 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(5);
851 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
853 /* cma */
854 pbuf = pbuf->prev;
855 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(6);
856 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
858 /* food cons. */
859 pbuf = pbuf->prev;
860 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(6);
861 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
863 /* food surplus */
864 pbuf = pbuf->prev;
865 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(10);
866 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
868 /* time to grow */
869 pbuf = pbuf->prev;
870 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(10);
871 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
873 /* trade */
874 pbuf = pbuf->prev;
875 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(5);
876 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
878 /* trade corruptions */
879 pbuf = pbuf->prev;
880 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(10);
881 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
883 /* net gold income */
884 pbuf = pbuf->prev;
885 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(10);
886 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
888 /* science income */
889 pbuf = pbuf->prev;
890 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(10);
891 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
893 /* luxuries income */
894 pbuf = pbuf->prev;
895 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(10);
896 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
898 /* total production */
899 pbuf = pbuf->prev;
900 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(6);
901 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
903 /* waste */
904 pbuf = pbuf->prev;
905 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(10);
906 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
908 /* units support */
909 pbuf = pbuf->prev;
910 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(10);
911 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
913 /* producrion surplus */
914 pbuf = pbuf->prev;
915 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(10);
916 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
918 /* currently build */
919 /* icon */
920 pbuf = pbuf->prev;
921 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(10);
922 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
924 /* label */
925 pbuf = pbuf->prev;
926 pbuf->size.x = pbuf->next->size.x + pbuf->next->size.w + adj_size(5);
927 pbuf->size.y = start_y + (H - pbuf->size.h) / 2;
928 pbuf->size.w = prod_w;
930 start_y += H;
931 if (pbuf == pCityRep->pBeginActiveWidgetList) {
932 break;
934 pbuf = pbuf->prev;
937 if (pCityRep->pScroll) {
938 setup_vertical_scrollbar_area(pCityRep->pScroll,
939 area.x + area.w, area.y,
940 area.h, TRUE);
944 /* ----------------------------------- */
945 redraw_group(pCityRep->pBeginWidgetList, pWindow, 0);
946 widget_mark_dirty(pWindow);
947 flush_dirty();
950 /**************************************************************************
951 Update city information in city report.
952 **************************************************************************/
953 static struct widget *real_city_report_dialog_update_city(struct widget *pWidget,
954 struct city *pCity)
956 char cbuf[64];
957 const char *pName;
958 int togrow;
959 SDL_Surface *pLogo;
960 SDL_Rect dst;
962 /* city name status */
963 if (city_unhappy(pCity)) {
964 pWidget->string_utf8->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_TRADE);
965 } else {
966 if (city_celebrating(pCity)) {
967 pWidget->string_utf8->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_CELEB);
968 } else {
969 if (city_happy(pCity)) {
970 pWidget->string_utf8->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_HAPPY);
975 /* city size */
976 pWidget = pWidget->prev;
977 fc_snprintf(cbuf, sizeof(cbuf), "%d", city_size_get(pCity));
978 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
980 /* cma check box */
981 pWidget = pWidget->prev;
982 if (cma_is_city_under_agent(pCity, NULL) != get_checkbox_state(pWidget)) {
983 toggle_checkbox(pWidget);
986 /* food consumptions */
987 pWidget = pWidget->prev;
988 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->prod[O_FOOD] - pCity->surplus[O_FOOD]);
989 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
991 /* food surplus */
992 pWidget = pWidget->prev;
993 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->surplus[O_FOOD]);
994 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
996 /* time to grow */
997 pWidget = pWidget->prev;
998 togrow = city_turns_to_grow(pCity);
999 switch (togrow) {
1000 case 0:
1001 fc_snprintf(cbuf, sizeof(cbuf), "#");
1002 break;
1003 case FC_INFINITY:
1004 fc_snprintf(cbuf, sizeof(cbuf), "--");
1005 break;
1006 default:
1007 fc_snprintf(cbuf, sizeof(cbuf), "%d", togrow);
1008 break;
1010 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
1012 if (togrow < 0) {
1013 pWidget->string_utf8->fgcol.r = 255;
1014 } else {
1015 pWidget->string_utf8->fgcol.r = 0;
1018 /* trade production */
1019 pWidget = pWidget->prev;
1020 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->surplus[O_TRADE]);
1021 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
1023 /* corruptions */
1024 pWidget = pWidget->prev;
1025 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->waste[O_TRADE]);
1026 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
1028 /* gold surplus */
1029 pWidget = pWidget->prev;
1030 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->surplus[O_GOLD]);
1031 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
1033 /* science income */
1034 pWidget = pWidget->prev;
1035 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->prod[O_SCIENCE]);
1036 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
1038 /* lugury income */
1039 pWidget = pWidget->prev;
1040 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->prod[O_LUXURY]);
1041 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
1043 /* total production */
1044 pWidget = pWidget->prev;
1045 fc_snprintf(cbuf, sizeof(cbuf), "%d",
1046 pCity->prod[O_SHIELD] + pCity->waste[O_SHIELD]);
1047 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
1049 /* waste */
1050 pWidget = pWidget->prev;
1051 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->waste[O_SHIELD]);
1052 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
1054 /* units support */
1055 pWidget = pWidget->prev;
1056 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->prod[O_SHIELD] +
1057 pCity->waste[O_SHIELD] - pCity->surplus[O_SHIELD]);
1058 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
1060 /* production income */
1061 pWidget = pWidget->prev;
1062 fc_snprintf(cbuf, sizeof(cbuf), "%d", pCity->surplus[O_SHIELD]);
1063 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
1065 /* change production */
1066 if (VUT_UTYPE == pCity->production.kind) {
1067 struct unit_type *pUnitType = pCity->production.value.utype;
1069 pLogo = ResizeSurface(get_unittype_surface(pUnitType, direction8_invalid()),
1070 adj_size(36), adj_size(24), 1);
1071 togrow = utype_build_shield_cost(pUnitType);
1072 pName = utype_name_translation(pUnitType);
1073 } else {
1074 struct impr_type *pImprove = pCity->production.value.building;
1076 pLogo = ResizeSurface(get_building_surface(pCity->production.value.building),
1077 adj_size(36), adj_size(24), 1);
1078 togrow = impr_build_shield_cost(pImprove);
1079 pName = improvement_name_translation(pImprove);
1082 if (!worklist_is_empty(&(pCity->worklist))) {
1083 dst.x = pLogo->w - pIcons->pWorklist->w;
1084 dst.y = 0;
1085 alphablit(pIcons->pWorklist, NULL, pLogo, &dst, 255);
1086 fc_snprintf(cbuf, sizeof(cbuf), "%s\n(%d/%d)\n%s",
1087 pName, pCity->shield_stock, togrow, _("worklist"));
1088 } else {
1089 fc_snprintf(cbuf, sizeof(cbuf), "%s\n(%d/%d)",
1090 pName, pCity->shield_stock, togrow);
1093 pWidget = pWidget->prev;
1094 copy_chars_to_utf8_str(pWidget->info_label, cbuf);
1095 FREESURFACE(pWidget->theme);
1096 pWidget->theme = pLogo;
1098 /* hurry productions */
1099 pWidget = pWidget->prev;
1100 togrow = city_production_turns_to_build(pCity, TRUE);
1101 if (togrow == 999) {
1102 fc_snprintf(cbuf, sizeof(cbuf), "%s", _("never"));
1103 } else {
1104 fc_snprintf(cbuf, sizeof(cbuf), "%d %s",
1105 togrow, PL_("turn", "turns", togrow));
1108 copy_chars_to_utf8_str(pWidget->string_utf8, cbuf);
1110 return pWidget->prev;
1113 /* ======================================================================== */
1115 /**************************************************************************
1116 Check if city report is open.
1117 **************************************************************************/
1118 bool is_city_report_open(void)
1120 return (pCityRep != NULL);
1123 /**************************************************************************
1124 Pop up or brings forward the city report dialog. It may or may not
1125 be modal.
1126 **************************************************************************/
1127 void city_report_dialog_popup(bool make_modal)
1129 if (!pCityRep) {
1130 real_info_city_report_dialog_update();
1134 /**************************************************************************
1135 Update (refresh) the entire city report dialog.
1136 **************************************************************************/
1137 void real_city_report_dialog_update(void)
1139 if (pCityRep) {
1140 struct widget *pWidget;
1141 int count;
1143 /* find if the lists are identical (if not then rebuild all) */
1144 pWidget = pCityRep->pEndActiveWidgetList;/* name of first city */
1145 city_list_iterate(client.conn.playing->cities, pCity) {
1146 if (pCity->id == MAX_ID - pWidget->ID) {
1147 count = COL;
1149 while (count) {
1150 count--;
1151 pWidget = pWidget->prev;
1153 } else {
1154 real_info_city_report_dialog_update();
1155 return;
1157 } city_list_iterate_end;
1159 /* check it there are some city widgets left on list */
1160 if (pWidget && pWidget->next != pCityRep->pBeginActiveWidgetList) {
1161 real_info_city_report_dialog_update();
1162 return;
1165 /* update widget city list (widget list is the same that city list) */
1166 pWidget = pCityRep->pEndActiveWidgetList;
1167 city_list_iterate(client.conn.playing->cities, pCity) {
1168 pWidget = real_city_report_dialog_update_city(pWidget, pCity);
1169 } city_list_iterate_end;
1171 /* -------------------------------------- */
1172 redraw_group(pCityRep->pBeginWidgetList, pCityRep->pEndWidgetList, 0);
1173 widget_mark_dirty(pCityRep->pEndWidgetList);
1175 flush_dirty();
1179 /**************************************************************************
1180 Update the city report dialog for a single city.
1181 **************************************************************************/
1182 void real_city_report_update_city(struct city *pCity)
1184 if (pCityRep && pCity) {
1185 struct widget *pBuf = pCityRep->pEndActiveWidgetList;
1187 while (pCity->id != MAX_ID - pBuf->ID
1188 && pBuf != pCityRep->pBeginActiveWidgetList) {
1189 pBuf = pBuf->prev;
1192 if (pBuf == pCityRep->pBeginActiveWidgetList) {
1193 real_info_city_report_dialog_update();
1194 return;
1196 real_city_report_dialog_update_city(pBuf, pCity);
1198 /* -------------------------------------- */
1199 redraw_group(pCityRep->pBeginWidgetList, pCityRep->pEndWidgetList, 0);
1200 widget_mark_dirty(pCityRep->pEndWidgetList);
1202 flush_dirty();
1206 /****************************************************************
1207 After a selection rectangle is defined, make the cities that
1208 are hilited on the canvas exclusively hilited in the
1209 City List window.
1210 *****************************************************************/
1211 void hilite_cities_from_canvas(void)
1213 log_debug("hilite_cities_from_canvas : PORT ME");
1216 /****************************************************************
1217 Toggle a city's hilited status.
1218 *****************************************************************/
1219 void toggle_city_hilite(struct city *pCity, bool on_off)
1221 log_debug("toggle_city_hilite : PORT ME");