Freeciv-3.3: /fast/freeciv/nightly/main/client/gui-sdl3/helpdlg.c Source File

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
48 static 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 {
59 struct widget *obsolete_by_button;
60 struct widget *requirement_button;
61 struct widget *dock;
62};
63
64 enum help_page_type current_help_dlg = HELP_LAST;
65
66 static const int bufsz = 8192;
67
68static int change_tech_callback(struct widget *pwidget);
69
70/**********************************************************************/
73 void popup_help_browser(void)
74{
75 popup_tech_info(A_NONE);
76}
77
78/**********************************************************************/
85 void popup_help_dialog_string(const char *item)
86{
87 popup_help_dialog_typed(Q_(item), HELP_ANY);
88}
89
90/**********************************************************************/
96 void popup_help_dialog_typed(const char *item, enum help_page_type eHPT)
97{
98 log_debug("popup_help_dialog_typed : PORT ME");
99}
100
101/**********************************************************************/
104 void popdown_help_dialog(void)
105{
106 if (help_dlg) {
107 popdown_window_group_dialog(help_dlg->begin_widget_list,
108 help_dlg->end_widget_list);
109 FC_FREE(help_dlg->scroll);
110 FC_FREE(help_dlg);
111 current_help_dlg = HELP_LAST;
112 }
113}
114
115/**********************************************************************/
118 static int help_dlg_window_callback(struct widget *pwindow)
119{
120 return -1;
121}
122
123/**********************************************************************/
126 static int exit_help_dlg_callback(struct widget *pwidget)
127{
128 if (PRESSED_EVENT(main_data.event)) {
129 popdown_help_dialog();
130 flush_dirty();
131 }
132
133 return -1;
134}
135
136/**********************************************************************/
139 static int change_gov_callback(struct widget *pwidget)
140{
141 if (PRESSED_EVENT(main_data.event)) {
142 popup_gov_info(MAX_ID - pwidget->id);
143 }
144
145 return -1;
146}
147
148/**********************************************************************/
151 void popup_gov_info(int gov)
152{
153}
154
155/**********************************************************************/
158 static int change_impr_callback(struct widget *pwidget)
159{
160 if (PRESSED_EVENT(main_data.event)) {
161 popup_impr_info(MAX_ID - pwidget->id);
162 }
163
164 return -1;
165}
166
167/**********************************************************************/
170 static 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,
188 get_theme_color(COLOR_THEME_HELPDLG_FRAME));
189
190 /*------------------------------------- */
191 redraw_group(help_dlg->begin_widget_list, pwindow->prev->prev, FALSE);
192 widget_flush(pwindow);
193}
194
195/**********************************************************************/
198 void popup_impr_info(Impr_type_id impr)
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;
204 struct widget *list_toggle_button = NULL;
205 struct widget *improvement_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;
210 struct widget *requirement_label2 = NULL;
211 struct widget *obsolete_by_label = NULL;
212 struct widget *obsolete_by_label2 = NULL;
213 struct widget *help_text_label = NULL;
214 struct widget *dock;
215 utf8_str *title;
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
226 if (current_help_dlg != HELP_IMPROVEMENT) {
227 popdown_help_dialog();
228 }
229
230 if (!help_dlg) {
231 SDL_Surface *background_tmpl, *background, *impr_name, *icon;
232 SDL_Rect dst;
233
234 current_help_dlg = HELP_IMPROVEMENT;
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"),
243 FONTO_ATTENTION);
244 title->style |= TTF_STYLE_BOLD;
245
246 pwindow = create_window_skeleton(NULL, title, WF_FREE_DATA);
247 pwindow->action = help_dlg_window_callback;
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,
260 WF_WIDGET_HAS_INFO_LABEL
261 | WF_RESTORE_BACKGROUND);
262 close_button->info_label
263 = create_utf8_from_char_fonto(_("Close Dialog (Esc)"),
264 FONTO_ATTENTION);
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
274 pstr = create_utf8_str_fonto(NULL, 0, FONTO_DEFAULT);
275 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
276
277 /* Background template for entries in scroll list */
278 background_tmpl = create_surf(adj_size(135), adj_size(40), SDL_SWSURFACE);
279 SDL_FillSurfaceRect(background_tmpl, NULL,
280 map_rgba(background_tmpl->format, bg_color));
281
282 create_frame(background_tmpl,
283 0, 0, background_tmpl->w - 1, background_tmpl->h - 1,
284 get_theme_color(COLOR_THEME_HELPDLG_FRAME));
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 */
293 copy_chars_to_utf8_str(pstr, improvement_name_translation(pimprove));
294 impr_name = create_text_surf_smaller_than_w(pstr, adj_size(100 - 4));
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);
298 FREESURFACE(impr_name);
299
300 /* Blit improvement icon */
301 icon = resize_surface_box(get_building_surface(pimprove),
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,
309 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
310
311 set_wstate(improvement_button, FC_WS_NORMAL);
312 improvement_button->action = change_impr_callback;
313 add_to_gui_list(MAX_ID - improvement_number(pimprove), improvement_button);
314
315 if (impr_type_count++ >= 10) {
316 set_wflag(improvement_button, WF_HIDDEN);
317 }
318
319 } improvement_iterate_end;
320
321 FREESURFACE(background_tmpl);
322
323 help_dlg->end_active_widget_list = dock->prev;
324 help_dlg->begin_widget_list = improvement_button ? improvement_button : close_button;
325 help_dlg->begin_active_widget_list = help_dlg->begin_widget_list;
326
327 if (impr_type_count > 10) {
328 help_dlg->active_widget_list = help_dlg->end_active_widget_list;
329 scrollbar_width = create_vertical_scrollbar(help_dlg, 1, 10, TRUE, TRUE);
330 }
331
332 /* Toggle techs list button */
333 list_toggle_button = create_themeicon_button_from_chars_fonto(
334 current_theme->up_icon,
335 pwindow->dst,
336 _("Improvements"),
337 FONTO_DEFAULT, 0);
338#if 0
339 list_toggle_button->action = toggle_full_tree_mode_in_help_dlg_callback;
340 if (store->show_tree) {
341 set_wstate(list_toggle_button, FC_WS_NORMAL);
342 }
343#endif
344
345 widget_resize(list_toggle_button, adj_size(160), adj_size(15));
346 list_toggle_button->string_utf8->fgcol = *get_theme_color(COLOR_THEME_HELPDLG_TEXT);
347
348 add_to_gui_list(ID_BUTTON, list_toggle_button);
349
350 dock = list_toggle_button;
351 store->dock = dock;
352 } else {
353 created = FALSE;
354 scrollbar_width = (help_dlg->scroll ? help_dlg->scroll->up_left_button->size.w : 0);
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 */
362 if (dock != help_dlg->begin_widget_list) {
363 del_group_of_widgets_from_gui_list(help_dlg->begin_widget_list,
364 dock->prev);
365 help_dlg->begin_widget_list = dock;
366 }
367 }
368
369 pimpr_type = improvement_by_number(impr);
370
371 surf = get_building_surface(pimpr_type);
372 impr_name_label
373 = create_iconlabel_from_chars_fonto(resize_surface_box(surf, adj_size(64),
374 adj_size(48), 1, TRUE, TRUE),
375 pwindow->dst,
376 city_improvement_name_translation(NULL, pimpr_type),
377 FONTO_MAX, WF_FREE_THEME);
378
379 impr_name_label->id = ID_LABEL;
380 widget_add_as_prev(impr_name_label, dock);
381 dock = impr_name_label;
382
383 if (!is_convert_improvement(pimpr_type)) {
384 sprintf(buffer, "%s %d", _("Base Cost:"),
385 impr_base_build_shield_cost(pimpr_type));
386 cost_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
387 buffer,
388 FONTO_ATTENTION, 0);
389 cost_label->id = ID_LABEL;
390 widget_add_as_prev(cost_label, dock);
391 dock = cost_label;
392
393 if (!is_wonder(pimpr_type)) {
394 sprintf(buffer, "%s %d", _("Upkeep:"), pimpr_type->upkeep);
395 upkeep_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
396 buffer,
397 FONTO_ATTENTION, 0);
398 upkeep_label->id = ID_LABEL;
399 widget_add_as_prev(upkeep_label, dock);
400 dock = upkeep_label;
401 }
402 }
403
404 /* Requirement */
405 requirement_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
406 _("Requirement:"),
407 FONTO_ATTENTION, 0);
408 requirement_label->id = ID_LABEL;
409 widget_add_as_prev(requirement_label, dock);
410 dock = requirement_label;
411
412 /* FIXME: this should show ranges, negated reqs, and all the reqs.
413 * Currently it's limited to 1 req. */
414 requirement_vector_iterate(&pimpr_type->reqs, preq) {
415 if (!preq->present) {
416 continue;
417 }
418 requirement_label2
419 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
420 universal_name_translation(&preq->source, buffer, sizeof(buffer)),
421 FONTO_ATTENTION,
422 WF_RESTORE_BACKGROUND);
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));
429 requirement_label2->action = change_tech_callback;
430 set_wstate(requirement_label2, FC_WS_NORMAL);
431 break;
432 } requirement_vector_iterate_end;
433
434 if (requirement_label2 == NULL) {
435 requirement_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
436 Q_("?req:None"),
437 FONTO_ATTENTION, 0);
438 requirement_label2->id = ID_LABEL;
439 }
440
441 widget_add_as_prev(requirement_label2, dock);
442 dock = requirement_label2;
443 store->requirement_button = requirement_label2;
444
445 /* Obsolete by */
446 obsolete_by_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
447 _("Obsolete by:"),
448 FONTO_ATTENTION, 0);
449 obsolete_by_label->id = ID_LABEL;
450 widget_add_as_prev(obsolete_by_label, dock);
451 dock = obsolete_by_label;
452
453 requirement_vector_iterate(&pimpr_type->obsolete_by, pobs) {
454 if (pobs->source.kind == VUT_ADVANCE) {
455 obsTech = pobs->source.value.advance;
456 break;
457 }
458 } requirement_vector_iterate_end;
459
460 if (obsTech == NULL) {
461 obsolete_by_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
462 _("Never"),
463 FONTO_ATTENTION, 0);
464 obsolete_by_label2->id = ID_LABEL;
465 } else {
466 obsolete_by_label2
467 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
468 advance_name_translation(obsTech),
469 FONTO_ATTENTION,
470 WF_RESTORE_BACKGROUND);
471 obsolete_by_label2->id = MAX_ID - advance_number(obsTech);
472 obsolete_by_label2->string_utf8->fgcol
473 = *get_tech_color(advance_number(obsTech));
474 obsolete_by_label2->action = change_tech_callback;
475 set_wstate(obsolete_by_label2, FC_WS_NORMAL);
476 }
477 widget_add_as_prev(obsolete_by_label2, dock);
478 dock = obsolete_by_label2;
479 store->obsolete_by_button = obsolete_by_label2;
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') {
488 utf8_str *bstr = create_utf8_from_char_fonto(buffer, FONTO_ATTENTION);
489
490 convert_utf8_str_to_const_surface_width(bstr, adj_size(640) - start_x - adj_size(20));
491 help_text_label = create_iconlabel(NULL, pwindow->dst, bstr, 0);
492 help_text_label->id = ID_LABEL;
493 widget_add_as_prev(help_text_label, dock);
494 text = TRUE;
495 }
496
497 help_dlg->begin_widget_list = help_text_label ? help_text_label : obsolete_by_label2;
498
499 /* --------------------------------------------------------- */
500 if (created) {
501 surf = theme_get_background(active_theme, BACKGROUND_HELPDLG);
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;
520 widget_set_position(list_toggle_button, area.x, area.y);
521
522 /* List entries */
523 h = setup_vertical_widgets_position(1, area.x + scrollbar_width,
524 area.y + list_toggle_button->size.h, 0, 0,
525 help_dlg->begin_active_widget_list,
526 help_dlg->end_active_widget_list);
527
528 /* Scrollbar */
529 if (help_dlg->scroll) {
530 setup_vertical_scrollbar_area(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
541 if (!is_convert_improvement(pimpr_type)) {
542 cost_label = impr_name_label->prev;
543 widget_set_position(cost_label, start_x, start_y);
544 if (!is_wonder(pimpr_type)) {
545 upkeep_label = cost_label->prev;
546 widget_set_position(upkeep_label,
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
553 requirement_label = store->requirement_button->next;
554 widget_set_position(requirement_label, start_x, start_y);
555
556 requirement_label2 = store->requirement_button;
557 widget_set_position(requirement_label2,
558 requirement_label->size.x + requirement_label->size.w + adj_size(5),
559 start_y);
560
561 if (store->obsolete_by_button) {
562 obsolete_by_label = store->obsolete_by_button->next;
563 widget_set_position(obsolete_by_label,
564 requirement_label2->size.x + requirement_label2->size.w + adj_size(10),
565 start_y);
566
567 obsolete_by_label2 = store->obsolete_by_button;
568 widget_set_position(obsolete_by_label2,
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) {
578 widget_set_position(help_text_label, start_x, start_y);
579 }
580
581 redraw_impr_info_dlg();
582}
583
584/**********************************************************************/
587 static int change_unit_callback(struct widget *pwidget)
588{
589 if (PRESSED_EVENT(main_data.event)) {
590 popup_unit_info(MAX_ID - pwidget->id);
591 }
592
593 return -1;
594}
595
596/**********************************************************************/
599 static 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,
617 get_theme_color(COLOR_THEME_HELPDLG_FRAME));
618
619 /*------------------------------------- */
620 redraw_group(help_dlg->begin_widget_list, pwindow->prev->prev, FALSE);
621 widget_flush(pwindow);
622}
623
624/**********************************************************************/
627 void popup_unit_info(Unit_type_id type_id)
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;
633 struct widget *list_toggle_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;
638 struct widget *requirement_label2 = NULL;
639 struct widget *obsolete_by_label = NULL;
640 struct widget *obsolete_by_label2 = NULL;
641 struct widget *help_text_label = NULL;
642 struct widget *dock;
643 utf8_str *title;
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
654 if (current_help_dlg != HELP_UNIT) {
655 popdown_help_dialog();
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
663 current_help_dlg = HELP_UNIT;
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 */
671 title = create_utf8_from_char_fonto(_("Help : Units"), FONTO_ATTENTION);
672 title->style |= TTF_STYLE_BOLD;
673
674 pwindow = create_window_skeleton(NULL, title, WF_FREE_DATA);
675 pwindow->action = help_dlg_window_callback;
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,
689 WF_WIDGET_HAS_INFO_LABEL
690 | WF_RESTORE_BACKGROUND);
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
704 pstr = create_utf8_str_fonto(NULL, 0, FONTO_DEFAULT);
705 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
706
707 /* Background template for entries in scroll list */
708 background_tmpl = create_surf(adj_size(135), adj_size(40), SDL_SWSURFACE);
709 SDL_FillSurfaceRect(background_tmpl, NULL,
710 map_rgba(background_tmpl->format, bg_color));
711
712 create_frame(background_tmpl,
713 0, 0, background_tmpl->w - 1, background_tmpl->h - 1,
714 get_theme_color(COLOR_THEME_HELPDLG_FRAME));
715
716 utype_count = 0;
717 unit_type_iterate(ut) {
718
719 /* Copy background surface */
720 background = copy_surface(background_tmpl);
721
722 /* Blit unit name */
723 copy_chars_to_utf8_str(pstr, utype_name_translation(ut));
724 unit_name = create_text_surf_smaller_than_w(pstr, adj_size(100 - 4));
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);
728 FREESURFACE(unit_name);
729
730 /* Blit unit icon */
731 icon = resize_surface_box(get_unittype_surface(ut, direction8_invalid()),
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,
739 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
740
741 set_wstate(unit_button, FC_WS_NORMAL);
742 unit_button->action = change_unit_callback;
743 add_to_gui_list(MAX_ID - utype_number(ut), unit_button);
744
745 if (utype_count++ >= 10) {
746 set_wflag(unit_button, WF_HIDDEN);
747 }
748
749 } unit_type_iterate_end;
750
751 FREESURFACE(background_tmpl);
752
753 help_dlg->end_active_widget_list = dock->prev;
754 help_dlg->begin_widget_list = unit_button ? unit_button : close_button;
755 help_dlg->begin_active_widget_list = help_dlg->begin_widget_list;
756
757 if (utype_count > 10) {
758 help_dlg->active_widget_list = help_dlg->end_active_widget_list;
759 scrollbar_width = create_vertical_scrollbar(help_dlg, 1, 10, TRUE, TRUE);
760 }
761
762 /* Toggle techs list button */
763 list_toggle_button = create_themeicon_button_from_chars_fonto(
764 current_theme->up_icon,
765 pwindow->dst,
766 _("Units"),
767 FONTO_DEFAULT, 0);
768#if 0
769 list_toggle_button->action = toggle_full_tree_mode_in_help_dlg_callback;
770 if (store->show_tree) {
771 set_wstate(list_toggle_button, FC_WS_NORMAL);
772 }
773#endif
774
775 widget_resize(list_toggle_button, adj_size(160), adj_size(15));
776 list_toggle_button->string_utf8->fgcol = *get_theme_color(COLOR_THEME_HELPDLG_TEXT);
777
778 add_to_gui_list(ID_BUTTON, list_toggle_button);
779
780 dock = list_toggle_button;
781 store->dock = dock;
782 } else {
783 created = FALSE;
784 scrollbar_width = (help_dlg->scroll ? help_dlg->scroll->up_left_button->size.w : 0);
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 */
792 if (dock != help_dlg->begin_widget_list) {
793 del_group_of_widgets_from_gui_list(help_dlg->begin_widget_list,
794 dock->prev);
795 help_dlg->begin_widget_list = dock;
796 }
797 }
798
799 punittype = utype_by_number(type_id);
800 unit_name_label
801 = create_iconlabel_from_chars_fonto(adj_surf(get_unittype_surface(punittype,
802 direction8_invalid())),
803 pwindow->dst, utype_name_translation(punittype),
804 FONTO_MAX, WF_FREE_THEME);
805
806 unit_name_label->id = ID_LABEL;
807 widget_add_as_prev(unit_name_label, dock);
808 dock = unit_name_label;
809
810 {
811 char buf[2048];
812
813 fc_snprintf(buf, sizeof(buf), "%s %d %s",
814 _("Cost:"), utype_build_shield_cost_base(punittype),
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
854 unit_info_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst, buf,
855 FONTO_ATTENTION, 0);
856 unit_info_label->id = ID_LABEL;
857 widget_add_as_prev(unit_info_label, dock);
858 dock = unit_info_label;
859 }
860
861 /* Requirement */
862 requirement_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
863 _("Requirement:"),
864 FONTO_ATTENTION, 0);
865 requirement_label->id = ID_LABEL;
866 widget_add_as_prev(requirement_label, dock);
867 dock = requirement_label;
868
869 req = utype_primary_tech_req(punittype);
870
871 if (advance_number(req) == A_NONE) {
872 requirement_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
873 Q_("?tech:None"),
874 FONTO_ATTENTION, 0);
875 requirement_label2->id = ID_LABEL;
876 } else {
877 Tech_type_id req_id = advance_number(req);
878
879 requirement_label2
880 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
881 advance_name_translation(req),
882 FONTO_ATTENTION,
883 WF_RESTORE_BACKGROUND);
884 requirement_label2->id = MAX_ID - req_id;
885 requirement_label2->string_utf8->fgcol = *get_tech_color(req_id);
886 requirement_label2->action = change_tech_callback;
887 set_wstate(requirement_label2, FC_WS_NORMAL);
888 }
889 widget_add_as_prev(requirement_label2, dock);
890 dock = requirement_label2;
891 store->requirement_button = requirement_label2;
892
893 /* Obsolete by */
894 obsolete_by_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
895 _("Obsolete by:"),
896 FONTO_ATTENTION, 0);
897 obsolete_by_label->id = ID_LABEL;
898 widget_add_as_prev(obsolete_by_label, dock);
899 dock = obsolete_by_label;
900
901 if (punittype->obsoleted_by == U_NOT_OBSOLETED) {
902 obsolete_by_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
903 Q_("?utype:None"),
904 FONTO_ATTENTION, 0);
905 obsolete_by_label2->id = ID_LABEL;
906 } else {
907 const struct unit_type *utype = punittype->obsoleted_by;
908 struct advance *obs_req = utype_primary_tech_req(utype);
909
910 obsolete_by_label2
911 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
912 utype_name_translation(utype),
913 FONTO_ATTENTION,
914 WF_RESTORE_BACKGROUND);
915 obsolete_by_label2->string_utf8->fgcol
916 = *get_tech_color(advance_number(obs_req));
917 obsolete_by_label2->id = MAX_ID - utype_number(utype);
918 obsolete_by_label2->action = change_unit_callback;
919 set_wstate(obsolete_by_label2, FC_WS_NORMAL);
920 }
921 widget_add_as_prev(obsolete_by_label2, dock);
922 dock = obsolete_by_label2;
923 store->obsolete_by_button = 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') {
931 utf8_str *ustr = create_utf8_from_char_fonto(buffer, FONTO_ATTENTION);
932
933 convert_utf8_str_to_const_surface_width(ustr, adj_size(640) - start_x - adj_size(20));
934 help_text_label = create_iconlabel(NULL, pwindow->dst, ustr, 0);
935 help_text_label->id = ID_LABEL;
936 widget_add_as_prev(help_text_label, dock);
937 text = TRUE;
938 }
939
940 help_dlg->begin_widget_list = help_text_label ? help_text_label : obsolete_by_label2;
941
942 /* --------------------------------------------------------- */
943 if (created) {
944
945 surf = theme_get_background(active_theme, BACKGROUND_HELPDLG);
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;
964 widget_set_position(list_toggle_button, area.x, area.y);
965
966 /* List entries */
967 h = setup_vertical_widgets_position(1, area.x + scrollbar_width,
968 area.y + list_toggle_button->size.h, 0, 0,
969 help_dlg->begin_active_widget_list,
970 help_dlg->end_active_widget_list);
971
972 /* Scrollbar */
973 if (help_dlg->scroll) {
974 setup_vertical_scrollbar_area(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
985 unit_info_label = unit_name_label->prev;
986 widget_set_position(unit_info_label, start_x, start_y);
987
988 start_y += unit_info_label->size.h;
989
990 requirement_label = store->requirement_button->next;
991 widget_set_position(requirement_label, start_x, start_y);
992
993 requirement_label2 = store->requirement_button;
994 widget_set_position(requirement_label2,
995 requirement_label->size.x + requirement_label->size.w + adj_size(5),
996 start_y);
997
998 obsolete_by_label = store->obsolete_by_button->next;
999 widget_set_position(obsolete_by_label,
1000 requirement_label2->size.x + requirement_label2->size.w + adj_size(10),
1001 start_y);
1002
1003 obsolete_by_label2 = store->obsolete_by_button;
1004 widget_set_position(obsolete_by_label2,
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) {
1011 help_text_label = store->obsolete_by_button->prev;
1012 widget_set_position(help_text_label, start_x, start_y);
1013 }
1014
1015 redraw_unit_info_dlg();
1016}
1017
1018/* =============================================== */
1019/* ==================== Tech Tree ================ */
1020/* =============================================== */
1021
1022/**********************************************************************/
1025 static int change_tech_callback(struct widget *pwidget)
1026{
1027 if (PRESSED_EVENT(main_data.event)) {
1028 popup_tech_info(MAX_ID - pwidget->id);
1029 }
1030
1031 return -1;
1032}
1033
1034/**********************************************************************/
1037 static int show_tech_tree_callback(struct widget *pwidget)
1038{
1039 if (PRESSED_EVENT(main_data.event)) {
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/**********************************************************************/
1056 static 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;
1061 SDL_Surface *text0, *text1 = NULL;
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,
1076 get_theme_color(COLOR_THEME_HELPDLG_FRAME));
1077
1078 /* -------------------------- */
1079 pstr = create_utf8_from_char_fonto(_("Allows"), FONTO_HEADING);
1080 pstr->style |= TTF_STYLE_BOLD;
1081
1082 text0 = create_text_surf_from_utf8(pstr);
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);
1092 FREESURFACE(text0);
1093
1094 if (store->sub_targets[0]) {
1095 int i;
1096
1097 change_fonto_utf8(pstr, FONTO_ATTENTION);
1098
1099 copy_chars_to_utf8_str(pstr, _("( with "));
1100 text0 = create_text_surf_from_utf8(pstr);
1101
1102 copy_chars_to_utf8_str(pstr, _(" )"));
1103 text1 = create_text_surf_from_utf8(pstr);
1104 i = 0;
1105 while (i < 6 && store-> sub_targets[i]) {
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
1117 FREESURFACE(text0);
1118 FREESURFACE(text1);
1119 }
1120 FREEUTF8STR(pstr);
1121
1122 redraw_group(help_dlg->begin_widget_list, pwindow->prev->prev, FALSE);
1123 widget_flush(pwindow);
1124}
1125
1126/**********************************************************************/
1129 static struct widget *create_tech_info(Tech_type_id tech, int width,
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;
1136 int i, targets_count, sub_targets_count, max_width = 0;
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,
1145 WF_RESTORE_BACKGROUND);
1146
1147 set_wstate(pwidget, FC_WS_NORMAL);
1148 pwidget->action = show_tech_tree_callback;
1149 pwidget->id = MAX_ID - tech;
1150 widget_add_as_prev(pwidget, dock);
1151 dock = pwidget;
1152
1153 /* Tech name (heading) */
1154 pwidget
1155 = create_iconlabel_from_chars_fonto(get_tech_icon(tech),
1156 pwindow->dst,
1157 advance_name_translation(advance_by_number(tech)),
1158 FONTO_MAX, WF_FREE_THEME);
1159
1160 pwidget->id = ID_LABEL;
1161 widget_add_as_prev(pwidget, dock);
1162 dock = pwidget;
1163
1164 /* Target techs */
1165 targets_count = 0;
1166 advance_index_iterate(A_FIRST, aidx) {
1167 if ((targets_count < 6)
1168 && (advance_required(aidx, AR_ONE) == tech
1169 || advance_required(aidx, AR_TWO) == tech)) {
1170 pwidget
1171 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
1172 advance_name_translation(advance_by_number(aidx)),
1173 FONTO_ATTENTION,
1174 WF_RESTORE_BACKGROUND);
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 }
1184 } advance_index_iterate_end;
1185 if (targets_count < 6) {
1186 store->targets[targets_count] = NULL;
1187 }
1188
1189 sub_targets_count = 0;
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
1196 && advance_required(sub_tech, AR_TWO) != A_NONE) {
1197 sub_tech = advance_required(sub_tech, AR_TWO);
1198 } else if (advance_required(sub_tech, AR_TWO) == tech
1199 && advance_required(sub_tech, AR_ONE) != A_NONE) {
1200 sub_tech = advance_required(sub_tech, AR_ONE);
1201 } else {
1202 continue;
1203 }
1204 pwidget
1205 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
1206 advance_name_translation(advance_by_number(sub_tech)),
1207 FONTO_ATTENTION,
1208 WF_RESTORE_BACKGROUND);
1209 pwidget->string_utf8->fgcol = *get_tech_color(sub_tech);
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) {
1219 store->sub_targets[sub_targets_count] = NULL;
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
1233 = create_iconlabel_from_chars_fonto(adj_surf(get_government_surface(gov)),
1234 pwindow->dst,
1235 government_name_translation(gov),
1236 FONTO_HEADING,
1237 WF_RESTORE_BACKGROUND | WF_SELECT_WITHOUT_BAR | WF_FREE_THEME);
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 }
1245 } requirement_vector_iterate_end;
1246 } governments_iterate_end;
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);
1258 pwidget = create_iconlabel_from_chars_fonto(
1259 resize_surface_box(surf, adj_size(48), adj_size(48), 1, TRUE,
1260 TRUE),
1261 pwindow->dst,
1262 improvement_name_translation(pimprove),
1263 FONTO_HEADING,
1264 WF_RESTORE_BACKGROUND | WF_SELECT_WITHOUT_BAR);
1265 set_wstate(pwidget, FC_WS_NORMAL);
1266 if (is_wonder(pimprove)) {
1267 pwidget->string_utf8->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_LUX);
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;
1277 } requirement_vector_iterate_end;
1278 }
1279 } improvement_iterate_end;
1280
1281 unit_count = 0;
1282 unit_type_iterate(un) {
1283 if (is_tech_req_for_utype(un, advance_by_number(tech))) {
1284 pwidget = create_iconlabel_from_chars_fonto(
1285 resize_surface_box(get_unittype_surface(un, direction8_invalid()),
1286 adj_size(48), adj_size(48), 1, TRUE, TRUE),
1287 pwindow->dst, utype_name_translation(un), FONTO_HEADING,
1288 (WF_FREE_THEME | WF_RESTORE_BACKGROUND | WF_SELECT_WITHOUT_BAR));
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 }
1296 } unit_type_iterate_end;
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') {
1303 utf8_str *pstr = create_utf8_from_char_fonto(buffer, FONTO_ATTENTION);
1304
1305 convert_utf8_str_to_const_surface_width(pstr, adj_size(640) - start_x - adj_size(20));
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/**********************************************************************/
1409 static void redraw_tech_tree_dlg(void)
1410{
1411 SDL_Color *line_color = get_theme_color(COLOR_THEME_HELPDLG_LINE);
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,
1434 get_theme_color(COLOR_THEME_HELPDLG_FRAME));
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 */
1483 create_line(store->requirement_button[i]->dst->surface,
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) {
1492 create_line(store->requirement_button[i]->dst->surface,
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) {
1501 create_line(store->requirement_button[i]->dst->surface,
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);
1507 create_line(store->requirement_button[i]->dst->surface,
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) {
1516 create_line(store->requirement_button[i]->dst->surface,
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);
1522 create_line(store->requirement_button[i]->dst->surface,
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:
1550 line_color = get_theme_color(COLOR_THEME_HELPDLG_LINE2);
1551 break;
1552 case 1:
1553 line_color = get_theme_color(COLOR_THEME_HELPDLG_LINE3);
1554 break;
1555 default:
1556 line_color = get_theme_color(COLOR_THEME_HELPDLG_LINE);
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 */
1643 redraw_group(help_dlg->begin_widget_list, pwindow->prev->prev, FALSE);
1644
1645 widget_flush(pwindow);
1646}
1647
1648/**********************************************************************/
1651 static int toggle_full_tree_mode_in_help_dlg_callback(struct widget *pwidget)
1652{
1653 if (PRESSED_EVENT(main_data.event)) {
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/**********************************************************************/
1671 static struct widget *create_tech_tree(Tech_type_id tech, int width,
1672 struct widget *pwindow,
1673 struct techs_buttons *store)
1674{
1675 int i, w, h, req_count, targets_count, sub_req_count, sub_targets_count;
1676 struct widget *pwidget;
1677 struct widget *ptech;
1678 utf8_str *pstr;
1679 SDL_Surface *surf;
1680 struct widget *dock = store->dock;
1681
1682 pstr = create_utf8_str_fonto(NULL, 0, FONTO_DEFAULT);
1683 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
1684
1685 copy_chars_to_utf8_str(pstr, advance_name_translation(advance_by_number(tech)));
1686 surf = create_select_tech_icon(pstr, tech, TIM_FULL_MODE);
1687 pwidget = create_icon2(surf, pwindow->dst,
1688 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
1689
1690 set_wstate(pwidget, FC_WS_NORMAL);
1691 pwidget->action = show_tech_tree_callback;
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++) {
1699 Tech_type_id ar = advance_required(tech, i);
1700 struct advance *vap = valid_advance_by_number(ar);
1701
1702 if (NULL != vap && A_NONE != ar) {
1703 copy_chars_to_utf8_str(pstr, advance_name_translation(vap));
1704 surf = create_select_tech_icon(pstr, ar, TIM_SMALL_MODE);
1705 pwidget = create_icon2(surf, pwindow->dst,
1706 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
1707 set_wstate(pwidget, FC_WS_NORMAL);
1708 pwidget->action = change_tech_callback;
1709 pwidget->id = MAX_ID - ar;
1710 widget_add_as_prev(pwidget, dock);
1711 dock = pwidget;
1712 store->requirement_button[req_count++] = pwidget;
1713 }
1714 }
1715
1716 sub_req_count = 0;
1717
1718 if (store->show_full_tree && req_count > 0) {
1719 int j, sub_tech;
1720
1721 for (j = 0; j < req_count; j++) {
1722 sub_tech = MAX_ID - store->requirement_button[j]->id;
1723 for (i = AR_ONE; i <= AR_TWO; i++) {
1724 Tech_type_id ar = advance_required(sub_tech, i);
1725 struct advance *vap = valid_advance_by_number(ar);
1726
1727 if (NULL != vap && A_NONE != ar) {
1728 copy_chars_to_utf8_str(pstr, advance_name_translation(vap));
1729 surf = create_select_tech_icon(pstr, ar, TIM_SMALL_MODE);
1730 pwidget = create_icon2(surf, pwindow->dst,
1731 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
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;
1748 advance_index_iterate(A_FIRST, aidx) {
1749 if ((targets_count < 6)
1750 && (advance_required(aidx, AR_ONE) == tech
1751 || advance_required(aidx, AR_TWO) == tech)) {
1752 copy_chars_to_utf8_str(pstr, advance_name_translation(advance_by_number(aidx)));
1753 surf = create_select_tech_icon(pstr, aidx, TIM_SMALL_MODE);
1754 pwidget = create_icon2(surf, pwindow->dst,
1755 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
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 }
1764 } advance_index_iterate_end;
1765 if (targets_count < 6) {
1766 store->targets[targets_count] = NULL;
1767 }
1768
1769 sub_targets_count = 0;
1770 if (targets_count > 0) {
1771 int sub_tech;
1772
1773 for (i = 0; i < targets_count; i++) {
1774 sub_tech = MAX_ID - store->targets[i]->id;
1775 if (advance_required(sub_tech, AR_ONE) == tech
1776 && advance_required(sub_tech, AR_TWO) != A_NONE) {
1777 sub_tech = advance_required(sub_tech, AR_TWO);
1778 } else if (advance_required(sub_tech, AR_TWO) == tech
1779 && advance_required(sub_tech, AR_ONE) != A_NONE) {
1780 sub_tech = advance_required(sub_tech, AR_ONE);
1781 } else {
1782 continue;
1783 }
1784
1785 copy_chars_to_utf8_str(pstr, advance_name_translation(advance_by_number(sub_tech)));
1786 surf = create_select_tech_icon(pstr, sub_tech, TIM_SMALL_MODE);
1787 pwidget = create_icon2(surf, pwindow->dst,
1788 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
1789 set_wstate(pwidget, FC_WS_NORMAL);
1790 pwidget->action = change_tech_callback;
1791 pwidget->id = MAX_ID - sub_tech;
1792 widget_add_as_prev(pwidget, dock);
1793 dock = pwidget;
1794 store->sub_targets[sub_targets_count++] = pwidget;
1795 }
1796 }
1797 if (sub_targets_count < 6) {
1798 store->sub_targets[sub_targets_count] = NULL;
1799 }
1800
1801 FREEUTF8STR(pstr);
1802
1803 /* ------------------------------------------ */
1804 if (sub_req_count > 0) {
1805 w = (adj_size(20) + store->sub_req[0]->size.w) * 2;
1806 w += (pwindow->size.w - (20 + store->sub_req[0]->size.w + w + ptech->size.w)) / 2;
1807 } else {
1808 if (req_count > 0) {
1809 w = (pwindow->area.x + 1
1810 + width + store->requirement_button[0]->size.w * 2 + adj_size(20));
1811 w += (pwindow->size.w - ((adj_size(20) + store->requirement_button[0]->size.w)
1812 + w + ptech->size.w)) / 2;
1813 } else {
1814 w = (pwindow->size.w - ptech->size.w) / 2;
1815 }
1816 }
1817
1818 ptech->size.x = pwindow->size.x + w;
1819 ptech->size.y = pwindow->area.y + (pwindow->area.h - ptech->size.h) / 2;
1820
1821 if (req_count > 0) {
1822 h = (req_count == 1 ? store->requirement_button[0]->size.h :
1823 req_count * (store->requirement_button[0]->size.h + adj_size(80)) - adj_size(80));
1824 h = ptech->size.y + (ptech->size.h - h) / 2;
1825 for (i = 0; i < req_count; i++) {
1826 store->requirement_button[i]->size.x
1827 = ptech->size.x - adj_size(20) - store->requirement_button[i]->size.w;
1828 store->requirement_button[i]->size.y = h;
1829 h += (store->requirement_button[i]->size.h + adj_size(80));
1830 }
1831 }
1832
1833 if (sub_req_count > 0) {
1834 h = (sub_req_count == 1 ? store->sub_req[0]->size.h :
1835 sub_req_count * (store->sub_req[0]->size.h + adj_size(20)) - adj_size(20));
1836 h = ptech->size.y + (ptech->size.h - h) / 2;
1837 for (i = 0; i < sub_req_count; i++) {
1838 store->sub_req[i]->size.x
1839 = ptech->size.x - (adj_size(20) + store->sub_req[i]->size.w) * 2;
1840 store->sub_req[i]->size.y = h;
1841 h += (store->sub_req[i]->size.h + adj_size(20));
1842 }
1843 }
1844
1845 if (targets_count > 0) {
1846 h = (targets_count == 1 ? store->targets[0]->size.h :
1847 targets_count * (store->targets[0]->size.h + adj_size(20)) - adj_size(20));
1848 h = ptech->size.y + (ptech->size.h - h) / 2;
1849 for (i = 0; i < targets_count; i++) {
1850 store->targets[i]->size.x = ptech->size.x + ptech->size.w + adj_size(20);
1851 store->targets[i]->size.y = h;
1852 h += (store->targets[i]->size.h + adj_size(20));
1853 }
1854 }
1855
1856 if (sub_targets_count > 0) {
1857 if (sub_targets_count < 3) {
1858 store->sub_targets[0]->size.x
1859 = ptech->size.x + ptech->size.w - store->sub_targets[0]->size.w;
1860 store->sub_targets[0]->size.y
1861 = ptech->size.y - store->sub_targets[0]->size.h - adj_size(10);
1862 if (store->sub_targets[1]) {
1863 store->sub_targets[1]->size.x
1864 = ptech->size.x + ptech->size.w - store->sub_targets[1]->size.w;
1865 store->sub_targets[1]->size.y = ptech->size.y + ptech->size.h + adj_size(10);
1866 }
1867 } else {
1868 if (sub_targets_count < 5) {
1869 for (i = 0; i < MIN(sub_targets_count, 4); i++) {
1870 store->sub_targets[i]->size.x
1871 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1872 if (i < 2) {
1873 store->sub_targets[i]->size.y
1874 = ptech->size.y - (store->sub_targets[i]->size.h + adj_size(5)) * (2 - i);
1875 } else {
1876 store->sub_targets[i]->size.y
1877 = ptech->size.y + ptech->size.h + adj_size(5)
1878 + (store->sub_targets[i]->size.h + adj_size(5)) * (i - 2);
1879 }
1880 }
1881 } else {
1882 h = (store->sub_targets[0]->size.h + adj_size(6));
1883 for (i = 0; i < MIN(sub_targets_count, 6); i++) {
1884 switch (i) {
1885 case 0:
1886 store->sub_targets[i]->size.x
1887 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1888 store->sub_targets[i]->size.y = ptech->size.y - h * 2;
1889 break;
1890 case 1:
1891 store->sub_targets[i]->size.x
1892 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w * 2
1893 - adj_size(10);
1894 store->sub_targets[i]->size.y = ptech->size.y - h - h / 2;
1895 break;
1896 case 2:
1897 store->sub_targets[i]->size.x
1898 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1899 store->sub_targets[i]->size.y = ptech->size.y - h;
1900 break;
1901 case 3:
1902 store->sub_targets[i]->size.x
1903 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1904 store->sub_targets[i]->size.y = ptech->size.y + ptech->size.h + adj_size(6);
1905 break;
1906 case 4:
1907 store->sub_targets[i]->size.x
1908 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1909 store->sub_targets[i]->size.y = ptech->size.y + ptech->size.h + adj_size(6) + h;
1910 break;
1911 default:
1912 store->sub_targets[i]->size.x
1913 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w * 2
1914 - adj_size(10);
1915 store->sub_targets[i]->size.y
1916 = ptech->size.y + ptech->size.h + adj_size(6) + h / 2 ;
1917 break;
1918 }
1919 }
1920 }
1921 }
1922 }
1923
1924 return pwidget;
1925}
1926
1927/**********************************************************************/
1930 void popup_tech_info(Tech_type_id tech)
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) {
1947 popdown_help_dialog();
1948 }
1949
1950 /* Create new dialog if it doesn't exist yet */
1951 if (!help_dlg) {
1952 current_help_dlg = HELP_TECH;
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"),
1964 FONTO_ATTENTION);
1965 title->style |= TTF_STYLE_BOLD;
1966
1967 pwindow = create_window_skeleton(NULL, title, WF_FREE_DATA);
1968 pwindow->data.ptr = (void *)store;
1969 pwindow->action = help_dlg_window_callback;
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,
1980 WF_WIDGET_HAS_INFO_LABEL
1981 | WF_RESTORE_BACKGROUND);
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 ---*/
1994 pstr = create_utf8_str_fonto(NULL, 0, FONTO_DEFAULT);
1995 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
1996
1997 tech_count = 0;
1998 advance_index_iterate(A_FIRST, i) {
1999 struct advance *vap = valid_advance_by_number(i);
2000
2001 if (vap) {
2002 copy_chars_to_utf8_str(pstr, advance_name_translation(vap));
2003 surf = create_select_tech_icon(pstr, i, TIM_SMALL_MODE);
2004 advance_label = create_icon2(surf, pwindow->dst,
2005 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
2006
2007 set_wstate(advance_label, FC_WS_NORMAL);
2008 advance_label->action = change_tech_callback;
2009 add_to_gui_list(MAX_ID - i, advance_label);
2010
2011 if (tech_count++ >= 10) {
2012 set_wflag(advance_label, WF_HIDDEN);
2013 }
2014 }
2015 } advance_index_iterate_end;
2016
2017 FREEUTF8STR(pstr);
2018
2019 help_dlg->end_active_widget_list = dock->prev;
2020 help_dlg->begin_widget_list = advance_label ? advance_label : close_button;
2021 help_dlg->begin_active_widget_list = help_dlg->begin_widget_list;
2022
2023 if (tech_count > 10) {
2024 help_dlg->active_widget_list = help_dlg->end_active_widget_list;
2025 scrollbar_width = create_vertical_scrollbar(help_dlg, 1, 10, TRUE, TRUE);
2026 }
2027
2028 /* Toggle techs list button */
2029 list_toggle_button = create_themeicon_button_from_chars_fonto(
2030 current_theme->up_icon,
2031 pwindow->dst,
2032 _("Advances"),
2033 FONTO_DEFAULT, 0);
2034 list_toggle_button->action = toggle_full_tree_mode_in_help_dlg_callback;
2035 if (store->show_tree) {
2036 set_wstate(list_toggle_button, FC_WS_NORMAL);
2037 }
2038 widget_resize(list_toggle_button, adj_size(160), adj_size(15));
2039 list_toggle_button->string_utf8->fgcol = *get_theme_color(COLOR_THEME_HELPDLG_TEXT);
2040
2041 add_to_gui_list(ID_BUTTON, list_toggle_button);
2042
2043 dock = list_toggle_button;
2044 store->dock = dock;
2045 } else {
2046 created = FALSE;
2047 scrollbar_width = (help_dlg->scroll ? help_dlg->scroll->up_left_button->size.w: 0);
2048 pwindow = help_dlg->end_widget_list;
2049 store = (struct techs_buttons *)pwindow->data.ptr;
2050 dock = store->dock;
2051
2052 /* Delete any previous list entries */
2053 if (dock != help_dlg->begin_widget_list) {
2054 del_group_of_widgets_from_gui_list(help_dlg->begin_widget_list, dock->prev);
2055 help_dlg->begin_widget_list = dock;
2056 }
2057
2058 /* Show/hide techs list */
2059 list_toggle_button = dock;
2060
2061 if (store->show_tree) {
2062 set_wstate(list_toggle_button, FC_WS_NORMAL);
2063 } else {
2064 set_wstate(list_toggle_button, FC_WS_DISABLED);
2065 }
2066
2067 if (store->show_full_tree) {
2068 /* All entries are visible without scrolling */
2069 hide_group(help_dlg->begin_active_widget_list,
2070 help_dlg->end_active_widget_list);
2071 hide_scrollbar(help_dlg->scroll);
2072 } else {
2073 int count = help_dlg->scroll->active;
2074
2075 advance_label = help_dlg->active_widget_list;
2076 while (advance_label->prev != NULL && --count > 0) {
2077 advance_label = advance_label->prev;
2078 }
2079 show_group(advance_label, help_dlg->active_widget_list);
2080 show_scrollbar(help_dlg->scroll);
2081 }
2082 }
2083
2084 /* --------------------------------------------------------- */
2085 if (created) {
2086
2087 surf = theme_get_background(active_theme, BACKGROUND_HELPDLG);
2088 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
2089 FREESURFACE(surf);
2090 }
2091
2092 area = pwindow->area;
2093
2094 widget_set_position(pwindow,
2095 (main_window_width() - pwindow->size.w) / 2,
2096 (main_window_height() - pwindow->size.h) / 2);
2097
2098 /* Exit button */
2099 close_button = pwindow->prev;
2100 widget_set_position(close_button,
2101 area.x + area.w - close_button->size.w - 1,
2102 pwindow->size.y + adj_size(2));
2103
2104 /* List toggle button */
2105 list_toggle_button = store->dock;
2106 widget_set_position(list_toggle_button, area.x, area.y);
2107
2108 /* List entries */
2109 h = setup_vertical_widgets_position(1, area.x + scrollbar_width,
2110 area.y + list_toggle_button->size.h, 0, 0,
2111 help_dlg->begin_active_widget_list,
2112 help_dlg->end_active_widget_list);
2113 /* Scrollbar */
2114 if (help_dlg->scroll) {
2115 setup_vertical_scrollbar_area(help_dlg->scroll,
2116 area.x, area.y + list_toggle_button->size.h,
2117 h, FALSE);
2118 }
2119 }
2120
2121 if (store->show_tree) {
2122 help_dlg->begin_widget_list = create_tech_tree(tech, scrollbar_width, pwindow, store);
2123 redraw_tech_tree_dlg();
2124 } else {
2125 help_dlg->begin_widget_list = create_tech_info(tech, scrollbar_width, pwindow, store);
2126 redraw_tech_info_dlg();
2127 }
2128}
width
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
city_improvement_name_translation
const char * city_improvement_name_translation(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:663
client
struct civclient client
Definition client_main.c:153
client_main.h
incite_cost
char * incite_cost
Definition comments.c:74
current_theme
QString current_theme
Definition fc_client.cpp:64
Tech_type_id
int Tech_type_id
Definition fc_types.h:381
Impr_type_id
int Impr_type_id
Definition fc_types.h:380
Unit_type_id
int Unit_type_id
Definition fc_types.h:386
O_SHIELD
@ O_SHIELD
Definition fc_types.h:101
O_FOOD
@ O_FOOD
Definition fc_types.h:101
O_GOLD
@ O_GOLD
Definition fc_types.h:101
fcintl.h
Q_
#define Q_(String)
Definition fcintl.h:70
PL_
#define PL_(String1, String2, n)
Definition fcintl.h:71
_
#define _(String)
Definition fcintl.h:67
game.h
government_name_translation
const char * government_name_translation(const struct government *pgovern)
Definition government.c:143
government_index
Government_type_id government_index(const struct government *pgovern)
Definition government.c:82
government.h
governments_iterate
#define governments_iterate(NAME_pgov)
Definition government.h:122
governments_iterate_end
#define governments_iterate_end
Definition government.h:125
unit_info_label
GtkWidget * unit_info_label
Definition gui_main.c:151
create_tech_tree
static void create_tech_tree(int tech, int levels, GtkTreeIter *parent)
Definition helpdlg.c:226
popdown_help_dialog
void popdown_help_dialog(void)
Definition helpdlg.c:186
popup_help_dialog_string
void popup_help_dialog_string(const char *item)
Definition helpdlg.c:212
popup_help_dialog_typed
void popup_help_dialog_typed(const char *item, enum help_page_type htype)
Definition helpdlg.c:196
flush_dirty
void flush_dirty(void)
Definition mapview.c:468
title
const char * title
Definition repodlgs.c:1314
get_theme_color
SDL_Color * get_theme_color(enum theme_color themecolor)
Definition colors.c:47
main_window_width
int main_window_width(void)
Definition graphics.c:685
fill_rect_alpha
int fill_rect_alpha(SDL_Surface *surf, SDL_Rect *prect, SDL_Color *pcolor)
Definition graphics.c:865
create_line
void create_line(SDL_Surface *dest, Sint16 x0, Sint16 y0, Sint16 x1, Sint16 y1, SDL_Color *pcolor)
Definition graphics.c:1381
copy_surface
SDL_Surface * copy_surface(SDL_Surface *src)
Definition graphics.c:1309
alphablit
int alphablit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, unsigned char alpha_mod)
Definition graphics.c:199
main_data
struct sdl2_data main_data
Definition graphics.c:57
create_surf
SDL_Surface * create_surf(int width, int height, Uint32 flags)
Definition graphics.c:351
create_frame
void create_frame(SDL_Surface *dest, Sint16 left, Sint16 top, Sint16 width, Sint16 height, SDL_Color *pcolor)
Definition graphics.c:1350
main_window_height
int main_window_height(void)
Definition graphics.c:693
resize_surface_box
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
FREESURFACE
#define FREESURFACE(ptr)
Definition graphics.h:322
adj_surf
#define adj_surf(surf)
Definition graphics.h:200
map_rgba
#define map_rgba(format, color)
Definition graphics.h:315
ID_BUTTON
@ ID_BUTTON
Definition gui_id.h:29
ID_LABEL
@ ID_LABEL
Definition gui_id.h:27
ID_WINDOW
@ ID_WINDOW
Definition gui_id.h:30
adj_size
#define adj_size(size)
Definition gui_main.h:141
PRESSED_EVENT
#define PRESSED_EVENT(event)
Definition gui_main.h:71
copy_chars_to_utf8_str
utf8_str * copy_chars_to_utf8_str(utf8_str *pstr, const char *pchars)
Definition gui_string.c:251
create_text_surf_from_utf8
SDL_Surface * create_text_surf_from_utf8(utf8_str *pstr)
Definition gui_string.c:425
change_fonto_utf8
void change_fonto_utf8(utf8_str *pstr, enum font_origin origin)
Definition gui_string.c:584
create_utf8_str_fonto
utf8_str * create_utf8_str_fonto(char *in_text, size_t n_alloc, enum font_origin origin)
Definition gui_string.c:241
convert_utf8_str_to_const_surface_width
bool convert_utf8_str_to_const_surface_width(utf8_str *pstr, int width)
Definition gui_string.c:449
create_text_surf_smaller_than_w
SDL_Surface * create_text_surf_smaller_than_w(utf8_str *pstr, int w)
Definition gui_string.c:539
FREEUTF8STR
#define FREEUTF8STR(pstr)
Definition gui_string.h:93
SF_CENTER
#define SF_CENTER
Definition gui_string.h:40
FONTO_HEADING
@ FONTO_HEADING
Definition gui_string.h:69
FONTO_DEFAULT
@ FONTO_DEFAULT
Definition gui_string.h:65
FONTO_ATTENTION
@ FONTO_ATTENTION
Definition gui_string.h:67
FONTO_MAX
@ FONTO_MAX
Definition gui_string.h:71
create_utf8_from_char_fonto
#define create_utf8_from_char_fonto(string_in, fonto)
Definition gui_string.h:108
get_tech_color
SDL_Color * get_tech_color(Tech_type_id tech_id)
Definition gui_tilespec.c:453
get_tech_icon
SDL_Surface * get_tech_icon(Tech_type_id tech)
Definition gui_tilespec.c:429
get_government_surface
static SDL_Surface * get_government_surface(const struct government *gov)
Definition gui_tilespec.h:235
get_building_surface
static SDL_Surface * get_building_surface(const struct impr_type *pimprove)
Definition gui_tilespec.h:251
get_unittype_surface
static SDL_Surface * get_unittype_surface(const struct unit_type *punittype, enum direction8 facing)
Definition gui_tilespec.h:259
exit_help_dlg_callback
static int exit_help_dlg_callback(struct widget *pwidget)
Definition helpdlg.c:130
popup_gov_info
void popup_gov_info(int gov)
Definition helpdlg.c:155
popup_tech_info
void popup_tech_info(Tech_type_id tech)
Definition helpdlg.c:1932
bufsz
static const int bufsz
Definition helpdlg.c:70
help_dlg
static struct advanced_dialog * help_dlg
Definition helpdlg.c:52
show_tech_tree_callback
static int show_tech_tree_callback(struct widget *pwidget)
Definition helpdlg.c:1039
current_help_dlg
enum help_page_type current_help_dlg
Definition helpdlg.c:68
redraw_tech_info_dlg
static void redraw_tech_info_dlg(void)
Definition helpdlg.c:1058
redraw_unit_info_dlg
static void redraw_unit_info_dlg(void)
Definition helpdlg.c:602
change_tech_callback
static int change_tech_callback(struct widget *pwidget)
Definition helpdlg.c:1027
popup_help_browser
void popup_help_browser(void)
Definition helpdlg.c:77
create_tech_info
static struct widget * create_tech_info(Tech_type_id tech, int width, struct widget *pwindow, struct techs_buttons *store)
Definition helpdlg.c:1131
popup_impr_info
void popup_impr_info(Impr_type_id impr)
Definition helpdlg.c:202
redraw_tech_tree_dlg
static void redraw_tech_tree_dlg(void)
Definition helpdlg.c:1411
help_dlg_window_callback
static int help_dlg_window_callback(struct widget *pwindow)
Definition helpdlg.c:122
change_unit_callback
static int change_unit_callback(struct widget *pwidget)
Definition helpdlg.c:590
popup_unit_info
void popup_unit_info(Unit_type_id type_id)
Definition helpdlg.c:630
change_gov_callback
static int change_gov_callback(struct widget *pwidget)
Definition helpdlg.c:143
redraw_impr_info_dlg
static void redraw_impr_info_dlg(void)
Definition helpdlg.c:174
toggle_full_tree_mode_in_help_dlg_callback
static int toggle_full_tree_mode_in_help_dlg_callback(struct widget *pwidget)
Definition helpdlg.c:1653
change_impr_callback
static int change_impr_callback(struct widget *pwidget)
Definition helpdlg.c:162
create_select_tech_icon
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
@ TIM_SMALL_MODE
Definition repodlgs.h:32
TIM_FULL_MODE
@ TIM_FULL_MODE
Definition repodlgs.h:30
theme_get_background
SDL_Surface * theme_get_background(const struct theme *t, enum theme_background background)
Definition themebackgrounds.c:94
BACKGROUND_HELPDLG
@ BACKGROUND_HELPDLG
Definition themebackgrounds.h:36
COLOR_THEME_HELPDLG_FRAME
@ COLOR_THEME_HELPDLG_FRAME
Definition themecolors.h:87
COLOR_THEME_HELPDLG_TEXT
@ COLOR_THEME_HELPDLG_TEXT
Definition themecolors.h:91
COLOR_THEME_HELPDLG_LINE3
@ COLOR_THEME_HELPDLG_LINE3
Definition themecolors.h:90
COLOR_THEME_CITYDLG_LUX
@ COLOR_THEME_CITYDLG_LUX
Definition themecolors.h:60
COLOR_THEME_HELPDLG_LINE
@ COLOR_THEME_HELPDLG_LINE
Definition themecolors.h:88
COLOR_THEME_HELPDLG_LINE2
@ COLOR_THEME_HELPDLG_LINE2
Definition themecolors.h:89
active_theme
struct theme * active_theme
Definition themespec.c:154
add_to_gui_list
void add_to_gui_list(Uint16 id, struct widget *gui)
Definition widget.c:586
del_group_of_widgets_from_gui_list
void del_group_of_widgets_from_gui_list(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:863
show_group
void show_group(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:934
hide_group
void hide_group(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:915
widget_add_as_prev
void widget_add_as_prev(struct widget *new_widget, struct widget *add_dock)
Definition widget.c:602
setup_vertical_widgets_position
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
redraw_group
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
popdown_window_group_dialog
void popdown_window_group_dialog(struct widget *begin_group_widget_list, struct widget *end_group_widget_list)
Definition widget.c:983
widget_set_position
static void widget_set_position(struct widget *pwidget, int x, int y)
Definition widget.h:266
MAX_ID
#define MAX_ID
Definition widget.h:38
FC_WS_DISABLED
@ FC_WS_DISABLED
Definition widget.h:99
FC_WS_NORMAL
@ FC_WS_NORMAL
Definition widget.h:96
widget_flush
static void widget_flush(struct widget *pwidget)
Definition widget.h:291
set_wstate
void set_wstate(struct widget *pwidget, enum widget_state state)
Definition widget_core.c:36
WF_WIDGET_HAS_INFO_LABEL
@ WF_WIDGET_HAS_INFO_LABEL
Definition widget.h:88
WF_FREE_DATA
@ WF_FREE_DATA
Definition widget.h:78
WF_SELECT_WITHOUT_BAR
@ WF_SELECT_WITHOUT_BAR
Definition widget.h:89
WF_RESTORE_BACKGROUND
@ WF_RESTORE_BACKGROUND
Definition widget.h:85
WF_HIDDEN
@ WF_HIDDEN
Definition widget.h:68
WF_FREE_THEME
@ WF_FREE_THEME
Definition widget.h:72
widget_resize
static void widget_resize(struct widget *pwidget, int w, int h)
Definition widget.h:271
set_wflag
void set_wflag(struct widget *pwidget, enum widget_flag flag)
Definition widget_core.c:54
create_themeicon_button_from_chars_fonto
#define create_themeicon_button_from_chars_fonto(icon_theme, pdest, char_string, fonto, flags)
Definition widget_button.h:36
create_themeicon
struct widget * create_themeicon(SDL_Surface *icon_theme, struct gui_layer *pdest, Uint32 flags)
Definition widget_icon.c:212
create_icon2
struct widget * create_icon2(SDL_Surface *icon, struct gui_layer *pdest, Uint32 flags)
Definition widget_icon.c:337
create_iconlabel
struct widget * create_iconlabel(SDL_Surface *icon, struct gui_layer *pdest, utf8_str *pstr, Uint32 flags)
Definition widget_label.c:215
create_iconlabel_from_chars_fonto
#define create_iconlabel_from_chars_fonto(picon, pdest, chars, fonto, flags)
Definition widget_label.h:20
setup_vertical_scrollbar_area
void setup_vertical_scrollbar_area(struct scroll_bar *scroll, Sint16 start_x, Sint16 start_y, Uint16 height, bool swap_start_x)
Definition widget_scrollbar.c:567
create_vertical_scrollbar
Uint32 create_vertical_scrollbar(struct advanced_dialog *dlg, Uint8 step, Uint8 active, bool create_scrollbar, bool create_buttons)
Definition widget_scrollbar.c:486
hide_scrollbar
#define hide_scrollbar(scrollbar)
Definition widget_scrollbar.h:36
show_scrollbar
#define show_scrollbar(scrollbar)
Definition widget_scrollbar.h:59
resize_window
bool resize_window(struct widget *pwindow, SDL_Surface *bcgd, SDL_Color *pcolor, Uint16 new_w, Uint16 new_h)
Definition widget_window.c:255
create_window_skeleton
struct widget * create_window_skeleton(struct gui_layer *pdest, utf8_str *title, Uint32 flags)
Definition widget_window.c:180
gui_id.h
gui_tilespec.h
themespec.h
widget.h
colors.h
graphics.h
gui_main.h
helpdlg.h
mapview.h
repodlgs.h
sprite.h
helptext_advance
void helptext_advance(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, int i)
Definition helpdata.c:3263
helptext_building
char * helptext_building(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct impr_type *pimprove)
Definition helpdata.c:1381
helptext_unit
char * helptext_unit(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, const struct unit_type *utype)
Definition helpdata.c:1865
helpdata.h
help_page_type
help_page_type
Definition helpdlg_g.h:20
HELP_ANY
@ HELP_ANY
Definition helpdlg_g.h:20
HELP_LAST
@ HELP_LAST
Definition helpdlg_g.h:25
HELP_IMPROVEMENT
@ HELP_IMPROVEMENT
Definition helpdlg_g.h:20
HELP_UNIT
@ HELP_UNIT
Definition helpdlg_g.h:20
HELP_TECH
@ HELP_TECH
Definition helpdlg_g.h:21
valid_improvement
const struct impr_type * valid_improvement(const struct impr_type *pimprove)
Definition improvement.c:211
improvement_by_number
struct impr_type * improvement_by_number(const Impr_type_id id)
Definition improvement.c:194
impr_base_build_shield_cost
int impr_base_build_shield_cost(const struct impr_type *pimprove)
Definition improvement.c:261
improvement_number
Impr_type_id improvement_number(const struct impr_type *pimprove)
Definition improvement.c:184
is_wonder
bool is_wonder(const struct impr_type *pimprove)
Definition improvement.c:343
is_convert_improvement
bool is_convert_improvement(const struct impr_type *pimprove)
Definition improvement.c:811
improvement_name_translation
const char * improvement_name_translation(const struct impr_type *pimprove)
Definition improvement.c:243
improvement_iterate_end
#define improvement_iterate_end
Definition improvement.h:205
improvement_iterate
#define improvement_iterate(_p)
Definition improvement.h:199
log.h
log_debug
#define log_debug(message,...)
Definition log.h:115
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
move_points_text
const char * move_points_text(int mp, bool reduce)
Definition movement.c:1016
movement.h
universal_name_translation
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
Definition requirements.c:7064
requirement_vector_iterate_end
#define requirement_vector_iterate_end
Definition requirements.h:94
requirement_vector_iterate
#define requirement_vector_iterate(req_vec, preq)
Definition requirements.h:92
MIN
#define MIN(x, y)
Definition shared.h:55
MAX
#define MAX(x, y)
Definition shared.h:54
step
int step
Definition specpq.h:92
y
struct sprite int int y
Definition sprite_g.h:31
advance
Definition tech.h:124
advanced_dialog
Definition widget.h:180
advanced_dialog::begin_active_widget_list
struct widget * begin_active_widget_list
Definition widget.h:184
advanced_dialog::end_widget_list
struct widget * end_widget_list
Definition widget.h:182
advanced_dialog::end_active_widget_list
struct widget * end_active_widget_list
Definition widget.h:185
advanced_dialog::active_widget_list
struct widget * active_widget_list
Definition widget.h:186
advanced_dialog::scroll
struct scroll_bar * scroll
Definition widget.h:187
advanced_dialog::begin_widget_list
struct widget * begin_widget_list
Definition widget.h:181
civclient::conn
struct connection conn
Definition client_main.h:96
connection::playing
struct player * playing
Definition connection.h:151
gui_layer::surface
SDL_Surface * surface
Definition graphics.h:229
impr_type
Definition improvement.h:50
item
Definition climisc.h:80
scroll_bar::active
Uint8 active
Definition widget_scrollbar.h:24
scroll_bar::up_left_button
struct widget * up_left_button
Definition widget_scrollbar.h:21
sdl2_data::event
SDL_Event event
Definition graphics.h:217
techs_buttons
Definition helpdlg.c:54
techs_buttons::targets
struct widget * targets[6]
Definition helpdlg.c:55
techs_buttons::requirement_button
struct widget * requirement_button[2]
Definition helpdlg.c:56
techs_buttons::sub_req
struct widget * sub_req[4]
Definition helpdlg.c:56
techs_buttons::show_tree
bool show_tree
Definition helpdlg.c:58
techs_buttons::dock
struct widget * dock
Definition helpdlg.c:57
techs_buttons::sub_targets
struct widget * sub_targets[6]
Definition helpdlg.c:55
techs_buttons::show_full_tree
bool show_full_tree
Definition helpdlg.c:59
unit_type
Definition unittype.h:507
unit_type::obsoleted_by
const struct unit_type * obsoleted_by
Definition unittype.h:536
units_buttons
Definition helpdlg.c:62
units_buttons::obsolete_by_button
struct widget * obsolete_by_button
Definition helpdlg.c:63
units_buttons::requirement_button
struct widget * requirement_button
Definition helpdlg.c:64
units_buttons::dock
struct widget * dock
Definition helpdlg.c:65
utf8_str
Definition gui_string.h:52
utf8_str::fgcol
SDL_Color fgcol
Definition gui_string.h:57
widget
Definition widget.h:112
widget::ptr
void * ptr
Definition widget.h:133
widget::key
SDL_Keycode key
Definition widget.h:153
widget::theme2
SDL_Surface * theme2
Definition widget.h:119
widget::prev
struct widget * prev
Definition widget.h:114
widget::dst
struct gui_layer * dst
Definition widget.h:116
widget::mod
Uint16 mod
Definition widget.h:154
widget::string_utf8
utf8_str * string_utf8
Definition widget.h:121
widget::action
int(* action)(struct widget *)
Definition widget.h:157
widget::area
SDL_Rect area
Definition widget.h:149
widget::next
struct widget * next
Definition widget.h:113
widget::info_label
utf8_str * info_label
Definition widget.h:122
widget::id
Uint16 id
Definition widget.h:155
widget::size
SDL_Rect size
Definition widget.h:145
widget::data
union widget::@217 data
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
cat_snprintf
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:986
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
advance_by_number
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
advance_name_translation
const char * advance_name_translation(const struct advance *padvance)
Definition tech.c:300
valid_advance_by_number
struct advance * valid_advance_by_number(const Tech_type_id id)
Definition tech.c:176
advance_required
Tech_type_id advance_required(const Tech_type_id tech, enum tech_req require)
Definition tech.c:121
advance_number
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
advance_index_iterate_end
#define advance_index_iterate_end
Definition tech.h:249
AR_TWO
@ AR_TWO
Definition tech.h:112
AR_ONE
@ AR_ONE
Definition tech.h:111
A_FIRST
#define A_FIRST
Definition tech.h:44
A_NONE
#define A_NONE
Definition tech.h:43
advance_index_iterate
#define advance_index_iterate(_start, _index)
Definition tech.h:245
is_tech_req_for_utype
bool is_tech_req_for_utype(const struct unit_type *ptype, struct advance *padv)
Definition unittype.c:2710
utype_build_shield_cost_base
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1468
utype_primary_tech_req
struct advance * utype_primary_tech_req(const struct unit_type *ptype)
Definition unittype.c:2696
utype_count
Unit_type_id utype_count(void)
Definition unittype.c:80
utype_by_number
struct unit_type * utype_by_number(const Unit_type_id id)
Definition unittype.c:112
utype_number
Unit_type_id utype_number(const struct unit_type *punittype)
Definition unittype.c:100
utype_name_translation
const char * utype_name_translation(const struct unit_type *punittype)
Definition unittype.c:1560
unit_type_iterate
#define unit_type_iterate(_p)
Definition unittype.h:859
unit_type_iterate_end
#define unit_type_iterate_end
Definition unittype.h:866
U_NOT_OBSOLETED
#define U_NOT_OBSOLETED
Definition unittype.h:535