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/* SDL3 */
19#include <SDL3/SDL.h>
20
21/* utility */
22#include "fcintl.h"
23#include "log.h"
24
25/* common */
26#include "game.h"
27#include "government.h"
28#include "movement.h"
29
30/* client */
31#include "client_main.h"
32#include "helpdata.h"
33
34/* gui-sdl3 */
35#include "colors.h"
36#include "graphics.h"
37#include "gui_id.h"
38#include "gui_main.h"
39#include "gui_tilespec.h"
40#include "mapview.h"
41#include "repodlgs.h"
42#include "sprite.h"
43#include "themespec.h"
44#include "widget.h"
45
46#include "helpdlg.h"
47
48static struct advanced_dialog *help_dlg = NULL;
49
50struct techs_buttons {
51 struct widget *targets[6], *sub_targets[6];
52 struct widget *requirement_button[2], *sub_req[4];
53 struct widget *dock;
54 bool show_tree;
55 bool show_full_tree;
56};
57
58struct units_buttons {
61 struct widget *dock;
62};
63
65
66static const int bufsz = 8192;
67
68static int change_tech_callback(struct widget *pwidget);
69
70/**********************************************************************/
77
78/**********************************************************************/
89
90/**********************************************************************/
97{
98 log_debug("popup_help_dialog_typed : PORT ME");
99}
100
101/**********************************************************************/
114
115/**********************************************************************/
118static int help_dlg_window_callback(struct widget *pwindow)
119{
120 return -1;
121}
122
123/**********************************************************************/
126static int exit_help_dlg_callback(struct widget *pwidget)
127{
130 flush_dirty();
131 }
132
133 return -1;
134}
135
136/**********************************************************************/
139static int change_gov_callback(struct widget *pwidget)
140{
142 popup_gov_info(MAX_ID - pwidget->id);
143 }
144
145 return -1;
146}
147
148/**********************************************************************/
151void popup_gov_info(int gov)
152{
153}
154
155/**********************************************************************/
158static int change_impr_callback(struct widget *pwidget)
159{
161 popup_impr_info(MAX_ID - pwidget->id);
162 }
163
164 return -1;
165}
166
167/**********************************************************************/
170static void redraw_impr_info_dlg(void)
171{
172 SDL_Color bg_color = {255, 255, 255, 64};
173 struct widget *pwindow = help_dlg->end_widget_list;
174 struct units_buttons *store = (struct units_buttons *)pwindow->data.ptr;
175 SDL_Rect dst;
176
177 redraw_group(pwindow->prev, pwindow, FALSE);
178
179 dst.x = store->dock->prev->size.x - adj_size(10);
180 dst.y = store->dock->prev->size.y - adj_size(10);
181 dst.w = pwindow->size.w - (dst.x - pwindow->size.x) - adj_size(10);
182 dst.h = pwindow->size.h - (dst.y - pwindow->size.y) - adj_size(10);
183
184 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
185
186 create_frame(pwindow->dst->surface,
187 dst.x, dst.y, dst.w, dst.h,
189
190 /*------------------------------------- */
192 widget_flush(pwindow);
193}
194
195/**********************************************************************/
199{
200 SDL_Color bg_color = {255, 255, 255, 128};
201 struct widget *pwindow;
202 struct units_buttons *store;
203 struct widget *close_button = NULL;
206 struct widget *impr_name_label = NULL;
207 struct widget *cost_label = NULL;
208 struct widget *upkeep_label = NULL;
209 struct widget *requirement_label = NULL;
211 struct widget *obsolete_by_label = NULL;
213 struct widget *help_text_label = NULL;
214 struct widget *dock;
216 utf8_str *pstr;
217 SDL_Surface *surf;
218 int h, start_x, start_y, impr_type_count;
219 bool created, text = FALSE;
220 int scrollbar_width = 0;
221 struct impr_type *pimpr_type;
222 char buffer[64000];
223 SDL_Rect area;
224 struct advance *obsTech = NULL;
225
228 }
229
230 if (!help_dlg) {
231 SDL_Surface *background_tmpl, *background, *impr_name, *icon;
232 SDL_Rect dst;
233
235 created = TRUE;
236
237 /* Create dialog */
238 help_dlg = fc_calloc(1, sizeof(struct advanced_dialog));
239 store = fc_calloc(1, sizeof(struct units_buttons));
240
241 /* Create window */
242 title = create_utf8_from_char_fonto(_("Help : Improvements"),
244 title->style |= TTF_STYLE_BOLD;
245
248 set_wstate(pwindow , FC_WS_NORMAL);
249 pwindow->data.ptr = (void *)store;
250 add_to_gui_list(ID_WINDOW, pwindow);
251
252 help_dlg->end_widget_list = pwindow;
253
254 area = pwindow->area;
255 /* ------------------ */
256
257 /* Close button */
258 close_button = create_themeicon(current_theme->small_cancel_icon,
259 pwindow->dst,
262 close_button->info_label
263 = create_utf8_from_char_fonto(_("Close Dialog (Esc)"),
265 close_button->action = exit_help_dlg_callback;
266 set_wstate(close_button, FC_WS_NORMAL);
267 close_button->key = SDLK_ESCAPE;
268
269 add_to_gui_list(ID_BUTTON, close_button);
270
271 /* ------------------ */
272 dock = close_button;
273
275 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
276
277 /* Background template for entries in scroll list */
281
283 0, 0, background_tmpl->w - 1, background_tmpl->h - 1,
285
286 impr_type_count = 0;
287 improvement_iterate(pimprove) {
288
289 /* Copy background surface */
290 background = copy_surface(background_tmpl);
291
292 /* Blit improvement name */
295 dst.x = adj_size(40) + (background->w - impr_name->w - adj_size(40)) / 2;
296 dst.y = (background->h - impr_name->h) / 2;
297 alphablit(impr_name, NULL, background, &dst, 255);
299
300 /* Blit improvement icon */
302 adj_size(36), adj_size(36), 1, TRUE, TRUE);
303 dst.x = adj_size(5);
304 dst.y = (background->h - icon->h) / 2;
305 alphablit(icon, NULL, background, &dst, 255);
306 FREESURFACE(icon);
307
308 improvement_button = create_icon2(background, pwindow->dst,
310
314
315 if (impr_type_count++ >= 10) {
317 }
318
320
322
326
327 if (impr_type_count > 10) {
330 }
331
332 /* Toggle techs list button */
334 current_theme->up_icon,
335 pwindow->dst,
336 _("Improvements"),
337 FONTO_DEFAULT, 0);
338#if 0
340 if (store->show_tree) {
342 }
343#endif
344
347
349
350 dock = list_toggle_button;
351 store->dock = dock;
352 } else {
353 created = FALSE;
355 pwindow = help_dlg->end_widget_list;
356 store = (struct units_buttons *)pwindow->data.ptr;
357 dock = store->dock;
358
359 area = pwindow->area;
360
361 /* Delete any previous list entries */
364 dock->prev);
366 }
367 }
368
370
374 adj_size(48), 1, TRUE, TRUE),
375 pwindow->dst,
378
382
384 sprintf(buffer, "%s %d", _("Base Cost:"),
387 buffer,
388 FONTO_ATTENTION, 0);
389 cost_label->id = ID_LABEL;
392
393 if (!is_wonder(pimpr_type)) {
394 sprintf(buffer, "%s %d", _("Upkeep:"), pimpr_type->upkeep);
396 buffer,
397 FONTO_ATTENTION, 0);
401 }
402 }
403
404 /* Requirement */
406 _("Requirement:"),
407 FONTO_ATTENTION, 0);
411
412 /* FIXME: this should show ranges, negated reqs, and all the reqs.
413 * Currently it's limited to 1 req. */
415 if (!preq->present) {
416 continue;
417 }
420 universal_name_translation(&preq->source, buffer, sizeof(buffer)),
423 if (preq->source.kind != VUT_ADVANCE) {
424 break; /* FIXME */
425 }
426 requirement_label2->id = MAX_ID - advance_number(preq->source.value.advance);
427 requirement_label2->string_utf8->fgcol
428 = *get_tech_color(advance_number(preq->source.value.advance));
431 break;
433
434 if (requirement_label2 == NULL) {
436 Q_("?req:None"),
437 FONTO_ATTENTION, 0);
439 }
440
444
445 /* Obsolete by */
447 _("Obsolete by:"),
448 FONTO_ATTENTION, 0);
452
454 if (pobs->source.kind == VUT_ADVANCE) {
455 obsTech = pobs->source.value.advance;
456 break;
457 }
459
460 if (obsTech == NULL) {
462 _("Never"),
463 FONTO_ATTENTION, 0);
465 } else {
472 obsolete_by_label2->string_utf8->fgcol
476 }
480
481 /* Helptext */
482 start_x = (area.x + 1 + scrollbar_width + help_dlg->end_active_widget_list->size.w + adj_size(20));
483
484 buffer[0] = '\0';
485 helptext_building(buffer, sizeof(buffer), client.conn.playing, NULL,
486 pimpr_type);
487 if (buffer[0] != '\0') {
489
494 text = TRUE;
495 }
496
498
499 /* --------------------------------------------------------- */
500 if (created) {
502 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
503 FREESURFACE(surf);
504 }
505
506 area = pwindow->area;
507
508 widget_set_position(pwindow,
509 (main_window_width() - pwindow->size.w) / 2,
510 (main_window_height() - pwindow->size.h) / 2);
511
512 /* Exit button */
513 close_button = pwindow->prev;
514 widget_set_position(close_button,
515 area.x + area.w - close_button->size.w - 1,
516 pwindow->size.y + adj_size(2));
517
518 /* List toggle button */
519 list_toggle_button = store->dock;
521
522 /* List entries */
524 area.y + list_toggle_button->size.h, 0, 0,
527
528 /* Scrollbar */
529 if (help_dlg->scroll) {
531 area.x, area.y + list_toggle_button->size.h,
532 h, FALSE);
533 }
534 }
535
536 impr_name_label = store->dock->prev;
537 widget_set_position(impr_name_label, start_x, area.y + adj_size(16));
538
539 start_y = impr_name_label->size.y + impr_name_label->size.h + adj_size(10);
540
544 if (!is_wonder(pimpr_type)) {
545 upkeep_label = cost_label->prev;
547 cost_label->size.x + cost_label->size.w + adj_size(20),
548 start_y);
549 }
550 start_y += cost_label->size.h;
551 }
552
555
558 requirement_label->size.x + requirement_label->size.w + adj_size(5),
559 start_y);
560
561 if (store->obsolete_by_button) {
564 requirement_label2->size.x + requirement_label2->size.w + adj_size(10),
565 start_y);
566
569 obsolete_by_label->size.x + obsolete_by_label->size.w + adj_size(5),
570 start_y);
571
572 start_y += obsolete_by_label2->size.h;
573 }
574
575 start_y += adj_size(30);
576
577 if (text) {
579 }
580
582}
583
584/**********************************************************************/
587static int change_unit_callback(struct widget *pwidget)
588{
590 popup_unit_info(MAX_ID - pwidget->id);
591 }
592
593 return -1;
594}
595
596/**********************************************************************/
599static void redraw_unit_info_dlg(void)
600{
601 SDL_Color bg_color = {255, 255, 255, 64};
602 struct widget *pwindow = help_dlg->end_widget_list;
603 struct units_buttons *store = (struct units_buttons *)pwindow->data.ptr;
604 SDL_Rect dst;
605
606 redraw_group(pwindow->prev, pwindow, FALSE);
607
608 dst.x = store->dock->prev->size.x - adj_size(10);
609 dst.y = store->dock->prev->size.y - adj_size(10);
610 dst.w = pwindow->size.w - (dst.x - pwindow->size.x) - adj_size(10);
611 dst.h = pwindow->size.h - (dst.y - pwindow->size.y) - adj_size(10);
612
613 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
614
615 create_frame(pwindow->dst->surface,
616 dst.x, dst.y, dst.w, dst.h,
618
619 /*------------------------------------- */
621 widget_flush(pwindow);
622}
623
624/**********************************************************************/
628{
629 SDL_Color bg_color = {255, 255, 255, 128};
630 struct widget *pwindow;
631 struct units_buttons *store;
632 struct widget *close_button = NULL;
634 struct widget *unit_button = NULL;
635 struct widget *unit_name_label = NULL;
636 struct widget *unit_info_label = NULL;
637 struct widget *requirement_label = NULL;
639 struct widget *obsolete_by_label = NULL;
641 struct widget *help_text_label = NULL;
642 struct widget *dock;
644 utf8_str *pstr;
645 SDL_Surface *surf;
646 int h, start_x, start_y, utype_count;
647 bool created, text = FALSE;
648 int scrollbar_width = 0;
649 struct unit_type *punittype;
650 char buffer[bufsz];
651 SDL_Rect area;
652 struct advance *req;
653
656 }
657
658 /* Create new dialog if it doesn't exist yet */
659 if (!help_dlg) {
660 SDL_Surface *background_tmpl, *background, *unit_name, *icon;
661 SDL_Rect dst;
662
664 created = TRUE;
665
666 /* Create dialog */
667 help_dlg = fc_calloc(1, sizeof(struct advanced_dialog));
668 store = fc_calloc(1, sizeof(struct units_buttons));
669
670 /* Create window */
672 title->style |= TTF_STYLE_BOLD;
673
676 set_wstate(pwindow , FC_WS_NORMAL);
677 pwindow->data.ptr = (void *)store;
678 add_to_gui_list(ID_WINDOW, pwindow);
679
680 help_dlg->end_widget_list = pwindow;
681
682 area = pwindow->area;
683
684 /* ------------------ */
685
686 /* Close button */
687 close_button = create_themeicon(current_theme->small_cancel_icon,
688 pwindow->dst,
691 close_button->info_label
692 = create_utf8_from_char_fonto(_("Close Dialog (Esc)"), FONTO_ATTENTION);
693 close_button->action = exit_help_dlg_callback;
694 set_wstate(close_button, FC_WS_NORMAL);
695 close_button->key = SDLK_ESCAPE;
696
697 add_to_gui_list(ID_BUTTON, close_button);
698
699 /* ------------------ */
700 dock = close_button;
701
702 /* --- Create scrollable unit list on the left side ---*/
703
705 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
706
707 /* Background template for entries in scroll list */
711
713 0, 0, background_tmpl->w - 1, background_tmpl->h - 1,
715
716 utype_count = 0;
718
719 /* Copy background surface */
720 background = copy_surface(background_tmpl);
721
722 /* Blit unit name */
725 dst.x = adj_size(35) + (background->w - unit_name->w - adj_size(35)) / 2;
726 dst.y = (background->h - unit_name->h) / 2;
727 alphablit(unit_name, NULL, background, &dst, 255);
729
730 /* Blit unit icon */
732 adj_size(36), adj_size(36), 1, TRUE, TRUE);
733 dst.x = (adj_size(35) - icon->w) / 2;
734 dst.y = (background->h - icon->h) / 2;
735 alphablit(icon, NULL, background, &dst, 255);
736 FREESURFACE(icon);
737
738 unit_button = create_icon2(background, pwindow->dst,
740
744
745 if (utype_count++ >= 10) {
747 }
748
750
752
756
757 if (utype_count > 10) {
760 }
761
762 /* Toggle techs list button */
764 current_theme->up_icon,
765 pwindow->dst,
766 _("Units"),
767 FONTO_DEFAULT, 0);
768#if 0
770 if (store->show_tree) {
772 }
773#endif
774
777
779
780 dock = list_toggle_button;
781 store->dock = dock;
782 } else {
783 created = FALSE;
785 pwindow = help_dlg->end_widget_list;
786 store = (struct units_buttons *)pwindow->data.ptr;
787 dock = store->dock;
788
789 area = pwindow->area;
790
791 /* Delete any previous list entries */
794 dock->prev);
796 }
797 }
798
805
809
810 {
811 char buf[2048];
812
813 fc_snprintf(buf, sizeof(buf), "%s %d %s",
815 PL_("shield", "shields", utype_build_shield_cost_base(punittype)));
816
817 if (punittype->pop_cost) {
818 cat_snprintf(buf, sizeof(buf), " %d %s",
819 punittype->pop_cost, PL_("citizen", "citizens",
820 punittype->pop_cost));
821 }
822
823 cat_snprintf(buf, sizeof(buf), " %s", _("Upkeep:"));
824
825 if (punittype->upkeep[O_SHIELD]) {
826 cat_snprintf(buf, sizeof(buf), " %d %s",
827 punittype->upkeep[O_SHIELD], PL_("shield", "shields",
828 punittype->upkeep[O_SHIELD]));
829 }
830 if (punittype->upkeep[O_FOOD]) {
831 cat_snprintf(buf, sizeof(buf), " %d %s",
832 punittype->upkeep[O_FOOD], PL_("food", "foods",
833 punittype->upkeep[O_FOOD]));
834 }
835 if (punittype->upkeep[O_GOLD]) {
836 cat_snprintf(buf, sizeof(buf), " %d %s",
837 punittype->upkeep[O_GOLD], PL_("gold", "golds",
838 punittype->upkeep[O_GOLD]));
839 }
840 if (punittype->happy_cost) {
841 cat_snprintf(buf, sizeof(buf), " %d %s",
842 punittype->happy_cost, PL_("citizen", "citizens",
843 punittype->happy_cost));
844 }
845
846 cat_snprintf(buf, sizeof(buf), "\n%s %d %s %d %s %s\n%s %d %s %d %s %d",
847 _("Attack:"), punittype->attack_strength,
848 _("Defense:"), punittype->defense_strength,
849 _("Move:"), move_points_text(punittype->move_rate, TRUE),
850 _("Vision:"), punittype->vision_radius_sq,
851 _("Firepower:"), punittype->firepower,
852 _("Hitpoints:"), punittype->hp);
853
855 FONTO_ATTENTION, 0);
859 }
860
861 /* Requirement */
863 _("Requirement:"),
864 FONTO_ATTENTION, 0);
868
870
871 if (advance_number(req) == A_NONE) {
873 Q_("?tech:None"),
874 FONTO_ATTENTION, 0);
876 } else {
878
885 requirement_label2->string_utf8->fgcol = *get_tech_color(req_id);
888 }
892
893 /* Obsolete by */
895 _("Obsolete by:"),
896 FONTO_ATTENTION, 0);
900
901 if (punittype->obsoleted_by == U_NOT_OBSOLETED) {
903 Q_("?utype:None"),
904 FONTO_ATTENTION, 0);
906 } else {
907 const struct unit_type *utype = punittype->obsoleted_by;
908 struct advance *obs_req = utype_primary_tech_req(utype);
909
915 obsolete_by_label2->string_utf8->fgcol
920 }
922 dock = obsolete_by_label2;
924
925 /* Helptext */
926 start_x = (area.x + 1 + scrollbar_width + help_dlg->active_widget_list->size.w + adj_size(20));
927
928 buffer[0] = '\0';
929 helptext_unit(buffer, sizeof(buffer), client.conn.playing, "", utype_by_number(type_id));
930 if (buffer[0] != '\0') {
932
937 text = TRUE;
938 }
939
941
942 /* --------------------------------------------------------- */
943 if (created) {
944
946 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
947 FREESURFACE(surf);
948 }
949
950 area = pwindow->area;
951
952 widget_set_position(pwindow,
953 (main_window_width() - pwindow->size.w) / 2,
954 (main_window_height() - pwindow->size.h) / 2);
955
956 /* Exit button */
957 close_button = pwindow->prev;
958 widget_set_position(close_button,
959 area.x + area.w - close_button->size.w - 1,
960 pwindow->size.y + adj_size(2));
961
962 /* List toggle button */
963 list_toggle_button = store->dock;
965
966 /* List entries */
968 area.y + list_toggle_button->size.h, 0, 0,
971
972 /* Scrollbar */
973 if (help_dlg->scroll) {
975 area.x, area.y + list_toggle_button->size.h,
976 h, FALSE);
977 }
978 }
979
980 unit_name_label = store->dock->prev;
981 widget_set_position(unit_name_label, start_x, area.y + adj_size(16));
982
983 start_y = unit_name_label->size.y + unit_name_label->size.h + adj_size(10);
984
987
988 start_y += unit_info_label->size.h;
989
992
995 requirement_label->size.x + requirement_label->size.w + adj_size(5),
996 start_y);
997
1000 requirement_label2->size.x + requirement_label2->size.w + adj_size(10),
1001 start_y);
1002
1005 obsolete_by_label->size.x + obsolete_by_label->size.w + adj_size(5),
1006 start_y);
1007
1008 start_y += obsolete_by_label2->size.h + adj_size(20);
1009
1010 if (text) {
1013 }
1014
1016}
1017
1018/* =============================================== */
1019/* ==================== Tech Tree ================ */
1020/* =============================================== */
1021
1022/**********************************************************************/
1025static int change_tech_callback(struct widget *pwidget)
1026{
1028 popup_tech_info(MAX_ID - pwidget->id);
1029 }
1030
1031 return -1;
1032}
1033
1034/**********************************************************************/
1037static int show_tech_tree_callback(struct widget *pwidget)
1038{
1040 struct techs_buttons *store = (struct techs_buttons *)help_dlg->end_widget_list->data.ptr;
1041
1042 store->show_tree = !store->show_tree;
1043 if (!store->show_tree) {
1044 store->show_full_tree = FALSE;
1045 store->dock->theme2 = current_theme->up_icon;
1046 }
1047 popup_tech_info(MAX_ID - store->dock->prev->id);
1048 }
1049
1050 return -1;
1051}
1052
1053/**********************************************************************/
1056static void redraw_tech_info_dlg(void)
1057{
1058 SDL_Color bg_color = {255, 255, 255, 64};
1059 struct widget *pwindow = help_dlg->end_widget_list;
1060 struct techs_buttons *store = (struct techs_buttons *)pwindow->data.ptr;
1062 utf8_str *pstr;
1063 SDL_Rect dst;
1064
1065 redraw_group(pwindow->prev, pwindow, FALSE);
1066
1067 dst.x = store->dock->prev->prev->size.x - adj_size(10);
1068 dst.y = store->dock->prev->prev->size.y - adj_size(10);
1069 dst.w = pwindow->size.w - (dst.x - pwindow->size.x) - adj_size(10);
1070 dst.h = pwindow->size.h - (dst.y - pwindow->size.y) - adj_size(10);
1071
1072 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
1073
1074 create_frame(pwindow->dst->surface,
1075 dst.x, dst.y, dst.w, dst.h,
1077
1078 /* -------------------------- */
1080 pstr->style |= TTF_STYLE_BOLD;
1081
1083 dst.x = store->dock->prev->prev->size.x;
1084 if (store->targets[0]) {
1085 dst.y = store->targets[0]->size.y - text0->h;
1086 } else {
1087 dst.y = store->dock->prev->prev->size.y
1088 + store->dock->prev->prev->size.h + adj_size(10);
1089 }
1090
1091 alphablit(text0, NULL, pwindow->dst->surface, &dst, 255);
1093
1094 if (store->sub_targets[0]) {
1095 int i;
1096
1098
1099 copy_chars_to_utf8_str(pstr, _("( with "));
1101
1104 i = 0;
1106 dst.x = store->sub_targets[i]->size.x - text0->w;
1107 dst.y = store->sub_targets[i]->size.y;
1108
1109 alphablit(text0, NULL, pwindow->dst->surface, &dst, 255);
1110 dst.x = store->sub_targets[i]->size.x + store->sub_targets[i]->size.w;
1111 dst.y = store->sub_targets[i]->size.y;
1112
1113 alphablit(text1, NULL, pwindow->dst->surface, &dst, 255);
1114 i++;
1115 }
1116
1119 }
1121
1123 widget_flush(pwindow);
1124}
1125
1126/**********************************************************************/
1130 struct widget *pwindow,
1131 struct techs_buttons *store)
1132{
1133 struct widget *pwidget;
1134 struct widget *last, *budynki;
1135 struct widget *dock = store->dock;
1137 int start_x, start_y, imp_count, unit_count, flags_count, gov_count;
1138 char buffer[bufsz];
1139 SDL_Surface *surf;
1140
1141 start_x = (pwindow->area.x + adj_size(1) + width + help_dlg->active_widget_list->size.w + adj_size(20));
1142
1143 /* Tech tree icon */
1144 pwidget = create_icon2(current_theme->tech_tree_icon, pwindow->dst,
1146
1147 set_wstate(pwidget, FC_WS_NORMAL);
1149 pwidget->id = MAX_ID - tech;
1150 widget_add_as_prev(pwidget, dock);
1151 dock = pwidget;
1152
1153 /* Tech name (heading) */
1154 pwidget
1156 pwindow->dst,
1159
1160 pwidget->id = ID_LABEL;
1161 widget_add_as_prev(pwidget, dock);
1162 dock = pwidget;
1163
1164 /* Target techs */
1165 targets_count = 0;
1167 if ((targets_count < 6)
1168 && (advance_required(aidx, AR_ONE) == tech
1169 || advance_required(aidx, AR_TWO) == tech)) {
1170 pwidget
1175 pwidget->string_utf8->fgcol = *get_tech_color(aidx);
1176 max_width = MAX(max_width, pwidget->size.w);
1177 set_wstate(pwidget, FC_WS_NORMAL);
1178 pwidget->action = change_tech_callback;
1179 pwidget->id = MAX_ID - aidx;
1180 widget_add_as_prev(pwidget, dock);
1181 dock = pwidget;
1182 store->targets[targets_count++] = pwidget;
1183 }
1185 if (targets_count < 6) {
1186 store->targets[targets_count] = NULL;
1187 }
1188
1190 if (targets_count > 0) {
1191 int sub_tech;
1192
1193 for (i = 0; i < targets_count; i++) {
1194 sub_tech = MAX_ID - store->targets[i]->id;
1195 if (advance_required(sub_tech, AR_ONE) == tech
1198 } else if (advance_required(sub_tech, AR_TWO) == tech
1201 } else {
1202 continue;
1203 }
1204 pwidget
1210 set_wstate(pwidget, FC_WS_NORMAL);
1211 pwidget->action = change_tech_callback;
1212 pwidget->id = MAX_ID - sub_tech;
1213 widget_add_as_prev(pwidget, dock);
1214 dock = pwidget;
1215 store->sub_targets[sub_targets_count++] = pwidget;
1216 }
1217 }
1218 if (sub_targets_count < 6) {
1220 }
1221
1222 /* Fill array with iprvm. icons */
1223 budynki = pwidget;
1224
1225 /* Target governments */
1226 gov_count = 0;
1227 governments_iterate(gov) {
1228 requirement_vector_iterate(&(gov->reqs), preq) {
1229 if (VUT_ADVANCE == preq->source.kind
1230 && advance_number(preq->source.value.advance) == tech) {
1231
1232 pwidget
1234 pwindow->dst,
1238 set_wstate(pwidget, FC_WS_NORMAL);
1239 pwidget->action = change_gov_callback;
1240 pwidget->id = MAX_ID - government_index(gov);
1241 widget_add_as_prev(pwidget, dock);
1242 dock = pwidget;
1243 gov_count++;
1244 }
1247
1248 /* Target improvements */
1249 imp_count = 0;
1250 improvement_iterate(pimprove) {
1251 if (valid_improvement(pimprove)) {
1252 /* FIXME: this should show ranges and all the reqs.
1253 * Currently it's limited to 1 req. */
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;
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++) {
1701
1702 if (NULL != vap && A_NONE != ar) {
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++) {
1726
1727 if (NULL != vap && A_NONE != ar) {
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)) {
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
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
1778 } else if (advance_required(sub_tech, AR_TWO) == tech
1781 } else {
1782 continue;
1783 }
1784
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) {
1799 }
1800
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;
2000
2001 if (vap) {
2004 advance_label = create_icon2(surf, pwindow->dst,
2006
2010
2011 if (tech_count++ >= 10) {
2013 }
2014 }
2016
2018
2022
2023 if (tech_count > 10) {
2026 }
2027
2028 /* Toggle techs list button */
2030 current_theme->up_icon,
2031 pwindow->dst,
2032 _("Advances"),
2033 FONTO_DEFAULT, 0);
2035 if (store->show_tree) {
2037 }
2040
2042
2043 dock = list_toggle_button;
2044 store->dock = dock;
2045 } else {
2046 created = FALSE;
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 */
2060
2061 if (store->show_tree) {
2063 } else {
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
2076 while (advance_label->prev != NULL && --count > 0) {
2078 }
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 */
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) {
2124 } else {
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:663
struct civclient client
char * incite_cost
Definition comments.c:74
QString current_theme
Definition fc_client.cpp:64
int Tech_type_id
Definition fc_types.h:381
int Impr_type_id
Definition fc_types.h:380
int Unit_type_id
Definition fc_types.h:386
@ 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:122
#define governments_iterate_end
Definition government.h:125
GtkWidget * unit_info_label
Definition gui_main.c:151
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:1932
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:1039
enum help_page_type current_help_dlg
Definition helpdlg.c:68
static void redraw_tech_info_dlg(void)
Definition helpdlg.c:1058
static void redraw_unit_info_dlg(void)
Definition helpdlg.c:602
static int change_tech_callback(struct widget *pwidget)
Definition helpdlg.c:1027
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:1131
void popup_impr_info(Impr_type_id impr)
Definition helpdlg.c:202
static void redraw_tech_tree_dlg(void)
Definition helpdlg.c:1411
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:1653
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:3263
char * helptext_building(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct impr_type *pimprove)
Definition helpdata.c:1381
char * helptext_unit(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct unit_type *utype)
Definition helpdata.c:1865
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: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: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:80
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
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
union widget::@217 data
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:249
@ 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:245
bool is_tech_req_for_utype(const struct unit_type *ptype, struct advance *padv)
Definition unittype.c:2710
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1468
struct advance * utype_primary_tech_req(const struct unit_type *ptype)
Definition unittype.c:2696
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:1560
#define unit_type_iterate(_p)
Definition unittype.h:859
#define unit_type_iterate_end
Definition unittype.h:866
#define U_NOT_OBSOLETED
Definition unittype.h:535