1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 /***********************************************************************
15 repodlgs.c - description
18 copyright : (C) 2002 by Rafał Bursig
19 email : Rafał Bursig <bursig@poczta.fm>
20 ***********************************************************************/
23 #include <fc_config.h>
32 #include "government.h"
37 #include "client_main.h"
47 #include "gui_tilespec.h"
52 #include "themespec.h"
58 /* ===================================================================== */
59 /* ======================== Active Units Report ======================== */
60 /* ===================================================================== */
61 static struct ADVANCED_DLG
*pUnitsDlg
= NULL
;
62 static struct SMALL_DLG
*pUnits_Upg_Dlg
= NULL
;
68 int soonest_completions
;
71 /**************************************************************************
72 Fill unit types specific report data + totals.
73 **************************************************************************/
74 static void get_units_report_data(struct units_entry
*entries
,
75 struct units_entry
*total
)
79 memset(entries
, '\0', U_LAST
* sizeof(struct units_entry
));
80 memset(total
, '\0', sizeof(struct units_entry
));
81 for (time_to_build
= 0; time_to_build
< U_LAST
; time_to_build
++) {
82 entries
[time_to_build
].soonest_completions
= FC_INFINITY
;
85 unit_list_iterate(client
.conn
.playing
->units
, punit
) {
86 Unit_type_id uti
= utype_index(unit_type_get(punit
));
88 (entries
[uti
].active_count
)++;
89 (total
->active_count
)++;
90 if (punit
->homecity
) {
91 output_type_iterate(o
) {
92 entries
[uti
].upkeep
[o
] += punit
->upkeep
[o
];
93 total
->upkeep
[o
] += punit
->upkeep
[o
];
94 } output_type_iterate_end
;
96 } unit_list_iterate_end
;
98 city_list_iterate(client
.conn
.playing
->cities
, pCity
) {
99 if (VUT_UTYPE
== pCity
->production
.kind
) {
100 struct unit_type
*pUnitType
= pCity
->production
.value
.utype
;
101 Unit_type_id uti
= utype_index(pUnitType
);
104 /* Account for build slots in city */
105 (void) city_production_build_units(pCity
, TRUE
, &num_units
);
106 /* Unit is in progress even if it won't be done this turn */
107 num_units
= MAX(num_units
, 1);
108 (entries
[uti
].building_count
) += num_units
;
109 (total
->building_count
) += num_units
;
110 entries
[uti
].soonest_completions
=
111 MIN(entries
[uti
].soonest_completions
,
112 city_production_turns_to_build(pCity
, TRUE
));
114 } city_list_iterate_end
;
117 /**************************************************************************
118 User interacted with Units Report button.
119 **************************************************************************/
120 static int units_dialog_callback(struct widget
*pWindow
)
122 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
123 move_window_group(pUnitsDlg
->pBeginWidgetList
, pWindow
);
129 /* --------------------------------------------------------------- */
131 /**************************************************************************
132 User interacted with accept button of the unit upgrade dialog.
133 **************************************************************************/
134 static int ok_upgrade_unit_window_callback(struct widget
*pWidget
)
136 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
137 int ut1
= MAX_ID
- pWidget
->ID
;
139 /* popdown upgrade dlg */
140 popdown_window_group_dialog(pUnits_Upg_Dlg
->pBeginWidgetList
,
141 pUnits_Upg_Dlg
->pEndWidgetList
);
142 FC_FREE(pUnits_Upg_Dlg
);
144 dsend_packet_unit_type_upgrade(&client
.conn
, ut1
);
150 /**************************************************************************
151 User interacted with Upgrade Obsolete button of the unit upgrade dialog.
152 **************************************************************************/
153 static int upgrade_unit_window_callback(struct widget
*pWindow
)
155 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
156 move_window_group(pUnits_Upg_Dlg
->pBeginWidgetList
, pWindow
);
162 /**************************************************************************
163 User interacted with Cancel button of the unit upgrade dialog.
164 **************************************************************************/
165 static int cancel_upgrade_unit_callback(struct widget
*pWidget
)
167 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
168 if (pUnits_Upg_Dlg
) {
169 popdown_window_group_dialog(pUnits_Upg_Dlg
->pBeginWidgetList
,
170 pUnits_Upg_Dlg
->pEndWidgetList
);
171 FC_FREE(pUnits_Upg_Dlg
);
179 /**************************************************************************
180 Open dialog for upgrading units.
181 **************************************************************************/
182 static int popup_upgrade_unit_callback(struct widget
*pWidget
)
184 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
185 struct unit_type
*ut1
;
186 struct unit_type
*ut2
;
188 char tBuf
[128], cBuf
[128];
189 struct widget
*pBuf
= NULL
, *pWindow
;
195 ut1
= utype_by_number(MAX_ID
- pWidget
->ID
);
197 if (pUnits_Upg_Dlg
) {
201 set_wstate(pWidget
, FC_WS_NORMAL
);
202 selected_widget
= NULL
;
203 widget_redraw(pWidget
);
204 widget_mark_dirty(pWidget
);
206 pUnits_Upg_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
208 ut2
= can_upgrade_unittype(client
.conn
.playing
, ut1
);
209 value
= unit_upgrade_price(client
.conn
.playing
, ut1
, ut2
);
211 fc_snprintf(tBuf
, ARRAY_SIZE(tBuf
), PL_("Treasury contains %d gold.",
212 "Treasury contains %d gold.",
213 client_player()->economic
.gold
),
214 client_player()->economic
.gold
);
216 fc_snprintf(cBuf
, sizeof(cBuf
),
217 /* TRANS: Last %s is pre-pluralised "Treasury contains %d gold." */
218 PL_("Upgrade as many %s to %s as possible for %d gold each?\n%s",
219 "Upgrade as many %s to %s as possible for %d gold each?\n%s",
221 utype_name_translation(ut1
),
222 utype_name_translation(ut2
),
225 pstr
= create_utf8_from_char(_("Upgrade Obsolete Units"), adj_font(12));
226 pstr
->style
|= TTF_STYLE_BOLD
;
228 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
230 pWindow
->action
= upgrade_unit_window_callback
;
231 set_wstate(pWindow
, FC_WS_NORMAL
);
233 add_to_gui_list(ID_WINDOW
, pWindow
);
235 pUnits_Upg_Dlg
->pEndWidgetList
= pWindow
;
237 area
= pWindow
->area
;
239 /* ============================================================= */
241 /* create text label */
242 pstr
= create_utf8_from_char(cBuf
, adj_font(10));
243 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
244 pstr
->fgcol
= *get_theme_color(COLOR_THEME_UNITUPGRADE_TEXT
);
246 pText
= create_text_surf_from_utf8(pstr
);
249 area
.h
+= (pText
->h
+ adj_size(10));
250 area
.w
= MAX(area
.w
, pText
->w
+ adj_size(20));
253 pBuf
= create_themeicon_button_from_chars(current_theme
->CANCEL_Icon
,
254 pWindow
->dst
, _("No"),
257 pBuf
->action
= cancel_upgrade_unit_callback
;
258 set_wstate(pBuf
, FC_WS_NORMAL
);
260 area
.h
+= (pBuf
->size
.h
+ adj_size(20));
262 add_to_gui_list(ID_BUTTON
, pBuf
);
264 if (value
<= client
.conn
.playing
->economic
.gold
) {
265 pBuf
= create_themeicon_button_from_chars(current_theme
->OK_Icon
, pWindow
->dst
,
266 _("Yes"), adj_font(12), 0);
268 pBuf
->action
= ok_upgrade_unit_window_callback
;
269 set_wstate(pBuf
, FC_WS_NORMAL
);
271 add_to_gui_list(pWidget
->ID
, pBuf
);
272 pBuf
->size
.w
= MAX(pBuf
->size
.w
, pBuf
->next
->size
.w
);
273 pBuf
->next
->size
.w
= pBuf
->size
.w
;
274 area
.w
= MAX(area
.w
, adj_size(30) + pBuf
->size
.w
* 2);
276 area
.w
= MAX(area
.w
, pBuf
->size
.w
+ adj_size(20));
278 /* ============================================ */
280 pUnits_Upg_Dlg
->pBeginWidgetList
= pBuf
;
282 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
283 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
284 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
286 widget_set_position(pWindow
,
287 pUnitsDlg
->pEndWidgetList
->size
.x
+
288 (pUnitsDlg
->pEndWidgetList
->size
.w
- pWindow
->size
.w
) / 2,
289 pUnitsDlg
->pEndWidgetList
->size
.y
+
290 (pUnitsDlg
->pEndWidgetList
->size
.h
- pWindow
->size
.h
) / 2);
292 /* setup rest of widgets */
294 dst
.x
= area
.x
+ (area
.w
- pText
->w
) / 2;
295 dst
.y
= area
.y
+ adj_size(10);
296 alphablit(pText
, NULL
, pWindow
->theme
, &dst
, 255);
300 pBuf
= pWindow
->prev
;
301 pBuf
->size
.y
= area
.y
+ area
.h
- pBuf
->size
.h
- adj_size(10);
303 if (value
<= client
.conn
.playing
->economic
.gold
) {
306 pBuf
->size
.x
= area
.x
+ (area
.w
- (2 * pBuf
->size
.w
+ adj_size(10))) / 2;
307 pBuf
->size
.y
= pBuf
->next
->size
.y
;
310 pBuf
->next
->size
.x
= pBuf
->size
.x
+ pBuf
->size
.w
+ adj_size(10);
312 /* x position of cancel button */
313 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- adj_size(10);
316 /* ================================================== */
318 redraw_group(pUnits_Upg_Dlg
->pBeginWidgetList
, pWindow
, 0);
320 widget_mark_dirty(pWindow
);
327 /**************************************************************************
328 User interacted with units dialog Close Dialog button.
329 **************************************************************************/
330 static int exit_units_dlg_callback(struct widget
*pWidget
)
332 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
334 if (pUnits_Upg_Dlg
) {
335 del_group_of_widgets_from_gui_list(pUnits_Upg_Dlg
->pBeginWidgetList
,
336 pUnits_Upg_Dlg
->pEndWidgetList
);
337 FC_FREE(pUnits_Upg_Dlg
);
339 popdown_window_group_dialog(pUnitsDlg
->pBeginWidgetList
,
340 pUnitsDlg
->pEndWidgetList
);
341 FC_FREE(pUnitsDlg
->pScroll
);
350 /**************************************************************************
351 Rebuild the units report.
352 **************************************************************************/
353 static void real_activeunits_report_dialog_update(struct units_entry
*units
,
354 struct units_entry
*total
)
356 SDL_Color bg_color
= {255, 255, 255, 136};
357 struct widget
*pBuf
= NULL
;
358 struct widget
*pWindow
, *pLast
;
360 SDL_Surface
*pText1
, *pText2
, *pText3
, *pText4
, *pText5
, *pLogo
;
361 int w
= 0 , count
, ww
, hh
= 0, name_w
= 0;
364 bool upgrade
= FALSE
;
368 popdown_window_group_dialog(pUnitsDlg
->pBeginWidgetList
,
369 pUnitsDlg
->pEndWidgetList
);
371 pUnitsDlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
374 fc_snprintf(cbuf
, sizeof(cbuf
), _("active"));
375 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
376 pstr
->style
|= SF_CENTER
;
377 pText1
= create_text_surf_from_utf8(pstr
);
379 fc_snprintf(cbuf
, sizeof(cbuf
), _("under\nconstruction"));
380 copy_chars_to_utf8_str(pstr
, cbuf
);
381 pText2
= create_text_surf_from_utf8(pstr
);
383 fc_snprintf(cbuf
, sizeof(cbuf
), _("soonest\ncompletion"));
384 copy_chars_to_utf8_str(pstr
, cbuf
);
385 pText5
= create_text_surf_from_utf8(pstr
);
387 fc_snprintf(cbuf
, sizeof(cbuf
), _("Total"));
388 copy_chars_to_utf8_str(pstr
, cbuf
);
389 pText3
= create_text_surf_from_utf8(pstr
);
391 fc_snprintf(cbuf
, sizeof(cbuf
), _("Units"));
392 copy_chars_to_utf8_str(pstr
, cbuf
);
393 pText4
= create_text_surf_from_utf8(pstr
);
397 /* --------------- */
398 pstr
= create_utf8_from_char(_("Units Report"), adj_font(12));
399 pstr
->style
|= TTF_STYLE_BOLD
;
401 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
402 set_wstate(pWindow
, FC_WS_NORMAL
);
403 pWindow
->action
= units_dialog_callback
;
405 add_to_gui_list(ID_UNITS_DIALOG_WINDOW
, pWindow
);
407 pUnitsDlg
->pEndWidgetList
= pWindow
;
409 area
= pWindow
->area
;
411 /* ------------------------- */
413 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
414 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
415 pBuf
->info_label
= create_utf8_from_char(_("Close Dialog (Esc)"), adj_font(12));
416 pBuf
->action
= exit_units_dlg_callback
;
417 set_wstate(pBuf
, FC_WS_NORMAL
);
418 pBuf
->key
= SDLK_ESCAPE
;
420 add_to_gui_list(ID_BUTTON
, pBuf
);
421 /* ------------------------- */
423 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", total
->active_count
);
425 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
426 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
428 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
,
429 WF_RESTORE_BACKGROUND
);
431 area
.h
+= pBuf
->size
.h
;
432 pBuf
->size
.w
= pText1
->w
+ adj_size(6);
433 add_to_gui_list(ID_LABEL
, pBuf
);
434 /* ---------------------------------------------- */
435 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", total
->upkeep
[O_SHIELD
]);
437 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
438 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
440 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
, WF_RESTORE_BACKGROUND
);
442 pBuf
->size
.w
= pText1
->w
;
443 add_to_gui_list(ID_LABEL
, pBuf
);
444 /* ---------------------------------------------- */
445 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", total
->upkeep
[O_FOOD
]);
447 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
448 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
450 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
, WF_RESTORE_BACKGROUND
);
452 pBuf
->size
.w
= pText1
->w
;
453 add_to_gui_list(ID_LABEL
, pBuf
);
454 /* ---------------------------------------------- */
455 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", total
->upkeep
[O_GOLD
]);
457 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
458 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
460 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
, WF_RESTORE_BACKGROUND
);
462 pBuf
->size
.w
= pText1
->w
;
463 add_to_gui_list(ID_LABEL
, pBuf
);
464 /* ---------------------------------------------- */
465 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", total
->building_count
);
467 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
468 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
470 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
,
471 WF_RESTORE_BACKGROUND
);
473 pBuf
->size
.w
= pText2
->w
+ adj_size(6);
474 add_to_gui_list(ID_LABEL
, pBuf
);
476 /* ------------------------- */
479 unit_type_iterate(i
) {
480 if ((units
[utype_index(i
)].active_count
> 0)
481 || (units
[utype_index(i
)].building_count
> 0)) {
482 upgrade
= (can_upgrade_unittype(client
.conn
.playing
, i
) != NULL
);
485 pBuf
= create_iconlabel(adj_surf(get_unittype_surface(i
, direction8_invalid())), pWindow
->dst
, NULL
,
486 WF_RESTORE_BACKGROUND
| WF_FREE_THEME
);
487 if (count
> adj_size(72)) {
488 set_wflag(pBuf
, WF_HIDDEN
);
491 add_to_gui_list(MAX_ID
- utype_number(i
), pBuf
);
494 pstr
= create_utf8_from_char(utype_name_translation(i
), adj_font(12));
495 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
496 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
,
497 (WF_RESTORE_BACKGROUND
| WF_SELECT_WITHOUT_BAR
));
499 pBuf
->string_utf8
->fgcol
= *get_theme_color(COLOR_THEME_UNITUPGRADE_TEXT
);
500 pBuf
->action
= popup_upgrade_unit_callback
;
501 set_wstate(pBuf
, FC_WS_NORMAL
);
503 pBuf
->string_utf8
->fgcol
= *get_theme_color(COLOR_THEME_UNITSREP_TEXT
);
505 pBuf
->string_utf8
->style
&= ~SF_CENTER
;
506 if (count
> adj_size(72)) {
507 set_wflag(pBuf
, WF_HIDDEN
);
509 hh
= MAX(hh
, pBuf
->size
.h
);
510 name_w
= MAX(pBuf
->size
.w
, name_w
);
511 add_to_gui_list(MAX_ID
- utype_number(i
), pBuf
);
514 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units
[utype_index(i
)].active_count
);
515 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
516 pstr
->style
|= SF_CENTER
;
517 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
,
518 WF_RESTORE_BACKGROUND
);
519 if (count
> adj_size(72)) {
520 set_wflag(pBuf
, WF_HIDDEN
);
522 hh
= MAX(hh
, pBuf
->size
.h
);
523 pBuf
->size
.w
= pText1
->w
+ adj_size(6);
524 add_to_gui_list(MAX_ID
- utype_number(i
), pBuf
);
527 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units
[utype_index(i
)].upkeep
[O_SHIELD
]);
528 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
529 pstr
->style
|= SF_CENTER
;
530 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
,
531 WF_RESTORE_BACKGROUND
);
532 if (count
> adj_size(72)) {
533 set_wflag(pBuf
, WF_HIDDEN
);
535 hh
= MAX(hh
, pBuf
->size
.h
);
536 pBuf
->size
.w
= pText1
->w
;
537 add_to_gui_list(MAX_ID
- utype_number(i
), pBuf
);
540 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units
[utype_index(i
)].upkeep
[O_FOOD
]);
541 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
542 pstr
->style
|= SF_CENTER
;
543 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
,
544 WF_RESTORE_BACKGROUND
);
545 if (count
> adj_size(72)) {
546 set_wflag(pBuf
, WF_HIDDEN
);
549 hh
= MAX(hh
, pBuf
->size
.h
);
550 pBuf
->size
.w
= pText1
->w
;
551 add_to_gui_list(MAX_ID
- utype_number(i
), pBuf
);
554 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units
[utype_index(i
)].upkeep
[O_GOLD
]);
555 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
556 pstr
->style
|= SF_CENTER
;
557 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
,
558 WF_RESTORE_BACKGROUND
);
559 if (count
> adj_size(72)) {
560 set_wflag(pBuf
, WF_HIDDEN
);
563 hh
= MAX(hh
, pBuf
->size
.h
);
564 pBuf
->size
.w
= pText1
->w
;
565 add_to_gui_list(MAX_ID
- utype_number(i
), pBuf
);
568 if (units
[utype_index(i
)].building_count
> 0) {
569 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units
[utype_index(i
)].building_count
);
571 fc_snprintf(cbuf
, sizeof(cbuf
), "--");
573 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
574 pstr
->style
|= SF_CENTER
;
575 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
,
576 WF_RESTORE_BACKGROUND
);
577 if (count
> adj_size(72)) {
578 set_wflag(pBuf
, WF_HIDDEN
);
580 hh
= MAX(hh
, pBuf
->size
.h
);
581 pBuf
->size
.w
= pText2
->w
+ adj_size(6);
582 add_to_gui_list(MAX_ID
- utype_number(i
), pBuf
);
584 /* soonest completion */
585 if (units
[utype_index(i
)].building_count
> 0) {
586 fc_snprintf(cbuf
, sizeof(cbuf
), "%d %s", units
[utype_index(i
)].soonest_completions
,
587 PL_("turn", "turns", units
[utype_index(i
)].soonest_completions
));
589 fc_snprintf(cbuf
, sizeof(cbuf
), "--");
592 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
593 pstr
->style
|= SF_CENTER
;
594 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
,
595 WF_RESTORE_BACKGROUND
);
597 if (count
> adj_size(72)) {
598 set_wflag(pBuf
, WF_HIDDEN
);
600 hh
= MAX(hh
, pBuf
->size
.h
);
601 pBuf
->size
.w
= pText5
->w
+ adj_size(6);
602 add_to_gui_list(MAX_ID
- utype_number(i
), pBuf
);
604 count
+= adj_size(8);
607 } unit_type_iterate_end
;
609 pUnitsDlg
->pBeginWidgetList
= pBuf
;
610 area
.w
= MAX(area
.w
, (tileset_full_tile_width(tileset
) * 2 + name_w
+ adj_size(15))
611 + (adj_size(4) * pText1
->w
+ adj_size(46)) + (pText2
->w
+ adj_size(16))
612 + (pText5
->w
+ adj_size(6)) + adj_size(2));
614 pUnitsDlg
->pEndActiveWidgetList
= pLast
->prev
;
615 pUnitsDlg
->pBeginActiveWidgetList
= pUnitsDlg
->pBeginWidgetList
;
616 if (count
> adj_size(80)) {
617 pUnitsDlg
->pActiveWidgetList
= pUnitsDlg
->pEndActiveWidgetList
;
618 if (pUnitsDlg
->pScroll
) {
619 pUnitsDlg
->pScroll
->count
= count
;
621 ww
= create_vertical_scrollbar(pUnitsDlg
, 8, 10, TRUE
, TRUE
);
623 area
.h
= (hh
+ 9 * (hh
/2) + adj_size(10));
628 area
.h
= adj_size(50);
631 area
.h
+= pText1
->h
+ adj_size(10);
632 area
.w
+= adj_size(2);
634 pLogo
= theme_get_background(theme
, BACKGROUND_UNITSREP
);
635 resize_window(pWindow
, pLogo
, NULL
,
636 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
637 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
641 pLogo
= SDL_DisplayFormat(pWindow
->theme
);
642 FREESURFACE(pWindow
->theme
);
643 pWindow
->theme
= pLogo
;
647 area
= pWindow
->area
;
649 widget_set_position(pWindow
,
650 (main_window_width() - pWindow
->size
.w
) / 2,
651 (main_window_height() - pWindow
->size
.h
) / 2);
654 pBuf
= pWindow
->prev
;
655 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
656 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
658 /* totals background and label */
659 dst
.x
= area
.x
+ adj_size(2);
660 dst
.y
= area
.y
+ area
.h
- (pText3
->h
+ adj_size(2)) - adj_size(2);
661 dst
.w
= name_w
+ tileset_full_tile_width(tileset
) * 2 + adj_size(5);
662 dst
.h
= pText3
->h
+ adj_size(2);
663 fill_rect_alpha(pWindow
->theme
, &dst
, &bg_color
);
665 create_frame(pWindow
->theme
,
666 dst
.x
, dst
.y
, dst
.w
, dst
.h
- 1,
667 get_theme_color(COLOR_THEME_UNITSREP_FRAME
));
670 dst
.x
+= ((name_w
+ tileset_full_tile_width(tileset
) * 2 + adj_size(5)) - pText3
->w
) / 2;
671 alphablit(pText3
, NULL
, pWindow
->theme
, &dst
, 255);
674 /* total active widget */
676 pBuf
->size
.x
= area
.x
+ name_w
677 + tileset_full_tile_width(tileset
) * 2 + adj_size(17);
678 pBuf
->size
.y
= dst
.y
;
680 /* total shields cost widget */
682 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(10);
683 pBuf
->size
.y
= dst
.y
;
685 /* total food cost widget */
687 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(10);
688 pBuf
->size
.y
= dst
.y
;
690 /* total gold cost widget */
692 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(10);
693 pBuf
->size
.y
= dst
.y
;
695 /* total building count widget */
697 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(10);
698 pBuf
->size
.y
= dst
.y
;
700 /* units background and labels */
701 dst
.x
= area
.x
+ adj_size(2);
703 dst
.w
= name_w
+ tileset_full_tile_width(tileset
) * 2 + adj_size(5);
704 dst
.h
= pText4
->h
+ adj_size(2);
705 fill_rect_alpha(pWindow
->theme
, &dst
, &bg_color
);
707 create_frame(pWindow
->theme
,
708 dst
.x
, dst
.y
, dst
.w
, dst
.h
- 1,
709 get_theme_color(COLOR_THEME_UNITSREP_FRAME
));
712 dst
.x
+= ((name_w
+ tileset_full_tile_width(tileset
) * 2 + adj_size(5))- pText4
->w
) / 2;
713 alphablit(pText4
, NULL
, pWindow
->theme
, &dst
, 255);
716 /* active count background and label */
717 dst
.x
= area
.x
+ adj_size(2) + name_w
+ tileset_full_tile_width(tileset
) * 2 + adj_size(15);
719 dst
.w
= pText1
->w
+ adj_size(6);
720 dst
.h
= area
.h
- adj_size(3);
721 fill_rect_alpha(pWindow
->theme
, &dst
, &bg_color
);
723 create_frame(pWindow
->theme
,
724 dst
.x
, dst
.y
, dst
.w
, dst
.h
- 1,
725 get_theme_color(COLOR_THEME_UNITSREP_FRAME
));
727 dst
.x
+= adj_size(3);
728 alphablit(pText1
, NULL
, pWindow
->theme
, &dst
, 255);
733 /* shields cost background and label */
734 dst
.x
+= (ww
+ adj_size(13));
737 dst
.h
= area
.h
- adj_size(3);
738 fill_rect_alpha(pWindow
->theme
, &dst
, &bg_color
);
740 create_frame(pWindow
->theme
,
741 dst
.x
, dst
.y
, dst
.w
, dst
.h
- 1,
742 get_theme_color(COLOR_THEME_UNITSREP_FRAME
));
744 dst
.y
= area
.y
+ adj_size(3);
745 dst
.x
+= ((ww
- pIcons
->pBIG_Shield
->w
) / 2);
746 alphablit(pIcons
->pBIG_Shield
, NULL
, pWindow
->theme
, &dst
, 255);
748 /* food cost background and label */
749 dst
.x
= w
+ ww
+ adj_size(10);
753 dst
.h
= area
.h
- adj_size(3);
754 fill_rect_alpha(pWindow
->theme
, &dst
, &bg_color
);
756 create_frame(pWindow
->theme
,
757 dst
.x
, dst
.y
, dst
.w
, dst
.h
- 1,
758 get_theme_color(COLOR_THEME_UNITSREP_FRAME
));
760 dst
.y
= area
.y
+ adj_size(3);
761 dst
.x
+= ((ww
- pIcons
->pBIG_Food
->w
) / 2);
762 alphablit(pIcons
->pBIG_Food
, NULL
, pWindow
->theme
, &dst
, 255);
764 /* gold cost background and label */
765 dst
.x
= w
+ ww
+ adj_size(10);
769 dst
.h
= area
.h
- adj_size(3);
770 fill_rect_alpha(pWindow
->theme
, &dst
, &bg_color
);
772 create_frame(pWindow
->theme
,
773 dst
.x
, dst
.y
, dst
.w
, dst
.h
- 1,
774 get_theme_color(COLOR_THEME_UNITSREP_FRAME
));
776 dst
.y
= area
.y
+ adj_size(3);
777 dst
.x
+= ((ww
- pIcons
->pBIG_Coin
->w
) / 2);
778 alphablit(pIcons
->pBIG_Coin
, NULL
, pWindow
->theme
, &dst
, 255);
780 /* building count background and label */
781 dst
.x
= w
+ ww
+ adj_size(10);
783 dst
.w
= pText2
->w
+ adj_size(6);
784 ww
= pText2
->w
+ adj_size(6);
786 dst
.h
= area
.h
- adj_size(3);
787 fill_rect_alpha(pWindow
->theme
, &dst
, &bg_color
);
789 create_frame(pWindow
->theme
,
790 dst
.x
, dst
.y
, dst
.w
, dst
.h
- 1,
791 get_theme_color(COLOR_THEME_UNITSREP_FRAME
));
793 dst
.x
+= adj_size(3);
794 alphablit(pText2
, NULL
, pWindow
->theme
, &dst
, 255);
797 /* building count background and label */
798 dst
.x
= w
+ ww
+ adj_size(10);
800 dst
.w
= pText5
->w
+ adj_size(6);
801 dst
.h
= area
.h
- adj_size(3);
802 fill_rect_alpha(pWindow
->theme
, &dst
, &bg_color
);
804 create_frame(pWindow
->theme
,
805 dst
.x
, dst
.y
, dst
.w
, dst
.h
- 1,
806 get_theme_color(COLOR_THEME_UNITSREP_FRAME
));
808 dst
.x
+= adj_size(3);
809 alphablit(pText5
, NULL
, pWindow
->theme
, &dst
, 255);
813 int start_x
= area
.x
+ adj_size(2);
814 int start_y
= area
.y
+ hh
+ adj_size(3);
820 pBuf
->size
.x
= start_x
+ (mod
? tileset_full_tile_width(tileset
) : 0);
821 pBuf
->size
.y
= start_y
;
827 pBuf
->size
.w
= name_w
;
828 pBuf
->size
.x
= start_x
+ tileset_full_tile_width(tileset
) * 2 + adj_size(5);
829 pBuf
->size
.y
= start_y
+ (hh
- pBuf
->size
.h
) / 2;
833 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(10);
834 pBuf
->size
.y
= start_y
+ (hh
- pBuf
->size
.h
) / 2;
838 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(10);
839 pBuf
->size
.y
= start_y
+ (hh
- pBuf
->size
.h
) / 2;
843 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(10);
844 pBuf
->size
.y
= start_y
+ (hh
- pBuf
->size
.h
) / 2;
848 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(10);
849 pBuf
->size
.y
= start_y
+ (hh
- pBuf
->size
.h
) / 2;
851 /* Number under construction */
853 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(10);
854 pBuf
->size
.y
= start_y
+ (hh
- pBuf
->size
.h
) / 2;
856 /* Soonest completion */
858 pBuf
->size
.x
= pBuf
->next
->size
.x
+ pBuf
->next
->size
.w
+ adj_size(10);
859 pBuf
->size
.y
= start_y
+ (hh
- pBuf
->size
.h
) / 2;
861 start_y
+= (hh
>> 1);
862 if (pBuf
== pUnitsDlg
->pBeginActiveWidgetList
) {
868 if (pUnitsDlg
->pScroll
) {
869 setup_vertical_scrollbar_area(pUnitsDlg
->pScroll
,
870 area
.x
+ area
.w
, area
.y
,
875 /* ----------------------------------- */
876 redraw_group(pUnitsDlg
->pBeginWidgetList
, pWindow
, 0);
877 widget_mark_dirty(pWindow
);
882 /**************************************************************************
883 update the units report.
884 **************************************************************************/
885 void real_units_report_dialog_update(void)
888 struct units_entry units
[U_LAST
];
889 struct units_entry units_total
;
890 struct widget
*pWidget
, *pbuf
;
891 bool is_in_list
= FALSE
;
894 bool search_finished
;
896 get_units_report_data(units
, &units_total
);
898 /* find if there are new units entry (if not then rebuild all) */
899 pWidget
= pUnitsDlg
->pEndActiveWidgetList
; /* icon of first list entry */
900 unit_type_iterate(i
) {
901 if ((units
[utype_index(i
)].active_count
> 0)
902 || (units
[utype_index(i
)].building_count
> 0)) {
905 pbuf
= pWidget
; /* unit type icon */
907 if ((MAX_ID
- pbuf
->ID
) == utype_number(i
)) {
912 if (pbuf
->prev
->prev
->prev
->prev
->prev
->prev
->prev
==
913 pUnitsDlg
->pBeginActiveWidgetList
) {
917 /* first widget of next list entry */
918 pbuf
= pbuf
->prev
->prev
->prev
->prev
->prev
->prev
->prev
->prev
;
922 real_activeunits_report_dialog_update(units
, &units_total
);
926 } unit_type_iterate_end
;
929 pWidget
= pUnitsDlg
->pEndActiveWidgetList
;
930 unit_type_iterate(i
) {
931 pbuf
= pWidget
; /* first widget (icon) of the first list entry */
933 if ((units
[utype_index(i
)].active_count
> 0) || (units
[utype_index(i
)].building_count
> 0)) {
934 /* the player has at least one unit of this type */
936 search_finished
= FALSE
;
937 while (!search_finished
) {
938 if ((MAX_ID
- pbuf
->ID
) == utype_number(i
)) { /* list entry for this unit type found */
940 upgrade
= (can_upgrade_unittype(client
.conn
.playing
, i
) != NULL
);
942 pbuf
= pbuf
->prev
; /* unit type name */
944 pbuf
->string_utf8
->fgcol
= *get_theme_color(COLOR_THEME_UNITUPGRADE_TEXT
);
945 pbuf
->action
= popup_upgrade_unit_callback
;
946 set_wstate(pbuf
, FC_WS_NORMAL
);
949 pbuf
= pbuf
->prev
; /* active */
950 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units
[utype_index(i
)].active_count
);
951 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
953 pbuf
= pbuf
->prev
; /* shield upkeep */
954 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units
[utype_index(i
)].upkeep
[O_SHIELD
]);
955 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
957 pbuf
= pbuf
->prev
; /* food upkeep */
958 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units
[utype_index(i
)].upkeep
[O_FOOD
]);
959 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
961 pbuf
= pbuf
->prev
; /* gold upkeep */
962 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units
[utype_index(i
)].upkeep
[O_GOLD
]);
963 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
965 pbuf
= pbuf
->prev
; /* building */
966 if (units
[utype_index(i
)].building_count
> 0) {
967 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units
[utype_index(i
)].building_count
);
969 fc_snprintf(cbuf
, sizeof(cbuf
), "--");
971 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
973 pbuf
= pbuf
->prev
; /* soonest completion */
974 if (units
[utype_index(i
)].building_count
> 0) {
975 fc_snprintf(cbuf
, sizeof(cbuf
), "%d %s", units
[utype_index(i
)].soonest_completions
,
976 PL_("turn", "turns", units
[utype_index(i
)].soonest_completions
));
978 fc_snprintf(cbuf
, sizeof(cbuf
), "--");
980 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
982 pWidget
= pbuf
->prev
; /* icon of next unit type */
984 search_finished
= TRUE
;
986 } else { /* list entry for this unit type not found yet */
989 pbuf
= pWidget
->next
;
991 del_widget_from_vertical_scroll_widget_list(pUnitsDlg
, pbuf
->prev
);
992 } while (((MAX_ID
- pbuf
->prev
->ID
) != utype_number(i
))
993 && (pbuf
->prev
!= pUnitsDlg
->pBeginActiveWidgetList
));
995 if (pbuf
->prev
== pUnitsDlg
->pBeginActiveWidgetList
) {
996 /* list entry not found - can this really happen? */
997 del_widget_from_vertical_scroll_widget_list(pUnitsDlg
, pbuf
->prev
);
998 pWidget
= pbuf
->prev
; /* pUnitsDlg->pBeginActiveWidgetList */
999 search_finished
= TRUE
;
1002 pbuf
= pbuf
->prev
; /* first widget (icon) of list entry */
1006 } else { /* player has no unit of this type */
1007 if (pbuf
&& pbuf
->next
!= pUnitsDlg
->pBeginActiveWidgetList
) {
1008 if (utype_number(i
) < (MAX_ID
- pbuf
->ID
)) {
1013 del_widget_from_vertical_scroll_widget_list(pUnitsDlg
,
1015 } while (((MAX_ID
- pbuf
->prev
->ID
) == utype_number(i
))
1016 && (pbuf
->prev
!= pUnitsDlg
->pBeginActiveWidgetList
));
1017 if (pbuf
->prev
== pUnitsDlg
->pBeginActiveWidgetList
) {
1018 del_widget_from_vertical_scroll_widget_list(pUnitsDlg
,
1021 pWidget
= pbuf
->prev
;
1025 } unit_type_iterate_end
;
1027 /* -------------------------------------- */
1030 pbuf
= pUnitsDlg
->pEndWidgetList
->prev
->prev
;
1031 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units_total
.active_count
);
1032 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
1034 /* total shields cost */
1036 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units_total
.upkeep
[O_SHIELD
]);
1037 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
1039 /* total food cost widget */
1041 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units_total
.upkeep
[O_FOOD
]);
1042 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
1044 /* total gold cost widget */
1046 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units_total
.upkeep
[O_GOLD
]);
1047 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
1049 /* total building count */
1051 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", units_total
.building_count
);
1052 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
1054 /* -------------------------------------- */
1055 redraw_group(pUnitsDlg
->pBeginWidgetList
, pUnitsDlg
->pEndWidgetList
, 0);
1056 widget_mark_dirty(pUnitsDlg
->pEndWidgetList
);
1062 /**************************************************************************
1063 Popup (or raise) the units report (F2). It may or may not be modal.
1064 **************************************************************************/
1065 void units_report_dialog_popup(bool make_modal
)
1067 struct units_entry units
[U_LAST
];
1068 struct units_entry units_total
;
1074 get_units_report_data(units
, &units_total
);
1075 real_activeunits_report_dialog_update(units
, &units_total
);
1078 /**************************************************************************
1079 Popdown the units report.
1080 **************************************************************************/
1081 void units_report_dialog_popdown(void)
1084 if (pUnits_Upg_Dlg
) {
1085 del_group_of_widgets_from_gui_list(pUnits_Upg_Dlg
->pBeginWidgetList
,
1086 pUnits_Upg_Dlg
->pEndWidgetList
);
1087 FC_FREE(pUnits_Upg_Dlg
);
1089 popdown_window_group_dialog(pUnitsDlg
->pBeginWidgetList
,
1090 pUnitsDlg
->pEndWidgetList
);
1091 FC_FREE(pUnitsDlg
->pScroll
);
1096 /* ===================================================================== */
1097 /* ======================== Economy Report ============================= */
1098 /* ===================================================================== */
1099 static struct ADVANCED_DLG
*pEconomyDlg
= NULL
;
1100 static struct SMALL_DLG
*pEconomy_Sell_Dlg
= NULL
;
1103 int min
, max
, tax
, x
, gov_max
;
1104 int *src_rate
, *dst_rate
;
1105 struct widget
*pHoriz_Src
, *pHoriz_Dst
;
1106 struct widget
*pLabel_Src
, *pLabel_Dst
;
1109 /**************************************************************************
1110 User interacted with Economy Report window.
1111 **************************************************************************/
1112 static int economy_dialog_callback(struct widget
*pWindow
)
1114 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1115 move_window_group(pEconomyDlg
->pBeginWidgetList
, pWindow
);
1121 /**************************************************************************
1122 User interacted with Economy dialog Close Dialog button.
1123 **************************************************************************/
1124 static int exit_economy_dialog_callback(struct widget
*pWidget
)
1126 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1128 if (pEconomy_Sell_Dlg
) {
1129 del_group_of_widgets_from_gui_list(pEconomy_Sell_Dlg
->pBeginWidgetList
,
1130 pEconomy_Sell_Dlg
->pEndWidgetList
);
1131 FC_FREE(pEconomy_Sell_Dlg
);
1133 popdown_window_group_dialog(pEconomyDlg
->pBeginWidgetList
,
1134 pEconomyDlg
->pEndWidgetList
);
1135 FC_FREE(pEconomyDlg
->pScroll
);
1136 FC_FREE(pEconomyDlg
);
1137 set_wstate(get_tax_rates_widget(), FC_WS_NORMAL
);
1138 widget_redraw(get_tax_rates_widget());
1139 widget_mark_dirty(get_tax_rates_widget());
1147 /**************************************************************************
1148 Toggle Rates dialog locking checkbox.
1149 **************************************************************************/
1150 static int toggle_block_callback(struct widget
*pCheckBox
)
1152 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1153 switch (pCheckBox
->ID
) {
1154 case ID_CHANGE_TAXRATE_DLG_LUX_BLOCK_CHECKBOX
:
1155 SDL_Client_Flags
^= CF_CHANGE_TAXRATE_LUX_BLOCK
;
1158 case ID_CHANGE_TAXRATE_DLG_SCI_BLOCK_CHECKBOX
:
1159 SDL_Client_Flags
^= CF_CHANGE_TAXRATE_SCI_BLOCK
;
1170 /**************************************************************************
1171 User released mouse button while adjusting rates.
1172 **************************************************************************/
1173 static Uint16
report_scroll_mouse_button_up(SDL_MouseButtonEvent
*pButtonEvent
,
1176 return (Uint16
)ID_SCROLLBAR
;
1179 /**************************************************************************
1180 User moved a mouse while adjusting rates.
1181 **************************************************************************/
1182 static Uint16
report_scroll_mouse_motion_handler(SDL_MouseMotionEvent
*pMotionEvent
,
1185 struct rates_move
*pMotion
= (struct rates_move
*)pData
;
1186 struct widget
*pTax_Label
= pEconomyDlg
->pEndWidgetList
->prev
->prev
;
1187 struct widget
*pbuf
= NULL
;
1189 int dir
, inc
, x
, *buf_rate
= NULL
;
1191 pMotionEvent
->x
-= pMotion
->pHoriz_Src
->dst
->dest_rect
.x
;
1193 if ((abs(pMotionEvent
->x
- pMotion
->x
) > 7)
1194 && (pMotionEvent
->x
>= pMotion
->min
)
1195 && (pMotionEvent
->x
<= pMotion
->max
)) {
1197 /* set up directions */
1198 if (pMotionEvent
->xrel
> 0) {
1207 x
= pMotion
->pHoriz_Src
->size
.x
;
1208 if (((x
+ dir
) <= pMotion
->max
) && ((x
+ dir
) >= pMotion
->min
)) {
1210 if (pMotion
->pHoriz_Dst
) {
1211 x
= pMotion
->pHoriz_Dst
->size
.x
;
1212 if (((x
+ (-1 * dir
)) > pMotion
->max
) || ((x
+ (-1 * dir
)) < pMotion
->min
)) {
1213 /* dst out of range */
1214 if (pMotion
->tax
+ (-1 * inc
) <= pMotion
->gov_max
1215 && pMotion
->tax
+ (-1 * inc
) >= 0) {
1217 pbuf
= pMotion
->pHoriz_Dst
;
1218 pMotion
->pHoriz_Dst
= NULL
;
1219 buf_rate
= pMotion
->dst_rate
;
1220 pMotion
->dst_rate
= &pMotion
->tax
;
1221 pMotion
->pLabel_Dst
= pTax_Label
;
1223 pMotion
->x
= pMotion
->pHoriz_Src
->size
.x
;
1228 if (pMotion
->tax
+ (-1 * inc
) > pMotion
->gov_max
1229 || pMotion
->tax
+ (-1 * inc
) < 0) {
1230 pMotion
->x
= pMotion
->pHoriz_Src
->size
.x
;
1235 /* undraw scrollbars */
1236 widget_undraw(pMotion
->pHoriz_Src
);
1237 widget_mark_dirty(pMotion
->pHoriz_Src
);
1239 if (pMotion
->pHoriz_Dst
) {
1240 widget_undraw(pMotion
->pHoriz_Dst
);
1241 widget_mark_dirty(pMotion
->pHoriz_Dst
);
1244 pMotion
->pHoriz_Src
->size
.x
+= dir
;
1245 if (pMotion
->pHoriz_Dst
) {
1246 pMotion
->pHoriz_Dst
->size
.x
-= dir
;
1249 *pMotion
->src_rate
+= inc
;
1250 *pMotion
->dst_rate
-= inc
;
1252 fc_snprintf(cbuf
, sizeof(cbuf
), "%d%%", *pMotion
->src_rate
);
1253 copy_chars_to_utf8_str(pMotion
->pLabel_Src
->string_utf8
, cbuf
);
1254 fc_snprintf(cbuf
, sizeof(cbuf
), "%d%%", *pMotion
->dst_rate
);
1255 copy_chars_to_utf8_str(pMotion
->pLabel_Dst
->string_utf8
, cbuf
);
1258 widget_redraw(pMotion
->pLabel_Src
);
1259 widget_mark_dirty(pMotion
->pLabel_Src
);
1261 widget_redraw(pMotion
->pLabel_Dst
);
1262 widget_mark_dirty(pMotion
->pLabel_Dst
);
1264 /* redraw scroolbar */
1265 if (get_wflags(pMotion
->pHoriz_Src
) & WF_RESTORE_BACKGROUND
) {
1266 refresh_widget_background(pMotion
->pHoriz_Src
);
1268 widget_redraw(pMotion
->pHoriz_Src
);
1269 widget_mark_dirty(pMotion
->pHoriz_Src
);
1271 if (pMotion
->pHoriz_Dst
) {
1272 if (get_wflags(pMotion
->pHoriz_Dst
) & WF_RESTORE_BACKGROUND
) {
1273 refresh_widget_background(pMotion
->pHoriz_Dst
);
1275 widget_redraw(pMotion
->pHoriz_Dst
);
1276 widget_mark_dirty(pMotion
->pHoriz_Dst
);
1282 pMotion
->pHoriz_Dst
= pbuf
;
1283 pMotion
->pLabel_Dst
= pMotion
->pHoriz_Dst
->prev
;
1284 pMotion
->dst_rate
= buf_rate
;
1288 pMotion
->x
= pMotion
->pHoriz_Src
->size
.x
;
1296 /**************************************************************************
1297 Handle Rates sliders.
1298 **************************************************************************/
1299 static int horiz_taxrate_callback(struct widget
*pHoriz_Src
)
1301 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1302 struct rates_move pMotion
;
1304 pMotion
.pHoriz_Src
= pHoriz_Src
;
1305 pMotion
.pLabel_Src
= pHoriz_Src
->prev
;
1307 switch (pHoriz_Src
->ID
) {
1308 case ID_CHANGE_TAXRATE_DLG_LUX_SCROLLBAR
:
1309 if (SDL_Client_Flags
& CF_CHANGE_TAXRATE_LUX_BLOCK
) {
1312 pMotion
.src_rate
= (int *)pHoriz_Src
->data
.ptr
;
1313 pMotion
.pHoriz_Dst
= pHoriz_Src
->prev
->prev
->prev
; /* sci */
1314 pMotion
.dst_rate
= (int *)pMotion
.pHoriz_Dst
->data
.ptr
;
1315 pMotion
.tax
= 100 - *pMotion
.src_rate
- *pMotion
.dst_rate
;
1316 if ((SDL_Client_Flags
& CF_CHANGE_TAXRATE_SCI_BLOCK
)) {
1317 if (pMotion
.tax
<= get_player_bonus(client
.conn
.playing
, EFT_MAX_RATES
)) {
1318 pMotion
.pHoriz_Dst
= NULL
; /* tax */
1319 pMotion
.dst_rate
= &pMotion
.tax
;
1321 goto END
; /* all blocked */
1327 case ID_CHANGE_TAXRATE_DLG_SCI_SCROLLBAR
:
1328 if ((SDL_Client_Flags
& CF_CHANGE_TAXRATE_SCI_BLOCK
)) {
1331 pMotion
.src_rate
= (int *)pHoriz_Src
->data
.ptr
;
1332 pMotion
.pHoriz_Dst
= pHoriz_Src
->next
->next
->next
; /* lux */
1333 pMotion
.dst_rate
= (int *)pMotion
.pHoriz_Dst
->data
.ptr
;
1334 pMotion
.tax
= 100 - *pMotion
.src_rate
- *pMotion
.dst_rate
;
1335 if (SDL_Client_Flags
& CF_CHANGE_TAXRATE_LUX_BLOCK
) {
1336 if (pMotion
.tax
<= get_player_bonus(client
.conn
.playing
, EFT_MAX_RATES
)) {
1338 pMotion
.pHoriz_Dst
= NULL
;
1339 pMotion
.dst_rate
= &pMotion
.tax
;
1341 goto END
; /* all blocked */
1351 if (pMotion
.pHoriz_Dst
) {
1352 pMotion
.pLabel_Dst
= pMotion
.pHoriz_Dst
->prev
;
1355 pMotion
.pLabel_Dst
= pEconomyDlg
->pEndWidgetList
->prev
->prev
;
1358 pMotion
.min
= pHoriz_Src
->next
->size
.x
+ pHoriz_Src
->next
->size
.w
+ adj_size(2);
1359 pMotion
.gov_max
= get_player_bonus(client
.conn
.playing
, EFT_MAX_RATES
);
1360 pMotion
.max
= pMotion
.min
+ pMotion
.gov_max
* 1.5;
1361 pMotion
.x
= pHoriz_Src
->size
.x
;
1364 /* Filter mouse motion events */
1365 SDL_SetEventFilter(FilterMouseMotionEvents
, NULL
);
1366 gui_event_loop((void *)(&pMotion
), NULL
, NULL
, NULL
, NULL
, NULL
,
1367 report_scroll_mouse_button_up
,
1368 report_scroll_mouse_motion_handler
);
1369 /* Turn off Filter mouse motion events */
1370 SDL_SetEventFilter(NULL
, NULL
);
1371 MOVE_STEP_Y
= DEFAULT_MOVE_STEP
;
1374 unselect_widget_action();
1375 selected_widget
= pHoriz_Src
;
1376 set_wstate(pHoriz_Src
, FC_WS_SELECTED
);
1377 widget_redraw(pHoriz_Src
);
1378 widget_flush(pHoriz_Src
);
1384 /**************************************************************************
1385 User interacted with Update button of the Rates.
1386 **************************************************************************/
1387 static int apply_taxrates_callback(struct widget
*pButton
)
1389 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1390 struct widget
*pBuf
;
1391 int science
, luxury
, tax
;
1393 if (C_S_RUNNING
!= client_state()) {
1397 /* Science Scrollbar */
1398 pBuf
= pButton
->next
->next
;
1399 science
= *(int *)pBuf
->data
.ptr
;
1401 /* Luxuries Scrollbar */
1402 pBuf
= pBuf
->next
->next
->next
;
1403 luxury
= *(int *)pBuf
->data
.ptr
;
1406 tax
= 100 - luxury
- science
;
1408 if (tax
!= client
.conn
.playing
->economic
.tax
1409 || science
!= client
.conn
.playing
->economic
.science
1410 || luxury
!= client
.conn
.playing
->economic
.luxury
) {
1411 dsend_packet_player_rates(&client
.conn
, tax
, luxury
, science
);
1414 widget_redraw(pButton
);
1415 widget_flush(pButton
);
1421 /**************************************************************************
1422 Set economy dialog widgets enabled.
1423 **************************************************************************/
1424 static void enable_economy_dlg(void)
1427 struct widget
*pBuf
= pEconomyDlg
->pEndWidgetList
->prev
->prev
->prev
->prev
->prev
->prev
;
1429 set_wstate(pBuf
, FC_WS_NORMAL
);
1433 set_wstate(pBuf
, FC_WS_NORMAL
);
1436 pBuf
= pBuf
->prev
->prev
;
1437 set_wstate(pBuf
, FC_WS_NORMAL
);
1441 set_wstate(pBuf
, FC_WS_NORMAL
);
1444 pBuf
= pBuf
->prev
->prev
;
1445 set_wstate(pBuf
, FC_WS_NORMAL
);
1449 set_wstate(pBuf
, FC_WS_NORMAL
);
1451 set_group_state(pEconomyDlg
->pBeginActiveWidgetList
,
1452 pEconomyDlg
->pEndActiveWidgetList
, FC_WS_NORMAL
);
1453 if (pEconomyDlg
->pScroll
&& pEconomyDlg
->pActiveWidgetList
) {
1454 set_wstate(pEconomyDlg
->pScroll
->pUp_Left_Button
, FC_WS_NORMAL
);
1455 set_wstate(pEconomyDlg
->pScroll
->pDown_Right_Button
, FC_WS_NORMAL
);
1456 set_wstate(pEconomyDlg
->pScroll
->pScrollBar
, FC_WS_NORMAL
);
1460 /**************************************************************************
1461 Set economy dialog widgets disabled.
1462 **************************************************************************/
1463 static void disable_economy_dlg(void)
1466 struct widget
*pBuf
= pEconomyDlg
->pEndWidgetList
->prev
->prev
->prev
->prev
->prev
->prev
;
1468 set_wstate(pBuf
, FC_WS_DISABLED
);
1472 set_wstate(pBuf
, FC_WS_DISABLED
);
1475 pBuf
= pBuf
->prev
->prev
;
1476 set_wstate(pBuf
, FC_WS_DISABLED
);
1480 set_wstate(pBuf
, FC_WS_DISABLED
);
1483 pBuf
= pBuf
->prev
->prev
;
1484 set_wstate(pBuf
, FC_WS_DISABLED
);
1488 set_wstate(pBuf
, FC_WS_DISABLED
);
1490 set_group_state(pEconomyDlg
->pBeginActiveWidgetList
,
1491 pEconomyDlg
->pEndActiveWidgetList
, FC_WS_DISABLED
);
1492 if (pEconomyDlg
->pScroll
&& pEconomyDlg
->pActiveWidgetList
) {
1493 set_wstate(pEconomyDlg
->pScroll
->pUp_Left_Button
, FC_WS_DISABLED
);
1494 set_wstate(pEconomyDlg
->pScroll
->pDown_Right_Button
, FC_WS_DISABLED
);
1495 set_wstate(pEconomyDlg
->pScroll
->pScrollBar
, FC_WS_DISABLED
);
1499 /* --------------------------------------------------------------- */
1501 /**************************************************************************
1502 User interacted with Yes button of the improvement selling dialog.
1503 **************************************************************************/
1504 static int ok_sell_impr_callback(struct widget
*pWidget
)
1506 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1507 int imp
, total_count
, count
= 0;
1508 struct widget
*pImpr
= (struct widget
*)pWidget
->data
.ptr
;
1510 imp
= pImpr
->data
.cont
->id0
;
1511 total_count
= pImpr
->data
.cont
->id1
;
1513 /* popdown sell dlg */
1514 popdown_window_group_dialog(pEconomy_Sell_Dlg
->pBeginWidgetList
,
1515 pEconomy_Sell_Dlg
->pEndWidgetList
);
1516 FC_FREE(pEconomy_Sell_Dlg
);
1517 enable_economy_dlg();
1520 city_list_iterate(client
.conn
.playing
->cities
, pCity
) {
1521 if (!pCity
->did_sell
&& city_has_building(pCity
, improvement_by_number(imp
))){
1524 city_sell_improvement(pCity
, imp
);
1526 } city_list_iterate_end
;
1528 if (count
== total_count
) {
1529 del_widget_from_vertical_scroll_widget_list(pEconomyDlg
, pImpr
);
1536 /**************************************************************************
1537 User interacted with the improvement selling window.
1538 **************************************************************************/
1539 static int sell_impr_window_callback(struct widget
*pWindow
)
1541 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1542 move_window_group(pEconomy_Sell_Dlg
->pBeginWidgetList
, pWindow
);
1548 /**************************************************************************
1549 User interacted with Cancel button of the improvement selling dialog.
1550 **************************************************************************/
1551 static int cancel_sell_impr_callback(struct widget
*pWidget
)
1553 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1554 if (pEconomy_Sell_Dlg
) {
1555 popdown_window_group_dialog(pEconomy_Sell_Dlg
->pBeginWidgetList
,
1556 pEconomy_Sell_Dlg
->pEndWidgetList
);
1557 FC_FREE(pEconomy_Sell_Dlg
);
1558 enable_economy_dlg();
1566 /**************************************************************************
1567 Open improvement selling dialog.
1568 **************************************************************************/
1569 static int popup_sell_impr_callback(struct widget
*pWidget
)
1571 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
1572 int imp
, total_count
,count
= 0, gold
= 0;
1575 struct widget
*pBuf
= NULL
, *pWindow
;
1581 if (pEconomy_Sell_Dlg
) {
1585 set_wstate(pWidget
, FC_WS_NORMAL
);
1586 selected_widget
= NULL
;
1587 widget_redraw(pWidget
);
1588 widget_mark_dirty(pWidget
);
1590 pEconomy_Sell_Dlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
1592 imp
= pWidget
->data
.cont
->id0
;
1593 total_count
= pWidget
->data
.cont
->id1
;
1594 value
= impr_sell_gold(improvement_by_number(imp
));
1596 city_list_iterate(client
.conn
.playing
->cities
, pCity
) {
1597 if (!pCity
->did_sell
&& city_has_building(pCity
, improvement_by_number(imp
))) {
1601 } city_list_iterate_end
;
1604 fc_snprintf(cBuf
, sizeof(cBuf
),
1605 _("We have %d of %s\n(total value is : %d)\n"
1606 "We can sell %d of them for %d gold."),
1608 improvement_name_translation(improvement_by_number(imp
)),
1609 total_count
* value
, count
, gold
);
1611 fc_snprintf(cBuf
, sizeof(cBuf
),
1612 _("We can't sell any %s in this turn."),
1613 improvement_name_translation(improvement_by_number(imp
)));
1616 pstr
= create_utf8_from_char(_("Sell It?"), adj_font(12));
1617 pstr
->style
|= TTF_STYLE_BOLD
;
1619 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
1621 pWindow
->action
= sell_impr_window_callback
;
1622 set_wstate(pWindow
, FC_WS_NORMAL
);
1624 pEconomy_Sell_Dlg
->pEndWidgetList
= pWindow
;
1626 add_to_gui_list(ID_WINDOW
, pWindow
);
1628 area
= pWindow
->area
;
1630 /* ============================================================= */
1632 /* create text label */
1633 pstr
= create_utf8_from_char(cBuf
, adj_font(10));
1634 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
1635 pstr
->fgcol
= *get_theme_color(COLOR_THEME_SELLIMPR_TEXT
);
1637 pText
= create_text_surf_from_utf8(pstr
);
1640 area
.w
= MAX(area
.w
, pText
->w
+ adj_size(20));
1641 area
.h
+= (pText
->h
+ adj_size(10));
1644 pBuf
= create_themeicon_button_from_chars(current_theme
->CANCEL_Icon
,
1645 pWindow
->dst
, _("No"),
1648 pBuf
->action
= cancel_sell_impr_callback
;
1649 set_wstate(pBuf
, FC_WS_NORMAL
);
1651 area
.h
+= (pBuf
->size
.h
+ adj_size(20));
1653 add_to_gui_list(ID_BUTTON
, pBuf
);
1656 pBuf
= create_themeicon_button_from_chars(current_theme
->OK_Icon
, pWindow
->dst
,
1657 _("Sell"), adj_font(12), 0);
1659 pBuf
->action
= ok_sell_impr_callback
;
1660 set_wstate(pBuf
, FC_WS_NORMAL
);
1661 pBuf
->data
.ptr
= (void *)pWidget
;
1663 add_to_gui_list(ID_BUTTON
, pBuf
);
1664 pBuf
->size
.w
= MAX(pBuf
->size
.w
, pBuf
->next
->size
.w
);
1665 pBuf
->next
->size
.w
= pBuf
->size
.w
;
1666 area
.w
= MAX(area
.w
, adj_size(30) + pBuf
->size
.w
* 2);
1668 area
.w
= MAX(area
.w
, pBuf
->size
.w
+ adj_size(20));
1670 /* ============================================ */
1672 pEconomy_Sell_Dlg
->pBeginWidgetList
= pBuf
;
1674 resize_window(pWindow
, NULL
, get_theme_color(COLOR_THEME_BACKGROUND
),
1675 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
1676 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
1678 area
= pWindow
->area
;
1680 widget_set_position(pWindow
,
1681 pEconomyDlg
->pEndWidgetList
->size
.x
+
1682 (pEconomyDlg
->pEndWidgetList
->size
.w
- pWindow
->size
.w
) / 2,
1683 pEconomyDlg
->pEndWidgetList
->size
.y
+
1684 (pEconomyDlg
->pEndWidgetList
->size
.h
- pWindow
->size
.h
) / 2);
1686 /* setup rest of widgets */
1688 dst
.x
= area
.x
+ (area
.w
- pText
->w
) / 2;
1689 dst
.y
= area
.y
+ adj_size(10);
1690 alphablit(pText
, NULL
, pWindow
->theme
, &dst
, 255);
1694 pBuf
= pWindow
->prev
;
1695 pBuf
->size
.y
= area
.y
+ area
.h
- pBuf
->size
.h
- adj_size(10);
1700 pBuf
->size
.x
= area
.x
+ (area
.w
- (2 * pBuf
->size
.w
+ adj_size(10))) / 2;
1701 pBuf
->size
.y
= pBuf
->next
->size
.y
;
1704 pBuf
->next
->size
.x
= pBuf
->size
.x
+ pBuf
->size
.w
+ adj_size(10);
1706 /* x position of cancel button */
1707 pBuf
->size
.x
= area
.x
+ area
.w
- adj_size(10) - pBuf
->size
.w
;
1710 /* ================================================== */
1712 redraw_group(pEconomy_Sell_Dlg
->pBeginWidgetList
, pWindow
, 0);
1713 disable_economy_dlg();
1715 widget_mark_dirty(pWindow
);
1722 /**************************************************************************
1723 Update the economy report.
1724 **************************************************************************/
1725 void real_economy_report_dialog_update(void)
1728 struct widget
*pbuf
= pEconomyDlg
->pEndWidgetList
;
1729 int tax
, total
, entries_used
= 0;
1731 struct improvement_entry entries
[B_LAST
];
1733 get_economy_report_data(entries
, &entries_used
, &total
, &tax
);
1737 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", client
.conn
.playing
->economic
.gold
);
1738 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
1739 remake_label_size(pbuf
);
1742 pbuf
= pbuf
->prev
->prev
;
1743 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", tax
);
1744 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
1745 remake_label_size(pbuf
);
1749 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", total
);
1750 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
1751 remake_label_size(pbuf
);
1755 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", tax
- total
);
1756 copy_chars_to_utf8_str(pbuf
->string_utf8
, cbuf
);
1757 remake_label_size(pbuf
);
1758 if (tax
- total
< 0) {
1759 pbuf
->string_utf8
->fgcol
= *get_theme_color(COLOR_THEME_ECONOMYDLG_NEG_TEXT
);
1761 pbuf
->string_utf8
->fgcol
= *get_theme_color(COLOR_THEME_ECONOMYDLG_TEXT
);
1764 /* ---------------- */
1765 redraw_group(pEconomyDlg
->pBeginWidgetList
, pEconomyDlg
->pEndWidgetList
, 0);
1766 widget_flush(pEconomyDlg
->pEndWidgetList
);
1770 /**************************************************************************
1771 Popdown the economy report.
1772 **************************************************************************/
1773 void economy_report_dialog_popdown(void)
1776 if (pEconomy_Sell_Dlg
) {
1777 del_group_of_widgets_from_gui_list(pEconomy_Sell_Dlg
->pBeginWidgetList
,
1778 pEconomy_Sell_Dlg
->pEndWidgetList
);
1779 FC_FREE(pEconomy_Sell_Dlg
);
1781 popdown_window_group_dialog(pEconomyDlg
->pBeginWidgetList
,
1782 pEconomyDlg
->pEndWidgetList
);
1783 FC_FREE(pEconomyDlg
->pScroll
);
1784 FC_FREE(pEconomyDlg
);
1785 set_wstate(get_tax_rates_widget(), FC_WS_NORMAL
);
1786 widget_redraw(get_tax_rates_widget());
1787 widget_mark_dirty(get_tax_rates_widget());
1791 #define TARGETS_ROW 2
1792 #define TARGETS_COL 4
1794 /**************************************************************************
1795 Popup (or raise) the economy report (F5). It may or may not be modal.
1796 **************************************************************************/
1797 void economy_report_dialog_popup(bool make_modal
)
1799 SDL_Color bg_color
= {255,255,255,128};
1800 SDL_Color bg_color2
= {255,255,255,136};
1801 SDL_Color bg_color3
= {255,255,255,64};
1802 struct widget
*pBuf
;
1803 struct widget
*pWindow
, *pLast
;
1804 utf8_str
*pstr
, *pstr2
;
1805 SDL_Surface
*pSurf
, *pText_Name
, *pText
, *pZoom
;
1806 SDL_Surface
*pBackground
;
1807 int i
, count
, h
= 0;
1808 int w
= 0; /* left column values */
1809 int w2
= 0; /* right column: lock + scrollbar + ... */
1810 int w3
= 0; /* left column text without values */
1811 int tax
, total
, entries_used
= 0;
1813 struct improvement_entry entries
[B_LAST
];
1816 struct government
*pGov
= government_of_player(client
.conn
.playing
);
1817 SDL_Surface
*pTreasuryText
;
1818 SDL_Surface
*pTaxRateText
;
1819 SDL_Surface
*pTotalIncomeText
;
1820 SDL_Surface
*pTotalCostText
;
1821 SDL_Surface
*pNetIncomeText
;
1822 SDL_Surface
*pMaxRateText
;
1828 /* disable "Economy" button */
1829 pBuf
= get_tax_rates_widget();
1830 set_wstate(pBuf
, FC_WS_DISABLED
);
1831 widget_redraw(pBuf
);
1832 widget_mark_dirty(pBuf
);
1834 pEconomyDlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
1836 get_economy_report_data(entries
, &entries_used
, &total
, &tax
);
1838 /* --------------- */
1839 pstr
= create_utf8_from_char(_("Economy Report"), adj_font(12));
1840 pstr
->style
|= TTF_STYLE_BOLD
;
1842 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
1843 pEconomyDlg
->pEndWidgetList
= pWindow
;
1844 set_wstate(pWindow
, FC_WS_NORMAL
);
1845 pWindow
->action
= economy_dialog_callback
;
1847 add_to_gui_list(ID_ECONOMY_DIALOG_WINDOW
, pWindow
);
1849 area
= pWindow
->area
;
1851 /* ------------------------- */
1853 /* "Treasury" text surface */
1854 fc_snprintf(cbuf
, sizeof(cbuf
), _("Treasury: "));
1855 pstr2
= create_utf8_from_char(cbuf
, adj_font(12));
1856 pstr2
->style
|= TTF_STYLE_BOLD
;
1857 pTreasuryText
= create_text_surf_from_utf8(pstr2
);
1858 w3
= MAX(w3
, pTreasuryText
->w
);
1860 /* "Treasury" value label*/
1861 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", client
.conn
.playing
->economic
.gold
);
1862 pstr
= create_utf8_from_char(cbuf
, adj_font(12));
1863 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
1865 pBuf
= create_iconlabel(pIcons
->pBIG_Coin
, pWindow
->dst
, pstr
,
1866 (WF_RESTORE_BACKGROUND
|WF_ICON_CENTER_RIGHT
));
1868 add_to_gui_list(ID_LABEL
, pBuf
);
1870 w
= MAX(w
, pBuf
->size
.w
);
1873 /* "Tax Rate" text surface */
1874 fc_snprintf(cbuf
, sizeof(cbuf
), _("Tax Rate: "));
1875 copy_chars_to_utf8_str(pstr2
, cbuf
);
1876 pTaxRateText
= create_text_surf_from_utf8(pstr2
);
1877 w3
= MAX(w3
, pTaxRateText
->w
);
1879 /* "Tax Rate" value label */
1880 /* it is important to leave 1 space at ending of this string */
1881 fc_snprintf(cbuf
, sizeof(cbuf
), "%d%% ", client
.conn
.playing
->economic
.tax
);
1882 pstr
= create_utf8_from_char(cbuf
, adj_font(12));
1883 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
1885 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
, WF_RESTORE_BACKGROUND
);
1887 add_to_gui_list(ID_LABEL
, pBuf
);
1889 w
= MAX(w
, pBuf
->size
.w
+ pBuf
->next
->size
.w
);
1892 /* "Total Income" text surface */
1893 fc_snprintf(cbuf
, sizeof(cbuf
), _("Total Income: "));
1894 copy_chars_to_utf8_str(pstr2
, cbuf
);
1895 pTotalIncomeText
= create_text_surf_from_utf8(pstr2
);
1896 w3
= MAX(w3
, pTotalIncomeText
->w
);
1898 /* "Total Icome" value label */
1899 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", tax
);
1900 pstr
= create_utf8_from_char(cbuf
, adj_font(12));
1901 pstr
->style
|= TTF_STYLE_BOLD
;
1903 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
, WF_RESTORE_BACKGROUND
);
1905 add_to_gui_list(ID_LABEL
, pBuf
);
1907 w
= MAX(w
, pBuf
->size
.w
);
1910 /* "Total Cost" text surface */
1911 fc_snprintf(cbuf
, sizeof(cbuf
), _("Total Cost: "));
1912 copy_chars_to_utf8_str(pstr2
, cbuf
);
1913 pTotalCostText
= create_text_surf_from_utf8(pstr2
);
1915 /* "Total Cost" value label */
1916 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", total
);
1917 pstr
= create_utf8_from_char(cbuf
, adj_font(12));
1918 pstr
->style
|= TTF_STYLE_BOLD
;
1920 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
, WF_RESTORE_BACKGROUND
);
1922 add_to_gui_list(ID_LABEL
, pBuf
);
1924 w
= MAX(w
, pBuf
->size
.w
);
1927 /* "Net Income" text surface */
1928 fc_snprintf(cbuf
, sizeof(cbuf
), _("Net Income: "));
1929 copy_chars_to_utf8_str(pstr2
, cbuf
);
1930 pNetIncomeText
= create_text_surf_from_utf8(pstr2
);
1931 w3
= MAX(w3
, pNetIncomeText
->w
);
1933 /* "Net Icome" value label */
1934 fc_snprintf(cbuf
, sizeof(cbuf
), "%d", tax
- total
);
1935 pstr
= create_utf8_from_char(cbuf
, adj_font(12));
1936 pstr
->style
|= (TTF_STYLE_BOLD
|SF_CENTER
);
1938 if (tax
- total
< 0) {
1939 pstr
->fgcol
= *get_theme_color(COLOR_THEME_ECONOMYDLG_NEG_TEXT
);
1942 pBuf
= create_iconlabel(NULL
, pWindow
->dst
, pstr
, WF_RESTORE_BACKGROUND
);
1944 add_to_gui_list(ID_LABEL
, pBuf
);
1946 w
= MAX(w
, pBuf
->size
.w
);
1949 /* gov and taxrate */
1950 fc_snprintf(cbuf
, sizeof(cbuf
), _("%s max rate : %d%%"),
1951 government_name_translation(pGov
),
1952 get_player_bonus(client
.conn
.playing
, EFT_MAX_RATES
));
1953 copy_chars_to_utf8_str(pstr2
, cbuf
);
1954 pMaxRateText
= create_text_surf_from_utf8(pstr2
);
1958 /* ------------------------- */
1962 fc_snprintf(cbuf
, sizeof(cbuf
), _("Lock"));
1963 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
1964 pstr
->style
|= TTF_STYLE_BOLD
;
1966 pBuf
= create_checkbox(pWindow
->dst
,
1967 SDL_Client_Flags
& CF_CHANGE_TAXRATE_LUX_BLOCK
,
1968 WF_RESTORE_BACKGROUND
| WF_WIDGET_HAS_INFO_LABEL
);
1969 set_new_checkbox_theme(pBuf
, current_theme
->LOCK_Icon
, current_theme
->UNLOCK_Icon
);
1970 pBuf
->info_label
= pstr
;
1971 pBuf
->action
= toggle_block_callback
;
1972 set_wstate(pBuf
, FC_WS_NORMAL
);
1974 add_to_gui_list(ID_CHANGE_TAXRATE_DLG_LUX_BLOCK_CHECKBOX
, pBuf
);
1976 w2
= adj_size(10) + pBuf
->size
.w
;
1978 /* lux rate slider */
1979 pBuf
= create_horizontal(current_theme
->Horiz
, pWindow
->dst
, adj_size(30),
1980 (WF_FREE_DATA
| WF_RESTORE_BACKGROUND
));
1982 pBuf
->action
= horiz_taxrate_callback
;
1983 pBuf
->data
.ptr
= fc_calloc(1, sizeof(int));
1984 *(int *)pBuf
->data
.ptr
= client
.conn
.playing
->economic
.luxury
;
1985 set_wstate(pBuf
, FC_WS_NORMAL
);
1987 add_to_gui_list(ID_CHANGE_TAXRATE_DLG_LUX_SCROLLBAR
, pBuf
);
1989 w2
+= adj_size(184);
1991 /* lux rate iconlabel */
1993 /* it is important to leave 1 space at ending of this string */
1994 fc_snprintf(cbuf
, sizeof(cbuf
), "%d%% ", client
.conn
.playing
->economic
.luxury
);
1995 pstr
= create_utf8_from_char(cbuf
, adj_font(11));
1996 pstr
->style
|= TTF_STYLE_BOLD
;
1998 pBuf
= create_iconlabel(pIcons
->pBIG_Luxury
, pWindow
->dst
, pstr
,
1999 WF_RESTORE_BACKGROUND
);
2000 add_to_gui_list(ID_CHANGE_TAXRATE_DLG_LUX_LABEL
, pBuf
);
2002 w2
+= (adj_size(5) + pBuf
->size
.w
+ adj_size(10));
2004 /* ------------------------- */
2007 /* science rate lock */
2008 fc_snprintf(cbuf
, sizeof(cbuf
), _("Lock"));
2009 pstr
= create_utf8_from_char(cbuf
, adj_font(10));
2010 pstr
->style
|= TTF_STYLE_BOLD
;
2012 pBuf
= create_checkbox(pWindow
->dst
,
2013 SDL_Client_Flags
& CF_CHANGE_TAXRATE_SCI_BLOCK
,
2014 WF_RESTORE_BACKGROUND
| WF_WIDGET_HAS_INFO_LABEL
);
2016 set_new_checkbox_theme(pBuf
, current_theme
->LOCK_Icon
, current_theme
->UNLOCK_Icon
);
2018 pBuf
->info_label
= pstr
;
2019 pBuf
->action
= toggle_block_callback
;
2020 set_wstate(pBuf
, FC_WS_NORMAL
);
2022 add_to_gui_list(ID_CHANGE_TAXRATE_DLG_SCI_BLOCK_CHECKBOX
, pBuf
);
2024 /* science rate slider */
2025 pBuf
= create_horizontal(current_theme
->Horiz
, pWindow
->dst
, adj_size(30),
2026 (WF_FREE_DATA
| WF_RESTORE_BACKGROUND
));
2028 pBuf
->action
= horiz_taxrate_callback
;
2029 pBuf
->data
.ptr
= fc_calloc(1, sizeof(int));
2030 *(int *)pBuf
->data
.ptr
= client
.conn
.playing
->economic
.science
;
2032 set_wstate(pBuf
, FC_WS_NORMAL
);
2034 add_to_gui_list(ID_CHANGE_TAXRATE_DLG_SCI_SCROLLBAR
, pBuf
);
2036 /* science rate iconlabel */
2037 /* it is important to leave 1 space at ending of this string */
2038 fc_snprintf(cbuf
, sizeof(cbuf
), "%d%% ", client
.conn
.playing
->economic
.science
);
2039 pstr
= create_utf8_from_char(cbuf
, adj_font(11));
2040 pstr
->style
|= TTF_STYLE_BOLD
;
2042 pBuf
= create_iconlabel(pIcons
->pBIG_Colb
, pWindow
->dst
, pstr
,
2043 WF_RESTORE_BACKGROUND
);
2045 add_to_gui_list(ID_CHANGE_TAXRATE_DLG_SCI_LABEL
, pBuf
);
2049 fc_snprintf(cbuf
, sizeof(cbuf
), _("Update"));
2050 pstr
= create_utf8_from_char(cbuf
, adj_font(12));
2051 pBuf
= create_themeicon_button(current_theme
->Small_OK_Icon
, pWindow
->dst
, pstr
, 0);
2052 pBuf
->action
= apply_taxrates_callback
;
2053 set_wstate(pBuf
, FC_WS_NORMAL
);
2055 add_to_gui_list(ID_CHANGE_TAXRATE_DLG_OK_BUTTON
, pBuf
);
2059 fc_snprintf(cbuf
, sizeof(cbuf
), _("Close Dialog (Esc)"));
2060 pstr
= create_utf8_from_char(cbuf
, adj_font(12));
2061 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
2062 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
2063 pBuf
->info_label
= pstr
;
2064 pBuf
->action
= exit_economy_dialog_callback
;
2065 set_wstate(pBuf
, FC_WS_NORMAL
);
2066 pBuf
->key
= SDLK_ESCAPE
;
2068 add_to_gui_list(ID_CHANGE_TAXRATE_DLG_CANCEL_BUTTON
, pBuf
);
2072 /* ------------------------- */
2074 if (entries_used
> 0) {
2076 /* Create Imprv Background Icon */
2077 pBackground
= create_surf(adj_size(116), adj_size(116), SDL_SWSURFACE
);
2079 SDL_FillRect(pBackground
, NULL
, map_rgba(pBackground
->format
, bg_color
));
2081 create_frame(pBackground
,
2082 0, 0, pBackground
->w
- 1, pBackground
->h
- 1,
2083 get_theme_color(COLOR_THEME_ECONOMYDLG_FRAME
));
2085 pstr
= create_utf8_str(NULL
, 0, adj_font(10));
2086 pstr
->style
|= (SF_CENTER
|TTF_STYLE_BOLD
);
2087 pstr
->bgcol
= (SDL_Color
) {0, 0, 0, 0};
2089 for (i
= 0; i
< entries_used
; i
++) {
2090 struct improvement_entry
*p
= &entries
[i
];
2091 struct impr_type
*pImprove
= p
->type
;
2093 pSurf
= crop_rect_from_surface(pBackground
, NULL
);
2095 fc_snprintf(cbuf
, sizeof(cbuf
), "%s", improvement_name_translation(pImprove
));
2097 copy_chars_to_utf8_str(pstr
, cbuf
);
2098 pstr
->style
|= TTF_STYLE_BOLD
;
2099 pText_Name
= create_text_surf_smaller_than_w(pstr
, pSurf
->w
- adj_size(4));
2101 fc_snprintf(cbuf
, sizeof(cbuf
), "%s %d\n%s %d",
2102 _("Built"), p
->count
, _("U Total"),p
->total_cost
);
2103 copy_chars_to_utf8_str(pstr
, cbuf
);
2104 pstr
->style
&= ~TTF_STYLE_BOLD
;
2106 pText
= create_text_surf_from_utf8(pstr
);
2108 /*-----------------*/
2110 pZoom
= get_building_surface(pImprove
);
2111 pZoom
= zoomSurface(pZoom
, DEFAULT_ZOOM
* ((float)54 / pZoom
->w
), DEFAULT_ZOOM
* ((float)54 / pZoom
->w
), 1);
2113 dst
.x
= (pSurf
->w
- pZoom
->w
) / 2;
2114 dst
.y
= (pSurf
->h
/ 2 - pZoom
->h
) / 2;
2115 alphablit(pZoom
, NULL
, pSurf
, &dst
, 255);
2119 dst
.x
= (pSurf
->w
- pText_Name
->w
)/2;
2120 dst
.y
+= ((pSurf
->h
- dst
.y
) -
2121 (pText_Name
->h
+ (pIcons
->pBIG_Coin
->h
+ 2) + pText
->h
)) / 2;
2122 alphablit(pText_Name
, NULL
, pSurf
, &dst
, 255);
2124 dst
.y
+= pText_Name
->h
;
2126 dst
.x
= (pSurf
->w
- p
->cost
* (pIcons
->pBIG_Coin
->w
+ 1))/2;
2127 for (count
= 0; count
< p
->cost
; count
++) {
2128 alphablit(pIcons
->pBIG_Coin
, NULL
, pSurf
, &dst
, 255);
2129 dst
.x
+= pIcons
->pBIG_Coin
->w
+ 1;
2133 if (!is_wonder(pImprove
)) {
2134 copy_chars_to_utf8_str(pstr
, _("Nation"));
2136 copy_chars_to_utf8_str(pstr
, _("Wonder"));
2138 /*pstr->style &= ~TTF_STYLE_BOLD;*/
2140 pZoom
= create_text_surf_from_utf8(pstr
);
2142 dst
.x
= (pSurf
->w
- pZoom
->w
) / 2;
2143 alphablit(pZoom
, NULL
, pSurf
, &dst
, 255);
2147 dst
.y
+= (pIcons
->pBIG_Coin
->h
+ adj_size(2));
2148 dst
.x
= (pSurf
->w
- pText
->w
) / 2;
2149 alphablit(pText
, NULL
, pSurf
, &dst
, 255);
2152 FREESURFACE(pText_Name
);
2154 pBuf
= create_icon2(pSurf
, pWindow
->dst
,
2155 (WF_RESTORE_BACKGROUND
|WF_FREE_THEME
|WF_FREE_DATA
));
2157 set_wstate(pBuf
, FC_WS_NORMAL
);
2159 pBuf
->data
.cont
= fc_calloc(1, sizeof(struct CONTAINER
));
2160 pBuf
->data
.cont
->id0
= improvement_number(p
->type
);
2161 pBuf
->data
.cont
->id1
= p
->count
;
2162 pBuf
->action
= popup_sell_impr_callback
;
2164 add_to_gui_list(MAX_ID
- i
, pBuf
);
2166 if (i
> (TARGETS_ROW
* TARGETS_COL
- 1)) {
2167 set_wflag(pBuf
, WF_HIDDEN
);
2172 FREESURFACE(pBackground
);
2174 pEconomyDlg
->pEndActiveWidgetList
= pLast
->prev
;
2175 pEconomyDlg
->pBeginWidgetList
= pBuf
;
2176 pEconomyDlg
->pBeginActiveWidgetList
= pEconomyDlg
->pBeginWidgetList
;
2178 if (entries_used
> (TARGETS_ROW
* TARGETS_COL
)) {
2179 pEconomyDlg
->pActiveWidgetList
= pEconomyDlg
->pEndActiveWidgetList
;
2180 count
= create_vertical_scrollbar(pEconomyDlg
,
2181 TARGETS_COL
, TARGETS_ROW
, TRUE
, TRUE
);
2182 h
+= (TARGETS_ROW
* pBuf
->size
.h
+ adj_size(10));
2185 if (entries_used
> TARGETS_COL
) {
2188 h
+= (adj_size(10) + pBuf
->size
.h
);
2190 count
= TARGETS_COL
* pBuf
->size
.w
+ count
;
2192 pEconomyDlg
->pBeginWidgetList
= pBuf
;
2197 area
.w
= MAX(area
.w
, MAX(adj_size(10) + w3
+ w
+ w2
, count
));
2200 pBackground
= theme_get_background(theme
, BACKGROUND_ECONOMYDLG
);
2201 if (resize_window(pWindow
, pBackground
, NULL
,
2202 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
2203 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
)) {
2204 FREESURFACE(pBackground
);
2207 area
= pWindow
->area
;
2209 widget_set_position(pWindow
,
2210 (main_window_width() - pWindow
->size
.w
) / 2,
2211 (main_window_height() - pWindow
->size
.h
) / 2);
2213 /* "Treasury" value label */
2214 pBuf
= pWindow
->prev
;
2215 pBuf
->size
.x
= area
.x
+ adj_size(10) + pTreasuryText
->w
;
2216 pBuf
->size
.y
= area
.y
+ adj_size(5);
2218 w
= pTreasuryText
->w
+ pBuf
->size
.w
;
2221 /* "Tax Rate" value label */
2223 pBuf
->size
.x
= area
.x
+ adj_size(10) + pTaxRateText
->w
;
2224 pBuf
->size
.y
= pBuf
->next
->size
.y
+ pBuf
->next
->size
.h
;
2226 w
= MAX(w
, pTaxRateText
->w
+ pBuf
->size
.w
);
2229 /* "Total Income" value label */
2231 pBuf
->size
.x
= area
.x
+ adj_size(10) + pTotalIncomeText
->w
;
2232 pBuf
->size
.y
= pBuf
->next
->size
.y
+ pBuf
->next
->size
.h
;
2234 w
= MAX(w
, pTotalIncomeText
->w
+ pBuf
->size
.w
);
2237 /* "Total Cost" value label */
2239 pBuf
->size
.x
= area
.x
+ adj_size(10) + pTotalCostText
->w
;
2240 pBuf
->size
.y
= pBuf
->next
->size
.y
+ pBuf
->next
->size
.h
;
2242 w
= MAX(w
, pTotalCostText
->w
+ pBuf
->size
.w
);
2245 /* "Net Income" value label */
2247 pBuf
->size
.x
= area
.x
+ adj_size(10) + pNetIncomeText
->w
;
2248 pBuf
->size
.y
= pBuf
->next
->size
.y
+ pBuf
->next
->size
.h
;
2250 w
= MAX(w
, pNetIncomeText
->w
+ pBuf
->size
.w
);
2257 dst
.h
= h
+ adj_size(15);
2260 fill_rect_alpha(pWindow
->theme
, &dst
, &bg_color2
);
2262 create_frame(pWindow
->theme
,
2263 dst
.x
, dst
.y
, dst
.w
- 1, dst
.h
- 1,
2264 get_theme_color(COLOR_THEME_ECONOMYDLG_FRAME
));
2266 /* draw statical strings */
2267 dst
.x
= area
.x
+ adj_size(10);
2268 dst
.y
= area
.y
+ adj_size(5);
2271 alphablit(pTreasuryText
, NULL
, pWindow
->theme
, &dst
, 255);
2272 dst
.y
+= pTreasuryText
->h
;
2273 FREESURFACE(pTreasuryText
);
2276 alphablit(pTaxRateText
, NULL
, pWindow
->theme
, &dst
, 255);
2277 dst
.y
+= pTaxRateText
->h
;
2278 FREESURFACE(pTaxRateText
);
2281 alphablit(pTotalIncomeText
, NULL
, pWindow
->theme
, &dst
, 255);
2282 dst
.y
+= pTotalIncomeText
->h
;
2283 FREESURFACE(pTotalIncomeText
);
2286 alphablit(pTotalCostText
, NULL
, pWindow
->theme
, &dst
, 255);
2287 dst
.y
+= pTotalCostText
->h
;
2288 FREESURFACE(pTotalCostText
);
2291 alphablit(pNetIncomeText
, NULL
, pWindow
->theme
, &dst
, 255);
2292 dst
.y
+= pNetIncomeText
->h
;
2293 FREESURFACE(pNetIncomeText
);
2295 /* gov and taxrate */
2296 dst
.x
= area
.x
+ adj_size(10) + w
+ ((area
.w
- (w
+ adj_size(10)) - pMaxRateText
->w
) / 2);
2297 dst
.y
= area
.y
+ adj_size(5);
2299 alphablit(pMaxRateText
, NULL
, pWindow
->theme
, &dst
, 255);
2300 dst
.y
+= (pMaxRateText
->h
+ 1);
2301 FREESURFACE(pMaxRateText
);
2303 /* Luxuries Horizontal Scrollbar Background */
2304 dst
.x
= area
.x
+ adj_size(10) + w
+ (area
.w
- (w
+ adj_size(10)) - adj_size(184)) / 2;
2305 dst
.w
= adj_size(184);
2306 dst
.h
= current_theme
->Horiz
->h
- adj_size(2);
2308 fill_rect_alpha(pWindow
->theme
, &dst
, &bg_color3
);
2310 create_frame(pWindow
->theme
,
2311 dst
.x
, dst
.y
, dst
.w
- 1, dst
.h
- 1,
2312 get_theme_color(COLOR_THEME_ECONOMYDLG_FRAME
));
2316 pBuf
->size
.x
= dst
.x
- pBuf
->size
.w
;
2317 pBuf
->size
.y
= dst
.y
- adj_size(2);
2321 pBuf
->size
.x
= dst
.x
+ adj_size(2) + (client
.conn
.playing
->economic
.luxury
* 3) / 2;
2322 pBuf
->size
.y
= dst
.y
-1;
2326 pBuf
->size
.x
= dst
.x
+ dst
.w
+ adj_size(5);
2327 pBuf
->size
.y
= dst
.y
+ 1;
2329 /* Science Horizontal Scrollbar Background */
2330 dst
.y
+= current_theme
->Horiz
->h
+ 1;
2331 fill_rect_alpha(pWindow
->theme
, &dst
, &bg_color3
);
2333 create_frame(pWindow
->theme
,
2334 dst
.x
, dst
.y
, dst
.w
- 1, dst
.h
- 1,
2335 get_theme_color(COLOR_THEME_ECONOMYDLG_FRAME
));
2337 /* science lock icon */
2339 pBuf
->size
.x
= dst
.x
- pBuf
->size
.w
;
2340 pBuf
->size
.y
= dst
.y
- adj_size(2);
2342 /* science scrollbar */
2344 pBuf
->size
.x
= dst
.x
+ adj_size(2) + (client
.conn
.playing
->economic
.science
* 3) / 2;
2345 pBuf
->size
.y
= dst
.y
-1;
2349 pBuf
->size
.x
= dst
.x
+ dst
.w
+ adj_size(5);
2350 pBuf
->size
.y
= dst
.y
+ 1;
2354 pBuf
->size
.x
= dst
.x
+ (dst
.w
- pBuf
->size
.w
) / 2;
2355 pBuf
->size
.y
= dst
.y
+ dst
.h
+ adj_size(3);
2359 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
2360 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
2361 /* ------------------------------- */
2363 if (entries_used
> 0) {
2364 setup_vertical_widgets_position(TARGETS_COL
,
2367 0, 0, pEconomyDlg
->pBeginActiveWidgetList
,
2368 pEconomyDlg
->pEndActiveWidgetList
);
2369 if (pEconomyDlg
->pScroll
) {
2370 setup_vertical_scrollbar_area(pEconomyDlg
->pScroll
,
2371 area
.x
+ area
.w
- 1,
2373 area
.h
- h
- 1, TRUE
);
2377 /* ------------------------ */
2378 redraw_group(pEconomyDlg
->pBeginWidgetList
, pWindow
, 0);
2379 widget_mark_dirty(pWindow
);
2383 /* ===================================================================== */
2384 /* ======================== Science Report ============================= */
2385 /* ===================================================================== */
2386 static struct SMALL_DLG
*pScienceDlg
= NULL
;
2388 static struct ADVANCED_DLG
*pChangeTechDlg
= NULL
;
2390 /**************************************************************************
2391 Create icon surface for a tech.
2392 **************************************************************************/
2393 SDL_Surface
*create_select_tech_icon(utf8_str
*pstr
, Tech_type_id tech_id
,
2394 enum tech_info_mode mode
)
2396 struct unit_type
*pUnit
= NULL
;
2397 SDL_Surface
*pSurf
, *pText
, *pTmp
, *pTmp2
;
2398 SDL_Surface
*Surf_Array
[10], **pBuf_Array
;
2403 color
= *get_tech_color(tech_id
);
2411 color
= *get_theme_color(COLOR_THEME_SCIENCEDLG_MED_TECHICON_BG
);
2418 pText
= create_text_surf_smaller_than_w(pstr
, adj_size(100 - 4));
2420 /* create label surface */
2421 pSurf
= create_surf(w
, h
, SDL_SWSURFACE
);
2423 if (tech_id
== research_get(client_player())->researching
) {
2429 SDL_FillRect(pSurf
, NULL
, map_rgba(pSurf
->format
, color
));
2432 0,0, pSurf
->w
- 1, pSurf
->h
- 1,
2433 get_theme_color(COLOR_THEME_SCIENCEDLG_FRAME
));
2435 pTmp
= get_tech_icon(tech_id
);
2437 if (mode
== SMALL_MODE
) {
2438 /* draw name tech text */
2439 dst
.x
= adj_size(35) + (pSurf
->w
- pText
->w
- adj_size(35)) / 2;
2440 dst
.y
= (pSurf
->h
- pText
->h
) / 2;
2441 alphablit(pText
, NULL
, pSurf
, &dst
, 255);
2444 /* draw tech icon */
2445 pText
= ResizeSurface(pTmp
, adj_size(25), adj_size(25), 1);
2446 dst
.x
= (adj_size(35) - pText
->w
) / 2;
2447 dst
.y
= (pSurf
->h
- pText
->h
) / 2;
2448 alphablit(pText
, NULL
, pSurf
, &dst
, 255);
2453 /* draw name tech text */
2454 dst
.x
= (pSurf
->w
- pText
->w
) / 2;
2455 dst
.y
= adj_size(20);
2456 alphablit(pText
, NULL
, pSurf
, &dst
, 255);
2457 dst
.y
+= pText
->h
+ adj_size(10);
2460 /* draw tech icon */
2461 dst
.x
= (pSurf
->w
- pTmp
->w
) / 2;
2462 alphablit(pTmp
, NULL
, pSurf
, &dst
, 255);
2463 dst
.y
+= pTmp
->w
+ adj_size(10);
2465 /* fill array with iprvm. icons */
2467 improvement_iterate(pImprove
) {
2468 requirement_vector_iterate(&pImprove
->reqs
, preq
) {
2469 if (VUT_ADVANCE
== preq
->source
.kind
2470 && advance_number(preq
->source
.value
.advance
) == tech_id
) {
2471 pTmp2
= get_building_surface(pImprove
);
2472 Surf_Array
[w
++] = zoomSurface(pTmp2
, DEFAULT_ZOOM
* ((float)36 / pTmp2
->w
), DEFAULT_ZOOM
* ((float)36 / pTmp2
->w
), 1);
2474 } requirement_vector_iterate_end
;
2475 } improvement_iterate_end
;
2479 dst
.x
= (pSurf
->w
- 2 * Surf_Array
[0]->w
) / 2;
2481 dst
.x
= (pSurf
->w
- Surf_Array
[0]->w
) / 2;
2484 /* draw iprvm. icons */
2485 pBuf_Array
= Surf_Array
;
2488 alphablit(*pBuf_Array
, NULL
, pSurf
, &dst
, 255);
2489 dst
.x
+= (*pBuf_Array
)->w
;
2494 dst
.x
= (pSurf
->w
- 2 * (*pBuf_Array
)->w
) / 2;
2496 dst
.x
= (pSurf
->w
- (*pBuf_Array
)->w
) / 2;
2498 dst
.y
+= (*pBuf_Array
)->h
;
2503 dst
.y
+= Surf_Array
[0]->h
+ adj_size(5);
2505 /* -------------------------------------------------------- */
2507 unit_type_iterate(un
) {
2509 if (advance_number(pUnit
->require_advance
) == tech_id
) {
2510 Surf_Array
[w
++] = adj_surf(get_unittype_surface(un
, direction8_invalid()));
2512 } unit_type_iterate_end
;
2517 if (Surf_Array
[0]->w
> 64) {
2518 float zoom
= DEFAULT_ZOOM
* (64.0 / Surf_Array
[0]->w
);
2519 SDL_Surface
*zoomed
= zoomSurface(Surf_Array
[0], zoom
, zoom
, 1);
2521 dst
.x
= (pSurf
->w
- zoomed
->w
) / 2;
2522 alphablit(zoomed
, NULL
, pSurf
, &dst
, 255);
2523 FREESURFACE(zoomed
);
2525 dst
.x
= (pSurf
->w
- Surf_Array
[0]->w
) / 2;
2526 alphablit(Surf_Array
[0], NULL
, pSurf
, &dst
, 255);
2532 zoom
= DEFAULT_ZOOM
* (38.0 / Surf_Array
[0]->w
);
2534 zoom
= DEFAULT_ZOOM
* (45.0 / Surf_Array
[0]->w
);
2536 dst
.x
= (pSurf
->w
- (Surf_Array
[0]->w
* 2) * zoom
- 2) / 2;
2537 pBuf_Array
= Surf_Array
;
2540 SDL_Surface
*zoomed
= zoomSurface((*pBuf_Array
), zoom
, zoom
, 1);
2542 alphablit(zoomed
, NULL
, pSurf
, &dst
, 255);
2543 dst
.x
+= zoomed
->w
+ 2;
2548 dst
.x
= (pSurf
->w
- 2 * zoomed
->w
- 2 ) / 2;
2550 dst
.x
= (pSurf
->w
- zoomed
->w
) / 2;
2552 dst
.y
+= zoomed
->h
+ 2;
2556 FREESURFACE(zoomed
);
2567 /**************************************************************************
2568 enable science dialog group ( without window )
2569 **************************************************************************/
2570 static void enable_science_dialog(void)
2572 set_group_state(pScienceDlg
->pBeginWidgetList
,
2573 pScienceDlg
->pEndWidgetList
->prev
, FC_WS_NORMAL
);
2576 /**************************************************************************
2577 disable science dialog group ( without window )
2578 **************************************************************************/
2579 static void disable_science_dialog(void)
2581 set_group_state(pScienceDlg
->pBeginWidgetList
,
2582 pScienceDlg
->pEndWidgetList
->prev
, FC_WS_DISABLED
);
2585 /**************************************************************************
2586 Update the science report.
2587 **************************************************************************/
2588 void real_science_report_dialog_update(void)
2590 SDL_Color bg_color
= {255, 255, 255, 136};
2593 const struct research
*presearch
= research_get(client_player());
2597 SDL_Surface
*pColb_Surface
= pIcons
->pBIG_Colb
;
2600 struct unit_type
*pUnit
;
2601 struct widget
*pChangeResearchButton
;
2602 struct widget
*pChangeResearchGoalButton
;
2604 struct widget
*pWindow
= pScienceDlg
->pEndWidgetList
;
2606 area
= pWindow
->area
;
2607 pChangeResearchButton
= pWindow
->prev
;
2608 pChangeResearchGoalButton
= pWindow
->prev
->prev
;
2610 if (A_UNSET
!= presearch
->researching
) {
2611 cost
= presearch
->client
.researching_cost
;
2616 /* update current research icons */
2617 FREESURFACE(pChangeResearchButton
->theme
);
2618 pChangeResearchButton
->theme
= get_tech_icon(presearch
->researching
);
2619 FREESURFACE(pChangeResearchGoalButton
->theme
);
2620 pChangeResearchGoalButton
->theme
= get_tech_icon(presearch
->tech_goal
);
2623 widget_redraw(pWindow
);
2625 /* ------------------------------------- */
2627 /* research progress text */
2628 pStr
= create_utf8_from_char(science_dialog_text(), adj_font(12));
2629 pStr
->style
|= SF_CENTER
;
2630 pStr
->fgcol
= *get_theme_color(COLOR_THEME_SCIENCEDLG_TEXT
);
2632 pSurf
= create_text_surf_from_utf8(pStr
);
2634 dest
.x
= area
.x
+ (area
.w
- pSurf
->w
) / 2;
2635 dest
.y
= area
.y
+ adj_size(2);
2636 alphablit(pSurf
, NULL
, pWindow
->dst
->surface
, &dest
, 255);
2638 dest
.y
+= pSurf
->h
+ adj_size(4);
2642 dest
.x
= area
.x
+ adj_size(16);
2645 create_line(pWindow
->dst
->surface
,
2646 dest
.x
, dest
.y
, (area
.x
+ area
.w
- adj_size(16)), dest
.y
,
2647 get_theme_color(COLOR_THEME_SCIENCEDLG_FRAME
));
2649 dest
.y
+= adj_size(6);
2651 widget_set_position(pChangeResearchButton
, dest
.x
, dest
.y
+ adj_size(18));
2653 /* current research text */
2654 fc_snprintf(cBuf
, sizeof(cBuf
), "%s: %s",
2655 research_advance_name_translation(presearch
,
2656 presearch
->researching
),
2657 get_science_target_text(NULL
));
2659 copy_chars_to_utf8_str(pStr
, cBuf
);
2661 pSurf
= create_text_surf_from_utf8(pStr
);
2663 dest
.x
= pChangeResearchButton
->size
.x
+ pChangeResearchButton
->size
.w
+ adj_size(10);
2665 alphablit(pSurf
, NULL
, pWindow
->dst
->surface
, &dest
, 255);
2667 dest
.y
+= pSurf
->h
+ adj_size(4);
2673 int cost_div_safe
= cost
- 1;
2675 cost_div_safe
= (cost_div_safe
!= 0 ? cost_div_safe
: 1);
2676 dest
.w
= cost
* pColb_Surface
->w
;
2677 step
= pColb_Surface
->w
;
2678 if (dest
.w
> (area
.w
- dest
.x
- adj_size(16))) {
2679 dest
.w
= (area
.w
- dest
.x
- adj_size(16));
2680 step
= ((area
.w
- dest
.x
- adj_size(16)) - pColb_Surface
->w
) / cost_div_safe
;
2687 dest
.h
= pColb_Surface
->h
+ adj_size(4);
2688 fill_rect_alpha(pWindow
->dst
->surface
, &dest
, &bg_color
);
2690 create_frame(pWindow
->dst
->surface
,
2691 dest
.x
- 1, dest
.y
- 1, dest
.w
, dest
.h
,
2692 get_theme_color(COLOR_THEME_SCIENCEDLG_FRAME
));
2694 if (cost
> adj_size(286)) {
2695 cost
= adj_size(286) * ((float) presearch
->bulbs_researched
/ cost
);
2697 cost
= (float) cost
* ((float) presearch
->bulbs_researched
/ cost
);
2700 dest
.y
+= adj_size(2);
2701 for (i
= 0; i
< cost
; i
++) {
2702 alphablit(pColb_Surface
, NULL
, pWindow
->dst
->surface
, &dest
, 255);
2707 /* improvement icons */
2709 dest
.y
+= dest
.h
+ adj_size(4);
2710 dest
.x
= pChangeResearchButton
->size
.x
+ pChangeResearchButton
->size
.w
+ adj_size(10);
2713 improvement_iterate(pImprove
) {
2714 requirement_vector_iterate(&pImprove
->reqs
, preq
) {
2715 if (VUT_ADVANCE
== preq
->source
.kind
2716 && (advance_number(preq
->source
.value
.advance
)
2717 == presearch
->researching
)) {
2718 pSurf
= adj_surf(get_building_surface(pImprove
));
2719 alphablit(pSurf
, NULL
, pWindow
->dst
->surface
, &dest
, 255);
2720 dest
.x
+= pSurf
->w
+ 1;
2722 } requirement_vector_iterate_end
;
2723 } improvement_iterate_end
;
2725 dest
.x
+= adj_size(5);
2728 unit_type_iterate(un
) {
2730 if (advance_number(pUnit
->require_advance
) == presearch
->researching
) {
2731 SDL_Surface
*surf
= get_unittype_surface(un
, direction8_invalid());
2735 float zoom
= DEFAULT_ZOOM
* (64.0 / w
);
2737 pSurf
= zoomSurface(surf
, zoom
, zoom
, 1);
2738 alphablit(pSurf
, NULL
, pWindow
->dst
->surface
, &dest
, 255);
2739 dest
.x
+= pSurf
->w
+ adj_size(2);
2742 pSurf
= adj_surf(surf
);
2743 alphablit(pSurf
, NULL
, pWindow
->dst
->surface
, &dest
, 255);
2744 dest
.x
+= pSurf
->w
+ adj_size(2);
2747 } unit_type_iterate_end
;
2749 /* -------------------------------- */
2750 /* draw separator line */
2751 dest
.x
= area
.x
+ adj_size(16);
2752 dest
.y
+= adj_size(48) + adj_size(6);
2754 create_line(pWindow
->dst
->surface
,
2755 dest
.x
, dest
.y
, (area
.x
+ area
.w
- adj_size(16)), dest
.y
,
2756 get_theme_color(COLOR_THEME_SCIENCEDLG_FRAME
));
2758 dest
.x
= pChangeResearchButton
->size
.x
;
2759 dest
.y
+= adj_size(6);
2761 widget_set_position(pChangeResearchGoalButton
, dest
.x
, dest
.y
+ adj_size(16));
2763 /* -------------------------------- */
2766 if (A_UNSET
!= presearch
->tech_goal
) {
2767 /* current goal text */
2768 copy_chars_to_utf8_str(pStr
, research_advance_name_translation
2769 (presearch
, presearch
->tech_goal
));
2770 pSurf
= create_text_surf_from_utf8(pStr
);
2772 dest
.x
= pChangeResearchGoalButton
->size
.x
+ pChangeResearchGoalButton
->size
.w
+ adj_size(10);
2773 alphablit(pSurf
, NULL
, pWindow
->dst
->surface
, &dest
, 255);
2779 copy_chars_to_utf8_str(pStr
, get_science_goal_text
2780 (presearch
->tech_goal
));
2781 pSurf
= create_text_surf_from_utf8(pStr
);
2783 dest
.x
= pChangeResearchGoalButton
->size
.x
+ pChangeResearchGoalButton
->size
.w
+ adj_size(10);
2784 alphablit(pSurf
, NULL
, pWindow
->dst
->surface
, &dest
, 255);
2786 dest
.y
+= pSurf
->h
+ adj_size(6);
2791 improvement_iterate(pImprove
) {
2792 requirement_vector_iterate(&pImprove
->reqs
, preq
) {
2793 if (VUT_ADVANCE
== preq
->source
.kind
2794 && (advance_number(preq
->source
.value
.advance
)
2795 == presearch
->tech_goal
)) {
2796 pSurf
= adj_surf(get_building_surface(pImprove
));
2797 alphablit(pSurf
, NULL
, pWindow
->dst
->surface
, &dest
, 255);
2798 dest
.x
+= pSurf
->w
+ 1;
2800 } requirement_vector_iterate_end
;
2801 } improvement_iterate_end
;
2803 dest
.x
+= adj_size(6);
2806 unit_type_iterate(un
) {
2808 if (advance_number(pUnit
->require_advance
) == presearch
->tech_goal
) {
2809 SDL_Surface
*surf
= get_unittype_surface(un
, direction8_invalid());
2813 float zoom
= DEFAULT_ZOOM
* (64.0 / w
);
2815 pSurf
= zoomSurface(surf
, zoom
, zoom
, 1);
2816 alphablit(pSurf
, NULL
, pWindow
->dst
->surface
, &dest
, 255);
2817 dest
.x
+= pSurf
->w
+ adj_size(2);
2820 pSurf
= adj_surf(surf
);
2821 alphablit(pSurf
, NULL
, pWindow
->dst
->surface
, &dest
, 255);
2822 dest
.x
+= pSurf
->w
+ adj_size(2);
2825 } unit_type_iterate_end
;
2828 /* -------------------------------- */
2829 widget_mark_dirty(pWindow
);
2830 redraw_group(pScienceDlg
->pBeginWidgetList
, pWindow
->prev
, 1);
2837 /**************************************************************************
2838 Close science report dialog.
2839 **************************************************************************/
2840 static void science_report_dialog_popdown(void)
2843 popdown_window_group_dialog(pScienceDlg
->pBeginWidgetList
,
2844 pScienceDlg
->pEndWidgetList
);
2845 FC_FREE(pScienceDlg
);
2846 set_wstate(get_research_widget(), FC_WS_NORMAL
);
2847 widget_redraw(get_research_widget());
2848 widget_mark_dirty(get_research_widget());
2853 /**************************************************************************
2854 Close research target changing dialog.
2855 **************************************************************************/
2856 static int exit_change_tech_dlg_callback(struct widget
*pWidget
)
2858 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2859 if (pChangeTechDlg
) {
2860 popdown_window_group_dialog(pChangeTechDlg
->pBeginWidgetList
,
2861 pChangeTechDlg
->pEndWidgetList
);
2862 FC_FREE(pChangeTechDlg
->pScroll
);
2863 FC_FREE(pChangeTechDlg
);
2864 enable_science_dialog();
2874 /**************************************************************************
2875 User interacted with button of specific Tech.
2876 **************************************************************************/
2877 static int change_research_callback(struct widget
*pWidget
)
2879 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2880 dsend_packet_player_research(&client
.conn
, (MAX_ID
- pWidget
->ID
));
2881 exit_change_tech_dlg_callback(NULL
);
2882 } else if (Main
.event
.button
.button
== SDL_BUTTON_MIDDLE
) {
2883 popup_tech_info((MAX_ID
- pWidget
->ID
));
2889 /**************************************************************************
2890 This function is used by change research and change goals dlgs.
2891 **************************************************************************/
2892 static int change_research_goal_dialog_callback(struct widget
*pWindow
)
2894 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
2895 if (select_window_group_dialog(pChangeTechDlg
->pBeginWidgetList
, pWindow
)) {
2896 widget_flush(pWindow
);
2903 /**************************************************************************
2904 Popup dialog to change current research.
2905 **************************************************************************/
2906 static void popup_change_research_dialog(void)
2908 const struct research
*presearch
= research_get(client_player());
2909 struct widget
*pBuf
= NULL
;
2910 struct widget
*pWindow
;
2913 int max_col
, max_row
, col
, i
, count
= 0, h
;
2916 if (is_future_tech(presearch
->researching
)) {
2920 advance_index_iterate(A_FIRST
, aidx
) {
2921 if (!research_invention_gettable(presearch
, aidx
, FALSE
)) {
2925 } advance_index_iterate_end
;
2931 pChangeTechDlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
2933 pstr
= create_utf8_from_char(_("What should we focus on now?"), adj_font(12));
2934 pstr
->style
|= TTF_STYLE_BOLD
;
2936 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
2937 pChangeTechDlg
->pEndWidgetList
= pWindow
;
2938 set_wstate(pWindow
, FC_WS_NORMAL
);
2939 pWindow
->action
= change_research_goal_dialog_callback
;
2941 add_to_gui_list(ID_SCIENCE_DLG_CHANGE_REASARCH_WINDOW
, pWindow
);
2943 area
= pWindow
->area
;
2945 /* ------------------------- */
2947 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
2948 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
2949 pBuf
->info_label
= create_utf8_from_char(_("Close Dialog (Esc)"),
2951 area
.w
+= pBuf
->size
.w
+ adj_size(10);
2952 pBuf
->action
= exit_change_tech_dlg_callback
;
2953 set_wstate(pBuf
, FC_WS_NORMAL
);
2954 pBuf
->key
= SDLK_ESCAPE
;
2956 add_to_gui_list(ID_TERRAIN_ADV_DLG_EXIT_BUTTON
, pBuf
);
2958 /* ------------------------- */
2959 /* max col - 104 is select tech widget width */
2960 max_col
= (main_window_width() - (pWindow
->size
.w
- pWindow
->area
.w
) - adj_size(2)) / adj_size(104);
2961 /* max row - 204 is select tech widget height */
2962 max_row
= (main_window_height() - (pWindow
->size
.h
- pWindow
->area
.h
) - adj_size(2)) / adj_size(204);
2964 /* make space on screen for scrollbar */
2965 if (max_col
* max_row
< count
) {
2969 if (count
< max_col
+ 1) {
2972 if (count
< max_col
+ 3) {
2975 if (count
< max_col
+ 5) {
2983 pstr
= create_utf8_str(NULL
, 0, adj_font(10));
2984 pstr
->style
|= (TTF_STYLE_BOLD
| SF_CENTER
);
2988 advance_index_iterate(A_FIRST
, aidx
) {
2989 if (!research_invention_gettable(presearch
, aidx
, FALSE
)) {
2995 copy_chars_to_utf8_str(pstr
, advance_name_translation(advance_by_number(aidx
)));
2996 pSurf
= create_select_tech_icon(pstr
, aidx
, MED_MODE
);
2997 pBuf
= create_icon2(pSurf
, pWindow
->dst
,
2998 WF_FREE_THEME
| WF_RESTORE_BACKGROUND
);
3000 set_wstate(pBuf
, FC_WS_NORMAL
);
3001 pBuf
->action
= change_research_callback
;
3003 add_to_gui_list(MAX_ID
- aidx
, pBuf
);
3006 set_wflag(pBuf
, WF_HIDDEN
);
3008 } advance_index_iterate_end
;
3012 pChangeTechDlg
->pBeginWidgetList
= pBuf
;
3013 pChangeTechDlg
->pBeginActiveWidgetList
= pChangeTechDlg
->pBeginWidgetList
;
3014 pChangeTechDlg
->pEndActiveWidgetList
= pChangeTechDlg
->pEndWidgetList
->prev
->prev
;
3016 /* -------------------------------------------------------------- */
3020 count
= (count
+ (col
- 1)) / col
;
3021 if (count
> max_row
) {
3022 pChangeTechDlg
->pActiveWidgetList
= pChangeTechDlg
->pEndActiveWidgetList
;
3024 i
= create_vertical_scrollbar(pChangeTechDlg
, col
, count
, TRUE
, TRUE
);
3030 disable_science_dialog();
3032 area
.w
= MAX(area
.w
, (col
* pBuf
->size
.w
+ adj_size(2) + i
));
3033 area
.h
= MAX(area
.h
, count
* pBuf
->size
.h
+ adj_size(2));
3035 /* alloca window theme and win background buffer */
3036 pSurf
= theme_get_background(theme
, BACKGROUND_CHANGERESEARCHDLG
);
3037 resize_window(pWindow
, pSurf
, NULL
,
3038 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
3039 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
3042 area
= pWindow
->area
;
3044 widget_set_position(pWindow
,
3045 (main_window_width() - pWindow
->size
.w
) / 2,
3046 (main_window_height() - pWindow
->size
.h
) / 2);
3049 pBuf
= pWindow
->prev
;
3050 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
3051 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
3053 setup_vertical_widgets_position(col
, area
.x
+ 1,
3055 pChangeTechDlg
->pBeginActiveWidgetList
,
3056 pChangeTechDlg
->pEndActiveWidgetList
);
3058 if (pChangeTechDlg
->pScroll
) {
3059 setup_vertical_scrollbar_area(pChangeTechDlg
->pScroll
,
3060 area
.x
+ area
.w
, area
.y
,
3064 redraw_group(pChangeTechDlg
->pBeginWidgetList
, pWindow
, FALSE
);
3066 widget_flush(pWindow
);
3069 /**************************************************************************
3070 User chose spesic tech as research goal.
3071 **************************************************************************/
3072 static int change_research_goal_callback(struct widget
*pWidget
)
3074 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
3075 dsend_packet_player_tech_goal(&client
.conn
, (MAX_ID
- pWidget
->ID
));
3077 exit_change_tech_dlg_callback(NULL
);
3079 /* Following is to make the menu go back to the current goal;
3080 * there may be a better way to do this? --dwp */
3081 real_science_report_dialog_update();
3082 } else if (Main
.event
.button
.button
== SDL_BUTTON_MIDDLE
) {
3083 popup_tech_info((MAX_ID
- pWidget
->ID
));
3089 /**************************************************************************
3090 Popup dialog to change research goal.
3091 **************************************************************************/
3092 static void popup_change_research_goal_dialog(void)
3094 const struct research
*presearch
= research_get(client_player());
3095 struct widget
*pBuf
= NULL
;
3096 struct widget
*pWindow
;
3100 int max_col
, max_row
, col
, i
, count
= 0, h
, num
;
3103 /* collect all techs which are reachable in under 11 steps
3104 * hist will hold afterwards the techid of the current choice
3106 advance_index_iterate(A_FIRST
, aidx
) {
3107 if (research_invention_reachable(presearch
, aidx
)
3108 && TECH_KNOWN
!= research_invention_state(presearch
, aidx
)
3109 && (11 > research_goal_unknown_techs(presearch
, aidx
)
3110 || aidx
== presearch
->tech_goal
)) {
3113 } advance_index_iterate_end
;
3119 pChangeTechDlg
= fc_calloc(1, sizeof(struct ADVANCED_DLG
));
3121 pstr
= create_utf8_from_char(_("Select target :"), adj_font(12));
3122 pstr
->style
|= TTF_STYLE_BOLD
;
3124 pWindow
= create_window_skeleton(NULL
, pstr
, 0);
3125 pChangeTechDlg
->pEndWidgetList
= pWindow
;
3126 set_wstate(pWindow
, FC_WS_NORMAL
);
3127 pWindow
->action
= change_research_goal_dialog_callback
;
3129 add_to_gui_list(ID_SCIENCE_DLG_CHANGE_GOAL_WINDOW
, pWindow
);
3131 area
= pWindow
->area
;
3133 /* ------------------------- */
3135 pBuf
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
3136 WF_WIDGET_HAS_INFO_LABEL
| WF_RESTORE_BACKGROUND
);
3137 pBuf
->info_label
= create_utf8_from_char(_("Close Dialog (Esc)"),
3139 area
.w
+= pBuf
->size
.w
+ adj_size(10);
3140 pBuf
->action
= exit_change_tech_dlg_callback
;
3141 set_wstate(pBuf
, FC_WS_NORMAL
);
3142 pBuf
->key
= SDLK_ESCAPE
;
3144 add_to_gui_list(ID_SCIENCE_DLG_CHANGE_GOAL_CANCEL_BUTTON
, pBuf
);
3146 /* ------------------------- */
3147 /* max col - 104 is goal tech widget width */
3148 max_col
= (main_window_width() - (pWindow
->size
.w
- pWindow
->area
.w
) - adj_size(2)) / adj_size(104);
3150 /* max row - 204 is goal tech widget height */
3151 max_row
= (main_window_height() - (pWindow
->size
.h
- pWindow
->area
.h
) - adj_size(2)) / adj_size(204);
3153 /* make space on screen for scrollbar */
3154 if (max_col
* max_row
< count
) {
3158 if (count
< max_col
+ 1) {
3161 if (count
< max_col
+ 3) {
3164 if (count
< max_col
+ 5) {
3172 pstr
= create_utf8_str(NULL
, 0, adj_font(10));
3173 pstr
->style
|= (TTF_STYLE_BOLD
| SF_CENTER
);
3175 /* collect all techs which are reachable in under 11 steps
3176 * hist will hold afterwards the techid of the current choice
3180 advance_index_iterate(A_FIRST
, aidx
) {
3181 if (research_invention_reachable(presearch
, aidx
)
3182 && TECH_KNOWN
!= research_invention_state(presearch
, aidx
)
3183 && (11 > (num
= research_goal_unknown_techs(presearch
, aidx
))
3184 || aidx
== presearch
->tech_goal
)) {
3187 fc_snprintf(cBuf
, sizeof(cBuf
), "%s\n%d %s",
3188 advance_name_translation(advance_by_number(aidx
)),
3190 PL_("step", "steps", num
));
3191 copy_chars_to_utf8_str(pstr
, cBuf
);
3192 pSurf
= create_select_tech_icon(pstr
, aidx
, FULL_MODE
);
3193 pBuf
= create_icon2(pSurf
, pWindow
->dst
,
3194 WF_FREE_THEME
| WF_RESTORE_BACKGROUND
);
3196 set_wstate(pBuf
, FC_WS_NORMAL
);
3197 pBuf
->action
= change_research_goal_callback
;
3199 add_to_gui_list(MAX_ID
- aidx
, pBuf
);
3202 set_wflag(pBuf
, WF_HIDDEN
);
3205 } advance_index_iterate_end
;
3209 pChangeTechDlg
->pBeginWidgetList
= pBuf
;
3210 pChangeTechDlg
->pBeginActiveWidgetList
= pChangeTechDlg
->pBeginWidgetList
;
3211 pChangeTechDlg
->pEndActiveWidgetList
= pChangeTechDlg
->pEndWidgetList
->prev
->prev
;
3213 /* -------------------------------------------------------------- */
3217 count
= (count
+ (col
-1)) / col
;
3218 if (count
> max_row
) {
3219 pChangeTechDlg
->pActiveWidgetList
= pChangeTechDlg
->pEndActiveWidgetList
;
3221 i
= create_vertical_scrollbar(pChangeTechDlg
, col
, count
, TRUE
, TRUE
);
3227 disable_science_dialog();
3229 area
.w
= MAX(area
.w
, (col
* pBuf
->size
.w
+ adj_size(2) + i
));
3230 area
.h
= MAX(area
.h
, count
* pBuf
->size
.h
+ adj_size(2));
3232 /* alloca window theme and win background buffer */
3233 pSurf
= theme_get_background(theme
, BACKGROUND_CHANGERESEARCHDLG
);
3234 resize_window(pWindow
, pSurf
, NULL
,
3235 (pWindow
->size
.w
- pWindow
->area
.w
) + area
.w
,
3236 (pWindow
->size
.h
- pWindow
->area
.h
) + area
.h
);
3239 area
= pWindow
->area
;
3241 widget_set_position(pWindow
,
3242 (main_window_width() - pWindow
->size
.w
) / 2,
3243 (main_window_height() - pWindow
->size
.h
) / 2);
3246 pBuf
= pWindow
->prev
;
3247 pBuf
->size
.x
= area
.x
+ area
.w
- pBuf
->size
.w
- 1;
3248 pBuf
->size
.y
= pWindow
->size
.y
+ adj_size(2);
3250 setup_vertical_widgets_position(col
, area
.x
+ 1,
3252 pChangeTechDlg
->pBeginActiveWidgetList
,
3253 pChangeTechDlg
->pEndActiveWidgetList
);
3255 if (pChangeTechDlg
->pScroll
) {
3256 setup_vertical_scrollbar_area(pChangeTechDlg
->pScroll
,
3257 area
.x
+ area
.w
, area
.y
,
3261 redraw_group(pChangeTechDlg
->pBeginWidgetList
, pWindow
, FALSE
);
3263 widget_flush(pWindow
);
3266 static int science_dialog_callback(struct widget
*pWindow
)
3268 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
3269 if (!pChangeTechDlg
) {
3270 if (select_window_group_dialog(pScienceDlg
->pBeginWidgetList
, pWindow
)) {
3271 widget_flush(pWindow
);
3273 if (move_window_group_dialog(pScienceDlg
->pBeginWidgetList
, pWindow
)) {
3274 real_science_report_dialog_update();
3282 /**************************************************************************
3283 Open research target changing dialog.
3284 **************************************************************************/
3285 static int popup_change_research_dialog_callback(struct widget
*pWidget
)
3287 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
3288 set_wstate(pWidget
, FC_WS_NORMAL
);
3289 selected_widget
= NULL
;
3290 widget_redraw(pWidget
);
3291 widget_flush(pWidget
);
3293 popup_change_research_dialog();
3298 /**************************************************************************
3299 Open research goal changing dialog.
3300 **************************************************************************/
3301 static int popup_change_research_goal_dialog_callback(struct widget
*pWidget
)
3303 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
3304 set_wstate(pWidget
, FC_WS_NORMAL
);
3305 selected_widget
= NULL
;
3306 widget_redraw(pWidget
);
3307 widget_flush(pWidget
);
3309 popup_change_research_goal_dialog();
3314 /**************************************************************************
3315 Close science dialog.
3316 **************************************************************************/
3317 static int popdown_science_dialog_callback(struct widget
*pWidget
)
3319 if (Main
.event
.button
.button
== SDL_BUTTON_LEFT
) {
3320 science_report_dialog_popdown();
3326 /**************************************************************************
3327 Popup (or raise) the science report(F6). It may or may not be modal.
3328 **************************************************************************/
3329 void science_report_dialog_popup(bool raise
)
3331 const struct research
*presearch
;
3332 struct widget
*pWidget
, *pWindow
;
3333 struct widget
*pChangeResearchButton
;
3334 struct widget
*pChangeResearchGoalButton
;
3335 struct widget
*pExitButton
;
3337 SDL_Surface
*pBackground
, *pTechIcon
;
3345 presearch
= research_get(client_player());
3347 /* disable research button */
3348 pWidget
= get_research_widget();
3349 set_wstate(pWidget
, FC_WS_DISABLED
);
3350 widget_redraw(pWidget
);
3351 widget_mark_dirty(pWidget
);
3353 pScienceDlg
= fc_calloc(1, sizeof(struct SMALL_DLG
));
3355 /* TRANS: Research report title */
3356 pstr
= create_utf8_from_char(_("Research"), adj_font(12));
3357 pstr
->style
|= TTF_STYLE_BOLD
;
3360 pWindow
= create_window(NULL
, pstr
, 200, 132, 0);
3361 #else /* SMALL_SCREEN */
3362 pWindow
= create_window(NULL
, pstr
, adj_size(400), adj_size(246), 0);
3363 #endif /* SMALL_SCREEN */
3364 set_wstate(pWindow
, FC_WS_NORMAL
);
3365 pWindow
->action
= science_dialog_callback
;
3367 pScienceDlg
->pEndWidgetList
= pWindow
;
3369 pBackground
= theme_get_background(theme
, BACKGROUND_SCIENCEDLG
);
3370 pWindow
->theme
= ResizeSurface(pBackground
, pWindow
->size
.w
, pWindow
->size
.h
, 1);
3371 FREESURFACE(pBackground
);
3373 area
= pWindow
->area
;
3375 widget_set_position(pWindow
,
3376 (main_window_width() - pWindow
->size
.w
) / 2,
3377 (main_window_height() - pWindow
->size
.h
) / 2);
3379 add_to_gui_list(ID_SCIENCE_DLG_WINDOW
, pWindow
);
3381 /* count number of researchable techs */
3383 advance_index_iterate(A_FIRST
, i
) {
3384 if (research_invention_reachable(presearch
, i
)
3385 && TECH_KNOWN
!= research_invention_state(presearch
, i
)) {
3388 } advance_index_iterate_end
;
3390 /* current research icon */
3391 pTechIcon
= get_tech_icon(presearch
->researching
);
3392 pChangeResearchButton
= create_icon2(pTechIcon
, pWindow
->dst
, WF_RESTORE_BACKGROUND
| WF_FREE_THEME
);
3394 pChangeResearchButton
->action
= popup_change_research_dialog_callback
;
3396 set_wstate(pChangeResearchButton
, FC_WS_NORMAL
);
3399 add_to_gui_list(ID_SCIENCE_DLG_CHANGE_REASARCH_BUTTON
, pChangeResearchButton
);
3401 /* current research goal icon */
3402 pTechIcon
= get_tech_icon(presearch
->tech_goal
);
3403 pChangeResearchGoalButton
= create_icon2(pTechIcon
, pWindow
->dst
, WF_RESTORE_BACKGROUND
| WF_FREE_THEME
);
3405 pChangeResearchGoalButton
->action
= popup_change_research_goal_dialog_callback
;
3407 set_wstate(pChangeResearchGoalButton
, FC_WS_NORMAL
);
3410 add_to_gui_list(ID_SCIENCE_DLG_CHANGE_GOAL_BUTTON
, pChangeResearchGoalButton
);
3414 pExitButton
= create_themeicon(current_theme
->Small_CANCEL_Icon
, pWindow
->dst
,
3415 WF_WIDGET_HAS_INFO_LABEL
3416 | WF_RESTORE_BACKGROUND
);
3417 pExitButton
->info_label
= create_utf8_from_char(_("Close Dialog (Esc)"),
3419 pExitButton
->action
= popdown_science_dialog_callback
;
3420 set_wstate(pExitButton
, FC_WS_NORMAL
);
3421 pExitButton
->key
= SDLK_ESCAPE
;
3423 add_to_gui_list(ID_SCIENCE_CANCEL_DLG_BUTTON
, pExitButton
);
3425 widget_set_position(pExitButton
,
3426 area
.x
+ area
.w
- pExitButton
->size
.w
- adj_size(1),
3427 pWindow
->size
.y
+ adj_size(2));
3429 /* ======================== */
3430 pScienceDlg
->pBeginWidgetList
= pExitButton
;
3432 real_science_report_dialog_update();
3435 /**************************************************************************
3436 Popdown all the science reports (report, change tech, change goals).
3437 **************************************************************************/
3438 void science_report_dialogs_popdown_all(void)
3440 if (pChangeTechDlg
) {
3441 popdown_window_group_dialog(pChangeTechDlg
->pBeginWidgetList
,
3442 pChangeTechDlg
->pEndWidgetList
);
3443 FC_FREE(pChangeTechDlg
->pScroll
);
3444 FC_FREE(pChangeTechDlg
);
3447 popdown_window_group_dialog(pScienceDlg
->pBeginWidgetList
,
3448 pScienceDlg
->pEndWidgetList
);
3449 FC_FREE(pScienceDlg
);
3450 set_wstate(get_research_widget(), FC_WS_NORMAL
);
3451 widget_redraw(get_research_widget());
3452 widget_mark_dirty(get_research_widget());
3456 /****************************************************************************
3457 Resize and redraw the requirement tree.
3458 ****************************************************************************/
3459 void science_report_dialog_redraw(void)
3461 /* No requirement tree yet. */
3464 /* ===================================================================== */
3465 /* ======================== Endgame Report ============================= */
3466 /* ===================================================================== */
3468 static char eg_buffer
[150 * MAX_NUM_PLAYERS
];
3469 static int eg_player_count
= 0;
3470 static int eg_players_received
= 0;
3472 /****************************************************************
3473 Show a dialog with player statistics at endgame.
3474 TODO: Display all statistics in packet_endgame_report.
3475 *****************************************************************/
3476 void endgame_report_dialog_start(const struct packet_endgame_report
*packet
)
3478 eg_buffer
[0] = '\0';
3479 eg_player_count
= packet
->player_num
;
3480 eg_players_received
= 0;
3483 /****************************************************************
3484 Received endgame report information about single player
3485 *****************************************************************/
3486 void endgame_report_dialog_player(const struct packet_endgame_player
*packet
)
3488 const struct player
*pplayer
= player_by_number(packet
->player_id
);
3490 eg_players_received
++;
3492 cat_snprintf(eg_buffer
, sizeof(eg_buffer
),
3493 PL_("%2d: The %s ruler %s scored %d point\n",
3494 "%2d: The %s ruler %s scored %d points\n",
3496 eg_players_received
, nation_adjective_for_player(pplayer
),
3497 player_name(pplayer
), packet
->score
);
3499 if (eg_players_received
== eg_player_count
) {
3500 popup_notify_dialog(_("Final Report:"),
3501 _("The Greatest Civilizations in the world."),