Freeciv-3.3
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
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
279 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
280
281 /* Background template for entries in scroll list */
284
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 */
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);
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
317
318 if (impr_type_count++ >= 10) {
320 }
321
323
325
329
330 if (impr_type_count > 10) {
333 }
334
335 /* Toggle techs list button */
337 current_theme->up_icon,
338 pwindow->dst,
339 _("Improvements"),
340 FONTO_DEFAULT, 0);
341#if 0
343 if (store->show_tree) {
345 }
346#endif
347
350
352
353 dock = list_toggle_button;
354 store->dock = dock;
355 } else {
356 created = FALSE;
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
373
377 adj_size(48), 1, TRUE, TRUE),
378 pwindow->dst,
381
385
387 sprintf(buffer, "%s %d", _("Base Cost:"),
390 buffer,
391 FONTO_ATTENTION, 0);
392 cost_label->id = ID_LABEL;
395
396 if (!is_wonder(pimpr_type)) {
397 sprintf(buffer, "%s %d", _("Upkeep:"), pimpr_type->upkeep);
399 buffer,
400 FONTO_ATTENTION, 0);
404 }
405 }
406
407 /* Requirement */
409 _("Requirement:"),
410 FONTO_ATTENTION, 0);
414
415 /* FIXME: this should show ranges, negated reqs, and all the reqs.
416 * Currently it's limited to 1 req. */
418 if (!preq->present) {
419 continue;
420 }
423 universal_name_translation(&preq->source, buffer, sizeof(buffer)),
426 if (preq->source.kind != VUT_ADVANCE) {
427 break; /* FIXME */
428 }
429 requirement_label2->id = MAX_ID - advance_number(preq->source.value.advance);
430 requirement_label2->string_utf8->fgcol
431 = *get_tech_color(advance_number(preq->source.value.advance));
434 break;
436
437 if (requirement_label2 == NULL) {
439 Q_("?req:None"),
440 FONTO_ATTENTION, 0);
442 }
443
447
448 /* Obsolete by */
450 _("Obsolete by:"),
451 FONTO_ATTENTION, 0);
455
457 if (pobs->source.kind == VUT_ADVANCE) {
458 obsTech = pobs->source.value.advance;
459 break;
460 }
462
463 if (obsTech == NULL) {
465 _("Never"),
466 FONTO_ATTENTION, 0);
468 } else {
475 obsolete_by_label2->string_utf8->fgcol
479 }
483
484 /* Helptext */
485 start_x = (area.x + 1 + scrollbar_width + help_dlg->end_active_widget_list->size.w + adj_size(20));
486
487 buffer[0] = '\0';
488 helptext_building(buffer, sizeof(buffer), client.conn.playing, NULL,
489 pimpr_type);
490 if (buffer[0] != '\0') {
492
497 text = TRUE;
498 }
499
501
502 /* --------------------------------------------------------- */
503 if (created) {
505 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
506 FREESURFACE(surf);
507 }
508
509 area = pwindow->area;
510
511 widget_set_position(pwindow,
512 (main_window_width() - pwindow->size.w) / 2,
513 (main_window_height() - pwindow->size.h) / 2);
514
515 /* Exit button */
516 close_button = pwindow->prev;
517 widget_set_position(close_button,
518 area.x + area.w - close_button->size.w - 1,
519 pwindow->size.y + adj_size(2));
520
521 /* List toggle button */
522 list_toggle_button = store->dock;
524
525 /* List entries */
527 area.y + list_toggle_button->size.h, 0, 0,
530
531 /* Scrollbar */
532 if (help_dlg->scroll) {
534 area.x, area.y + list_toggle_button->size.h,
535 h, FALSE);
536 }
537 }
538
539 impr_name_label = store->dock->prev;
540 widget_set_position(impr_name_label, start_x, area.y + adj_size(16));
541
542 start_y = impr_name_label->size.y + impr_name_label->size.h + adj_size(10);
543
547 if (!is_wonder(pimpr_type)) {
548 upkeep_label = cost_label->prev;
550 cost_label->size.x + cost_label->size.w + adj_size(20),
551 start_y);
552 }
553 start_y += cost_label->size.h;
554 }
555
558
561 requirement_label->size.x + requirement_label->size.w + adj_size(5),
562 start_y);
563
564 if (store->obsolete_by_button) {
567 requirement_label2->size.x + requirement_label2->size.w + adj_size(10),
568 start_y);
569
572 obsolete_by_label->size.x + obsolete_by_label->size.w + adj_size(5),
573 start_y);
574
575 start_y += obsolete_by_label2->size.h;
576 }
577
578 start_y += adj_size(30);
579
580 if (text) {
582 }
583
585}
586
587/**********************************************************************/
590static int change_unit_callback(struct widget *pwidget)
591{
593 popup_unit_info(MAX_ID - pwidget->id);
594 }
595
596 return -1;
597}
598
599/**********************************************************************/
602static void redraw_unit_info_dlg(void)
603{
604 SDL_Color bg_color = {255, 255, 255, 64};
605 struct widget *pwindow = help_dlg->end_widget_list;
606 struct units_buttons *store = (struct units_buttons *)pwindow->data.ptr;
607 SDL_Rect dst;
608
609 redraw_group(pwindow->prev, pwindow, FALSE);
610
611 dst.x = store->dock->prev->size.x - adj_size(10);
612 dst.y = store->dock->prev->size.y - adj_size(10);
613 dst.w = pwindow->size.w - (dst.x - pwindow->size.x) - adj_size(10);
614 dst.h = pwindow->size.h - (dst.y - pwindow->size.y) - adj_size(10);
615
616 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
617
618 create_frame(pwindow->dst->surface,
619 dst.x, dst.y, dst.w, dst.h,
621
622 /*------------------------------------- */
624 widget_flush(pwindow);
625}
626
627/**********************************************************************/
631{
632 SDL_Color bg_color = {255, 255, 255, 128};
633 struct widget *pwindow;
634 struct units_buttons *store;
635 struct widget *close_button = NULL;
637 struct widget *unit_button = NULL;
638 struct widget *unit_name_label = NULL;
639 struct widget *unit_info_label = NULL;
640 struct widget *requirement_label = NULL;
642 struct widget *obsolete_by_label = NULL;
644 struct widget *help_text_label = NULL;
645 struct widget *dock;
647 utf8_str *pstr;
648 SDL_Surface *surf;
649 int h, start_x, start_y, utype_count;
650 bool created, text = FALSE;
651 int scrollbar_width = 0;
652 struct unit_type *punittype;
653 char buffer[bufsz];
654 SDL_Rect area;
655 struct advance *req;
656
659 }
660
661 /* Create new dialog if it doesn't exist yet */
662 if (!help_dlg) {
663 SDL_Surface *background_tmpl, *background, *unit_name, *icon;
664 SDL_Rect dst;
665
667 created = TRUE;
668
669 /* Create dialog */
670 help_dlg = fc_calloc(1, sizeof(struct advanced_dialog));
671 store = fc_calloc(1, sizeof(struct units_buttons));
672
673 /* Create window */
675 title->style |= TTF_STYLE_BOLD;
676
679 set_wstate(pwindow , FC_WS_NORMAL);
680 pwindow->data.ptr = (void *)store;
681 add_to_gui_list(ID_WINDOW, pwindow);
682
683 help_dlg->end_widget_list = pwindow;
684
685 area = pwindow->area;
686
687 /* ------------------ */
688
689 /* Close button */
690 close_button = create_themeicon(current_theme->small_cancel_icon,
691 pwindow->dst,
694 close_button->info_label
695 = create_utf8_from_char_fonto(_("Close Dialog (Esc)"), FONTO_ATTENTION);
696 close_button->action = exit_help_dlg_callback;
697 set_wstate(close_button, FC_WS_NORMAL);
698 close_button->key = SDLK_ESCAPE;
699
700 add_to_gui_list(ID_BUTTON, close_button);
701
702 /* ------------------ */
703 dock = close_button;
704
705 /* --- Create scrollable unit list on the left side ---*/
706
708 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
709
710 /* Background template for entries in scroll list */
713
715 0, 0, background_tmpl->w - 1, background_tmpl->h - 1,
717
718 utype_count = 0;
720
721 /* Copy background surface */
722 background = copy_surface(background_tmpl);
723
724 /* Blit unit name */
727 dst.x = adj_size(35) + (background->w - unit_name->w - adj_size(35)) / 2;
728 dst.y = (background->h - unit_name->h) / 2;
729 alphablit(unit_name, NULL, background, &dst, 255);
731
732 /* Blit unit icon */
734 adj_size(36), adj_size(36), 1, TRUE, TRUE);
735 dst.x = (adj_size(35) - icon->w) / 2;
736 dst.y = (background->h - icon->h) / 2;
737 alphablit(icon, NULL, background, &dst, 255);
738 FREESURFACE(icon);
739
740 unit_button = create_icon2(background, pwindow->dst,
742
746
747 if (utype_count++ >= 10) {
749 }
750
752
754
758
759 if (utype_count > 10) {
762 }
763
764 /* Toggle techs list button */
766 current_theme->up_icon,
767 pwindow->dst,
768 _("Units"),
769 FONTO_DEFAULT, 0);
770#if 0
772 if (store->show_tree) {
774 }
775#endif
776
779
781
782 dock = list_toggle_button;
783 store->dock = dock;
784 } else {
785 created = FALSE;
787 pwindow = help_dlg->end_widget_list;
788 store = (struct units_buttons *)pwindow->data.ptr;
789 dock = store->dock;
790
791 area = pwindow->area;
792
793 /* Delete any previous list entries */
796 dock->prev);
798 }
799 }
800
807
811
812 {
813 char buf[2048];
814
815 fc_snprintf(buf, sizeof(buf), "%s %d %s",
817 PL_("shield", "shields", utype_build_shield_cost_base(punittype)));
818
819 if (punittype->pop_cost) {
820 cat_snprintf(buf, sizeof(buf), " %d %s",
821 punittype->pop_cost, PL_("citizen", "citizens",
822 punittype->pop_cost));
823 }
824
825 cat_snprintf(buf, sizeof(buf), " %s", _("Upkeep:"));
826
827 if (punittype->upkeep[O_SHIELD]) {
828 cat_snprintf(buf, sizeof(buf), " %d %s",
829 punittype->upkeep[O_SHIELD], PL_("shield", "shields",
830 punittype->upkeep[O_SHIELD]));
831 }
832 if (punittype->upkeep[O_FOOD]) {
833 cat_snprintf(buf, sizeof(buf), " %d %s",
834 punittype->upkeep[O_FOOD], PL_("food", "foods",
835 punittype->upkeep[O_FOOD]));
836 }
837 if (punittype->upkeep[O_GOLD]) {
838 cat_snprintf(buf, sizeof(buf), " %d %s",
839 punittype->upkeep[O_GOLD], PL_("gold", "golds",
840 punittype->upkeep[O_GOLD]));
841 }
842 if (punittype->happy_cost) {
843 cat_snprintf(buf, sizeof(buf), " %d %s",
844 punittype->happy_cost, PL_("citizen", "citizens",
845 punittype->happy_cost));
846 }
847
848 cat_snprintf(buf, sizeof(buf), "\n%s %d %s %d %s %s\n%s %d %s %d %s %d",
849 _("Attack:"), punittype->attack_strength,
850 _("Defense:"), punittype->defense_strength,
851 _("Move:"), move_points_text(punittype->move_rate, TRUE),
852 _("Vision:"), punittype->vision_radius_sq,
853 _("Firepower:"), punittype->firepower,
854 _("Hitpoints:"), punittype->hp);
855
857 FONTO_ATTENTION, 0);
861 }
862
863 /* Requirement */
865 _("Requirement:"),
866 FONTO_ATTENTION, 0);
870
872
873 if (advance_number(req) == A_NONE) {
875 Q_("?tech:None"),
876 FONTO_ATTENTION, 0);
878 } else {
880
887 requirement_label2->string_utf8->fgcol = *get_tech_color(req_id);
890 }
894
895 /* Obsolete by */
897 _("Obsolete by:"),
898 FONTO_ATTENTION, 0);
902
903 if (punittype->obsoleted_by == U_NOT_OBSOLETED) {
905 Q_("?utype:None"),
906 FONTO_ATTENTION, 0);
908 } else {
909 const struct unit_type *utype = punittype->obsoleted_by;
910 struct advance *obs_req = utype_primary_tech_req(utype);
911
917 obsolete_by_label2->string_utf8->fgcol
922 }
924 dock = obsolete_by_label2;
926
927 /* Helptext */
928 start_x = (area.x + 1 + scrollbar_width + help_dlg->active_widget_list->size.w + adj_size(20));
929
930 buffer[0] = '\0';
931 helptext_unit(buffer, sizeof(buffer), client.conn.playing, "", utype_by_number(type_id),
932 TRUE);
933 if (buffer[0] != '\0') {
935
940 text = TRUE;
941 }
942
944
945 /* --------------------------------------------------------- */
946 if (created) {
947
949 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
950 FREESURFACE(surf);
951 }
952
953 area = pwindow->area;
954
955 widget_set_position(pwindow,
956 (main_window_width() - pwindow->size.w) / 2,
957 (main_window_height() - pwindow->size.h) / 2);
958
959 /* Exit button */
960 close_button = pwindow->prev;
961 widget_set_position(close_button,
962 area.x + area.w - close_button->size.w - 1,
963 pwindow->size.y + adj_size(2));
964
965 /* List toggle button */
966 list_toggle_button = store->dock;
968
969 /* List entries */
971 area.y + list_toggle_button->size.h, 0, 0,
974
975 /* Scrollbar */
976 if (help_dlg->scroll) {
978 area.x, area.y + list_toggle_button->size.h,
979 h, FALSE);
980 }
981 }
982
983 unit_name_label = store->dock->prev;
984 widget_set_position(unit_name_label, start_x, area.y + adj_size(16));
985
986 start_y = unit_name_label->size.y + unit_name_label->size.h + adj_size(10);
987
990
991 start_y += unit_info_label->size.h;
992
995
998 requirement_label->size.x + requirement_label->size.w + adj_size(5),
999 start_y);
1000
1003 requirement_label2->size.x + requirement_label2->size.w + adj_size(10),
1004 start_y);
1005
1008 obsolete_by_label->size.x + obsolete_by_label->size.w + adj_size(5),
1009 start_y);
1010
1011 start_y += obsolete_by_label2->size.h + adj_size(20);
1012
1013 if (text) {
1016 }
1017
1019}
1020
1021/* =============================================== */
1022/* ==================== Tech Tree ================ */
1023/* =============================================== */
1024
1025/**********************************************************************/
1028static int change_tech_callback(struct widget *pwidget)
1029{
1031 popup_tech_info(MAX_ID - pwidget->id);
1032 }
1033
1034 return -1;
1035}
1036
1037/**********************************************************************/
1040static int show_tech_tree_callback(struct widget *pwidget)
1041{
1043 struct techs_buttons *store = (struct techs_buttons *)help_dlg->end_widget_list->data.ptr;
1044
1045 store->show_tree = !store->show_tree;
1046 if (!store->show_tree) {
1047 store->show_full_tree = FALSE;
1048 store->dock->theme2 = current_theme->up_icon;
1049 }
1050 popup_tech_info(MAX_ID - store->dock->prev->id);
1051 }
1052
1053 return -1;
1054}
1055
1056/**********************************************************************/
1059static void redraw_tech_info_dlg(void)
1060{
1061 SDL_Color bg_color = {255, 255, 255, 64};
1062 struct widget *pwindow = help_dlg->end_widget_list;
1063 struct techs_buttons *store = (struct techs_buttons *)pwindow->data.ptr;
1065 utf8_str *pstr;
1066 SDL_Rect dst;
1067
1068 redraw_group(pwindow->prev, pwindow, FALSE);
1069
1070 dst.x = store->dock->prev->prev->size.x - adj_size(10);
1071 dst.y = store->dock->prev->prev->size.y - adj_size(10);
1072 dst.w = pwindow->size.w - (dst.x - pwindow->size.x) - adj_size(10);
1073 dst.h = pwindow->size.h - (dst.y - pwindow->size.y) - adj_size(10);
1074
1075 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
1076
1077 create_frame(pwindow->dst->surface,
1078 dst.x, dst.y, dst.w, dst.h,
1080
1081 /* -------------------------- */
1083 pstr->style |= TTF_STYLE_BOLD;
1084
1086 dst.x = store->dock->prev->prev->size.x;
1087 if (store->targets[0]) {
1088 dst.y = store->targets[0]->size.y - text0->h;
1089 } else {
1090 dst.y = store->dock->prev->prev->size.y
1091 + store->dock->prev->prev->size.h + adj_size(10);
1092 }
1093
1094 alphablit(text0, NULL, pwindow->dst->surface, &dst, 255);
1096
1097 if (store->sub_targets[0]) {
1098 int i;
1099
1101
1102 copy_chars_to_utf8_str(pstr, _("( with "));
1104
1107 i = 0;
1109 dst.x = store->sub_targets[i]->size.x - text0->w;
1110 dst.y = store->sub_targets[i]->size.y;
1111
1112 alphablit(text0, NULL, pwindow->dst->surface, &dst, 255);
1113 dst.x = store->sub_targets[i]->size.x + store->sub_targets[i]->size.w;
1114 dst.y = store->sub_targets[i]->size.y;
1115
1116 alphablit(text1, NULL, pwindow->dst->surface, &dst, 255);
1117 i++;
1118 }
1119
1122 }
1124
1126 widget_flush(pwindow);
1127}
1128
1129/**********************************************************************/
1133 struct widget *pwindow,
1134 struct techs_buttons *store)
1135{
1136 struct widget *pwidget;
1137 struct widget *last, *budynki;
1138 struct widget *dock = store->dock;
1140 int start_x, start_y, imp_count, unit_count, flags_count, gov_count;
1141 char buffer[bufsz];
1142 SDL_Surface *surf;
1143
1144 start_x = (pwindow->area.x + adj_size(1) + width + help_dlg->active_widget_list->size.w + adj_size(20));
1145
1146 /* Tech tree icon */
1147 pwidget = create_icon2(current_theme->tech_tree_icon, pwindow->dst,
1149
1150 set_wstate(pwidget, FC_WS_NORMAL);
1152 pwidget->id = MAX_ID - tech;
1153 widget_add_as_prev(pwidget, dock);
1154 dock = pwidget;
1155
1156 /* Tech name (heading) */
1157 pwidget
1159 pwindow->dst,
1162
1163 pwidget->id = ID_LABEL;
1164 widget_add_as_prev(pwidget, dock);
1165 dock = pwidget;
1166
1167 /* Target techs */
1168 targets_count = 0;
1170 if ((targets_count < 6)
1171 && (advance_required(aidx, AR_ONE) == tech
1172 || advance_required(aidx, AR_TWO) == tech)) {
1173 pwidget
1178 pwidget->string_utf8->fgcol = *get_tech_color(aidx);
1179 max_width = MAX(max_width, pwidget->size.w);
1180 set_wstate(pwidget, FC_WS_NORMAL);
1181 pwidget->action = change_tech_callback;
1182 pwidget->id = MAX_ID - aidx;
1183 widget_add_as_prev(pwidget, dock);
1184 dock = pwidget;
1185 store->targets[targets_count++] = pwidget;
1186 }
1188 if (targets_count < 6) {
1189 store->targets[targets_count] = NULL;
1190 }
1191
1193 if (targets_count > 0) {
1194 int sub_tech;
1195
1196 for (i = 0; i < targets_count; i++) {
1197 sub_tech = MAX_ID - store->targets[i]->id;
1198 if (advance_required(sub_tech, AR_ONE) == tech
1201 } else if (advance_required(sub_tech, AR_TWO) == tech
1204 } else {
1205 continue;
1206 }
1207 pwidget
1213 set_wstate(pwidget, FC_WS_NORMAL);
1214 pwidget->action = change_tech_callback;
1215 pwidget->id = MAX_ID - sub_tech;
1216 widget_add_as_prev(pwidget, dock);
1217 dock = pwidget;
1218 store->sub_targets[sub_targets_count++] = pwidget;
1219 }
1220 }
1221 if (sub_targets_count < 6) {
1223 }
1224
1225 /* Fill array with iprvm. icons */
1226 budynki = pwidget;
1227
1228 /* Target governments */
1229 gov_count = 0;
1230 governments_iterate(gov) {
1231 requirement_vector_iterate(&(gov->reqs), preq) {
1232 if (VUT_ADVANCE == preq->source.kind
1233 && advance_number(preq->source.value.advance) == tech) {
1234
1235 pwidget
1237 pwindow->dst,
1241 set_wstate(pwidget, FC_WS_NORMAL);
1242 pwidget->action = change_gov_callback;
1243 pwidget->id = MAX_ID - government_index(gov);
1244 widget_add_as_prev(pwidget, dock);
1245 dock = pwidget;
1246 gov_count++;
1247 }
1250
1251 /* Target improvements */
1252 imp_count = 0;
1253 improvement_iterate(pimprove) {
1254 if (valid_improvement(pimprove)) {
1255 /* FIXME: this should show ranges and all the reqs.
1256 * Currently it's limited to 1 req. */
1257 requirement_vector_iterate(&(pimprove->reqs), preq) {
1258 if (VUT_ADVANCE == preq->source.kind
1259 && advance_number(preq->source.value.advance) == tech) {
1260 surf = get_building_surface(pimprove);
1262 resize_surface_box(surf, adj_size(48), adj_size(48), 1, TRUE,
1263 TRUE),
1264 pwindow->dst,
1268 set_wstate(pwidget, FC_WS_NORMAL);
1269 if (is_wonder(pimprove)) {
1271 }
1272 pwidget->action = change_impr_callback;
1273 pwidget->id = MAX_ID - improvement_number(pimprove);
1274 widget_add_as_prev(pwidget, dock);
1275 dock = pwidget;
1276 imp_count++;
1277 }
1278
1279 break;
1281 }
1283
1284 unit_count = 0;
1289 adj_size(48), adj_size(48), 1, TRUE, TRUE),
1292 set_wstate(pwidget, FC_WS_NORMAL);
1293 pwidget->action = change_unit_callback;
1294 pwidget->id = MAX_ID - utype_number(un);
1295 widget_add_as_prev(pwidget, dock);
1296 dock = pwidget;
1297 unit_count++;
1298 }
1300
1301 buffer[0] = '\0';
1302 if (tech != A_NONE) {
1303 helptext_advance(buffer, sizeof(buffer), client.conn.playing, "", tech);
1304 }
1305 if (buffer[0] != '\0') {
1307
1309 pwidget = create_iconlabel(NULL, pwindow->dst, pstr, 0);
1310 pwidget->id = ID_LABEL;
1311 widget_add_as_prev(pwidget, dock);
1312 flags_count = 1;
1313 } else {
1314 flags_count = 0;
1315 }
1316
1317 last = pwidget;
1318 /* --------------------------------------------- */
1319
1320 /* Tree button */
1321 pwidget = store->dock->prev;
1322 pwidget->size.x = pwindow->area.x + pwindow->area.w - pwidget->size.w - adj_size(17);
1323 pwidget->size.y = pwindow->area.y + adj_size(16);
1324
1325 /* Tech label */
1326 pwidget = pwidget->prev;
1327 pwidget->size.x = start_x;
1328 pwidget->size.y = pwindow->area.y + adj_size(16);
1329 start_y = pwidget->size.y + pwidget->size.h + adj_size(30);
1330
1331 if (targets_count) {
1332 int j = 0;
1333
1334 i = 0;
1335
1336 while (i < 6 && store->targets[i]) {
1337 store->targets[i]->size.x = pwindow->size.x + start_x;
1338 store->targets[i]->size.y = start_y;
1339
1340 if (store->sub_targets[j]) {
1341 int t0 = MAX_ID - store->targets[i]->id;
1342 int t1 = MAX_ID - store->sub_targets[j]->id;
1343
1344 if (advance_required(t0, AR_ONE) == t1
1345 || advance_required(t0, AR_TWO) == t1) {
1346 store->sub_targets[j]->size.x = pwindow->size.x + start_x + max_width + 60;
1347 store->sub_targets[j]->size.y = store->targets[i]->size.y;
1348 j++;
1349 }
1350 }
1351
1352 start_y += store->targets[i]->size.h;
1353 i++;
1354 }
1355
1356 start_y += adj_size(10);
1357 }
1358 pwidget = NULL;
1359
1360 if (gov_count) {
1361 pwidget = budynki->prev;
1362 while (gov_count-- && pwidget) {
1363 pwidget->size.x = pwindow->size.x + start_x;
1364 pwidget->size.y = start_y;
1365 start_y += pwidget->size.h + adj_size(2);
1366 pwidget = pwidget->prev;
1367 }
1368 }
1369
1370 if (imp_count) {
1371 if (!pwidget) {
1372 pwidget = budynki->prev;
1373 }
1374 while (imp_count-- && pwidget) {
1375 pwidget->size.x = pwindow->size.x + start_x;
1376 pwidget->size.y = start_y;
1377 start_y += pwidget->size.h + adj_size(2);
1378 pwidget = pwidget->prev;
1379 }
1380 }
1381
1382 if (unit_count) {
1383 if (!pwidget) {
1384 pwidget = budynki->prev;
1385 }
1386 while (unit_count-- && pwidget) {
1387 pwidget->size.x = pwindow->size.x + start_x;
1388 pwidget->size.y = start_y;
1389 start_y += pwidget->size.h + adj_size(2);
1390 pwidget = pwidget->prev;
1391 }
1392 }
1393
1394 if (flags_count) {
1395 if (!pwidget) {
1396 pwidget = budynki->prev;
1397 }
1398 while (flags_count-- && pwidget) {
1399 pwidget->size.x = pwindow->size.x + start_x;
1400 pwidget->size.y = start_y;
1401 start_y += pwidget->size.h + adj_size(2);
1402 pwidget = pwidget->prev;
1403 }
1404 }
1405
1406 return last;
1407}
1408
1409/**********************************************************************/
1412static void redraw_tech_tree_dlg(void)
1413{
1415 SDL_Color bg_color = {255, 255, 255, 64};
1416 struct widget *pwindow = help_dlg->end_widget_list;
1417 struct widget *sub0, *sub1;
1418 struct techs_buttons *store = (struct techs_buttons *)pwindow->data.ptr;
1419 struct widget *ptech = store->dock->prev;
1420 int i,j, tech, count;
1421 int step;
1422 int mod;
1423 SDL_Rect dst;
1424
1425 /* Redraw Window with exit button */
1426 redraw_group(pwindow->prev, pwindow, FALSE);
1427
1428 dst.x = pwindow->area.x + pwindow->area.w - adj_size(459) - adj_size(7);
1429 dst.y = pwindow->area.y + adj_size(6);
1430 dst.w = pwindow->area.w - (dst.x - pwindow->area.x) - adj_size(10);
1431 dst.h = pwindow->area.h - (dst.y - pwindow->area.y) - adj_size(10);
1432
1433 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
1434
1435 create_frame(pwindow->dst->surface,
1436 dst.x, dst.y, dst.w, dst.h,
1438
1439 /* Draw req arrows */
1440 i = 0;
1441 while (i < 4 && store->sub_req[i]) {
1442 i++;
1443 }
1444 count = i;
1445
1446 i = 0;
1447 while (i < 2 && store->requirement_button[i]) {
1448 tech = MAX_ID - store->requirement_button[i]->id;
1449
1450 /* Find sub req's */
1451 if (i) {
1452 sub0 = NULL;
1453 for (j = count - 1; j >= 0; j--) {
1454 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_ONE)) {
1455 sub0 = store->sub_req[j];
1456 break;
1457 }
1458 }
1459
1460 sub1 = NULL;
1461 for (j = count - 1; j >= 0; j--) {
1462 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_TWO)) {
1463 sub1 = store->sub_req[j];
1464 break;
1465 }
1466 }
1467 } else {
1468 sub0 = NULL;
1469 for (j = 0; j < 4 && store->sub_req[j]; j++) {
1470 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_ONE)) {
1471 sub0 = store->sub_req[j];
1472 break;
1473 }
1474 }
1475
1476 sub1 = NULL;
1477 for (j = 0; j < 4 && store->sub_req[j]; j++) {
1478 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_TWO)) {
1479 sub1 = store->sub_req[j];
1480 break;
1481 }
1482 }
1483 }
1484
1485 /* Draw main Arrow */
1487 store->requirement_button[i]->size.x + store->requirement_button[i]->size.w,
1488 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1489 ptech->size.x,
1490 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1491 line_color);
1492
1493 /* Draw sub req arrows */
1494 if (sub0 || sub1) {
1496 store->requirement_button[i]->size.x - adj_size(10),
1497 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1498 store->requirement_button[i]->size.x ,
1499 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1500 line_color);
1501 }
1502
1503 if (sub0) {
1505 store->requirement_button[i]->size.x - adj_size(10),
1506 sub0->size.y + sub0->size.h / 2,
1507 store->requirement_button[i]->size.x - adj_size(10),
1508 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1509 line_color);
1511 sub0->size.x + sub0->size.w,
1512 sub0->size.y + sub0->size.h / 2,
1513 store->requirement_button[i]->size.x - adj_size(10),
1514 sub0->size.y + sub0->size.h / 2,
1515 line_color);
1516 }
1517
1518 if (sub1) {
1520 store->requirement_button[i]->size.x - adj_size(10),
1521 sub1->size.y + sub1->size.h / 2,
1522 store->requirement_button[i]->size.x - adj_size(10),
1523 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1524 line_color);
1526 sub1->size.x + sub1->size.w,
1527 sub1->size.y + sub1->size.h / 2,
1528 store->requirement_button[i]->size.x - adj_size(10),
1529 sub1->size.y + sub1->size.h / 2,
1530 line_color);
1531 }
1532 i++;
1533 }
1534
1535 i = 0;
1536 while (i < 6 && store->targets[i]) {
1537 i++;
1538 }
1539 count = i;
1540
1541 if (count > 4) {
1542 mod = 3;
1543 } else {
1544 mod = 2;
1545 }
1546
1547 for (i = 0; i < count; i++) {
1548 tech = MAX_ID - store->targets[i]->id;
1549 step = ptech->size.h / (count + 1);
1550
1551 switch ((i % mod)) {
1552 case 2:
1554 break;
1555 case 1:
1557 break;
1558 default:
1560 break;
1561 }
1562
1563 /* Find sub reqs */
1564 if (advance_required(tech, AR_ONE) == MAX_ID - ptech->id) {
1565 sub0 = ptech;
1566 } else {
1567 sub0 = NULL;
1568 for (j = 0; j < 6 && store->sub_targets[j]; j++) {
1569 if (MAX_ID - store->sub_targets[j]->id == advance_required(tech, AR_ONE)) {
1570 sub0 = store->sub_targets[j];
1571 break;
1572 }
1573 }
1574 }
1575
1576 if (advance_required(tech, AR_TWO) == MAX_ID - ptech->id) {
1577 sub1 = ptech;
1578 } else {
1579 sub1 = NULL;
1580 for (j = 0; j < 6 && store->sub_targets[j]; j++) {
1581 if (MAX_ID - store->sub_targets[j]->id == advance_required(tech, AR_TWO)) {
1582 sub1 = store->sub_targets[j];
1583 break;
1584 }
1585 }
1586 }
1587
1588 /* Draw sub targets arrows */
1589 if (sub0 || sub1) {
1590 create_line(store->targets[i]->dst->surface,
1591 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1592 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1593 store->targets[i]->size.x ,
1594 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1595 line_color);
1596 }
1597
1598 if (sub0) {
1599 int y;
1600
1601 if (sub0 == ptech) {
1602 y = sub0->size.y + step * (i + 1);
1603 } else {
1604 y = sub0->size.y + sub0->size.h / 2;
1605 }
1606
1607 create_line(store->targets[i]->dst->surface,
1608 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1609 y,
1610 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1611 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1612 line_color);
1613 create_line(store->targets[i]->dst->surface,
1614 sub0->size.x + sub0->size.w,
1615 y,
1616 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1617 y,
1618 line_color);
1619 }
1620
1621 if (sub1) {
1622 int y;
1623
1624 if (sub1 == ptech) {
1625 y = sub1->size.y + step * (i + 1);
1626 } else {
1627 y = sub1->size.y + sub1->size.h / 2;
1628 }
1629
1630 create_line(store->targets[i]->dst->surface,
1631 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1632 y,
1633 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1634 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1635 line_color);
1636 create_line(store->targets[i]->dst->surface,
1637 sub1->size.x + sub1->size.w,
1638 y,
1639 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1640 y,
1641 line_color);
1642 }
1643 }
1644
1645 /* Redraw rest */
1647
1648 widget_flush(pwindow);
1649}
1650
1651/**********************************************************************/
1655{
1657 struct techs_buttons *store = (struct techs_buttons *)help_dlg->end_widget_list->data.ptr;
1658
1659 if (store->show_full_tree) {
1660 pwidget->theme2 = current_theme->up_icon;
1661 } else {
1662 pwidget->theme2 = current_theme->down_icon;
1663 }
1664 store->show_full_tree = !store->show_full_tree;
1665 popup_tech_info(MAX_ID - store->dock->prev->id);
1666 }
1667
1668 return -1;
1669}
1670
1671/**********************************************************************/
1675 struct widget *pwindow,
1676 struct techs_buttons *store)
1677{
1679 struct widget *pwidget;
1680 struct widget *ptech;
1681 utf8_str *pstr;
1682 SDL_Surface *surf;
1683 struct widget *dock = store->dock;
1684
1686 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
1687
1690 pwidget = create_icon2(surf, pwindow->dst,
1692
1693 set_wstate(pwidget, FC_WS_NORMAL);
1695 pwidget->id = MAX_ID - tech;
1696 widget_add_as_prev(pwidget, dock);
1697 ptech = pwidget;
1698 dock = pwidget;
1699
1700 req_count = 0;
1701 for (i = AR_ONE; i <= AR_TWO; i++) {
1704
1705 if (NULL != vap && A_NONE != ar) {
1708 pwidget = create_icon2(surf, pwindow->dst,
1710 set_wstate(pwidget, FC_WS_NORMAL);
1711 pwidget->action = change_tech_callback;
1712 pwidget->id = MAX_ID - ar;
1713 widget_add_as_prev(pwidget, dock);
1714 dock = pwidget;
1715 store->requirement_button[req_count++] = pwidget;
1716 }
1717 }
1718
1719 sub_req_count = 0;
1720
1721 if (store->show_full_tree && req_count > 0) {
1722 int j, sub_tech;
1723
1724 for (j = 0; j < req_count; j++) {
1725 sub_tech = MAX_ID - store->requirement_button[j]->id;
1726 for (i = AR_ONE; i <= AR_TWO; i++) {
1729
1730 if (NULL != vap && A_NONE != ar) {
1733 pwidget = create_icon2(surf, pwindow->dst,
1735 set_wstate(pwidget, FC_WS_NORMAL);
1736 pwidget->action = change_tech_callback;
1737 pwidget->id = MAX_ID - ar;
1738 widget_add_as_prev(pwidget, dock);
1739 dock = pwidget;
1740 store->sub_req[sub_req_count++] = pwidget;
1741 }
1742 }
1743 }
1744 }
1745
1746 if (sub_req_count < 4) {
1747 store->sub_req[sub_req_count] = NULL;
1748 }
1749
1750 targets_count = 0;
1752 if ((targets_count < 6)
1753 && (advance_required(aidx, AR_ONE) == tech
1754 || advance_required(aidx, AR_TWO) == tech)) {
1757 pwidget = create_icon2(surf, pwindow->dst,
1759
1760 set_wstate(pwidget, FC_WS_NORMAL);
1761 pwidget->action = change_tech_callback;
1762 pwidget->id = MAX_ID - aidx;
1763 widget_add_as_prev(pwidget, dock);
1764 dock = pwidget;
1765 store->targets[targets_count++] = pwidget;
1766 }
1768 if (targets_count < 6) {
1769 store->targets[targets_count] = NULL;
1770 }
1771
1773 if (targets_count > 0) {
1774 int sub_tech;
1775
1776 for (i = 0; i < targets_count; i++) {
1777 sub_tech = MAX_ID - store->targets[i]->id;
1778 if (advance_required(sub_tech, AR_ONE) == tech
1781 } else if (advance_required(sub_tech, AR_TWO) == tech
1784 } else {
1785 continue;
1786 }
1787
1790 pwidget = create_icon2(surf, pwindow->dst,
1792 set_wstate(pwidget, FC_WS_NORMAL);
1793 pwidget->action = change_tech_callback;
1794 pwidget->id = MAX_ID - sub_tech;
1795 widget_add_as_prev(pwidget, dock);
1796 dock = pwidget;
1797 store->sub_targets[sub_targets_count++] = pwidget;
1798 }
1799 }
1800 if (sub_targets_count < 6) {
1802 }
1803
1805
1806 /* ------------------------------------------ */
1807 if (sub_req_count > 0) {
1808 w = (adj_size(20) + store->sub_req[0]->size.w) * 2;
1809 w += (pwindow->size.w - (20 + store->sub_req[0]->size.w + w + ptech->size.w)) / 2;
1810 } else {
1811 if (req_count > 0) {
1812 w = (pwindow->area.x + 1
1813 + width + store->requirement_button[0]->size.w * 2 + adj_size(20));
1814 w += (pwindow->size.w - ((adj_size(20) + store->requirement_button[0]->size.w)
1815 + w + ptech->size.w)) / 2;
1816 } else {
1817 w = (pwindow->size.w - ptech->size.w) / 2;
1818 }
1819 }
1820
1821 ptech->size.x = pwindow->size.x + w;
1822 ptech->size.y = pwindow->area.y + (pwindow->area.h - ptech->size.h) / 2;
1823
1824 if (req_count > 0) {
1825 h = (req_count == 1 ? store->requirement_button[0]->size.h :
1826 req_count * (store->requirement_button[0]->size.h + adj_size(80)) - adj_size(80));
1827 h = ptech->size.y + (ptech->size.h - h) / 2;
1828 for (i = 0; i < req_count; i++) {
1829 store->requirement_button[i]->size.x
1830 = ptech->size.x - adj_size(20) - store->requirement_button[i]->size.w;
1831 store->requirement_button[i]->size.y = h;
1832 h += (store->requirement_button[i]->size.h + adj_size(80));
1833 }
1834 }
1835
1836 if (sub_req_count > 0) {
1837 h = (sub_req_count == 1 ? store->sub_req[0]->size.h :
1838 sub_req_count * (store->sub_req[0]->size.h + adj_size(20)) - adj_size(20));
1839 h = ptech->size.y + (ptech->size.h - h) / 2;
1840 for (i = 0; i < sub_req_count; i++) {
1841 store->sub_req[i]->size.x
1842 = ptech->size.x - (adj_size(20) + store->sub_req[i]->size.w) * 2;
1843 store->sub_req[i]->size.y = h;
1844 h += (store->sub_req[i]->size.h + adj_size(20));
1845 }
1846 }
1847
1848 if (targets_count > 0) {
1849 h = (targets_count == 1 ? store->targets[0]->size.h :
1850 targets_count * (store->targets[0]->size.h + adj_size(20)) - adj_size(20));
1851 h = ptech->size.y + (ptech->size.h - h) / 2;
1852 for (i = 0; i < targets_count; i++) {
1853 store->targets[i]->size.x = ptech->size.x + ptech->size.w + adj_size(20);
1854 store->targets[i]->size.y = h;
1855 h += (store->targets[i]->size.h + adj_size(20));
1856 }
1857 }
1858
1859 if (sub_targets_count > 0) {
1860 if (sub_targets_count < 3) {
1861 store->sub_targets[0]->size.x
1862 = ptech->size.x + ptech->size.w - store->sub_targets[0]->size.w;
1863 store->sub_targets[0]->size.y
1864 = ptech->size.y - store->sub_targets[0]->size.h - adj_size(10);
1865 if (store->sub_targets[1]) {
1866 store->sub_targets[1]->size.x
1867 = ptech->size.x + ptech->size.w - store->sub_targets[1]->size.w;
1868 store->sub_targets[1]->size.y = ptech->size.y + ptech->size.h + adj_size(10);
1869 }
1870 } else {
1871 if (sub_targets_count < 5) {
1872 for (i = 0; i < MIN(sub_targets_count, 4); i++) {
1873 store->sub_targets[i]->size.x
1874 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1875 if (i < 2) {
1876 store->sub_targets[i]->size.y
1877 = ptech->size.y - (store->sub_targets[i]->size.h + adj_size(5)) * (2 - i);
1878 } else {
1879 store->sub_targets[i]->size.y
1880 = ptech->size.y + ptech->size.h + adj_size(5)
1881 + (store->sub_targets[i]->size.h + adj_size(5)) * (i - 2);
1882 }
1883 }
1884 } else {
1885 h = (store->sub_targets[0]->size.h + adj_size(6));
1886 for (i = 0; i < MIN(sub_targets_count, 6); i++) {
1887 switch (i) {
1888 case 0:
1889 store->sub_targets[i]->size.x
1890 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1891 store->sub_targets[i]->size.y = ptech->size.y - h * 2;
1892 break;
1893 case 1:
1894 store->sub_targets[i]->size.x
1895 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w * 2
1896 - adj_size(10);
1897 store->sub_targets[i]->size.y = ptech->size.y - h - h / 2;
1898 break;
1899 case 2:
1900 store->sub_targets[i]->size.x
1901 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1902 store->sub_targets[i]->size.y = ptech->size.y - h;
1903 break;
1904 case 3:
1905 store->sub_targets[i]->size.x
1906 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1907 store->sub_targets[i]->size.y = ptech->size.y + ptech->size.h + adj_size(6);
1908 break;
1909 case 4:
1910 store->sub_targets[i]->size.x
1911 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1912 store->sub_targets[i]->size.y = ptech->size.y + ptech->size.h + adj_size(6) + h;
1913 break;
1914 default:
1915 store->sub_targets[i]->size.x
1916 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w * 2
1917 - adj_size(10);
1918 store->sub_targets[i]->size.y
1919 = ptech->size.y + ptech->size.h + adj_size(6) + h / 2 ;
1920 break;
1921 }
1922 }
1923 }
1924 }
1925 }
1926
1927 return pwidget;
1928}
1929
1930/**********************************************************************/
1934{
1935 struct widget *pwindow;
1936 struct techs_buttons *store;
1937 struct widget *close_button = NULL;
1938 struct widget *advance_label = NULL;
1939 struct widget *list_toggle_button = NULL;
1940 struct widget *dock;
1941 utf8_str *title;
1942 utf8_str *pstr;
1943 SDL_Surface *surf;
1944 int h, tech_count;
1945 bool created;
1946 int scrollbar_width = 0;
1947 SDL_Rect area;
1948
1949 if (current_help_dlg != HELP_TECH) {
1951 }
1952
1953 /* Create new dialog if it doesn't exist yet */
1954 if (!help_dlg) {
1956 created = TRUE;
1957
1958 /* Create dialog */
1959 help_dlg = fc_calloc(1, sizeof(struct advanced_dialog));
1960 store = fc_calloc(1, sizeof(struct techs_buttons));
1961
1962 store->show_tree = FALSE;
1963 store->show_full_tree = FALSE;
1964
1965 /* Create window */
1966 title = create_utf8_from_char_fonto(_("Help : Advances Tree"),
1968 title->style |= TTF_STYLE_BOLD;
1969
1971 pwindow->data.ptr = (void *)store;
1973 set_wstate(pwindow, FC_WS_NORMAL);
1974
1975 add_to_gui_list(ID_WINDOW, pwindow);
1976
1977 help_dlg->end_widget_list = pwindow;
1978
1979 /* ------------------ */
1980
1981 /* Close button */
1982 close_button = create_themeicon(current_theme->small_cancel_icon, pwindow->dst,
1985 close_button->info_label
1986 = create_utf8_from_char_fonto(_("Close Dialog (Esc)"), FONTO_ATTENTION);
1987 close_button->action = exit_help_dlg_callback;
1988 set_wstate(close_button, FC_WS_NORMAL);
1989 close_button->key = SDLK_ESCAPE;
1990
1991 add_to_gui_list(ID_BUTTON, close_button);
1992
1993 /* ------------------ */
1994 dock = close_button;
1995
1996 /* --- Create scrollable advance list on the left side ---*/
1998 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
1999
2000 tech_count = 0;
2003
2004 if (vap) {
2007 advance_label = create_icon2(surf, pwindow->dst,
2009
2013
2014 if (tech_count++ >= 10) {
2016 }
2017 }
2019
2021
2025
2026 if (tech_count > 10) {
2029 }
2030
2031 /* Toggle techs list button */
2033 current_theme->up_icon,
2034 pwindow->dst,
2035 _("Advances"),
2036 FONTO_DEFAULT, 0);
2038 if (store->show_tree) {
2040 }
2043
2045
2046 dock = list_toggle_button;
2047 store->dock = dock;
2048 } else {
2049 created = FALSE;
2051 pwindow = help_dlg->end_widget_list;
2052 store = (struct techs_buttons *)pwindow->data.ptr;
2053 dock = store->dock;
2054
2055 /* Delete any previous list entries */
2059 }
2060
2061 /* Show/hide techs list */
2063
2064 if (store->show_tree) {
2066 } else {
2068 }
2069
2070 if (store->show_full_tree) {
2071 /* All entries are visible without scrolling */
2075 } else {
2076 int count = help_dlg->scroll->active;
2077
2079 while (advance_label->prev != NULL && --count > 0) {
2081 }
2084 }
2085 }
2086
2087 /* --------------------------------------------------------- */
2088 if (created) {
2089
2091 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
2092 FREESURFACE(surf);
2093 }
2094
2095 area = pwindow->area;
2096
2097 widget_set_position(pwindow,
2098 (main_window_width() - pwindow->size.w) / 2,
2099 (main_window_height() - pwindow->size.h) / 2);
2100
2101 /* Exit button */
2102 close_button = pwindow->prev;
2103 widget_set_position(close_button,
2104 area.x + area.w - close_button->size.w - 1,
2105 pwindow->size.y + adj_size(2));
2106
2107 /* List toggle button */
2108 list_toggle_button = store->dock;
2109 widget_set_position(list_toggle_button, area.x, area.y);
2110
2111 /* List entries */
2113 area.y + list_toggle_button->size.h, 0, 0,
2116 /* Scrollbar */
2117 if (help_dlg->scroll) {
2119 area.x, area.y + list_toggle_button->size.h,
2120 h, FALSE);
2121 }
2122 }
2123
2124 if (store->show_tree) {
2127 } else {
2130 }
2131}
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:663
struct civclient client
char * incite_cost
Definition comments.c:76
QString current_theme
Definition fc_client.cpp:64
int Tech_type_id
Definition fc_types.h:236
int Impr_type_id
Definition fc_types.h:235
int Unit_type_id
Definition fc_types.h:241
@ O_SHIELD
Definition fc_types.h:101
@ O_FOOD
Definition fc_types.h:101
@ O_GOLD
Definition fc_types.h:101
#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:143
Government_type_id government_index(const struct government *pgovern)
Definition government.c:82
#define governments_iterate(NAME_pgov)
Definition government.h:124
#define governments_iterate_end
Definition government.h:127
GtkWidget * unit_info_label
Definition gui_main.c:152
static void create_tech_tree(int tech, int levels, GtkTreeIter *parent)
Definition helpdlg.c:226
void popdown_help_dialog(void)
Definition helpdlg.c:186
void popup_help_dialog_string(const char *item)
Definition helpdlg.c:212
void popup_help_dialog_typed(const char *item, enum help_page_type htype)
Definition helpdlg.c:196
void flush_dirty(void)
Definition mapview.c:468
const char * title
Definition repodlgs.c:1314
SDL_Color * get_theme_color(enum theme_color themecolor)
Definition colors.c:47
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:1381
SDL_Surface * copy_surface(SDL_Surface *src)
Definition graphics.c:1309
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:1350
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:1257
#define FREESURFACE(ptr)
Definition graphics.h:322
#define adj_surf(surf)
Definition graphics.h:200
#define map_rgba(format, color)
Definition graphics.h:315
@ ID_BUTTON
Definition gui_id.h:29
@ ID_LABEL
Definition gui_id.h:27
@ ID_WINDOW
Definition gui_id.h:30
#define adj_size(size)
Definition gui_main.h:141
#define PRESSED_EVENT(event)
Definition gui_main.h:71
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:93
#define SF_CENTER
Definition gui_string.h:40
@ FONTO_HEADING
Definition gui_string.h:69
@ FONTO_DEFAULT
Definition gui_string.h:65
@ FONTO_ATTENTION
Definition gui_string.h:67
@ FONTO_MAX
Definition gui_string.h:71
#define create_utf8_from_char_fonto(string_in, fonto)
Definition gui_string.h:108
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)
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:1933
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:1040
enum help_page_type current_help_dlg
Definition helpdlg.c:68
static void redraw_tech_info_dlg(void)
Definition helpdlg.c:1059
static void redraw_unit_info_dlg(void)
Definition helpdlg.c:602
static int change_tech_callback(struct widget *pwidget)
Definition helpdlg.c:1028
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:1132
void popup_impr_info(Impr_type_id impr)
Definition helpdlg.c:202
static void redraw_tech_tree_dlg(void)
Definition helpdlg.c:1412
static int help_dlg_window_callback(struct widget *pwindow)
Definition helpdlg.c:122
static int change_unit_callback(struct widget *pwidget)
Definition helpdlg.c:590
void popup_unit_info(Unit_type_id type_id)
Definition helpdlg.c:630
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:1654
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
SDL_Surface * theme_get_background(const struct theme *t, enum theme_background background)
@ BACKGROUND_HELPDLG
@ COLOR_THEME_HELPDLG_FRAME
Definition themecolors.h:87
@ COLOR_THEME_HELPDLG_TEXT
Definition themecolors.h:91
@ COLOR_THEME_HELPDLG_LINE3
Definition themecolors.h:90
@ COLOR_THEME_CITYDLG_LUX
Definition themecolors.h:60
@ COLOR_THEME_HELPDLG_LINE
Definition themecolors.h:88
@ COLOR_THEME_HELPDLG_LINE2
Definition themecolors.h:89
struct theme * active_theme
Definition themespec.c:154
void add_to_gui_list(Uint16 id, struct widget *gui)
Definition widget.c:586
void del_group_of_widgets_from_gui_list(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:863
void show_group(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:934
void hide_group(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:915
void widget_add_as_prev(struct widget *new_widget, struct widget *add_dock)
Definition widget.c:602
int setup_vertical_widgets_position(int step, Sint16 start_x, Sint16 start_y, Uint16 w, Uint16 h, struct widget *begin, struct widget *end)
Definition widget.c:1051
Uint16 redraw_group(const struct widget *begin_group_widget_list, const struct widget *end_group_widget_list, int add_to_update)
Definition widget.c:720
void popdown_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:983
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)
bool 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)
void helptext_advance(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, int i)
Definition helpdata.c:3294
char * helptext_unit(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct unit_type *utype, bool class_help)
Definition helpdata.c:1932
char * helptext_building(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct impr_type *pimprove)
Definition helpdata.c:1381
help_page_type
Definition helpdlg_g.h:20
@ HELP_ANY
Definition helpdlg_g.h:20
@ HELP_LAST
Definition helpdlg_g.h:25
@ 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 is_convert_improvement(const struct impr_type *pimprove)
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:116
#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:1016
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 sprite int int y
Definition sprite_g.h:31
struct widget * begin_active_widget_list
Definition widget.h:184
struct widget * end_widget_list
Definition widget.h:182
struct widget * end_active_widget_list
Definition widget.h:185
struct widget * active_widget_list
Definition widget.h:186
struct scroll_bar * scroll
Definition widget.h:187
struct widget * begin_widget_list
Definition widget.h:181
struct connection conn
Definition client_main.h:96
struct player * playing
Definition connection.h:151
SDL_Surface * surface
Definition graphics.h:229
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 * requirement_button[2]
Definition helpdlg.c:56
struct widget * sub_req[4]
Definition helpdlg.c:56
bool show_tree
Definition helpdlg.c:58
struct widget * dock
Definition helpdlg.c:57
struct widget * sub_targets[6]
Definition helpdlg.c:55
bool show_full_tree
Definition helpdlg.c:59
const struct unit_type * obsoleted_by
Definition unittype.h:536
struct widget * obsolete_by_button
Definition helpdlg.c:63
struct widget * requirement_button
Definition helpdlg.c:64
struct widget * dock
Definition helpdlg.c:65
SDL_Color fgcol
Definition gui_string.h:57
void * ptr
Definition widget.h:133
SDL_Keycode key
Definition widget.h:153
union widget::@223 data
SDL_Surface * theme2
Definition widget.h:119
struct widget * prev
Definition widget.h:114
struct gui_layer * dst
Definition widget.h:116
Uint16 mod
Definition widget.h:154
utf8_str * string_utf8
Definition widget.h:121
int(* action)(struct widget *)
Definition widget.h:157
SDL_Rect area
Definition widget.h:149
struct widget * next
Definition widget.h:113
utf8_str * info_label
Definition widget.h:122
Uint16 id
Definition widget.h:155
SDL_Rect size
Definition widget.h:145
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:986
#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:300
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 advance_index_iterate_end
Definition tech.h:244
@ AR_TWO
Definition tech.h:107
@ AR_ONE
Definition tech.h:106
#define A_FIRST
Definition tech.h:44
#define A_NONE
Definition tech.h:43
#define advance_index_iterate(_start, _index)
Definition tech.h:240
bool is_tech_req_for_utype(const struct unit_type *ptype, struct advance *padv)
Definition unittype.c:2730
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1474
struct advance * utype_primary_tech_req(const struct unit_type *ptype)
Definition unittype.c:2716
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:1566
#define unit_type_iterate(_p)
Definition unittype.h:862
#define unit_type_iterate_end
Definition unittype.h:869
#define U_NOT_OBSOLETED
Definition unittype.h:535