Freeciv-3.1
Loading...
Searching...
No Matches
helpdlg.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* SDL2 */
19#ifdef SDL2_PLAIN_INCLUDE
20#include <SDL.h>
21#else /* SDL2_PLAIN_INCLUDE */
22#include <SDL2/SDL.h>
23#endif /* SDL2_PLAIN_INCLUDE */
24
25/* utility */
26#include "fcintl.h"
27#include "log.h"
28
29/* common */
30#include "game.h"
31#include "government.h"
32#include "movement.h"
33
34/* client */
35#include "client_main.h"
36#include "helpdata.h"
37
38/* gui-sdl2 */
39#include "colors.h"
40#include "graphics.h"
41#include "gui_id.h"
42#include "gui_main.h"
43#include "gui_tilespec.h"
44#include "mapview.h"
45#include "repodlgs.h"
46#include "sprite.h"
47#include "themespec.h"
48#include "widget.h"
49
50#include "helpdlg.h"
51
52static struct advanced_dialog *help_dlg = NULL;
53
55 struct widget *targets[6], *sub_targets[6];
57 struct widget *dock;
60};
61
67
69
70static const int bufsz = 8192;
71
72static int change_tech_callback(struct widget *pwidget);
73
74/**********************************************************************/
81
82/**********************************************************************/
93
94/**********************************************************************/
101{
102 log_debug("popup_help_dialog_typed : PORT ME");
103}
104
105/**********************************************************************/
118
119/**********************************************************************/
122static int help_dlg_window_callback(struct widget *pwindow)
123{
124 return -1;
125}
126
127/**********************************************************************/
130static int exit_help_dlg_callback(struct widget *pwidget)
131{
134 flush_dirty();
135 }
136
137 return -1;
138}
139
140/**********************************************************************/
143static int change_gov_callback(struct widget *pwidget)
144{
146 popup_gov_info(MAX_ID - pwidget->id);
147 }
148
149 return -1;
150}
151
152/**********************************************************************/
155void popup_gov_info(int gov)
156{
157}
158
159/**********************************************************************/
162static int change_impr_callback(struct widget *pwidget)
163{
165 popup_impr_info(MAX_ID - pwidget->id);
166 }
167
168 return -1;
169}
170
171/**********************************************************************/
174static void redraw_impr_info_dlg(void)
175{
176 SDL_Color bg_color = {255, 255, 255, 64};
177 struct widget *pwindow = help_dlg->end_widget_list;
178 struct units_buttons *store = (struct units_buttons *)pwindow->data.ptr;
179 SDL_Rect dst;
180
181 redraw_group(pwindow->prev, pwindow, FALSE);
182
183 dst.x = store->dock->prev->size.x - adj_size(10);
184 dst.y = store->dock->prev->size.y - adj_size(10);
185 dst.w = pwindow->size.w - (dst.x - pwindow->size.x) - adj_size(10);
186 dst.h = pwindow->size.h - (dst.y - pwindow->size.y) - adj_size(10);
187
188 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
189
190 create_frame(pwindow->dst->surface,
191 dst.x, dst.y, dst.w, dst.h,
193
194 /*------------------------------------- */
196 widget_flush(pwindow);
197}
198
199/**********************************************************************/
203{
204 SDL_Color bg_color = {255, 255, 255, 128};
205 struct widget *pwindow;
206 struct units_buttons *store;
207 struct widget *close_button = NULL;
210 struct widget *impr_name_label = NULL;
211 struct widget *cost_label = NULL;
212 struct widget *upkeep_label = NULL;
213 struct widget *requirement_label = NULL;
215 struct widget *obsolete_by_label = NULL;
217 struct widget *help_text_label = NULL;
218 struct widget *dock;
220 utf8_str *pstr;
221 SDL_Surface *surf;
222 int h, start_x, start_y, impr_type_count;
223 bool created, text = FALSE;
224 int scrollbar_width = 0;
225 struct impr_type *pimpr_type;
226 char buffer[64000];
227 SDL_Rect area;
228 struct advance *obsTech = NULL;
229
232 }
233
234 if (!help_dlg) {
235 SDL_Surface *background_tmpl, *background, *impr_name, *icon;
236 SDL_Rect dst;
237
239 created = TRUE;
240
241 /* Create dialog */
242 help_dlg = fc_calloc(1, sizeof(struct advanced_dialog));
243 store = fc_calloc(1, sizeof(struct units_buttons));
244
245 /* Create window */
246 title = create_utf8_from_char_fonto(_("Help : Improvements"),
248 title->style |= TTF_STYLE_BOLD;
249
250 pwindow = create_window_skeleton(NULL, title, WF_FREE_DATA);
252 set_wstate(pwindow , FC_WS_NORMAL);
253 pwindow->data.ptr = (void *)store;
254 add_to_gui_list(ID_WINDOW, pwindow);
255
256 help_dlg->end_widget_list = pwindow;
257
258 area = pwindow->area;
259 /* ------------------ */
260
261 /* Close button */
262 close_button = create_themeicon(current_theme->small_cancel_icon,
263 pwindow->dst,
266 close_button->info_label
267 = create_utf8_from_char_fonto(_("Close Dialog (Esc)"),
269 close_button->action = exit_help_dlg_callback;
270 set_wstate(close_button, FC_WS_NORMAL);
271 close_button->key = SDLK_ESCAPE;
272
273 add_to_gui_list(ID_BUTTON, close_button);
274
275 /* ------------------ */
276 dock = close_button;
277
278 pstr = create_utf8_str_fonto(NULL, 0, FONTO_DEFAULT);
279 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
280
281 /* Background template for entries in scroll list */
282 background_tmpl = create_surf(adj_size(135), adj_size(40), SDL_SWSURFACE);
283 SDL_FillRect(background_tmpl, NULL, map_rgba(background_tmpl->format, bg_color));
284
285 create_frame(background_tmpl,
286 0, 0, background_tmpl->w - 1, background_tmpl->h - 1,
288
289 impr_type_count = 0;
290 improvement_iterate(pimprove) {
291
292 /* Copy background surface */
293 background = copy_surface(background_tmpl);
294
295 /* Blit improvement name */
297 impr_name = create_text_surf_smaller_than_w(pstr, adj_size(100 - 4));
298 dst.x = adj_size(40) + (background->w - impr_name->w - adj_size(40)) / 2;
299 dst.y = (background->h - impr_name->h) / 2;
300 alphablit(impr_name, NULL, background, &dst, 255);
301 FREESURFACE(impr_name);
302
303 /* Blit improvement icon */
305 adj_size(36), adj_size(36), 1, TRUE, TRUE);
306 dst.x = adj_size(5);
307 dst.y = (background->h - icon->h) / 2;
308 alphablit(icon, NULL, background, &dst, 255);
309 FREESURFACE(icon);
310
311 improvement_button = create_icon2(background, pwindow->dst,
313
314 set_wstate(improvement_button, FC_WS_NORMAL);
315 improvement_button->action = change_impr_callback;
316 add_to_gui_list(MAX_ID - improvement_number(pimprove), improvement_button);
317
318 if (impr_type_count++ >= 10) {
319 set_wflag(improvement_button, WF_HIDDEN);
320 }
321
323
324 FREESURFACE(background_tmpl);
325
327 help_dlg->begin_widget_list = improvement_button ? improvement_button : close_button;
329
330 if (impr_type_count > 10) {
332 scrollbar_width = create_vertical_scrollbar(help_dlg, 1, 10, TRUE, TRUE);
333 }
334
335 /* Toggle techs list button */
336 list_toggle_button = create_themeicon_button_from_chars_fonto(
337 current_theme->up_icon,
338 pwindow->dst,
339 _("Improvements"),
340 FONTO_DEFAULT, 0);
341#if 0
343 if (store->show_tree) {
344 set_wstate(list_toggle_button, FC_WS_NORMAL);
345 }
346#endif
347
348 widget_resize(list_toggle_button, adj_size(160), adj_size(15));
350
351 add_to_gui_list(ID_BUTTON, list_toggle_button);
352
353 dock = list_toggle_button;
354 store->dock = dock;
355 } else {
356 created = FALSE;
357 scrollbar_width = (help_dlg->scroll ? help_dlg->scroll->up_left_button->size.w : 0);
358 pwindow = help_dlg->end_widget_list;
359 store = (struct units_buttons *)pwindow->data.ptr;
360 dock = store->dock;
361
362 area = pwindow->area;
363
364 /* Delete any previous list entries */
367 dock->prev);
369 }
370 }
371
372 pimpr_type = improvement_by_number(impr);
373
374 surf = get_building_surface(pimpr_type);
375 impr_name_label
377 adj_size(48), 1, TRUE, TRUE),
378 pwindow->dst,
379 city_improvement_name_translation(NULL, pimpr_type),
381
382 impr_name_label->id = ID_LABEL;
383 widget_add_as_prev(impr_name_label, dock);
384 dock = impr_name_label;
385
386 if (!improvement_has_flag(pimpr_type, IF_GOLD)) {
387 sprintf(buffer, "%s %d", _("Base Cost:"),
388 impr_base_build_shield_cost(pimpr_type));
389 cost_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
390 buffer,
391 FONTO_ATTENTION, 0);
392 cost_label->id = ID_LABEL;
393 widget_add_as_prev(cost_label, dock);
394 dock = cost_label;
395
396 if (!is_wonder(pimpr_type)) {
397 sprintf(buffer, "%s %d", _("Upkeep:"), pimpr_type->upkeep);
398 upkeep_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
399 buffer,
400 FONTO_ATTENTION, 0);
401 upkeep_label->id = ID_LABEL;
402 widget_add_as_prev(upkeep_label, dock);
403 dock = upkeep_label;
404 }
405 }
406
407 /* Requirement */
408 requirement_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
409 _("Requirement:"),
410 FONTO_ATTENTION, 0);
411 requirement_label->id = ID_LABEL;
412 widget_add_as_prev(requirement_label, dock);
413 dock = requirement_label;
414
415 /* FIXME: this should show ranges, negated reqs, and all the
416 * MAX_NUM_REQS reqs.
417 * Currently it's limited to 1 req. Remember MAX_NUM_REQS is a compile-time
418 * definition. */
419 requirement_vector_iterate(&pimpr_type->reqs, preq) {
420 if (!preq->present) {
421 continue;
422 }
423 requirement_label2
424 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
425 universal_name_translation(&preq->source, buffer, sizeof(buffer)),
428 if (preq->source.kind != VUT_ADVANCE) {
429 break; /* FIXME */
430 }
431 requirement_label2->id = MAX_ID - advance_number(preq->source.value.advance);
432 requirement_label2->string_utf8->fgcol
433 = *get_tech_color(advance_number(preq->source.value.advance));
434 requirement_label2->action = change_tech_callback;
435 set_wstate(requirement_label2, FC_WS_NORMAL);
436 break;
438
439 if (requirement_label2 == NULL) {
440 requirement_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
441 Q_("?req:None"),
442 FONTO_ATTENTION, 0);
443 requirement_label2->id = ID_LABEL;
444 }
445
446 widget_add_as_prev(requirement_label2, dock);
447 dock = requirement_label2;
448 store->requirement_button = requirement_label2;
449
450 /* Obsolete by */
451 obsolete_by_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
452 _("Obsolete by:"),
453 FONTO_ATTENTION, 0);
454 obsolete_by_label->id = ID_LABEL;
455 widget_add_as_prev(obsolete_by_label, dock);
456 dock = obsolete_by_label;
457
458 requirement_vector_iterate(&pimpr_type->obsolete_by, pobs) {
459 if (pobs->source.kind == VUT_ADVANCE) {
460 obsTech = pobs->source.value.advance;
461 break;
462 }
464
465 if (obsTech == NULL) {
466 obsolete_by_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
467 _("Never"),
468 FONTO_ATTENTION, 0);
469 obsolete_by_label2->id = ID_LABEL;
470 } else {
471 obsolete_by_label2
472 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
476 obsolete_by_label2->id = MAX_ID - advance_number(obsTech);
477 obsolete_by_label2->string_utf8->fgcol
478 = *get_tech_color(advance_number(obsTech));
479 obsolete_by_label2->action = change_tech_callback;
480 set_wstate(obsolete_by_label2, FC_WS_NORMAL);
481 }
482 widget_add_as_prev(obsolete_by_label2, dock);
483 dock = obsolete_by_label2;
484 store->obsolete_by_button = obsolete_by_label2;
485
486 /* Helptext */
487 start_x = (area.x + 1 + scrollbar_width + help_dlg->end_active_widget_list->size.w + adj_size(20));
488
489 buffer[0] = '\0';
490 helptext_building(buffer, sizeof(buffer), client.conn.playing, NULL,
491 pimpr_type);
492 if (buffer[0] != '\0') {
494
496 help_text_label = create_iconlabel(NULL, pwindow->dst, bstr, 0);
497 help_text_label->id = ID_LABEL;
498 widget_add_as_prev(help_text_label, dock);
499 text = TRUE;
500 }
501
502 help_dlg->begin_widget_list = help_text_label ? help_text_label : obsolete_by_label2;
503
504 /* --------------------------------------------------------- */
505 if (created) {
507 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
508 FREESURFACE(surf);
509 }
510
511 area = pwindow->area;
512
513 widget_set_position(pwindow,
514 (main_window_width() - pwindow->size.w) / 2,
515 (main_window_height() - pwindow->size.h) / 2);
516
517 /* Exit button */
518 close_button = pwindow->prev;
519 widget_set_position(close_button,
520 area.x + area.w - close_button->size.w - 1,
521 pwindow->size.y + adj_size(2));
522
523 /* List toggle button */
524 list_toggle_button = store->dock;
525 widget_set_position(list_toggle_button, area.x, area.y);
526
527 /* List entries */
528 h = setup_vertical_widgets_position(1, area.x + scrollbar_width,
529 area.y + list_toggle_button->size.h, 0, 0,
532
533 /* Scrollbar */
534 if (help_dlg->scroll) {
536 area.x, area.y + list_toggle_button->size.h,
537 h, FALSE);
538 }
539 }
540
541 impr_name_label = store->dock->prev;
542 widget_set_position(impr_name_label, start_x, area.y + adj_size(16));
543
544 start_y = impr_name_label->size.y + impr_name_label->size.h + adj_size(10);
545
546 if (!improvement_has_flag(pimpr_type, IF_GOLD)) {
547 cost_label = impr_name_label->prev;
548 widget_set_position(cost_label, start_x, start_y);
549 if (!is_wonder(pimpr_type)) {
550 upkeep_label = cost_label->prev;
551 widget_set_position(upkeep_label,
552 cost_label->size.x + cost_label->size.w + adj_size(20),
553 start_y);
554 }
555 start_y += cost_label->size.h;
556 }
557
558 requirement_label = store->requirement_button->next;
559 widget_set_position(requirement_label, start_x, start_y);
560
561 requirement_label2 = store->requirement_button;
562 widget_set_position(requirement_label2,
563 requirement_label->size.x + requirement_label->size.w + adj_size(5),
564 start_y);
565
566 if (store->obsolete_by_button) {
567 obsolete_by_label = store->obsolete_by_button->next;
568 widget_set_position(obsolete_by_label,
569 requirement_label2->size.x + requirement_label2->size.w + adj_size(10),
570 start_y);
571
572 obsolete_by_label2 = store->obsolete_by_button;
573 widget_set_position(obsolete_by_label2,
574 obsolete_by_label->size.x + obsolete_by_label->size.w + adj_size(5),
575 start_y);
576
577 start_y += obsolete_by_label2->size.h;
578 }
579
580 start_y += adj_size(30);
581
582 if (text) {
583 widget_set_position(help_text_label, start_x, start_y);
584 }
585
587}
588
589/**********************************************************************/
592static int change_unit_callback(struct widget *pwidget)
593{
595 popup_unit_info(MAX_ID - pwidget->id);
596 }
597
598 return -1;
599}
600
601/**********************************************************************/
604static void redraw_unit_info_dlg(void)
605{
606 SDL_Color bg_color = {255, 255, 255, 64};
607 struct widget *pwindow = help_dlg->end_widget_list;
608 struct units_buttons *store = (struct units_buttons *)pwindow->data.ptr;
609 SDL_Rect dst;
610
611 redraw_group(pwindow->prev, pwindow, FALSE);
612
613 dst.x = store->dock->prev->size.x - adj_size(10);
614 dst.y = store->dock->prev->size.y - adj_size(10);
615 dst.w = pwindow->size.w - (dst.x - pwindow->size.x) - adj_size(10);
616 dst.h = pwindow->size.h - (dst.y - pwindow->size.y) - adj_size(10);
617
618 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
619
620 create_frame(pwindow->dst->surface,
621 dst.x, dst.y, dst.w, dst.h,
623
624 /*------------------------------------- */
626 widget_flush(pwindow);
627}
628
629/**********************************************************************/
633{
634 SDL_Color bg_color = {255, 255, 255, 128};
635 struct widget *pwindow;
636 struct units_buttons *store;
637 struct widget *close_button = NULL;
639 struct widget *unit_button = NULL;
640 struct widget *unit_name_label = NULL;
641 struct widget *unit_info_label = NULL;
642 struct widget *requirement_label = NULL;
644 struct widget *obsolete_by_label = NULL;
646 struct widget *help_text_label = NULL;
647 struct widget *dock;
649 utf8_str *pstr;
650 SDL_Surface *surf;
651 int h, start_x, start_y, utype_count;
652 bool created, text = FALSE;
653 int scrollbar_width = 0;
654 struct unit_type *punittype;
655 char buffer[bufsz];
656 SDL_Rect area;
657
660 }
661
662 /* Create new dialog if it doesn't exist yet */
663 if (!help_dlg) {
664 SDL_Surface *background_tmpl, *background, *unit_name, *icon;
665 SDL_Rect dst;
666
668 created = TRUE;
669
670 /* Create dialog */
671 help_dlg = fc_calloc(1, sizeof(struct advanced_dialog));
672 store = fc_calloc(1, sizeof(struct units_buttons));
673
674 /* Create window */
676 title->style |= TTF_STYLE_BOLD;
677
678 pwindow = create_window_skeleton(NULL, title, WF_FREE_DATA);
680 set_wstate(pwindow , FC_WS_NORMAL);
681 pwindow->data.ptr = (void *)store;
682 add_to_gui_list(ID_WINDOW, pwindow);
683
684 help_dlg->end_widget_list = pwindow;
685
686 area = pwindow->area;
687
688 /* ------------------ */
689
690 /* Close button */
691 close_button = create_themeicon(current_theme->small_cancel_icon,
692 pwindow->dst,
695 close_button->info_label
696 = create_utf8_from_char_fonto(_("Close Dialog (Esc)"), FONTO_ATTENTION);
697 close_button->action = exit_help_dlg_callback;
698 set_wstate(close_button, FC_WS_NORMAL);
699 close_button->key = SDLK_ESCAPE;
700
701 add_to_gui_list(ID_BUTTON, close_button);
702
703 /* ------------------ */
704 dock = close_button;
705
706 /* --- Create scrollable unit list on the left side ---*/
707
708 pstr = create_utf8_str_fonto(NULL, 0, FONTO_DEFAULT);
709 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
710
711 /* Background template for entries in scroll list */
712 background_tmpl = create_surf(adj_size(135), adj_size(40), SDL_SWSURFACE);
713 SDL_FillRect(background_tmpl, NULL, map_rgba(background_tmpl->format, bg_color));
714
715 create_frame(background_tmpl,
716 0, 0, background_tmpl->w - 1, background_tmpl->h - 1,
718
719 utype_count = 0;
721
722 /* Copy background surface */
723 background = copy_surface(background_tmpl);
724
725 /* Blit unit name */
727 unit_name = create_text_surf_smaller_than_w(pstr, adj_size(100 - 4));
728 dst.x = adj_size(35) + (background->w - unit_name->w - adj_size(35)) / 2;
729 dst.y = (background->h - unit_name->h) / 2;
730 alphablit(unit_name, NULL, background, &dst, 255);
731 FREESURFACE(unit_name);
732
733 /* Blit unit icon */
734 icon = resize_surface_box(get_unittype_surface(ut, direction8_invalid()),
735 adj_size(36), adj_size(36), 1, TRUE, TRUE);
736 dst.x = (adj_size(35) - icon->w) / 2;
737 dst.y = (background->h - icon->h) / 2;
738 alphablit(icon, NULL, background, &dst, 255);
739 FREESURFACE(icon);
740
741 unit_button = create_icon2(background, pwindow->dst,
743
744 set_wstate(unit_button, FC_WS_NORMAL);
745 unit_button->action = change_unit_callback;
746 add_to_gui_list(MAX_ID - utype_number(ut), unit_button);
747
748 if (utype_count++ >= 10) {
749 set_wflag(unit_button, WF_HIDDEN);
750 }
751
753
754 FREESURFACE(background_tmpl);
755
757 help_dlg->begin_widget_list = unit_button ? unit_button : close_button;
759
760 if (utype_count > 10) {
762 scrollbar_width = create_vertical_scrollbar(help_dlg, 1, 10, TRUE, TRUE);
763 }
764
765 /* Toggle techs list button */
766 list_toggle_button = create_themeicon_button_from_chars_fonto(
767 current_theme->up_icon,
768 pwindow->dst,
769 _("Units"),
770 FONTO_DEFAULT, 0);
771#if 0
773 if (store->show_tree) {
774 set_wstate(list_toggle_button, FC_WS_NORMAL);
775 }
776#endif
777
778 widget_resize(list_toggle_button, adj_size(160), adj_size(15));
780
781 add_to_gui_list(ID_BUTTON, list_toggle_button);
782
783 dock = list_toggle_button;
784 store->dock = dock;
785 } else {
786 created = FALSE;
787 scrollbar_width = (help_dlg->scroll ? help_dlg->scroll->up_left_button->size.w : 0);
788 pwindow = help_dlg->end_widget_list;
789 store = (struct units_buttons *)pwindow->data.ptr;
790 dock = store->dock;
791
792 area = pwindow->area;
793
794 /* Delete any previous list entries */
797 dock->prev);
799 }
800 }
801
802 punittype = utype_by_number(type_id);
803 unit_name_label
806 direction8_invalid())),
807 pwindow->dst, utype_name_translation(punittype),
809
810 unit_name_label->id = ID_LABEL;
811 widget_add_as_prev(unit_name_label, dock);
812 dock = unit_name_label;
813
814 {
815 char buf[2048];
816
817 fc_snprintf(buf, sizeof(buf), "%s %d %s",
818 _("Cost:"), utype_build_shield_cost_base(punittype),
819 PL_("shield", "shields", utype_build_shield_cost_base(punittype)));
820
821 if (punittype->pop_cost) {
822 cat_snprintf(buf, sizeof(buf), " %d %s",
823 punittype->pop_cost, PL_("citizen", "citizens",
824 punittype->pop_cost));
825 }
826
827 cat_snprintf(buf, sizeof(buf), " %s", _("Upkeep:"));
828
829 if (punittype->upkeep[O_SHIELD]) {
830 cat_snprintf(buf, sizeof(buf), " %d %s",
831 punittype->upkeep[O_SHIELD], PL_("shield", "shields",
832 punittype->upkeep[O_SHIELD]));
833 }
834 if (punittype->upkeep[O_FOOD]) {
835 cat_snprintf(buf, sizeof(buf), " %d %s",
836 punittype->upkeep[O_FOOD], PL_("food", "foods",
837 punittype->upkeep[O_FOOD]));
838 }
839 if (punittype->upkeep[O_GOLD]) {
840 cat_snprintf(buf, sizeof(buf), " %d %s",
841 punittype->upkeep[O_GOLD], PL_("gold", "golds",
842 punittype->upkeep[O_GOLD]));
843 }
844 if (punittype->happy_cost) {
845 cat_snprintf(buf, sizeof(buf), " %d %s",
846 punittype->happy_cost, PL_("citizen", "citizens",
847 punittype->happy_cost));
848 }
849
850 cat_snprintf(buf, sizeof(buf), "\n%s %d %s %d %s %s\n%s %d %s %d %s %d",
851 _("Attack:"), punittype->attack_strength,
852 _("Defense:"), punittype->defense_strength,
853 _("Move:"), move_points_text(punittype->move_rate, TRUE),
854 _("Vision:"), punittype->vision_radius_sq,
855 _("Firepower:"), punittype->firepower,
856 _("Hitpoints:"), punittype->hp);
857
859 FONTO_ATTENTION, 0);
863 }
864
865 /* Requirement */
866 requirement_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
867 _("Requirement:"),
868 FONTO_ATTENTION, 0);
869 requirement_label->id = ID_LABEL;
870 widget_add_as_prev(requirement_label, dock);
871 dock = requirement_label;
872
873 if (A_NEVER == punittype->require_advance
874 || advance_by_number(A_NONE) == punittype->require_advance) {
875 requirement_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
876 Q_("?tech:None"),
877 FONTO_ATTENTION, 0);
878 requirement_label2->id = ID_LABEL;
879 } else {
880 requirement_label2
881 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
885 requirement_label2->id = MAX_ID - advance_number(punittype->require_advance);
886 requirement_label2->string_utf8->fgcol = *get_tech_color(advance_number(punittype->require_advance));
887 requirement_label2->action = change_tech_callback;
888 set_wstate(requirement_label2, FC_WS_NORMAL);
889 }
890 widget_add_as_prev(requirement_label2, dock);
891 dock = requirement_label2;
892 store->requirement_button = requirement_label2;
893
894 /* Obsolete by */
895 obsolete_by_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
896 _("Obsolete by:"),
897 FONTO_ATTENTION, 0);
898 obsolete_by_label->id = ID_LABEL;
899 widget_add_as_prev(obsolete_by_label, dock);
900 dock = obsolete_by_label;
901
902 if (punittype->obsoleted_by == U_NOT_OBSOLETED) {
903 obsolete_by_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
904 Q_("?utype:None"),
905 FONTO_ATTENTION, 0);
906 obsolete_by_label2->id = ID_LABEL;
907 } else {
908 const struct unit_type *utype = punittype->obsoleted_by;
909
910 obsolete_by_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
914 obsolete_by_label2->string_utf8->fgcol
916 obsolete_by_label2->id = MAX_ID - utype_number(punittype->obsoleted_by);
917 obsolete_by_label2->action = change_unit_callback;
918 set_wstate(obsolete_by_label2, FC_WS_NORMAL);
919 }
920 widget_add_as_prev(obsolete_by_label2, dock);
921 dock = obsolete_by_label2;
922 store->obsolete_by_button = obsolete_by_label2;
923
924 /* Helptext */
925 start_x = (area.x + 1 + scrollbar_width + help_dlg->active_widget_list->size.w + adj_size(20));
926
927 buffer[0] = '\0';
928 helptext_unit(buffer, sizeof(buffer), client.conn.playing, "", utype_by_number(type_id));
929 if (buffer[0] != '\0') {
931
933 help_text_label = create_iconlabel(NULL, pwindow->dst, ustr, 0);
934 help_text_label->id = ID_LABEL;
935 widget_add_as_prev(help_text_label, dock);
936 text = TRUE;
937 }
938
939 help_dlg->begin_widget_list = help_text_label ? help_text_label : obsolete_by_label2;
940
941 /* --------------------------------------------------------- */
942 if (created) {
943
945 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
946 FREESURFACE(surf);
947 }
948
949 area = pwindow->area;
950
951 widget_set_position(pwindow,
952 (main_window_width() - pwindow->size.w) / 2,
953 (main_window_height() - pwindow->size.h) / 2);
954
955 /* Exit button */
956 close_button = pwindow->prev;
957 widget_set_position(close_button,
958 area.x + area.w - close_button->size.w - 1,
959 pwindow->size.y + adj_size(2));
960
961 /* List toggle button */
962 list_toggle_button = store->dock;
963 widget_set_position(list_toggle_button, area.x, area.y);
964
965 /* List entries */
966 h = setup_vertical_widgets_position(1, area.x + scrollbar_width,
967 area.y + list_toggle_button->size.h, 0, 0,
970
971 /* Scrollbar */
972 if (help_dlg->scroll) {
974 area.x, area.y + list_toggle_button->size.h,
975 h, FALSE);
976 }
977 }
978
979 unit_name_label = store->dock->prev;
980 widget_set_position(unit_name_label, start_x, area.y + adj_size(16));
981
982 start_y = unit_name_label->size.y + unit_name_label->size.h + adj_size(10);
983
984 unit_info_label = unit_name_label->prev;
985 widget_set_position(unit_info_label, start_x, start_y);
986
987 start_y += unit_info_label->size.h;
988
989 requirement_label = store->requirement_button->next;
990 widget_set_position(requirement_label, start_x, start_y);
991
992 requirement_label2 = store->requirement_button;
993 widget_set_position(requirement_label2,
994 requirement_label->size.x + requirement_label->size.w + adj_size(5),
995 start_y);
996
997 obsolete_by_label = store->obsolete_by_button->next;
998 widget_set_position(obsolete_by_label,
999 requirement_label2->size.x + requirement_label2->size.w + adj_size(10),
1000 start_y);
1001
1002 obsolete_by_label2 = store->obsolete_by_button;
1003 widget_set_position(obsolete_by_label2,
1004 obsolete_by_label->size.x + obsolete_by_label->size.w + adj_size(5),
1005 start_y);
1006
1007 start_y += obsolete_by_label2->size.h + adj_size(20);
1008
1009 if (text) {
1010 help_text_label = store->obsolete_by_button->prev;
1011 widget_set_position(help_text_label, start_x, start_y);
1012 }
1013
1015}
1016
1017/* =============================================== */
1018/* ==================== Tech Tree ================ */
1019/* =============================================== */
1020
1021/**********************************************************************/
1024static int change_tech_callback(struct widget *pwidget)
1025{
1027 popup_tech_info(MAX_ID - pwidget->id);
1028 }
1029
1030 return -1;
1031}
1032
1033/**********************************************************************/
1036static int show_tech_tree_callback(struct widget *pwidget)
1037{
1039 struct techs_buttons *store = (struct techs_buttons *)help_dlg->end_widget_list->data.ptr;
1040
1041 store->show_tree = !store->show_tree;
1042 if (!store->show_tree) {
1043 store->show_full_tree = FALSE;
1044 store->dock->theme2 = current_theme->up_icon;
1045 }
1046 popup_tech_info(MAX_ID - store->dock->prev->id);
1047 }
1048
1049 return -1;
1050}
1051
1052/**********************************************************************/
1055static void redraw_tech_info_dlg(void)
1056{
1057 SDL_Color bg_color = {255, 255, 255, 64};
1058 struct widget *pwindow = help_dlg->end_widget_list;
1059 struct techs_buttons *store = (struct techs_buttons *)pwindow->data.ptr;
1060 SDL_Surface *text0, *text1 = NULL;
1061 utf8_str *pstr;
1062 SDL_Rect dst;
1063
1064 redraw_group(pwindow->prev, pwindow, FALSE);
1065
1066 dst.x = store->dock->prev->prev->size.x - adj_size(10);
1067 dst.y = store->dock->prev->prev->size.y - adj_size(10);
1068 dst.w = pwindow->size.w - (dst.x - pwindow->size.x) - adj_size(10);
1069 dst.h = pwindow->size.h - (dst.y - pwindow->size.y) - adj_size(10);
1070
1071 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
1072
1073 create_frame(pwindow->dst->surface,
1074 dst.x, dst.y, dst.w, dst.h,
1076
1077 /* -------------------------- */
1078 pstr = create_utf8_from_char_fonto(_("Allows"), FONTO_HEADING);
1079 pstr->style |= TTF_STYLE_BOLD;
1080
1081 text0 = create_text_surf_from_utf8(pstr);
1082 dst.x = store->dock->prev->prev->size.x;
1083 if (store->targets[0]) {
1084 dst.y = store->targets[0]->size.y - text0->h;
1085 } else {
1086 dst.y = store->dock->prev->prev->size.y
1087 + store->dock->prev->prev->size.h + adj_size(10);
1088 }
1089
1090 alphablit(text0, NULL, pwindow->dst->surface, &dst, 255);
1091 FREESURFACE(text0);
1092
1093 if (store->sub_targets[0]) {
1094 int i;
1095
1097
1098 copy_chars_to_utf8_str(pstr, _("( with "));
1099 text0 = create_text_surf_from_utf8(pstr);
1100
1101 copy_chars_to_utf8_str(pstr, _(" )"));
1102 text1 = create_text_surf_from_utf8(pstr);
1103 i = 0;
1104 while (i < 6 && store->sub_targets[i]) {
1105 dst.x = store->sub_targets[i]->size.x - text0->w;
1106 dst.y = store->sub_targets[i]->size.y;
1107
1108 alphablit(text0, NULL, pwindow->dst->surface, &dst, 255);
1109 dst.x = store->sub_targets[i]->size.x + store->sub_targets[i]->size.w;
1110 dst.y = store->sub_targets[i]->size.y;
1111
1112 alphablit(text1, NULL, pwindow->dst->surface, &dst, 255);
1113 i++;
1114 }
1115
1116 FREESURFACE(text0);
1117 FREESURFACE(text1);
1118 }
1119 FREEUTF8STR(pstr);
1120
1122 widget_flush(pwindow);
1123}
1124
1125/**********************************************************************/
1129 struct widget *pwindow,
1130 struct techs_buttons *store)
1131{
1132 struct widget *pwidget;
1133 struct widget *last, *budynki;
1134 struct widget *dock = store->dock;
1136 int start_x, start_y, imp_count, unit_count, flags_count, gov_count;
1137 char buffer[bufsz];
1138 SDL_Surface *surf;
1139
1140 start_x = (pwindow->area.x + adj_size(1) + width + help_dlg->active_widget_list->size.w + adj_size(20));
1141
1142 /* Tech tree icon */
1143 pwidget = create_icon2(current_theme->tech_tree_icon, pwindow->dst,
1145
1146 set_wstate(pwidget, FC_WS_NORMAL);
1148 pwidget->id = MAX_ID - tech;
1149 widget_add_as_prev(pwidget, dock);
1150 dock = pwidget;
1151
1152 /* Tech name (heading) */
1153 pwidget
1155 pwindow->dst,
1158
1159 pwidget->id = ID_LABEL;
1160 widget_add_as_prev(pwidget, dock);
1161 dock = pwidget;
1162
1163 /* Target techs */
1164 targets_count = 0;
1166 if ((targets_count < 6)
1167 && (advance_required(aidx, AR_ONE) == tech
1168 || advance_required(aidx, AR_TWO) == tech)) {
1169 pwidget
1174 pwidget->string_utf8->fgcol = *get_tech_color(aidx);
1175 max_width = MAX(max_width, pwidget->size.w);
1176 set_wstate(pwidget, FC_WS_NORMAL);
1177 pwidget->action = change_tech_callback;
1178 pwidget->id = MAX_ID - aidx;
1179 widget_add_as_prev(pwidget, dock);
1180 dock = pwidget;
1181 store->targets[targets_count++] = pwidget;
1182 }
1184 if (targets_count < 6) {
1185 store->targets[targets_count] = NULL;
1186 }
1187
1189 if (targets_count > 0) {
1190 int sub_tech;
1191
1192 for (i = 0; i < targets_count; i++) {
1193 sub_tech = MAX_ID - store->targets[i]->id;
1194 if (advance_required(sub_tech, AR_ONE) == tech
1197 } else if (advance_required(sub_tech, AR_TWO) == tech
1200 } else {
1201 continue;
1202 }
1203 pwidget
1209 set_wstate(pwidget, FC_WS_NORMAL);
1210 pwidget->action = change_tech_callback;
1211 pwidget->id = MAX_ID - sub_tech;
1212 widget_add_as_prev(pwidget, dock);
1213 dock = pwidget;
1214 store->sub_targets[sub_targets_count++] = pwidget;
1215 }
1216 }
1217 if (sub_targets_count < 6) {
1219 }
1220
1221 /* Fill array with iprvm. icons */
1222 budynki = pwidget;
1223
1224 /* Target governments */
1225 gov_count = 0;
1226 governments_iterate(gov) {
1227 requirement_vector_iterate(&(gov->reqs), preq) {
1228 if (VUT_ADVANCE == preq->source.kind
1229 && advance_number(preq->source.value.advance) == tech) {
1230
1231 pwidget
1233 pwindow->dst,
1237 set_wstate(pwidget, FC_WS_NORMAL);
1238 pwidget->action = change_gov_callback;
1239 pwidget->id = MAX_ID - government_index(gov);
1240 widget_add_as_prev(pwidget, dock);
1241 dock = pwidget;
1242 gov_count++;
1243 }
1246
1247 /* Target improvements */
1248 imp_count = 0;
1249 improvement_iterate(pimprove) {
1250 if (valid_improvement(pimprove)) {
1251 /* FIXME: this should show ranges and all the MAX_NUM_REQS reqs.
1252 * Currently it's limited to 1 req. Remember MAX_NUM_REQS is a compile-time
1253 * definition. */
1254 requirement_vector_iterate(&(pimprove->reqs), preq) {
1255 if (VUT_ADVANCE == preq->source.kind
1256 && advance_number(preq->source.value.advance) == tech) {
1257 surf = get_building_surface(pimprove);
1259 resize_surface_box(surf, adj_size(48), adj_size(48), 1, TRUE,
1260 TRUE),
1261 pwindow->dst,
1265 set_wstate(pwidget, FC_WS_NORMAL);
1266 if (is_wonder(pimprove)) {
1268 }
1269 pwidget->action = change_impr_callback;
1270 pwidget->id = MAX_ID - improvement_number(pimprove);
1271 widget_add_as_prev(pwidget, dock);
1272 dock = pwidget;
1273 imp_count++;
1274 }
1275
1276 break;
1278 }
1280
1281 unit_count = 0;
1283 if (advance_number(un->require_advance) == tech) {
1286 adj_size(48), adj_size(48), 1, TRUE, TRUE),
1289 set_wstate(pwidget, FC_WS_NORMAL);
1290 pwidget->action = change_unit_callback;
1291 pwidget->id = MAX_ID - utype_number(un);
1292 widget_add_as_prev(pwidget, dock);
1293 dock = pwidget;
1294 unit_count++;
1295 }
1297
1298 buffer[0] = '\0';
1299 if (tech != A_NONE) {
1300 helptext_advance(buffer, sizeof(buffer), client.conn.playing, "", tech);
1301 }
1302 if (buffer[0] != '\0') {
1304
1306 pwidget = create_iconlabel(NULL, pwindow->dst, pstr, 0);
1307 pwidget->id = ID_LABEL;
1308 widget_add_as_prev(pwidget, dock);
1309 flags_count = 1;
1310 } else {
1311 flags_count = 0;
1312 }
1313
1314 last = pwidget;
1315 /* --------------------------------------------- */
1316
1317 /* Tree button */
1318 pwidget = store->dock->prev;
1319 pwidget->size.x = pwindow->area.x + pwindow->area.w - pwidget->size.w - adj_size(17);
1320 pwidget->size.y = pwindow->area.y + adj_size(16);
1321
1322 /* Tech label */
1323 pwidget = pwidget->prev;
1324 pwidget->size.x = start_x;
1325 pwidget->size.y = pwindow->area.y + adj_size(16);
1326 start_y = pwidget->size.y + pwidget->size.h + adj_size(30);
1327
1328 if (targets_count) {
1329 int j = 0;
1330
1331 i = 0;
1332
1333 while (i < 6 && store->targets[i]) {
1334 store->targets[i]->size.x = pwindow->size.x + start_x;
1335 store->targets[i]->size.y = start_y;
1336
1337 if (store->sub_targets[j]) {
1338 int t0 = MAX_ID - store->targets[i]->id;
1339 int t1 = MAX_ID - store->sub_targets[j]->id;
1340
1341 if (advance_required(t0, AR_ONE) == t1
1342 || advance_required(t0, AR_TWO) == t1) {
1343 store->sub_targets[j]->size.x = pwindow->size.x + start_x + max_width + 60;
1344 store->sub_targets[j]->size.y = store->targets[i]->size.y;
1345 j++;
1346 }
1347 }
1348
1349 start_y += store->targets[i]->size.h;
1350 i++;
1351 }
1352
1353 start_y += adj_size(10);
1354 }
1355 pwidget = NULL;
1356
1357 if (gov_count) {
1358 pwidget = budynki->prev;
1359 while (gov_count-- && pwidget) {
1360 pwidget->size.x = pwindow->size.x + start_x;
1361 pwidget->size.y = start_y;
1362 start_y += pwidget->size.h + adj_size(2);
1363 pwidget = pwidget->prev;
1364 }
1365 }
1366
1367 if (imp_count) {
1368 if (!pwidget) {
1369 pwidget = budynki->prev;
1370 }
1371 while (imp_count-- && pwidget) {
1372 pwidget->size.x = pwindow->size.x + start_x;
1373 pwidget->size.y = start_y;
1374 start_y += pwidget->size.h + adj_size(2);
1375 pwidget = pwidget->prev;
1376 }
1377 }
1378
1379 if (unit_count) {
1380 if (!pwidget) {
1381 pwidget = budynki->prev;
1382 }
1383 while (unit_count-- && pwidget) {
1384 pwidget->size.x = pwindow->size.x + start_x;
1385 pwidget->size.y = start_y;
1386 start_y += pwidget->size.h + adj_size(2);
1387 pwidget = pwidget->prev;
1388 }
1389 }
1390
1391 if (flags_count) {
1392 if (!pwidget) {
1393 pwidget = budynki->prev;
1394 }
1395 while (flags_count-- && pwidget) {
1396 pwidget->size.x = pwindow->size.x + start_x;
1397 pwidget->size.y = start_y;
1398 start_y += pwidget->size.h + adj_size(2);
1399 pwidget = pwidget->prev;
1400 }
1401 }
1402
1403 return last;
1404}
1405
1406/**********************************************************************/
1409static void redraw_tech_tree_dlg(void)
1410{
1412 SDL_Color bg_color = {255, 255, 255, 64};
1413 struct widget *pwindow = help_dlg->end_widget_list;
1414 struct widget *sub0, *sub1;
1415 struct techs_buttons *store = (struct techs_buttons *)pwindow->data.ptr;
1416 struct widget *ptech = store->dock->prev;
1417 int i,j, tech, count;
1418 int step;
1419 int mod;
1420 SDL_Rect dst;
1421
1422 /* Redraw Window with exit button */
1423 redraw_group(pwindow->prev, pwindow, FALSE);
1424
1425 dst.x = pwindow->area.x + pwindow->area.w - adj_size(459) - adj_size(7);
1426 dst.y = pwindow->area.y + adj_size(6);
1427 dst.w = pwindow->area.w - (dst.x - pwindow->area.x) - adj_size(10);
1428 dst.h = pwindow->area.h - (dst.y - pwindow->area.y) - adj_size(10);
1429
1430 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
1431
1432 create_frame(pwindow->dst->surface,
1433 dst.x, dst.y, dst.w, dst.h,
1435
1436 /* Draw req arrows */
1437 i = 0;
1438 while (i < 4 && store->sub_req[i]) {
1439 i++;
1440 }
1441 count = i;
1442
1443 i = 0;
1444 while (i < 2 && store->requirement_button[i]) {
1445 tech = MAX_ID - store->requirement_button[i]->id;
1446
1447 /* Find sub req's */
1448 if (i) {
1449 sub0 = NULL;
1450 for (j = count - 1; j >= 0; j--) {
1451 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_ONE)) {
1452 sub0 = store->sub_req[j];
1453 break;
1454 }
1455 }
1456
1457 sub1 = NULL;
1458 for (j = count - 1; j >= 0; j--) {
1459 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_TWO)) {
1460 sub1 = store->sub_req[j];
1461 break;
1462 }
1463 }
1464 } else {
1465 sub0 = NULL;
1466 for (j = 0; j < 4 && store->sub_req[j]; j++) {
1467 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_ONE)) {
1468 sub0 = store->sub_req[j];
1469 break;
1470 }
1471 }
1472
1473 sub1 = NULL;
1474 for (j = 0; j < 4 && store->sub_req[j]; j++) {
1475 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_TWO)) {
1476 sub1 = store->sub_req[j];
1477 break;
1478 }
1479 }
1480 }
1481
1482 /* Draw main Arrow */
1484 store->requirement_button[i]->size.x + store->requirement_button[i]->size.w,
1485 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1486 ptech->size.x,
1487 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1488 line_color);
1489
1490 /* Draw sub req arrows */
1491 if (sub0 || sub1) {
1493 store->requirement_button[i]->size.x - adj_size(10),
1494 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1495 store->requirement_button[i]->size.x ,
1496 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1497 line_color);
1498 }
1499
1500 if (sub0) {
1502 store->requirement_button[i]->size.x - adj_size(10),
1503 sub0->size.y + sub0->size.h / 2,
1504 store->requirement_button[i]->size.x - adj_size(10),
1505 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1506 line_color);
1508 sub0->size.x + sub0->size.w,
1509 sub0->size.y + sub0->size.h / 2,
1510 store->requirement_button[i]->size.x - adj_size(10),
1511 sub0->size.y + sub0->size.h / 2,
1512 line_color);
1513 }
1514
1515 if (sub1) {
1517 store->requirement_button[i]->size.x - adj_size(10),
1518 sub1->size.y + sub1->size.h / 2,
1519 store->requirement_button[i]->size.x - adj_size(10),
1520 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1521 line_color);
1523 sub1->size.x + sub1->size.w,
1524 sub1->size.y + sub1->size.h / 2,
1525 store->requirement_button[i]->size.x - adj_size(10),
1526 sub1->size.y + sub1->size.h / 2,
1527 line_color);
1528 }
1529 i++;
1530 }
1531
1532 i = 0;
1533 while (i < 6 && store->targets[i]) {
1534 i++;
1535 }
1536 count = i;
1537
1538 if (count > 4) {
1539 mod = 3;
1540 } else {
1541 mod = 2;
1542 }
1543
1544 for (i = 0; i < count; i++) {
1545 tech = MAX_ID - store->targets[i]->id;
1546 step = ptech->size.h / (count + 1);
1547
1548 switch ((i % mod)) {
1549 case 2:
1551 break;
1552 case 1:
1554 break;
1555 default:
1557 break;
1558 }
1559
1560 /* Find sub reqs */
1561 if (advance_required(tech, AR_ONE) == MAX_ID - ptech->id) {
1562 sub0 = ptech;
1563 } else {
1564 sub0 = NULL;
1565 for (j = 0; j < 6 && store->sub_targets[j]; j++) {
1566 if (MAX_ID - store->sub_targets[j]->id == advance_required(tech, AR_ONE)) {
1567 sub0 = store->sub_targets[j];
1568 break;
1569 }
1570 }
1571 }
1572
1573 if (advance_required(tech, AR_TWO) == MAX_ID - ptech->id) {
1574 sub1 = ptech;
1575 } else {
1576 sub1 = NULL;
1577 for (j = 0; j < 6 && store->sub_targets[j]; j++) {
1578 if (MAX_ID - store->sub_targets[j]->id == advance_required(tech, AR_TWO)) {
1579 sub1 = store->sub_targets[j];
1580 break;
1581 }
1582 }
1583 }
1584
1585 /* Draw sub targets arrows */
1586 if (sub0 || sub1) {
1587 create_line(store->targets[i]->dst->surface,
1588 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1589 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1590 store->targets[i]->size.x ,
1591 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1592 line_color);
1593 }
1594
1595 if (sub0) {
1596 int y;
1597
1598 if (sub0 == ptech) {
1599 y = sub0->size.y + step * (i + 1);
1600 } else {
1601 y = sub0->size.y + sub0->size.h / 2;
1602 }
1603
1604 create_line(store->targets[i]->dst->surface,
1605 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1606 y,
1607 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1608 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1609 line_color);
1610 create_line(store->targets[i]->dst->surface,
1611 sub0->size.x + sub0->size.w,
1612 y,
1613 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1614 y,
1615 line_color);
1616 }
1617
1618 if (sub1) {
1619 int y;
1620
1621 if (sub1 == ptech) {
1622 y = sub1->size.y + step * (i + 1);
1623 } else {
1624 y = sub1->size.y + sub1->size.h / 2;
1625 }
1626
1627 create_line(store->targets[i]->dst->surface,
1628 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1629 y,
1630 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1631 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1632 line_color);
1633 create_line(store->targets[i]->dst->surface,
1634 sub1->size.x + sub1->size.w,
1635 y,
1636 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1637 y,
1638 line_color);
1639 }
1640 }
1641
1642 /* Redraw rest */
1644
1645 widget_flush(pwindow);
1646}
1647
1648/**********************************************************************/
1652{
1654 struct techs_buttons *store = (struct techs_buttons *)help_dlg->end_widget_list->data.ptr;
1655
1656 if (store->show_full_tree) {
1657 pwidget->theme2 = current_theme->up_icon;
1658 } else {
1659 pwidget->theme2 = current_theme->down_icon;
1660 }
1661 store->show_full_tree = !store->show_full_tree;
1662 popup_tech_info(MAX_ID - store->dock->prev->id);
1663 }
1664
1665 return -1;
1666}
1667
1668/**********************************************************************/
1672 struct widget *pwindow,
1673 struct techs_buttons *store)
1674{
1676 struct widget *pwidget;
1677 struct widget *ptech;
1678 utf8_str *pstr;
1679 SDL_Surface *surf;
1680 struct widget *dock = store->dock;
1681
1683 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
1684
1687 pwidget = create_icon2(surf, pwindow->dst,
1689
1690 set_wstate(pwidget, FC_WS_NORMAL);
1692 pwidget->id = MAX_ID - tech;
1693 widget_add_as_prev(pwidget, dock);
1694 ptech = pwidget;
1695 dock = pwidget;
1696
1697 req_count = 0;
1698 for (i = AR_ONE; i <= AR_TWO; i++) {
1700 struct advance *vap = valid_advance_by_number(ar);
1701
1702 if (NULL != vap && A_NONE != ar) {
1704 surf = create_select_tech_icon(pstr, ar, TIM_SMALL_MODE);
1705 pwidget = create_icon2(surf, pwindow->dst,
1707 set_wstate(pwidget, FC_WS_NORMAL);
1708 pwidget->action = change_tech_callback;
1709 pwidget->id = MAX_ID - ar;
1710 widget_add_as_prev(pwidget, dock);
1711 dock = pwidget;
1712 store->requirement_button[req_count++] = pwidget;
1713 }
1714 }
1715
1716 sub_req_count = 0;
1717
1718 if (store->show_full_tree && req_count > 0) {
1719 int j, sub_tech;
1720
1721 for (j = 0; j < req_count; j++) {
1722 sub_tech = MAX_ID - store->requirement_button[j]->id;
1723 for (i = AR_ONE; i <= AR_TWO; i++) {
1724 Tech_type_id ar = advance_required(sub_tech, i);
1725 struct advance *vap = valid_advance_by_number(ar);
1726
1727 if (NULL != vap && A_NONE != ar) {
1729 surf = create_select_tech_icon(pstr, ar, TIM_SMALL_MODE);
1730 pwidget = create_icon2(surf, pwindow->dst,
1732 set_wstate(pwidget, FC_WS_NORMAL);
1733 pwidget->action = change_tech_callback;
1734 pwidget->id = MAX_ID - ar;
1735 widget_add_as_prev(pwidget, dock);
1736 dock = pwidget;
1737 store->sub_req[sub_req_count++] = pwidget;
1738 }
1739 }
1740 }
1741 }
1742
1743 if (sub_req_count < 4) {
1744 store->sub_req[sub_req_count] = NULL;
1745 }
1746
1747 targets_count = 0;
1749 if ((targets_count < 6)
1750 && (advance_required(aidx, AR_ONE) == tech
1751 || advance_required(aidx, AR_TWO) == tech)) {
1753 surf = create_select_tech_icon(pstr, aidx, TIM_SMALL_MODE);
1754 pwidget = create_icon2(surf, pwindow->dst,
1756
1757 set_wstate(pwidget, FC_WS_NORMAL);
1758 pwidget->action = change_tech_callback;
1759 pwidget->id = MAX_ID - aidx;
1760 widget_add_as_prev(pwidget, dock);
1761 dock = pwidget;
1762 store->targets[targets_count++] = pwidget;
1763 }
1765 if (targets_count < 6) {
1766 store->targets[targets_count] = NULL;
1767 }
1768
1769 sub_targets_count = 0;
1770 if (targets_count > 0) {
1771 int sub_tech;
1772
1773 for (i = 0; i < targets_count; i++) {
1774 sub_tech = MAX_ID - store->targets[i]->id;
1775 if (advance_required(sub_tech, AR_ONE) == tech
1776 && advance_required(sub_tech, AR_TWO) != A_NONE) {
1777 sub_tech = advance_required(sub_tech, AR_TWO);
1778 } else if (advance_required(sub_tech, AR_TWO) == tech
1779 && advance_required(sub_tech, AR_ONE) != A_NONE) {
1780 sub_tech = advance_required(sub_tech, AR_ONE);
1781 } else {
1782 continue;
1783 }
1784
1786 surf = create_select_tech_icon(pstr, sub_tech, TIM_SMALL_MODE);
1787 pwidget = create_icon2(surf, pwindow->dst,
1789 set_wstate(pwidget, FC_WS_NORMAL);
1790 pwidget->action = change_tech_callback;
1791 pwidget->id = MAX_ID - sub_tech;
1792 widget_add_as_prev(pwidget, dock);
1793 dock = pwidget;
1794 store->sub_targets[sub_targets_count++] = pwidget;
1795 }
1796 }
1797 if (sub_targets_count < 6) {
1798 store->sub_targets[sub_targets_count] = NULL;
1799 }
1800
1801 FREEUTF8STR(pstr);
1802
1803 /* ------------------------------------------ */
1804 if (sub_req_count > 0) {
1805 w = (adj_size(20) + store->sub_req[0]->size.w) * 2;
1806 w += (pwindow->size.w - (20 + store->sub_req[0]->size.w + w + ptech->size.w)) / 2;
1807 } else {
1808 if (req_count > 0) {
1809 w = (pwindow->area.x + 1
1810 + width + store->requirement_button[0]->size.w * 2 + adj_size(20));
1811 w += (pwindow->size.w - ((adj_size(20) + store->requirement_button[0]->size.w)
1812 + w + ptech->size.w)) / 2;
1813 } else {
1814 w = (pwindow->size.w - ptech->size.w) / 2;
1815 }
1816 }
1817
1818 ptech->size.x = pwindow->size.x + w;
1819 ptech->size.y = pwindow->area.y + (pwindow->area.h - ptech->size.h) / 2;
1820
1821 if (req_count > 0) {
1822 h = (req_count == 1 ? store->requirement_button[0]->size.h :
1823 req_count * (store->requirement_button[0]->size.h + adj_size(80)) - adj_size(80));
1824 h = ptech->size.y + (ptech->size.h - h) / 2;
1825 for (i = 0; i < req_count; i++) {
1826 store->requirement_button[i]->size.x
1827 = ptech->size.x - adj_size(20) - store->requirement_button[i]->size.w;
1828 store->requirement_button[i]->size.y = h;
1829 h += (store->requirement_button[i]->size.h + adj_size(80));
1830 }
1831 }
1832
1833 if (sub_req_count > 0) {
1834 h = (sub_req_count == 1 ? store->sub_req[0]->size.h :
1835 sub_req_count * (store->sub_req[0]->size.h + adj_size(20)) - adj_size(20));
1836 h = ptech->size.y + (ptech->size.h - h) / 2;
1837 for (i = 0; i < sub_req_count; i++) {
1838 store->sub_req[i]->size.x
1839 = ptech->size.x - (adj_size(20) + store->sub_req[i]->size.w) * 2;
1840 store->sub_req[i]->size.y = h;
1841 h += (store->sub_req[i]->size.h + adj_size(20));
1842 }
1843 }
1844
1845 if (targets_count > 0) {
1846 h = (targets_count == 1 ? store->targets[0]->size.h :
1847 targets_count * (store->targets[0]->size.h + adj_size(20)) - adj_size(20));
1848 h = ptech->size.y + (ptech->size.h - h) / 2;
1849 for (i = 0; i < targets_count; i++) {
1850 store->targets[i]->size.x = ptech->size.x + ptech->size.w + adj_size(20);
1851 store->targets[i]->size.y = h;
1852 h += (store->targets[i]->size.h + adj_size(20));
1853 }
1854 }
1855
1856 if (sub_targets_count > 0) {
1857 if (sub_targets_count < 3) {
1858 store->sub_targets[0]->size.x
1859 = ptech->size.x + ptech->size.w - store->sub_targets[0]->size.w;
1860 store->sub_targets[0]->size.y
1861 = ptech->size.y - store->sub_targets[0]->size.h - adj_size(10);
1862 if (store->sub_targets[1]) {
1863 store->sub_targets[1]->size.x
1864 = ptech->size.x + ptech->size.w - store->sub_targets[1]->size.w;
1865 store->sub_targets[1]->size.y = ptech->size.y + ptech->size.h + adj_size(10);
1866 }
1867 } else {
1868 if (sub_targets_count < 5) {
1869 for (i = 0; i < MIN(sub_targets_count, 4); i++) {
1870 store->sub_targets[i]->size.x
1871 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1872 if (i < 2) {
1873 store->sub_targets[i]->size.y
1874 = ptech->size.y - (store->sub_targets[i]->size.h + adj_size(5)) * (2 - i);
1875 } else {
1876 store->sub_targets[i]->size.y
1877 = ptech->size.y + ptech->size.h + adj_size(5)
1878 + (store->sub_targets[i]->size.h + adj_size(5)) * (i - 2);
1879 }
1880 }
1881 } else {
1882 h = (store->sub_targets[0]->size.h + adj_size(6));
1883 for (i = 0; i < MIN(sub_targets_count, 6); i++) {
1884 switch (i) {
1885 case 0:
1886 store->sub_targets[i]->size.x
1887 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1888 store->sub_targets[i]->size.y = ptech->size.y - h * 2;
1889 break;
1890 case 1:
1891 store->sub_targets[i]->size.x
1892 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w * 2
1893 - adj_size(10);
1894 store->sub_targets[i]->size.y = ptech->size.y - h - h / 2;
1895 break;
1896 case 2:
1897 store->sub_targets[i]->size.x
1898 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1899 store->sub_targets[i]->size.y = ptech->size.y - h;
1900 break;
1901 case 3:
1902 store->sub_targets[i]->size.x
1903 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1904 store->sub_targets[i]->size.y = ptech->size.y + ptech->size.h + adj_size(6);
1905 break;
1906 case 4:
1907 store->sub_targets[i]->size.x
1908 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1909 store->sub_targets[i]->size.y = ptech->size.y + ptech->size.h + adj_size(6) + h;
1910 break;
1911 default:
1912 store->sub_targets[i]->size.x
1913 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w * 2
1914 - adj_size(10);
1915 store->sub_targets[i]->size.y
1916 = ptech->size.y + ptech->size.h + adj_size(6) + h / 2 ;
1917 break;
1918 }
1919 }
1920 }
1921 }
1922 }
1923
1924 return pwidget;
1925}
1926
1927/**********************************************************************/
1931{
1932 struct widget *pwindow;
1933 struct techs_buttons *store;
1934 struct widget *close_button = NULL;
1935 struct widget *advance_label = NULL;
1936 struct widget *list_toggle_button = NULL;
1937 struct widget *dock;
1938 utf8_str *title;
1939 utf8_str *pstr;
1940 SDL_Surface *surf;
1941 int h, tech_count;
1942 bool created;
1943 int scrollbar_width = 0;
1944 SDL_Rect area;
1945
1946 if (current_help_dlg != HELP_TECH) {
1948 }
1949
1950 /* Create new dialog if it doesn't exist yet */
1951 if (!help_dlg) {
1953 created = TRUE;
1954
1955 /* Create dialog */
1956 help_dlg = fc_calloc(1, sizeof(struct advanced_dialog));
1957 store = fc_calloc(1, sizeof(struct techs_buttons));
1958
1959 store->show_tree = FALSE;
1960 store->show_full_tree = FALSE;
1961
1962 /* Create window */
1963 title = create_utf8_from_char_fonto(_("Help : Advances Tree"),
1965 title->style |= TTF_STYLE_BOLD;
1966
1968 pwindow->data.ptr = (void *)store;
1970 set_wstate(pwindow, FC_WS_NORMAL);
1971
1972 add_to_gui_list(ID_WINDOW, pwindow);
1973
1974 help_dlg->end_widget_list = pwindow;
1975
1976 /* ------------------ */
1977
1978 /* Close button */
1979 close_button = create_themeicon(current_theme->small_cancel_icon, pwindow->dst,
1982 close_button->info_label
1983 = create_utf8_from_char_fonto(_("Close Dialog (Esc)"), FONTO_ATTENTION);
1984 close_button->action = exit_help_dlg_callback;
1985 set_wstate(close_button, FC_WS_NORMAL);
1986 close_button->key = SDLK_ESCAPE;
1987
1988 add_to_gui_list(ID_BUTTON, close_button);
1989
1990 /* ------------------ */
1991 dock = close_button;
1992
1993 /* --- Create scrollable advance list on the left side ---*/
1995 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
1996
1997 tech_count = 0;
1999 struct advance *vap = valid_advance_by_number(i);
2000
2001 if (vap) {
2003 surf = create_select_tech_icon(pstr, i, TIM_SMALL_MODE);
2004 advance_label = create_icon2(surf, pwindow->dst,
2006
2007 set_wstate(advance_label, FC_WS_NORMAL);
2008 advance_label->action = change_tech_callback;
2009 add_to_gui_list(MAX_ID - i, advance_label);
2010
2011 if (tech_count++ >= 10) {
2012 set_wflag(advance_label, WF_HIDDEN);
2013 }
2014 }
2016
2017 FREEUTF8STR(pstr);
2018
2020 help_dlg->begin_widget_list = advance_label ? advance_label : close_button;
2022
2023 if (tech_count > 10) {
2025 scrollbar_width = create_vertical_scrollbar(help_dlg, 1, 10, TRUE, TRUE);
2026 }
2027
2028 /* Toggle techs list button */
2029 list_toggle_button = create_themeicon_button_from_chars_fonto(
2030 current_theme->up_icon,
2031 pwindow->dst,
2032 _("Advances"),
2033 FONTO_DEFAULT, 0);
2035 if (store->show_tree) {
2036 set_wstate(list_toggle_button, FC_WS_NORMAL);
2037 }
2038 widget_resize(list_toggle_button, adj_size(160), adj_size(15));
2040
2041 add_to_gui_list(ID_BUTTON, list_toggle_button);
2042
2043 dock = list_toggle_button;
2044 store->dock = dock;
2045 } else {
2046 created = FALSE;
2047 scrollbar_width = (help_dlg->scroll ? help_dlg->scroll->up_left_button->size.w: 0);
2048 pwindow = help_dlg->end_widget_list;
2049 store = (struct techs_buttons *)pwindow->data.ptr;
2050 dock = store->dock;
2051
2052 /* Delete any previous list entries */
2056 }
2057
2058 /* Show/hide techs list */
2059 list_toggle_button = dock;
2060
2061 if (store->show_tree) {
2062 set_wstate(list_toggle_button, FC_WS_NORMAL);
2063 } else {
2064 set_wstate(list_toggle_button, FC_WS_DISABLED);
2065 }
2066
2067 if (store->show_full_tree) {
2068 /* All entries are visible without scrolling */
2072 } else {
2073 int count = help_dlg->scroll->active;
2074
2075 advance_label = help_dlg->active_widget_list;
2076 while (advance_label->prev != NULL && --count > 0) {
2077 advance_label = advance_label->prev;
2078 }
2079 show_group(advance_label, help_dlg->active_widget_list);
2081 }
2082 }
2083
2084 /* --------------------------------------------------------- */
2085 if (created) {
2086
2088 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
2089 FREESURFACE(surf);
2090 }
2091
2092 area = pwindow->area;
2093
2094 widget_set_position(pwindow,
2095 (main_window_width() - pwindow->size.w) / 2,
2096 (main_window_height() - pwindow->size.h) / 2);
2097
2098 /* Exit button */
2099 close_button = pwindow->prev;
2100 widget_set_position(close_button,
2101 area.x + area.w - close_button->size.w - 1,
2102 pwindow->size.y + adj_size(2));
2103
2104 /* List toggle button */
2105 list_toggle_button = store->dock;
2106 widget_set_position(list_toggle_button, area.x, area.y);
2107
2108 /* List entries */
2109 h = setup_vertical_widgets_position(1, area.x + scrollbar_width,
2110 area.y + list_toggle_button->size.h, 0, 0,
2113 /* Scrollbar */
2114 if (help_dlg->scroll) {
2116 area.x, area.y + list_toggle_button->size.h,
2117 h, FALSE);
2118 }
2119 }
2120
2121 if (store->show_tree) {
2122 help_dlg->begin_widget_list = create_tech_tree(tech, scrollbar_width, pwindow, store);
2124 } else {
2125 help_dlg->begin_widget_list = create_tech_info(tech, scrollbar_width, pwindow, store);
2127 }
2128}
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
const char * city_improvement_name_translation(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:658
struct civclient client
QString current_theme
Definition fc_client.cpp:65
int Tech_type_id
Definition fc_types.h:347
int Impr_type_id
Definition fc_types.h:346
int Unit_type_id
Definition fc_types.h:352
@ O_SHIELD
Definition fc_types.h:91
@ O_FOOD
Definition fc_types.h:91
@ O_GOLD
Definition fc_types.h:91
#define Q_(String)
Definition fcintl.h:70
#define PL_(String1, String2, n)
Definition fcintl.h:71
#define _(String)
Definition fcintl.h:67
const char * government_name_translation(const struct government *pgovern)
Definition government.c:142
Government_type_id government_index(const struct government *pgovern)
Definition government.c:81
#define governments_iterate(NAME_pgov)
Definition government.h:121
#define governments_iterate_end
Definition government.h:124
GtkWidget * unit_info_label
Definition gui_main.c:150
static void create_tech_tree(int tech, int levels, GtkTreeIter *parent)
Definition helpdlg.c:225
void popdown_help_dialog(void)
Definition helpdlg.c:185
void popup_help_dialog_string(const char *item)
Definition helpdlg.c:211
void popup_help_dialog_typed(const char *item, enum help_page_type htype)
Definition helpdlg.c:195
void flush_dirty(void)
Definition mapview.c:450
const char * title
Definition repodlgs.c:1313
SDL_Color * get_theme_color(enum theme_color themecolor)
Definition colors.c:44
int main_window_width(void)
Definition graphics.c:685
int fill_rect_alpha(SDL_Surface *surf, SDL_Rect *prect, SDL_Color *pcolor)
Definition graphics.c:865
void create_line(SDL_Surface *dest, Sint16 x0, Sint16 y0, Sint16 x1, Sint16 y1, SDL_Color *pcolor)
Definition graphics.c:1378
SDL_Surface * copy_surface(SDL_Surface *src)
Definition graphics.c:1308
int alphablit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:199
struct sdl2_data main_data
Definition graphics.c:57
SDL_Surface * create_surf(int width, int height, Uint32 flags)
Definition graphics.c:351
void create_frame(SDL_Surface *dest, Sint16 left, Sint16 top, Sint16 width, Sint16 height, SDL_Color *pcolor)
Definition graphics.c:1347
int main_window_height(void)
Definition graphics.c:693
SDL_Surface * resize_surface_box(const SDL_Surface *psrc, Uint16 new_width, Uint16 new_height, int smooth, bool scale_up, bool absolute_dimensions)
Definition graphics.c:1256
#define FREESURFACE(ptr)
Definition graphics.h:322
#define adj_surf(surf)
Definition graphics.h:200
#define map_rgba(format, color)
Definition graphics.h:315
#define adj_size(size)
Definition gui_main.h:138
#define PRESSED_EVENT(event)
Definition gui_main.h:68
static int exit_help_dlg_callback(struct widget *pwidget)
Definition helpdlg.c:130
void popup_gov_info(int gov)
Definition helpdlg.c:155
void popup_tech_info(Tech_type_id tech)
Definition helpdlg.c:1930
static const int bufsz
Definition helpdlg.c:70
static struct advanced_dialog * help_dlg
Definition helpdlg.c:52
static int show_tech_tree_callback(struct widget *pwidget)
Definition helpdlg.c:1036
enum help_page_type current_help_dlg
Definition helpdlg.c:68
static void redraw_tech_info_dlg(void)
Definition helpdlg.c:1055
static void redraw_unit_info_dlg(void)
Definition helpdlg.c:604
static int change_tech_callback(struct widget *pwidget)
Definition helpdlg.c:1024
void popup_help_browser(void)
Definition helpdlg.c:77
static struct widget * create_tech_info(Tech_type_id tech, int width, struct widget *pwindow, struct techs_buttons *store)
Definition helpdlg.c:1128
void popup_impr_info(Impr_type_id impr)
Definition helpdlg.c:202
static void redraw_tech_tree_dlg(void)
Definition helpdlg.c:1409
static int help_dlg_window_callback(struct widget *pwindow)
Definition helpdlg.c:122
static int change_unit_callback(struct widget *pwidget)
Definition helpdlg.c:592
void popup_unit_info(Unit_type_id type_id)
Definition helpdlg.c:632
static int change_gov_callback(struct widget *pwidget)
Definition helpdlg.c:143
static void redraw_impr_info_dlg(void)
Definition helpdlg.c:174
static int toggle_full_tree_mode_in_help_dlg_callback(struct widget *pwidget)
Definition helpdlg.c:1651
static int change_impr_callback(struct widget *pwidget)
Definition helpdlg.c:162
SDL_Surface * create_select_tech_icon(utf8_str *pstr, Tech_type_id tech_id, enum tech_info_mode mode)
Definition repodlgs.c:2423
@ TIM_SMALL_MODE
Definition repodlgs.h:32
@ TIM_FULL_MODE
Definition repodlgs.h:30
@ ID_BUTTON
Definition gui_id.h:29
@ ID_LABEL
Definition gui_id.h:27
@ ID_WINDOW
Definition gui_id.h:30
utf8_str * copy_chars_to_utf8_str(utf8_str *pstr, const char *pchars)
Definition gui_string.c:251
SDL_Surface * create_text_surf_from_utf8(utf8_str *pstr)
Definition gui_string.c:425
void change_fonto_utf8(utf8_str *pstr, enum font_origin origin)
Definition gui_string.c:584
utf8_str * create_utf8_str_fonto(char *in_text, size_t n_alloc, enum font_origin origin)
Definition gui_string.c:241
bool convert_utf8_str_to_const_surface_width(utf8_str *pstr, int width)
Definition gui_string.c:449
SDL_Surface * create_text_surf_smaller_than_w(utf8_str *pstr, int w)
Definition gui_string.c:539
#define FREEUTF8STR(pstr)
Definition gui_string.h:92
#define SF_CENTER
Definition gui_string.h:40
@ FONTO_HEADING
Definition gui_string.h:68
@ FONTO_DEFAULT
Definition gui_string.h:64
@ FONTO_ATTENTION
Definition gui_string.h:66
@ FONTO_MAX
Definition gui_string.h:70
#define create_utf8_from_char_fonto(string_in, fonto)
Definition gui_string.h:107
SDL_Color * get_tech_color(Tech_type_id tech_id)
SDL_Surface * get_tech_icon(Tech_type_id tech)
static SDL_Surface * get_government_surface(const struct government *gov)
static SDL_Surface * get_building_surface(const struct impr_type *pimprove)
static SDL_Surface * get_unittype_surface(const struct unit_type *punittype, enum direction8 facing)
void helptext_advance(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, int i)
Definition helpdata.c:3115
char * helptext_building(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct impr_type *pimprove)
Definition helpdata.c:1316
char * helptext_unit(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct unit_type *utype)
Definition helpdata.c:1763
help_page_type
Definition helpdlg_g.h:20
@ HELP_ANY
Definition helpdlg_g.h:20
@ HELP_LAST
Definition helpdlg_g.h:24
@ HELP_IMPROVEMENT
Definition helpdlg_g.h:20
@ HELP_UNIT
Definition helpdlg_g.h:20
@ HELP_TECH
Definition helpdlg_g.h:21
const struct impr_type * valid_improvement(const struct impr_type *pimprove)
struct impr_type * improvement_by_number(const Impr_type_id id)
int impr_base_build_shield_cost(const struct impr_type *pimprove)
Impr_type_id improvement_number(const struct impr_type *pimprove)
bool is_wonder(const struct impr_type *pimprove)
bool improvement_has_flag(const struct impr_type *pimprove, enum impr_flag_id flag)
const char * improvement_name_translation(const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define log_debug(message,...)
Definition log.h:115
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
const char * move_points_text(int mp, bool reduce)
Definition movement.c:973
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
#define MIN(x, y)
Definition shared.h:55
#define MAX(x, y)
Definition shared.h:54
int step
Definition specpq.h:92
struct widget * active_widget_list
Definition widget.h:186
struct widget * end_widget_list
Definition widget.h:182
struct widget * begin_widget_list
Definition widget.h:181
struct widget * begin_active_widget_list
Definition widget.h:184
struct widget * end_active_widget_list
Definition widget.h:185
struct scroll_bar * scroll
Definition widget.h:187
struct connection conn
Definition client_main.h:96
struct player * playing
Definition connection.h:156
int value
Definition widget.h:105
SDL_Surface * surface
Definition graphics.h:229
struct requirement_vector obsolete_by
Definition improvement.h:76
struct requirement_vector reqs
Definition improvement.h:75
Definition climisc.h:82
struct widget * up_left_button
SDL_Event event
Definition graphics.h:217
struct widget * targets[6]
Definition helpdlg.c:55
struct widget * sub_req[4]
Definition helpdlg.c:56
struct widget * dock
Definition helpdlg.c:57
bool show_tree
Definition helpdlg.c:58
struct widget * sub_targets[6]
Definition helpdlg.c:55
struct widget * requirement_button[2]
Definition helpdlg.c:56
bool show_full_tree
Definition helpdlg.c:59
int pop_cost
Definition unittype.h:493
int defense_strength
Definition unittype.h:496
int firepower
Definition unittype.h:506
const struct unit_type * obsoleted_by
Definition unittype.h:510
int vision_radius_sq
Definition unittype.h:503
int move_rate
Definition unittype.h:497
struct advance * require_advance
Definition unittype.h:500
int upkeep[O_LAST]
Definition unittype.h:519
int attack_strength
Definition unittype.h:495
int happy_cost
Definition unittype.h:518
struct widget * dock
Definition helpdlg.c:65
struct widget * requirement_button
Definition helpdlg.c:64
struct widget * obsolete_by_button
Definition helpdlg.c:63
Uint8 style
Definition gui_string.h:53
SDL_Color fgcol
Definition gui_string.h:57
struct widget * next
Definition widget.h:113
void * ptr
Definition widget.h:133
utf8_str * info_label
Definition widget.h:122
SDL_Keycode key
Definition widget.h:153
union widget::@214 data
struct gui_layer * dst
Definition widget.h:116
struct widget * prev
Definition widget.h:114
int(* action)(struct widget *)
Definition widget.h:157
struct container * cont
Definition widget.h:127
Uint16 mod
Definition widget.h:154
utf8_str * string_utf8
Definition widget.h:121
SDL_Rect area
Definition widget.h:149
Uint16 id
Definition widget.h:155
SDL_Rect size
Definition widget.h:145
SDL_Surface * theme2
Definition widget.h:119
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:995
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
const char * advance_name_translation(const struct advance *padvance)
Definition tech.c:290
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
Tech_type_id advance_required(const Tech_type_id tech, enum tech_req require)
Definition tech.c:121
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#define A_NEVER
Definition tech.h:51
#define advance_index_iterate_end
Definition tech.h:248
@ AR_TWO
Definition tech.h:112
@ AR_ONE
Definition tech.h:111
#define A_FIRST
Definition tech.h:44
#define A_NONE
Definition tech.h:43
#define advance_index_iterate(_start, _index)
Definition tech.h:244
SDL_Surface * theme_get_background(const struct theme *t, enum theme_background background)
@ BACKGROUND_HELPDLG
@ COLOR_THEME_HELPDLG_FRAME
Definition themecolors.h:86
@ COLOR_THEME_HELPDLG_TEXT
Definition themecolors.h:90
@ COLOR_THEME_HELPDLG_LINE3
Definition themecolors.h:89
@ COLOR_THEME_CITYDLG_LUX
Definition themecolors.h:59
@ COLOR_THEME_HELPDLG_LINE
Definition themecolors.h:87
@ COLOR_THEME_HELPDLG_LINE2
Definition themecolors.h:88
struct theme * active_theme
Definition themespec.c:154
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1520
Unit_type_id utype_count(void)
Definition unittype.c:80
struct unit_type * utype_by_number(const Unit_type_id id)
Definition unittype.c:112
Unit_type_id utype_number(const struct unit_type *punittype)
Definition unittype.c:100
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1612
#define unit_type_iterate(_p)
Definition unittype.h:841
#define unit_type_iterate_end
Definition unittype.h:848
#define U_NOT_OBSOLETED
Definition unittype.h:509
void add_to_gui_list(Uint16 id, struct widget *gui)
Definition widget.c:585
void del_group_of_widgets_from_gui_list(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:862
void show_group(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:933
void hide_group(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:914
void widget_add_as_prev(struct widget *new_widget, struct widget *add_dock)
Definition widget.c:601
int setup_vertical_widgets_position(int step, Sint16 start_x, Sint16 start_y, Uint16 w, Uint16 h, struct widget *begin, struct widget *end)
Definition widget.c:1050
Uint16 redraw_group(const struct widget *begin_group_widget_list, const struct widget *end_group_widget_list, int add_to_update)
Definition widget.c:719
void popdown_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:982
static void widget_set_position(struct widget *pwidget, int x, int y)
Definition widget.h:266
#define MAX_ID
Definition widget.h:38
@ FC_WS_DISABLED
Definition widget.h:99
@ FC_WS_NORMAL
Definition widget.h:96
static void widget_flush(struct widget *pwidget)
Definition widget.h:291
void set_wstate(struct widget *pwidget, enum widget_state state)
Definition widget_core.c:36
@ WF_WIDGET_HAS_INFO_LABEL
Definition widget.h:88
@ WF_FREE_DATA
Definition widget.h:78
@ WF_SELECT_WITHOUT_BAR
Definition widget.h:89
@ WF_RESTORE_BACKGROUND
Definition widget.h:85
@ WF_HIDDEN
Definition widget.h:68
@ WF_FREE_THEME
Definition widget.h:72
static void widget_resize(struct widget *pwidget, int w, int h)
Definition widget.h:271
void set_wflag(struct widget *pwidget, enum widget_flag flag)
Definition widget_core.c:54
#define create_themeicon_button_from_chars_fonto(icon_theme, pdest, char_string, fonto, flags)
struct widget * create_themeicon(SDL_Surface *icon_theme, struct gui_layer *pdest, Uint32 flags)
struct widget * create_icon2(SDL_Surface *icon, struct gui_layer *pdest, Uint32 flags)
struct widget * create_iconlabel(SDL_Surface *icon, struct gui_layer *pdest, utf8_str *pstr, Uint32 flags)
#define create_iconlabel_from_chars_fonto(picon, pdest, chars, fonto, flags)
void setup_vertical_scrollbar_area(struct scroll_bar *scroll, Sint16 start_x, Sint16 start_y, Uint16 height, bool swap_start_x)
Uint32 create_vertical_scrollbar(struct advanced_dialog *dlg, Uint8 step, Uint8 active, bool create_scrollbar, bool create_buttons)
#define hide_scrollbar(scrollbar)
#define show_scrollbar(scrollbar)
int resize_window(struct widget *pwindow, SDL_Surface *bcgd, SDL_Color *pcolor, Uint16 new_w, Uint16 new_h)
struct widget * create_window_skeleton(struct gui_layer *pdest, utf8_str *title, Uint32 flags)