Freeciv-3.2: /fast/freeciv/nightly/S3_2/client/gui-sdl3/helpdlg.c Source File

Freeciv-3.2

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
413 * MAX_NUM_REQS reqs.
414 * Currently it's limited to 1 req. Remember MAX_NUM_REQS is a compile-time
415 * definition. */
416 requirement_vector_iterate(&pimpr_type->reqs, preq) {
417 if (!preq->present) {
418 continue;
419 }
420 requirement_label2
421 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
422 universal_name_translation(&preq->source, buffer, sizeof(buffer)),
423 FONTO_ATTENTION,
424 WF_RESTORE_BACKGROUND);
425 if (preq->source.kind != VUT_ADVANCE) {
426 break; /* FIXME */
427 }
428 requirement_label2->id = MAX_ID - advance_number(preq->source.value.advance);
429 requirement_label2->string_utf8->fgcol
430 = *get_tech_color(advance_number(preq->source.value.advance));
431 requirement_label2->action = change_tech_callback;
432 set_wstate(requirement_label2, FC_WS_NORMAL);
433 break;
434 } requirement_vector_iterate_end;
435
436 if (requirement_label2 == NULL) {
437 requirement_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
438 Q_("?req:None"),
439 FONTO_ATTENTION, 0);
440 requirement_label2->id = ID_LABEL;
441 }
442
443 widget_add_as_prev(requirement_label2, dock);
444 dock = requirement_label2;
445 store->requirement_button = requirement_label2;
446
447 /* Obsolete by */
448 obsolete_by_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
449 _("Obsolete by:"),
450 FONTO_ATTENTION, 0);
451 obsolete_by_label->id = ID_LABEL;
452 widget_add_as_prev(obsolete_by_label, dock);
453 dock = obsolete_by_label;
454
455 requirement_vector_iterate(&pimpr_type->obsolete_by, pobs) {
456 if (pobs->source.kind == VUT_ADVANCE) {
457 obsTech = pobs->source.value.advance;
458 break;
459 }
460 } requirement_vector_iterate_end;
461
462 if (obsTech == NULL) {
463 obsolete_by_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
464 _("Never"),
465 FONTO_ATTENTION, 0);
466 obsolete_by_label2->id = ID_LABEL;
467 } else {
468 obsolete_by_label2
469 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
470 advance_name_translation(obsTech),
471 FONTO_ATTENTION,
472 WF_RESTORE_BACKGROUND);
473 obsolete_by_label2->id = MAX_ID - advance_number(obsTech);
474 obsolete_by_label2->string_utf8->fgcol
475 = *get_tech_color(advance_number(obsTech));
476 obsolete_by_label2->action = change_tech_callback;
477 set_wstate(obsolete_by_label2, FC_WS_NORMAL);
478 }
479 widget_add_as_prev(obsolete_by_label2, dock);
480 dock = obsolete_by_label2;
481 store->obsolete_by_button = obsolete_by_label2;
482
483 /* Helptext */
484 start_x = (area.x + 1 + scrollbar_width + help_dlg->end_active_widget_list->size.w + adj_size(20));
485
486 buffer[0] = '\0';
487 helptext_building(buffer, sizeof(buffer), client.conn.playing, NULL,
488 pimpr_type);
489 if (buffer[0] != '\0') {
490 utf8_str *bstr = create_utf8_from_char_fonto(buffer, FONTO_ATTENTION);
491
492 convert_utf8_str_to_const_surface_width(bstr, adj_size(640) - start_x - adj_size(20));
493 help_text_label = create_iconlabel(NULL, pwindow->dst, bstr, 0);
494 help_text_label->id = ID_LABEL;
495 widget_add_as_prev(help_text_label, dock);
496 text = TRUE;
497 }
498
499 help_dlg->begin_widget_list = help_text_label ? help_text_label : obsolete_by_label2;
500
501 /* --------------------------------------------------------- */
502 if (created) {
503 surf = theme_get_background(active_theme, BACKGROUND_HELPDLG);
504 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
505 FREESURFACE(surf);
506 }
507
508 area = pwindow->area;
509
510 widget_set_position(pwindow,
511 (main_window_width() - pwindow->size.w) / 2,
512 (main_window_height() - pwindow->size.h) / 2);
513
514 /* Exit button */
515 close_button = pwindow->prev;
516 widget_set_position(close_button,
517 area.x + area.w - close_button->size.w - 1,
518 pwindow->size.y + adj_size(2));
519
520 /* List toggle button */
521 list_toggle_button = store->dock;
522 widget_set_position(list_toggle_button, area.x, area.y);
523
524 /* List entries */
525 h = setup_vertical_widgets_position(1, area.x + scrollbar_width,
526 area.y + list_toggle_button->size.h, 0, 0,
527 help_dlg->begin_active_widget_list,
528 help_dlg->end_active_widget_list);
529
530 /* Scrollbar */
531 if (help_dlg->scroll) {
532 setup_vertical_scrollbar_area(help_dlg->scroll,
533 area.x, area.y + list_toggle_button->size.h,
534 h, FALSE);
535 }
536 }
537
538 impr_name_label = store->dock->prev;
539 widget_set_position(impr_name_label, start_x, area.y + adj_size(16));
540
541 start_y = impr_name_label->size.y + impr_name_label->size.h + adj_size(10);
542
543 if (!is_convert_improvement(pimpr_type)) {
544 cost_label = impr_name_label->prev;
545 widget_set_position(cost_label, start_x, start_y);
546 if (!is_wonder(pimpr_type)) {
547 upkeep_label = cost_label->prev;
548 widget_set_position(upkeep_label,
549 cost_label->size.x + cost_label->size.w + adj_size(20),
550 start_y);
551 }
552 start_y += cost_label->size.h;
553 }
554
555 requirement_label = store->requirement_button->next;
556 widget_set_position(requirement_label, start_x, start_y);
557
558 requirement_label2 = store->requirement_button;
559 widget_set_position(requirement_label2,
560 requirement_label->size.x + requirement_label->size.w + adj_size(5),
561 start_y);
562
563 if (store->obsolete_by_button) {
564 obsolete_by_label = store->obsolete_by_button->next;
565 widget_set_position(obsolete_by_label,
566 requirement_label2->size.x + requirement_label2->size.w + adj_size(10),
567 start_y);
568
569 obsolete_by_label2 = store->obsolete_by_button;
570 widget_set_position(obsolete_by_label2,
571 obsolete_by_label->size.x + obsolete_by_label->size.w + adj_size(5),
572 start_y);
573
574 start_y += obsolete_by_label2->size.h;
575 }
576
577 start_y += adj_size(30);
578
579 if (text) {
580 widget_set_position(help_text_label, start_x, start_y);
581 }
582
583 redraw_impr_info_dlg();
584}
585
586/**********************************************************************/
589 static int change_unit_callback(struct widget *pwidget)
590{
591 if (PRESSED_EVENT(main_data.event)) {
592 popup_unit_info(MAX_ID - pwidget->id);
593 }
594
595 return -1;
596}
597
598/**********************************************************************/
601 static void redraw_unit_info_dlg(void)
602{
603 SDL_Color bg_color = {255, 255, 255, 64};
604 struct widget *pwindow = help_dlg->end_widget_list;
605 struct units_buttons *store = (struct units_buttons *)pwindow->data.ptr;
606 SDL_Rect dst;
607
608 redraw_group(pwindow->prev, pwindow, FALSE);
609
610 dst.x = store->dock->prev->size.x - adj_size(10);
611 dst.y = store->dock->prev->size.y - adj_size(10);
612 dst.w = pwindow->size.w - (dst.x - pwindow->size.x) - adj_size(10);
613 dst.h = pwindow->size.h - (dst.y - pwindow->size.y) - adj_size(10);
614
615 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
616
617 create_frame(pwindow->dst->surface,
618 dst.x, dst.y, dst.w, dst.h,
619 get_theme_color(COLOR_THEME_HELPDLG_FRAME));
620
621 /*------------------------------------- */
622 redraw_group(help_dlg->begin_widget_list, pwindow->prev->prev, FALSE);
623 widget_flush(pwindow);
624}
625
626/**********************************************************************/
629 void popup_unit_info(Unit_type_id type_id)
630{
631 SDL_Color bg_color = {255, 255, 255, 128};
632 struct widget *pwindow;
633 struct units_buttons *store;
634 struct widget *close_button = NULL;
635 struct widget *list_toggle_button = NULL;
636 struct widget *unit_button = NULL;
637 struct widget *unit_name_label = NULL;
638 struct widget *unit_info_label = NULL;
639 struct widget *requirement_label = NULL;
640 struct widget *requirement_label2 = NULL;
641 struct widget *obsolete_by_label = NULL;
642 struct widget *obsolete_by_label2 = NULL;
643 struct widget *help_text_label = NULL;
644 struct widget *dock;
645 utf8_str *title;
646 utf8_str *pstr;
647 SDL_Surface *surf;
648 int h, start_x, start_y, utype_count;
649 bool created, text = FALSE;
650 int scrollbar_width = 0;
651 struct unit_type *punittype;
652 char buffer[bufsz];
653 SDL_Rect area;
654 struct advance *req;
655
656 if (current_help_dlg != HELP_UNIT) {
657 popdown_help_dialog();
658 }
659
660 /* Create new dialog if it doesn't exist yet */
661 if (!help_dlg) {
662 SDL_Surface *background_tmpl, *background, *unit_name, *icon;
663 SDL_Rect dst;
664
665 current_help_dlg = HELP_UNIT;
666 created = TRUE;
667
668 /* Create dialog */
669 help_dlg = fc_calloc(1, sizeof(struct advanced_dialog));
670 store = fc_calloc(1, sizeof(struct units_buttons));
671
672 /* Create window */
673 title = create_utf8_from_char_fonto(_("Help : Units"), FONTO_ATTENTION);
674 title->style |= TTF_STYLE_BOLD;
675
676 pwindow = create_window_skeleton(NULL, title, WF_FREE_DATA);
677 pwindow->action = help_dlg_window_callback;
678 set_wstate(pwindow , FC_WS_NORMAL);
679 pwindow->data.ptr = (void *)store;
680 add_to_gui_list(ID_WINDOW, pwindow);
681
682 help_dlg->end_widget_list = pwindow;
683
684 area = pwindow->area;
685
686 /* ------------------ */
687
688 /* Close button */
689 close_button = create_themeicon(current_theme->small_cancel_icon,
690 pwindow->dst,
691 WF_WIDGET_HAS_INFO_LABEL
692 | WF_RESTORE_BACKGROUND);
693 close_button->info_label
694 = create_utf8_from_char_fonto(_("Close Dialog (Esc)"), FONTO_ATTENTION);
695 close_button->action = exit_help_dlg_callback;
696 set_wstate(close_button, FC_WS_NORMAL);
697 close_button->key = SDLK_ESCAPE;
698
699 add_to_gui_list(ID_BUTTON, close_button);
700
701 /* ------------------ */
702 dock = close_button;
703
704 /* --- Create scrollable unit list on the left side ---*/
705
706 pstr = create_utf8_str_fonto(NULL, 0, FONTO_DEFAULT);
707 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
708
709 /* Background template for entries in scroll list */
710 background_tmpl = create_surf(adj_size(135), adj_size(40), SDL_SWSURFACE);
711 SDL_FillSurfaceRect(background_tmpl, NULL,
712 map_rgba(background_tmpl->format, bg_color));
713
714 create_frame(background_tmpl,
715 0, 0, background_tmpl->w - 1, background_tmpl->h - 1,
716 get_theme_color(COLOR_THEME_HELPDLG_FRAME));
717
718 utype_count = 0;
719 unit_type_iterate(ut) {
720
721 /* Copy background surface */
722 background = copy_surface(background_tmpl);
723
724 /* Blit unit name */
725 copy_chars_to_utf8_str(pstr, utype_name_translation(ut));
726 unit_name = create_text_surf_smaller_than_w(pstr, adj_size(100 - 4));
727 dst.x = adj_size(35) + (background->w - unit_name->w - adj_size(35)) / 2;
728 dst.y = (background->h - unit_name->h) / 2;
729 alphablit(unit_name, NULL, background, &dst, 255);
730 FREESURFACE(unit_name);
731
732 /* Blit unit icon */
733 icon = resize_surface_box(get_unittype_surface(ut, direction8_invalid()),
734 adj_size(36), adj_size(36), 1, TRUE, TRUE);
735 dst.x = (adj_size(35) - icon->w) / 2;
736 dst.y = (background->h - icon->h) / 2;
737 alphablit(icon, NULL, background, &dst, 255);
738 FREESURFACE(icon);
739
740 unit_button = create_icon2(background, pwindow->dst,
741 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
742
743 set_wstate(unit_button, FC_WS_NORMAL);
744 unit_button->action = change_unit_callback;
745 add_to_gui_list(MAX_ID - utype_number(ut), unit_button);
746
747 if (utype_count++ >= 10) {
748 set_wflag(unit_button, WF_HIDDEN);
749 }
750
751 } unit_type_iterate_end;
752
753 FREESURFACE(background_tmpl);
754
755 help_dlg->end_active_widget_list = dock->prev;
756 help_dlg->begin_widget_list = unit_button ? unit_button : close_button;
757 help_dlg->begin_active_widget_list = help_dlg->begin_widget_list;
758
759 if (utype_count > 10) {
760 help_dlg->active_widget_list = help_dlg->end_active_widget_list;
761 scrollbar_width = create_vertical_scrollbar(help_dlg, 1, 10, TRUE, TRUE);
762 }
763
764 /* Toggle techs list button */
765 list_toggle_button = create_themeicon_button_from_chars_fonto(
766 current_theme->up_icon,
767 pwindow->dst,
768 _("Units"),
769 FONTO_DEFAULT, 0);
770#if 0
771 list_toggle_button->action = toggle_full_tree_mode_in_help_dlg_callback;
772 if (store->show_tree) {
773 set_wstate(list_toggle_button, FC_WS_NORMAL);
774 }
775#endif
776
777 widget_resize(list_toggle_button, adj_size(160), adj_size(15));
778 list_toggle_button->string_utf8->fgcol = *get_theme_color(COLOR_THEME_HELPDLG_TEXT);
779
780 add_to_gui_list(ID_BUTTON, list_toggle_button);
781
782 dock = list_toggle_button;
783 store->dock = dock;
784 } else {
785 created = FALSE;
786 scrollbar_width = (help_dlg->scroll ? help_dlg->scroll->up_left_button->size.w : 0);
787 pwindow = help_dlg->end_widget_list;
788 store = (struct units_buttons *)pwindow->data.ptr;
789 dock = store->dock;
790
791 area = pwindow->area;
792
793 /* Delete any previous list entries */
794 if (dock != help_dlg->begin_widget_list) {
795 del_group_of_widgets_from_gui_list(help_dlg->begin_widget_list,
796 dock->prev);
797 help_dlg->begin_widget_list = dock;
798 }
799 }
800
801 punittype = utype_by_number(type_id);
802 unit_name_label
803 = create_iconlabel_from_chars_fonto(adj_surf(get_unittype_surface(punittype,
804 direction8_invalid())),
805 pwindow->dst, utype_name_translation(punittype),
806 FONTO_MAX, WF_FREE_THEME);
807
808 unit_name_label->id = ID_LABEL;
809 widget_add_as_prev(unit_name_label, dock);
810 dock = unit_name_label;
811
812 {
813 char buf[2048];
814
815 fc_snprintf(buf, sizeof(buf), "%s %d %s",
816 _("Cost:"), utype_build_shield_cost_base(punittype),
817 PL_("shield", "shields", utype_build_shield_cost_base(punittype)));
818
819 if (punittype->pop_cost) {
820 cat_snprintf(buf, sizeof(buf), " %d %s",
821 punittype->pop_cost, PL_("citizen", "citizens",
822 punittype->pop_cost));
823 }
824
825 cat_snprintf(buf, sizeof(buf), " %s", _("Upkeep:"));
826
827 if (punittype->upkeep[O_SHIELD]) {
828 cat_snprintf(buf, sizeof(buf), " %d %s",
829 punittype->upkeep[O_SHIELD], PL_("shield", "shields",
830 punittype->upkeep[O_SHIELD]));
831 }
832 if (punittype->upkeep[O_FOOD]) {
833 cat_snprintf(buf, sizeof(buf), " %d %s",
834 punittype->upkeep[O_FOOD], PL_("food", "foods",
835 punittype->upkeep[O_FOOD]));
836 }
837 if (punittype->upkeep[O_GOLD]) {
838 cat_snprintf(buf, sizeof(buf), " %d %s",
839 punittype->upkeep[O_GOLD], PL_("gold", "golds",
840 punittype->upkeep[O_GOLD]));
841 }
842 if (punittype->happy_cost) {
843 cat_snprintf(buf, sizeof(buf), " %d %s",
844 punittype->happy_cost, PL_("citizen", "citizens",
845 punittype->happy_cost));
846 }
847
848 cat_snprintf(buf, sizeof(buf), "\n%s %d %s %d %s %s\n%s %d %s %d %s %d",
849 _("Attack:"), punittype->attack_strength,
850 _("Defense:"), punittype->defense_strength,
851 _("Move:"), move_points_text(punittype->move_rate, TRUE),
852 _("Vision:"), punittype->vision_radius_sq,
853 _("Firepower:"), punittype->firepower,
854 _("Hitpoints:"), punittype->hp);
855
856 unit_info_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst, buf,
857 FONTO_ATTENTION, 0);
858 unit_info_label->id = ID_LABEL;
859 widget_add_as_prev(unit_info_label, dock);
860 dock = unit_info_label;
861 }
862
863 /* Requirement */
864 requirement_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
865 _("Requirement:"),
866 FONTO_ATTENTION, 0);
867 requirement_label->id = ID_LABEL;
868 widget_add_as_prev(requirement_label, dock);
869 dock = requirement_label;
870
871 req = utype_primary_tech_req(punittype);
872
873 if (advance_number(req) == A_NONE) {
874 requirement_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
875 Q_("?tech:None"),
876 FONTO_ATTENTION, 0);
877 requirement_label2->id = ID_LABEL;
878 } else {
879 Tech_type_id req_id = advance_number(req);
880
881 requirement_label2
882 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
883 advance_name_translation(req),
884 FONTO_ATTENTION,
885 WF_RESTORE_BACKGROUND);
886 requirement_label2->id = MAX_ID - req_id;
887 requirement_label2->string_utf8->fgcol = *get_tech_color(req_id);
888 requirement_label2->action = change_tech_callback;
889 set_wstate(requirement_label2, FC_WS_NORMAL);
890 }
891 widget_add_as_prev(requirement_label2, dock);
892 dock = requirement_label2;
893 store->requirement_button = requirement_label2;
894
895 /* Obsolete by */
896 obsolete_by_label = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
897 _("Obsolete by:"),
898 FONTO_ATTENTION, 0);
899 obsolete_by_label->id = ID_LABEL;
900 widget_add_as_prev(obsolete_by_label, dock);
901 dock = obsolete_by_label;
902
903 if (punittype->obsoleted_by == U_NOT_OBSOLETED) {
904 obsolete_by_label2 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
905 Q_("?utype:None"),
906 FONTO_ATTENTION, 0);
907 obsolete_by_label2->id = ID_LABEL;
908 } else {
909 const struct unit_type *utype = punittype->obsoleted_by;
910 struct advance *obs_req = utype_primary_tech_req(utype);
911
912 obsolete_by_label2
913 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
914 utype_name_translation(utype),
915 FONTO_ATTENTION,
916 WF_RESTORE_BACKGROUND);
917 obsolete_by_label2->string_utf8->fgcol
918 = *get_tech_color(advance_number(obs_req));
919 obsolete_by_label2->id = MAX_ID - utype_number(utype);
920 obsolete_by_label2->action = change_unit_callback;
921 set_wstate(obsolete_by_label2, FC_WS_NORMAL);
922 }
923 widget_add_as_prev(obsolete_by_label2, dock);
924 dock = obsolete_by_label2;
925 store->obsolete_by_button = obsolete_by_label2;
926
927 /* Helptext */
928 start_x = (area.x + 1 + scrollbar_width + help_dlg->active_widget_list->size.w + adj_size(20));
929
930 buffer[0] = '\0';
931 helptext_unit(buffer, sizeof(buffer), client.conn.playing, "", utype_by_number(type_id));
932 if (buffer[0] != '\0') {
933 utf8_str *ustr = create_utf8_from_char_fonto(buffer, FONTO_ATTENTION);
934
935 convert_utf8_str_to_const_surface_width(ustr, adj_size(640) - start_x - adj_size(20));
936 help_text_label = create_iconlabel(NULL, pwindow->dst, ustr, 0);
937 help_text_label->id = ID_LABEL;
938 widget_add_as_prev(help_text_label, dock);
939 text = TRUE;
940 }
941
942 help_dlg->begin_widget_list = help_text_label ? help_text_label : obsolete_by_label2;
943
944 /* --------------------------------------------------------- */
945 if (created) {
946
947 surf = theme_get_background(active_theme, BACKGROUND_HELPDLG);
948 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
949 FREESURFACE(surf);
950 }
951
952 area = pwindow->area;
953
954 widget_set_position(pwindow,
955 (main_window_width() - pwindow->size.w) / 2,
956 (main_window_height() - pwindow->size.h) / 2);
957
958 /* Exit button */
959 close_button = pwindow->prev;
960 widget_set_position(close_button,
961 area.x + area.w - close_button->size.w - 1,
962 pwindow->size.y + adj_size(2));
963
964 /* List toggle button */
965 list_toggle_button = store->dock;
966 widget_set_position(list_toggle_button, area.x, area.y);
967
968 /* List entries */
969 h = setup_vertical_widgets_position(1, area.x + scrollbar_width,
970 area.y + list_toggle_button->size.h, 0, 0,
971 help_dlg->begin_active_widget_list,
972 help_dlg->end_active_widget_list);
973
974 /* Scrollbar */
975 if (help_dlg->scroll) {
976 setup_vertical_scrollbar_area(help_dlg->scroll,
977 area.x, area.y + list_toggle_button->size.h,
978 h, FALSE);
979 }
980 }
981
982 unit_name_label = store->dock->prev;
983 widget_set_position(unit_name_label, start_x, area.y + adj_size(16));
984
985 start_y = unit_name_label->size.y + unit_name_label->size.h + adj_size(10);
986
987 unit_info_label = unit_name_label->prev;
988 widget_set_position(unit_info_label, start_x, start_y);
989
990 start_y += unit_info_label->size.h;
991
992 requirement_label = store->requirement_button->next;
993 widget_set_position(requirement_label, start_x, start_y);
994
995 requirement_label2 = store->requirement_button;
996 widget_set_position(requirement_label2,
997 requirement_label->size.x + requirement_label->size.w + adj_size(5),
998 start_y);
999
1000 obsolete_by_label = store->obsolete_by_button->next;
1001 widget_set_position(obsolete_by_label,
1002 requirement_label2->size.x + requirement_label2->size.w + adj_size(10),
1003 start_y);
1004
1005 obsolete_by_label2 = store->obsolete_by_button;
1006 widget_set_position(obsolete_by_label2,
1007 obsolete_by_label->size.x + obsolete_by_label->size.w + adj_size(5),
1008 start_y);
1009
1010 start_y += obsolete_by_label2->size.h + adj_size(20);
1011
1012 if (text) {
1013 help_text_label = store->obsolete_by_button->prev;
1014 widget_set_position(help_text_label, start_x, start_y);
1015 }
1016
1017 redraw_unit_info_dlg();
1018}
1019
1020/* =============================================== */
1021/* ==================== Tech Tree ================ */
1022/* =============================================== */
1023
1024/**********************************************************************/
1027 static int change_tech_callback(struct widget *pwidget)
1028{
1029 if (PRESSED_EVENT(main_data.event)) {
1030 popup_tech_info(MAX_ID - pwidget->id);
1031 }
1032
1033 return -1;
1034}
1035
1036/**********************************************************************/
1039 static int show_tech_tree_callback(struct widget *pwidget)
1040{
1041 if (PRESSED_EVENT(main_data.event)) {
1042 struct techs_buttons *store = (struct techs_buttons *)help_dlg->end_widget_list->data.ptr;
1043
1044 store->show_tree = !store->show_tree;
1045 if (!store->show_tree) {
1046 store->show_full_tree = FALSE;
1047 store->dock->theme2 = current_theme->up_icon;
1048 }
1049 popup_tech_info(MAX_ID - store->dock->prev->id);
1050 }
1051
1052 return -1;
1053}
1054
1055/**********************************************************************/
1058 static void redraw_tech_info_dlg(void)
1059{
1060 SDL_Color bg_color = {255, 255, 255, 64};
1061 struct widget *pwindow = help_dlg->end_widget_list;
1062 struct techs_buttons *store = (struct techs_buttons *)pwindow->data.ptr;
1063 SDL_Surface *text0, *text1 = NULL;
1064 utf8_str *pstr;
1065 SDL_Rect dst;
1066
1067 redraw_group(pwindow->prev, pwindow, FALSE);
1068
1069 dst.x = store->dock->prev->prev->size.x - adj_size(10);
1070 dst.y = store->dock->prev->prev->size.y - adj_size(10);
1071 dst.w = pwindow->size.w - (dst.x - pwindow->size.x) - adj_size(10);
1072 dst.h = pwindow->size.h - (dst.y - pwindow->size.y) - adj_size(10);
1073
1074 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
1075
1076 create_frame(pwindow->dst->surface,
1077 dst.x, dst.y, dst.w, dst.h,
1078 get_theme_color(COLOR_THEME_HELPDLG_FRAME));
1079
1080 /* -------------------------- */
1081 pstr = create_utf8_from_char_fonto(_("Allows"), FONTO_HEADING);
1082 pstr->style |= TTF_STYLE_BOLD;
1083
1084 text0 = create_text_surf_from_utf8(pstr);
1085 dst.x = store->dock->prev->prev->size.x;
1086 if (store->targets[0]) {
1087 dst.y = store->targets[0]->size.y - text0->h;
1088 } else {
1089 dst.y = store->dock->prev->prev->size.y
1090 + store->dock->prev->prev->size.h + adj_size(10);
1091 }
1092
1093 alphablit(text0, NULL, pwindow->dst->surface, &dst, 255);
1094 FREESURFACE(text0);
1095
1096 if (store->sub_targets[0]) {
1097 int i;
1098
1099 change_fonto_utf8(pstr, FONTO_ATTENTION);
1100
1101 copy_chars_to_utf8_str(pstr, _("( with "));
1102 text0 = create_text_surf_from_utf8(pstr);
1103
1104 copy_chars_to_utf8_str(pstr, _(" )"));
1105 text1 = create_text_surf_from_utf8(pstr);
1106 i = 0;
1107 while (i < 6 && store-> sub_targets[i]) {
1108 dst.x = store->sub_targets[i]->size.x - text0->w;
1109 dst.y = store->sub_targets[i]->size.y;
1110
1111 alphablit(text0, NULL, pwindow->dst->surface, &dst, 255);
1112 dst.x = store->sub_targets[i]->size.x + store->sub_targets[i]->size.w;
1113 dst.y = store->sub_targets[i]->size.y;
1114
1115 alphablit(text1, NULL, pwindow->dst->surface, &dst, 255);
1116 i++;
1117 }
1118
1119 FREESURFACE(text0);
1120 FREESURFACE(text1);
1121 }
1122 FREEUTF8STR(pstr);
1123
1124 redraw_group(help_dlg->begin_widget_list, pwindow->prev->prev, FALSE);
1125 widget_flush(pwindow);
1126}
1127
1128/**********************************************************************/
1131 static struct widget *create_tech_info(Tech_type_id tech, int width,
1132 struct widget *pwindow,
1133 struct techs_buttons *store)
1134{
1135 struct widget *pwidget;
1136 struct widget *last, *budynki;
1137 struct widget *dock = store->dock;
1138 int i, targets_count, sub_targets_count, max_width = 0;
1139 int start_x, start_y, imp_count, unit_count, flags_count, gov_count;
1140 char buffer[bufsz];
1141 SDL_Surface *surf;
1142
1143 start_x = (pwindow->area.x + adj_size(1) + width + help_dlg->active_widget_list->size.w + adj_size(20));
1144
1145 /* Tech tree icon */
1146 pwidget = create_icon2(current_theme->tech_tree_icon, pwindow->dst,
1147 WF_RESTORE_BACKGROUND);
1148
1149 set_wstate(pwidget, FC_WS_NORMAL);
1150 pwidget->action = show_tech_tree_callback;
1151 pwidget->id = MAX_ID - tech;
1152 widget_add_as_prev(pwidget, dock);
1153 dock = pwidget;
1154
1155 /* Tech name (heading) */
1156 pwidget
1157 = create_iconlabel_from_chars_fonto(get_tech_icon(tech),
1158 pwindow->dst,
1159 advance_name_translation(advance_by_number(tech)),
1160 FONTO_MAX, WF_FREE_THEME);
1161
1162 pwidget->id = ID_LABEL;
1163 widget_add_as_prev(pwidget, dock);
1164 dock = pwidget;
1165
1166 /* Target techs */
1167 targets_count = 0;
1168 advance_index_iterate(A_FIRST, aidx) {
1169 if ((targets_count < 6)
1170 && (advance_required(aidx, AR_ONE) == tech
1171 || advance_required(aidx, AR_TWO) == tech)) {
1172 pwidget
1173 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
1174 advance_name_translation(advance_by_number(aidx)),
1175 FONTO_ATTENTION,
1176 WF_RESTORE_BACKGROUND);
1177 pwidget->string_utf8->fgcol = *get_tech_color(aidx);
1178 max_width = MAX(max_width, pwidget->size.w);
1179 set_wstate(pwidget, FC_WS_NORMAL);
1180 pwidget->action = change_tech_callback;
1181 pwidget->id = MAX_ID - aidx;
1182 widget_add_as_prev(pwidget, dock);
1183 dock = pwidget;
1184 store->targets[targets_count++] = pwidget;
1185 }
1186 } advance_index_iterate_end;
1187 if (targets_count < 6) {
1188 store->targets[targets_count] = NULL;
1189 }
1190
1191 sub_targets_count = 0;
1192 if (targets_count > 0) {
1193 int sub_tech;
1194
1195 for (i = 0; i < targets_count; i++) {
1196 sub_tech = MAX_ID - store->targets[i]->id;
1197 if (advance_required(sub_tech, AR_ONE) == tech
1198 && advance_required(sub_tech, AR_TWO) != A_NONE) {
1199 sub_tech = advance_required(sub_tech, AR_TWO);
1200 } else if (advance_required(sub_tech, AR_TWO) == tech
1201 && advance_required(sub_tech, AR_ONE) != A_NONE) {
1202 sub_tech = advance_required(sub_tech, AR_ONE);
1203 } else {
1204 continue;
1205 }
1206 pwidget
1207 = create_iconlabel_from_chars_fonto(NULL, pwindow->dst,
1208 advance_name_translation(advance_by_number(sub_tech)),
1209 FONTO_ATTENTION,
1210 WF_RESTORE_BACKGROUND);
1211 pwidget->string_utf8->fgcol = *get_tech_color(sub_tech);
1212 set_wstate(pwidget, FC_WS_NORMAL);
1213 pwidget->action = change_tech_callback;
1214 pwidget->id = MAX_ID - sub_tech;
1215 widget_add_as_prev(pwidget, dock);
1216 dock = pwidget;
1217 store->sub_targets[sub_targets_count++] = pwidget;
1218 }
1219 }
1220 if (sub_targets_count < 6) {
1221 store->sub_targets[sub_targets_count] = NULL;
1222 }
1223
1224 /* Fill array with iprvm. icons */
1225 budynki = pwidget;
1226
1227 /* Target governments */
1228 gov_count = 0;
1229 governments_iterate(gov) {
1230 requirement_vector_iterate(&(gov->reqs), preq) {
1231 if (VUT_ADVANCE == preq->source.kind
1232 && advance_number(preq->source.value.advance) == tech) {
1233
1234 pwidget
1235 = create_iconlabel_from_chars_fonto(adj_surf(get_government_surface(gov)),
1236 pwindow->dst,
1237 government_name_translation(gov),
1238 FONTO_HEADING,
1239 WF_RESTORE_BACKGROUND | WF_SELECT_WITHOUT_BAR | WF_FREE_THEME);
1240 set_wstate(pwidget, FC_WS_NORMAL);
1241 pwidget->action = change_gov_callback;
1242 pwidget->id = MAX_ID - government_index(gov);
1243 widget_add_as_prev(pwidget, dock);
1244 dock = pwidget;
1245 gov_count++;
1246 }
1247 } requirement_vector_iterate_end;
1248 } governments_iterate_end;
1249
1250 /* Target improvements */
1251 imp_count = 0;
1252 improvement_iterate(pimprove) {
1253 if (valid_improvement(pimprove)) {
1254 /* FIXME: this should show ranges and all the MAX_NUM_REQS reqs.
1255 * Currently it's limited to 1 req. Remember MAX_NUM_REQS is a compile-time
1256 * definition. */
1257 requirement_vector_iterate(&(pimprove->reqs), preq) {
1258 if (VUT_ADVANCE == preq->source.kind
1259 && advance_number(preq->source.value.advance) == tech) {
1260 surf = get_building_surface(pimprove);
1261 pwidget = create_iconlabel_from_chars_fonto(
1262 resize_surface_box(surf, adj_size(48), adj_size(48), 1, TRUE,
1263 TRUE),
1264 pwindow->dst,
1265 improvement_name_translation(pimprove),
1266 FONTO_HEADING,
1267 WF_RESTORE_BACKGROUND | WF_SELECT_WITHOUT_BAR);
1268 set_wstate(pwidget, FC_WS_NORMAL);
1269 if (is_wonder(pimprove)) {
1270 pwidget->string_utf8->fgcol = *get_theme_color(COLOR_THEME_CITYDLG_LUX);
1271 }
1272 pwidget->action = change_impr_callback;
1273 pwidget->id = MAX_ID - improvement_number(pimprove);
1274 widget_add_as_prev(pwidget, dock);
1275 dock = pwidget;
1276 imp_count++;
1277 }
1278
1279 break;
1280 } requirement_vector_iterate_end;
1281 }
1282 } improvement_iterate_end;
1283
1284 unit_count = 0;
1285 unit_type_iterate(un) {
1286 if (is_tech_req_for_utype(un, advance_by_number(tech))) {
1287 pwidget = create_iconlabel_from_chars_fonto(
1288 resize_surface_box(get_unittype_surface(un, direction8_invalid()),
1289 adj_size(48), adj_size(48), 1, TRUE, TRUE),
1290 pwindow->dst, utype_name_translation(un), FONTO_HEADING,
1291 (WF_FREE_THEME | WF_RESTORE_BACKGROUND | WF_SELECT_WITHOUT_BAR));
1292 set_wstate(pwidget, FC_WS_NORMAL);
1293 pwidget->action = change_unit_callback;
1294 pwidget->id = MAX_ID - utype_number(un);
1295 widget_add_as_prev(pwidget, dock);
1296 dock = pwidget;
1297 unit_count++;
1298 }
1299 } unit_type_iterate_end;
1300
1301 buffer[0] = '\0';
1302 if (tech != A_NONE) {
1303 helptext_advance(buffer, sizeof(buffer), client.conn.playing, "", tech);
1304 }
1305 if (buffer[0] != '\0') {
1306 utf8_str *pstr = create_utf8_from_char_fonto(buffer, FONTO_ATTENTION);
1307
1308 convert_utf8_str_to_const_surface_width(pstr, adj_size(640) - start_x - adj_size(20));
1309 pwidget = create_iconlabel(NULL, pwindow->dst, pstr, 0);
1310 pwidget->id = ID_LABEL;
1311 widget_add_as_prev(pwidget, dock);
1312 flags_count = 1;
1313 } else {
1314 flags_count = 0;
1315 }
1316
1317 last = pwidget;
1318 /* --------------------------------------------- */
1319
1320 /* Tree button */
1321 pwidget = store->dock->prev;
1322 pwidget->size.x = pwindow->area.x + pwindow->area.w - pwidget->size.w - adj_size(17);
1323 pwidget->size.y = pwindow->area.y + adj_size(16);
1324
1325 /* Tech label */
1326 pwidget = pwidget->prev;
1327 pwidget->size.x = start_x;
1328 pwidget->size.y = pwindow->area.y + adj_size(16);
1329 start_y = pwidget->size.y + pwidget->size.h + adj_size(30);
1330
1331 if (targets_count) {
1332 int j = 0;
1333
1334 i = 0;
1335
1336 while (i < 6 && store->targets[i]) {
1337 store->targets[i]->size.x = pwindow->size.x + start_x;
1338 store->targets[i]->size.y = start_y;
1339
1340 if (store->sub_targets[j]) {
1341 int t0 = MAX_ID - store->targets[i]->id;
1342 int t1 = MAX_ID - store->sub_targets[j]->id;
1343
1344 if (advance_required(t0, AR_ONE) == t1
1345 || advance_required(t0, AR_TWO) == t1) {
1346 store->sub_targets[j]->size.x = pwindow->size.x + start_x + max_width + 60;
1347 store->sub_targets[j]->size.y = store->targets[i]->size.y;
1348 j++;
1349 }
1350 }
1351
1352 start_y += store->targets[i]->size.h;
1353 i++;
1354 }
1355
1356 start_y += adj_size(10);
1357 }
1358 pwidget = NULL;
1359
1360 if (gov_count) {
1361 pwidget = budynki->prev;
1362 while (gov_count-- && pwidget) {
1363 pwidget->size.x = pwindow->size.x + start_x;
1364 pwidget->size.y = start_y;
1365 start_y += pwidget->size.h + adj_size(2);
1366 pwidget = pwidget->prev;
1367 }
1368 }
1369
1370 if (imp_count) {
1371 if (!pwidget) {
1372 pwidget = budynki->prev;
1373 }
1374 while (imp_count-- && pwidget) {
1375 pwidget->size.x = pwindow->size.x + start_x;
1376 pwidget->size.y = start_y;
1377 start_y += pwidget->size.h + adj_size(2);
1378 pwidget = pwidget->prev;
1379 }
1380 }
1381
1382 if (unit_count) {
1383 if (!pwidget) {
1384 pwidget = budynki->prev;
1385 }
1386 while (unit_count-- && pwidget) {
1387 pwidget->size.x = pwindow->size.x + start_x;
1388 pwidget->size.y = start_y;
1389 start_y += pwidget->size.h + adj_size(2);
1390 pwidget = pwidget->prev;
1391 }
1392 }
1393
1394 if (flags_count) {
1395 if (!pwidget) {
1396 pwidget = budynki->prev;
1397 }
1398 while (flags_count-- && pwidget) {
1399 pwidget->size.x = pwindow->size.x + start_x;
1400 pwidget->size.y = start_y;
1401 start_y += pwidget->size.h + adj_size(2);
1402 pwidget = pwidget->prev;
1403 }
1404 }
1405
1406 return last;
1407}
1408
1409/**********************************************************************/
1412 static void redraw_tech_tree_dlg(void)
1413{
1414 SDL_Color *line_color = get_theme_color(COLOR_THEME_HELPDLG_LINE);
1415 SDL_Color bg_color = {255, 255, 255, 64};
1416 struct widget *pwindow = help_dlg->end_widget_list;
1417 struct widget *sub0, *sub1;
1418 struct techs_buttons *store = (struct techs_buttons *)pwindow->data.ptr;
1419 struct widget *ptech = store->dock->prev;
1420 int i,j, tech, count;
1421 int step;
1422 int mod;
1423 SDL_Rect dst;
1424
1425 /* Redraw Window with exit button */
1426 redraw_group(pwindow->prev, pwindow, FALSE);
1427
1428 dst.x = pwindow->area.x + pwindow->area.w - adj_size(459) - adj_size(7);
1429 dst.y = pwindow->area.y + adj_size(6);
1430 dst.w = pwindow->area.w - (dst.x - pwindow->area.x) - adj_size(10);
1431 dst.h = pwindow->area.h - (dst.y - pwindow->area.y) - adj_size(10);
1432
1433 fill_rect_alpha(pwindow->dst->surface, &dst, &bg_color);
1434
1435 create_frame(pwindow->dst->surface,
1436 dst.x, dst.y, dst.w, dst.h,
1437 get_theme_color(COLOR_THEME_HELPDLG_FRAME));
1438
1439 /* Draw req arrows */
1440 i = 0;
1441 while (i < 4 && store->sub_req[i]) {
1442 i++;
1443 }
1444 count = i;
1445
1446 i = 0;
1447 while (i < 2 && store->requirement_button[i]) {
1448 tech = MAX_ID - store->requirement_button[i]->id;
1449
1450 /* Find sub req's */
1451 if (i) {
1452 sub0 = NULL;
1453 for (j = count - 1; j >= 0; j--) {
1454 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_ONE)) {
1455 sub0 = store->sub_req[j];
1456 break;
1457 }
1458 }
1459
1460 sub1 = NULL;
1461 for (j = count - 1; j >= 0; j--) {
1462 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_TWO)) {
1463 sub1 = store->sub_req[j];
1464 break;
1465 }
1466 }
1467 } else {
1468 sub0 = NULL;
1469 for (j = 0; j < 4 && store->sub_req[j]; j++) {
1470 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_ONE)) {
1471 sub0 = store->sub_req[j];
1472 break;
1473 }
1474 }
1475
1476 sub1 = NULL;
1477 for (j = 0; j < 4 && store->sub_req[j]; j++) {
1478 if (MAX_ID - store->sub_req[j]->id == advance_required(tech, AR_TWO)) {
1479 sub1 = store->sub_req[j];
1480 break;
1481 }
1482 }
1483 }
1484
1485 /* Draw main Arrow */
1486 create_line(store->requirement_button[i]->dst->surface,
1487 store->requirement_button[i]->size.x + store->requirement_button[i]->size.w,
1488 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1489 ptech->size.x,
1490 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1491 line_color);
1492
1493 /* Draw sub req arrows */
1494 if (sub0 || sub1) {
1495 create_line(store->requirement_button[i]->dst->surface,
1496 store->requirement_button[i]->size.x - adj_size(10),
1497 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1498 store->requirement_button[i]->size.x ,
1499 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1500 line_color);
1501 }
1502
1503 if (sub0) {
1504 create_line(store->requirement_button[i]->dst->surface,
1505 store->requirement_button[i]->size.x - adj_size(10),
1506 sub0->size.y + sub0->size.h / 2,
1507 store->requirement_button[i]->size.x - adj_size(10),
1508 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1509 line_color);
1510 create_line(store->requirement_button[i]->dst->surface,
1511 sub0->size.x + sub0->size.w,
1512 sub0->size.y + sub0->size.h / 2,
1513 store->requirement_button[i]->size.x - adj_size(10),
1514 sub0->size.y + sub0->size.h / 2,
1515 line_color);
1516 }
1517
1518 if (sub1) {
1519 create_line(store->requirement_button[i]->dst->surface,
1520 store->requirement_button[i]->size.x - adj_size(10),
1521 sub1->size.y + sub1->size.h / 2,
1522 store->requirement_button[i]->size.x - adj_size(10),
1523 store->requirement_button[i]->size.y + store->requirement_button[i]->size.h / 2,
1524 line_color);
1525 create_line(store->requirement_button[i]->dst->surface,
1526 sub1->size.x + sub1->size.w,
1527 sub1->size.y + sub1->size.h / 2,
1528 store->requirement_button[i]->size.x - adj_size(10),
1529 sub1->size.y + sub1->size.h / 2,
1530 line_color);
1531 }
1532 i++;
1533 }
1534
1535 i = 0;
1536 while (i < 6 && store->targets[i]) {
1537 i++;
1538 }
1539 count = i;
1540
1541 if (count > 4) {
1542 mod = 3;
1543 } else {
1544 mod = 2;
1545 }
1546
1547 for (i = 0; i < count; i++) {
1548 tech = MAX_ID - store->targets[i]->id;
1549 step = ptech->size.h / (count + 1);
1550
1551 switch ((i % mod)) {
1552 case 2:
1553 line_color = get_theme_color(COLOR_THEME_HELPDLG_LINE2);
1554 break;
1555 case 1:
1556 line_color = get_theme_color(COLOR_THEME_HELPDLG_LINE3);
1557 break;
1558 default:
1559 line_color = get_theme_color(COLOR_THEME_HELPDLG_LINE);
1560 break;
1561 }
1562
1563 /* Find sub reqs */
1564 if (advance_required(tech, AR_ONE) == MAX_ID - ptech->id) {
1565 sub0 = ptech;
1566 } else {
1567 sub0 = NULL;
1568 for (j = 0; j < 6 && store->sub_targets[j]; j++) {
1569 if (MAX_ID - store->sub_targets[j]->id == advance_required(tech, AR_ONE)) {
1570 sub0 = store->sub_targets[j];
1571 break;
1572 }
1573 }
1574 }
1575
1576 if (advance_required(tech, AR_TWO) == MAX_ID - ptech->id) {
1577 sub1 = ptech;
1578 } else {
1579 sub1 = NULL;
1580 for (j = 0; j < 6 && store->sub_targets[j]; j++) {
1581 if (MAX_ID - store->sub_targets[j]->id == advance_required(tech, AR_TWO)) {
1582 sub1 = store->sub_targets[j];
1583 break;
1584 }
1585 }
1586 }
1587
1588 /* Draw sub targets arrows */
1589 if (sub0 || sub1) {
1590 create_line(store->targets[i]->dst->surface,
1591 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1592 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1593 store->targets[i]->size.x ,
1594 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1595 line_color);
1596 }
1597
1598 if (sub0) {
1599 int y;
1600
1601 if (sub0 == ptech) {
1602 y = sub0->size.y + step * (i + 1);
1603 } else {
1604 y = sub0->size.y + sub0->size.h / 2;
1605 }
1606
1607 create_line(store->targets[i]->dst->surface,
1608 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1609 y,
1610 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1611 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1612 line_color);
1613 create_line(store->targets[i]->dst->surface,
1614 sub0->size.x + sub0->size.w,
1615 y,
1616 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1617 y,
1618 line_color);
1619 }
1620
1621 if (sub1) {
1622 int y;
1623
1624 if (sub1 == ptech) {
1625 y = sub1->size.y + step * (i + 1);
1626 } else {
1627 y = sub1->size.y + sub1->size.h / 2;
1628 }
1629
1630 create_line(store->targets[i]->dst->surface,
1631 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1632 y,
1633 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1634 store->targets[i]->size.y + store->targets[i]->size.h / 2,
1635 line_color);
1636 create_line(store->targets[i]->dst->surface,
1637 sub1->size.x + sub1->size.w,
1638 y,
1639 store->targets[i]->size.x - ((i % mod) + 1) * 6,
1640 y,
1641 line_color);
1642 }
1643 }
1644
1645 /* Redraw rest */
1646 redraw_group(help_dlg->begin_widget_list, pwindow->prev->prev, FALSE);
1647
1648 widget_flush(pwindow);
1649}
1650
1651/**********************************************************************/
1654 static int toggle_full_tree_mode_in_help_dlg_callback(struct widget *pwidget)
1655{
1656 if (PRESSED_EVENT(main_data.event)) {
1657 struct techs_buttons *store = (struct techs_buttons *)help_dlg->end_widget_list->data.ptr;
1658
1659 if (store->show_full_tree) {
1660 pwidget->theme2 = current_theme->up_icon;
1661 } else {
1662 pwidget->theme2 = current_theme->down_icon;
1663 }
1664 store->show_full_tree = !store->show_full_tree;
1665 popup_tech_info(MAX_ID - store->dock->prev->id);
1666 }
1667
1668 return -1;
1669}
1670
1671/**********************************************************************/
1674 static struct widget *create_tech_tree(Tech_type_id tech, int width,
1675 struct widget *pwindow,
1676 struct techs_buttons *store)
1677{
1678 int i, w, h, req_count, targets_count, sub_req_count, sub_targets_count;
1679 struct widget *pwidget;
1680 struct widget *ptech;
1681 utf8_str *pstr;
1682 SDL_Surface *surf;
1683 struct widget *dock = store->dock;
1684
1685 pstr = create_utf8_str_fonto(NULL, 0, FONTO_DEFAULT);
1686 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
1687
1688 copy_chars_to_utf8_str(pstr, advance_name_translation(advance_by_number(tech)));
1689 surf = create_select_tech_icon(pstr, tech, TIM_FULL_MODE);
1690 pwidget = create_icon2(surf, pwindow->dst,
1691 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
1692
1693 set_wstate(pwidget, FC_WS_NORMAL);
1694 pwidget->action = show_tech_tree_callback;
1695 pwidget->id = MAX_ID - tech;
1696 widget_add_as_prev(pwidget, dock);
1697 ptech = pwidget;
1698 dock = pwidget;
1699
1700 req_count = 0;
1701 for (i = AR_ONE; i <= AR_TWO; i++) {
1702 Tech_type_id ar = advance_required(tech, i);
1703 struct advance *vap = valid_advance_by_number(ar);
1704
1705 if (NULL != vap && A_NONE != ar) {
1706 copy_chars_to_utf8_str(pstr, advance_name_translation(vap));
1707 surf = create_select_tech_icon(pstr, ar, TIM_SMALL_MODE);
1708 pwidget = create_icon2(surf, pwindow->dst,
1709 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
1710 set_wstate(pwidget, FC_WS_NORMAL);
1711 pwidget->action = change_tech_callback;
1712 pwidget->id = MAX_ID - ar;
1713 widget_add_as_prev(pwidget, dock);
1714 dock = pwidget;
1715 store->requirement_button[req_count++] = pwidget;
1716 }
1717 }
1718
1719 sub_req_count = 0;
1720
1721 if (store->show_full_tree && req_count > 0) {
1722 int j, sub_tech;
1723
1724 for (j = 0; j < req_count; j++) {
1725 sub_tech = MAX_ID - store->requirement_button[j]->id;
1726 for (i = AR_ONE; i <= AR_TWO; i++) {
1727 Tech_type_id ar = advance_required(sub_tech, i);
1728 struct advance *vap = valid_advance_by_number(ar);
1729
1730 if (NULL != vap && A_NONE != ar) {
1731 copy_chars_to_utf8_str(pstr, advance_name_translation(vap));
1732 surf = create_select_tech_icon(pstr, ar, TIM_SMALL_MODE);
1733 pwidget = create_icon2(surf, pwindow->dst,
1734 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
1735 set_wstate(pwidget, FC_WS_NORMAL);
1736 pwidget->action = change_tech_callback;
1737 pwidget->id = MAX_ID - ar;
1738 widget_add_as_prev(pwidget, dock);
1739 dock = pwidget;
1740 store->sub_req[sub_req_count++] = pwidget;
1741 }
1742 }
1743 }
1744 }
1745
1746 if (sub_req_count < 4) {
1747 store->sub_req[sub_req_count] = NULL;
1748 }
1749
1750 targets_count = 0;
1751 advance_index_iterate(A_FIRST, aidx) {
1752 if ((targets_count < 6)
1753 && (advance_required(aidx, AR_ONE) == tech
1754 || advance_required(aidx, AR_TWO) == tech)) {
1755 copy_chars_to_utf8_str(pstr, advance_name_translation(advance_by_number(aidx)));
1756 surf = create_select_tech_icon(pstr, aidx, TIM_SMALL_MODE);
1757 pwidget = create_icon2(surf, pwindow->dst,
1758 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
1759
1760 set_wstate(pwidget, FC_WS_NORMAL);
1761 pwidget->action = change_tech_callback;
1762 pwidget->id = MAX_ID - aidx;
1763 widget_add_as_prev(pwidget, dock);
1764 dock = pwidget;
1765 store->targets[targets_count++] = pwidget;
1766 }
1767 } advance_index_iterate_end;
1768 if (targets_count < 6) {
1769 store->targets[targets_count] = NULL;
1770 }
1771
1772 sub_targets_count = 0;
1773 if (targets_count > 0) {
1774 int sub_tech;
1775
1776 for (i = 0; i < targets_count; i++) {
1777 sub_tech = MAX_ID - store->targets[i]->id;
1778 if (advance_required(sub_tech, AR_ONE) == tech
1779 && advance_required(sub_tech, AR_TWO) != A_NONE) {
1780 sub_tech = advance_required(sub_tech, AR_TWO);
1781 } else if (advance_required(sub_tech, AR_TWO) == tech
1782 && advance_required(sub_tech, AR_ONE) != A_NONE) {
1783 sub_tech = advance_required(sub_tech, AR_ONE);
1784 } else {
1785 continue;
1786 }
1787
1788 copy_chars_to_utf8_str(pstr, advance_name_translation(advance_by_number(sub_tech)));
1789 surf = create_select_tech_icon(pstr, sub_tech, TIM_SMALL_MODE);
1790 pwidget = create_icon2(surf, pwindow->dst,
1791 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
1792 set_wstate(pwidget, FC_WS_NORMAL);
1793 pwidget->action = change_tech_callback;
1794 pwidget->id = MAX_ID - sub_tech;
1795 widget_add_as_prev(pwidget, dock);
1796 dock = pwidget;
1797 store->sub_targets[sub_targets_count++] = pwidget;
1798 }
1799 }
1800 if (sub_targets_count < 6) {
1801 store->sub_targets[sub_targets_count] = NULL;
1802 }
1803
1804 FREEUTF8STR(pstr);
1805
1806 /* ------------------------------------------ */
1807 if (sub_req_count > 0) {
1808 w = (adj_size(20) + store->sub_req[0]->size.w) * 2;
1809 w += (pwindow->size.w - (20 + store->sub_req[0]->size.w + w + ptech->size.w)) / 2;
1810 } else {
1811 if (req_count > 0) {
1812 w = (pwindow->area.x + 1
1813 + width + store->requirement_button[0]->size.w * 2 + adj_size(20));
1814 w += (pwindow->size.w - ((adj_size(20) + store->requirement_button[0]->size.w)
1815 + w + ptech->size.w)) / 2;
1816 } else {
1817 w = (pwindow->size.w - ptech->size.w) / 2;
1818 }
1819 }
1820
1821 ptech->size.x = pwindow->size.x + w;
1822 ptech->size.y = pwindow->area.y + (pwindow->area.h - ptech->size.h) / 2;
1823
1824 if (req_count > 0) {
1825 h = (req_count == 1 ? store->requirement_button[0]->size.h :
1826 req_count * (store->requirement_button[0]->size.h + adj_size(80)) - adj_size(80));
1827 h = ptech->size.y + (ptech->size.h - h) / 2;
1828 for (i = 0; i < req_count; i++) {
1829 store->requirement_button[i]->size.x
1830 = ptech->size.x - adj_size(20) - store->requirement_button[i]->size.w;
1831 store->requirement_button[i]->size.y = h;
1832 h += (store->requirement_button[i]->size.h + adj_size(80));
1833 }
1834 }
1835
1836 if (sub_req_count > 0) {
1837 h = (sub_req_count == 1 ? store->sub_req[0]->size.h :
1838 sub_req_count * (store->sub_req[0]->size.h + adj_size(20)) - adj_size(20));
1839 h = ptech->size.y + (ptech->size.h - h) / 2;
1840 for (i = 0; i < sub_req_count; i++) {
1841 store->sub_req[i]->size.x
1842 = ptech->size.x - (adj_size(20) + store->sub_req[i]->size.w) * 2;
1843 store->sub_req[i]->size.y = h;
1844 h += (store->sub_req[i]->size.h + adj_size(20));
1845 }
1846 }
1847
1848 if (targets_count > 0) {
1849 h = (targets_count == 1 ? store->targets[0]->size.h :
1850 targets_count * (store->targets[0]->size.h + adj_size(20)) - adj_size(20));
1851 h = ptech->size.y + (ptech->size.h - h) / 2;
1852 for (i = 0; i < targets_count; i++) {
1853 store->targets[i]->size.x = ptech->size.x + ptech->size.w + adj_size(20);
1854 store->targets[i]->size.y = h;
1855 h += (store->targets[i]->size.h + adj_size(20));
1856 }
1857 }
1858
1859 if (sub_targets_count > 0) {
1860 if (sub_targets_count < 3) {
1861 store->sub_targets[0]->size.x
1862 = ptech->size.x + ptech->size.w - store->sub_targets[0]->size.w;
1863 store->sub_targets[0]->size.y
1864 = ptech->size.y - store->sub_targets[0]->size.h - adj_size(10);
1865 if (store->sub_targets[1]) {
1866 store->sub_targets[1]->size.x
1867 = ptech->size.x + ptech->size.w - store->sub_targets[1]->size.w;
1868 store->sub_targets[1]->size.y = ptech->size.y + ptech->size.h + adj_size(10);
1869 }
1870 } else {
1871 if (sub_targets_count < 5) {
1872 for (i = 0; i < MIN(sub_targets_count, 4); i++) {
1873 store->sub_targets[i]->size.x
1874 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1875 if (i < 2) {
1876 store->sub_targets[i]->size.y
1877 = ptech->size.y - (store->sub_targets[i]->size.h + adj_size(5)) * (2 - i);
1878 } else {
1879 store->sub_targets[i]->size.y
1880 = ptech->size.y + ptech->size.h + adj_size(5)
1881 + (store->sub_targets[i]->size.h + adj_size(5)) * (i - 2);
1882 }
1883 }
1884 } else {
1885 h = (store->sub_targets[0]->size.h + adj_size(6));
1886 for (i = 0; i < MIN(sub_targets_count, 6); i++) {
1887 switch (i) {
1888 case 0:
1889 store->sub_targets[i]->size.x
1890 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1891 store->sub_targets[i]->size.y = ptech->size.y - h * 2;
1892 break;
1893 case 1:
1894 store->sub_targets[i]->size.x
1895 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w * 2
1896 - adj_size(10);
1897 store->sub_targets[i]->size.y = ptech->size.y - h - h / 2;
1898 break;
1899 case 2:
1900 store->sub_targets[i]->size.x
1901 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1902 store->sub_targets[i]->size.y = ptech->size.y - h;
1903 break;
1904 case 3:
1905 store->sub_targets[i]->size.x
1906 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1907 store->sub_targets[i]->size.y = ptech->size.y + ptech->size.h + adj_size(6);
1908 break;
1909 case 4:
1910 store->sub_targets[i]->size.x
1911 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w;
1912 store->sub_targets[i]->size.y = ptech->size.y + ptech->size.h + adj_size(6) + h;
1913 break;
1914 default:
1915 store->sub_targets[i]->size.x
1916 = ptech->size.x + ptech->size.w - store->sub_targets[i]->size.w * 2
1917 - adj_size(10);
1918 store->sub_targets[i]->size.y
1919 = ptech->size.y + ptech->size.h + adj_size(6) + h / 2 ;
1920 break;
1921 }
1922 }
1923 }
1924 }
1925 }
1926
1927 return pwidget;
1928}
1929
1930/**********************************************************************/
1933 void popup_tech_info(Tech_type_id tech)
1934{
1935 struct widget *pwindow;
1936 struct techs_buttons *store;
1937 struct widget *close_button = NULL;
1938 struct widget *advance_label = NULL;
1939 struct widget *list_toggle_button = NULL;
1940 struct widget *dock;
1941 utf8_str *title;
1942 utf8_str *pstr;
1943 SDL_Surface *surf;
1944 int h, tech_count;
1945 bool created;
1946 int scrollbar_width = 0;
1947 SDL_Rect area;
1948
1949 if (current_help_dlg != HELP_TECH) {
1950 popdown_help_dialog();
1951 }
1952
1953 /* Create new dialog if it doesn't exist yet */
1954 if (!help_dlg) {
1955 current_help_dlg = HELP_TECH;
1956 created = TRUE;
1957
1958 /* Create dialog */
1959 help_dlg = fc_calloc(1, sizeof(struct advanced_dialog));
1960 store = fc_calloc(1, sizeof(struct techs_buttons));
1961
1962 store->show_tree = FALSE;
1963 store->show_full_tree = FALSE;
1964
1965 /* Create window */
1966 title = create_utf8_from_char_fonto(_("Help : Advances Tree"),
1967 FONTO_ATTENTION);
1968 title->style |= TTF_STYLE_BOLD;
1969
1970 pwindow = create_window_skeleton(NULL, title, WF_FREE_DATA);
1971 pwindow->data.ptr = (void *)store;
1972 pwindow->action = help_dlg_window_callback;
1973 set_wstate(pwindow, FC_WS_NORMAL);
1974
1975 add_to_gui_list(ID_WINDOW, pwindow);
1976
1977 help_dlg->end_widget_list = pwindow;
1978
1979 /* ------------------ */
1980
1981 /* Close button */
1982 close_button = create_themeicon(current_theme->small_cancel_icon, pwindow->dst,
1983 WF_WIDGET_HAS_INFO_LABEL
1984 | WF_RESTORE_BACKGROUND);
1985 close_button->info_label
1986 = create_utf8_from_char_fonto(_("Close Dialog (Esc)"), FONTO_ATTENTION);
1987 close_button->action = exit_help_dlg_callback;
1988 set_wstate(close_button, FC_WS_NORMAL);
1989 close_button->key = SDLK_ESCAPE;
1990
1991 add_to_gui_list(ID_BUTTON, close_button);
1992
1993 /* ------------------ */
1994 dock = close_button;
1995
1996 /* --- Create scrollable advance list on the left side ---*/
1997 pstr = create_utf8_str_fonto(NULL, 0, FONTO_DEFAULT);
1998 pstr->style |= (TTF_STYLE_BOLD | SF_CENTER);
1999
2000 tech_count = 0;
2001 advance_index_iterate(A_FIRST, i) {
2002 struct advance *vap = valid_advance_by_number(i);
2003
2004 if (vap) {
2005 copy_chars_to_utf8_str(pstr, advance_name_translation(vap));
2006 surf = create_select_tech_icon(pstr, i, TIM_SMALL_MODE);
2007 advance_label = create_icon2(surf, pwindow->dst,
2008 WF_FREE_THEME | WF_RESTORE_BACKGROUND);
2009
2010 set_wstate(advance_label, FC_WS_NORMAL);
2011 advance_label->action = change_tech_callback;
2012 add_to_gui_list(MAX_ID - i, advance_label);
2013
2014 if (tech_count++ >= 10) {
2015 set_wflag(advance_label, WF_HIDDEN);
2016 }
2017 }
2018 } advance_index_iterate_end;
2019
2020 FREEUTF8STR(pstr);
2021
2022 help_dlg->end_active_widget_list = dock->prev;
2023 help_dlg->begin_widget_list = advance_label ? advance_label : close_button;
2024 help_dlg->begin_active_widget_list = help_dlg->begin_widget_list;
2025
2026 if (tech_count > 10) {
2027 help_dlg->active_widget_list = help_dlg->end_active_widget_list;
2028 scrollbar_width = create_vertical_scrollbar(help_dlg, 1, 10, TRUE, TRUE);
2029 }
2030
2031 /* Toggle techs list button */
2032 list_toggle_button = create_themeicon_button_from_chars_fonto(
2033 current_theme->up_icon,
2034 pwindow->dst,
2035 _("Advances"),
2036 FONTO_DEFAULT, 0);
2037 list_toggle_button->action = toggle_full_tree_mode_in_help_dlg_callback;
2038 if (store->show_tree) {
2039 set_wstate(list_toggle_button, FC_WS_NORMAL);
2040 }
2041 widget_resize(list_toggle_button, adj_size(160), adj_size(15));
2042 list_toggle_button->string_utf8->fgcol = *get_theme_color(COLOR_THEME_HELPDLG_TEXT);
2043
2044 add_to_gui_list(ID_BUTTON, list_toggle_button);
2045
2046 dock = list_toggle_button;
2047 store->dock = dock;
2048 } else {
2049 created = FALSE;
2050 scrollbar_width = (help_dlg->scroll ? help_dlg->scroll->up_left_button->size.w: 0);
2051 pwindow = help_dlg->end_widget_list;
2052 store = (struct techs_buttons *)pwindow->data.ptr;
2053 dock = store->dock;
2054
2055 /* Delete any previous list entries */
2056 if (dock != help_dlg->begin_widget_list) {
2057 del_group_of_widgets_from_gui_list(help_dlg->begin_widget_list, dock->prev);
2058 help_dlg->begin_widget_list = dock;
2059 }
2060
2061 /* Show/hide techs list */
2062 list_toggle_button = dock;
2063
2064 if (store->show_tree) {
2065 set_wstate(list_toggle_button, FC_WS_NORMAL);
2066 } else {
2067 set_wstate(list_toggle_button, FC_WS_DISABLED);
2068 }
2069
2070 if (store->show_full_tree) {
2071 /* All entries are visible without scrolling */
2072 hide_group(help_dlg->begin_active_widget_list,
2073 help_dlg->end_active_widget_list);
2074 hide_scrollbar(help_dlg->scroll);
2075 } else {
2076 int count = help_dlg->scroll->active;
2077
2078 advance_label = help_dlg->active_widget_list;
2079 while (advance_label->prev != NULL && --count > 0) {
2080 advance_label = advance_label->prev;
2081 }
2082 show_group(advance_label, help_dlg->active_widget_list);
2083 show_scrollbar(help_dlg->scroll);
2084 }
2085 }
2086
2087 /* --------------------------------------------------------- */
2088 if (created) {
2089
2090 surf = theme_get_background(active_theme, BACKGROUND_HELPDLG);
2091 if (resize_window(pwindow, surf, NULL, adj_size(640), adj_size(480))) {
2092 FREESURFACE(surf);
2093 }
2094
2095 area = pwindow->area;
2096
2097 widget_set_position(pwindow,
2098 (main_window_width() - pwindow->size.w) / 2,
2099 (main_window_height() - pwindow->size.h) / 2);
2100
2101 /* Exit button */
2102 close_button = pwindow->prev;
2103 widget_set_position(close_button,
2104 area.x + area.w - close_button->size.w - 1,
2105 pwindow->size.y + adj_size(2));
2106
2107 /* List toggle button */
2108 list_toggle_button = store->dock;
2109 widget_set_position(list_toggle_button, area.x, area.y);
2110
2111 /* List entries */
2112 h = setup_vertical_widgets_position(1, area.x + scrollbar_width,
2113 area.y + list_toggle_button->size.h, 0, 0,
2114 help_dlg->begin_active_widget_list,
2115 help_dlg->end_active_widget_list);
2116 /* Scrollbar */
2117 if (help_dlg->scroll) {
2118 setup_vertical_scrollbar_area(help_dlg->scroll,
2119 area.x, area.y + list_toggle_button->size.h,
2120 h, FALSE);
2121 }
2122 }
2123
2124 if (store->show_tree) {
2125 help_dlg->begin_widget_list = create_tech_tree(tech, scrollbar_width, pwindow, store);
2126 redraw_tech_tree_dlg();
2127 } else {
2128 help_dlg->begin_widget_list = create_tech_info(tech, scrollbar_width, pwindow, store);
2129 redraw_tech_info_dlg();
2130 }
2131}
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:662
client
struct civclient client
Definition client_main.c:150
client_main.h
incite_cost
char * incite_cost
Definition comments.c:74
current_theme
QString current_theme
Definition fc_client.cpp:65
Tech_type_id
int Tech_type_id
Definition fc_types.h:380
Impr_type_id
int Impr_type_id
Definition fc_types.h:379
Unit_type_id
int Unit_type_id
Definition fc_types.h:385
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:120
governments_iterate_end
#define governments_iterate_end
Definition government.h:123
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:1379
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:1348
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:1935
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:1041
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:1060
redraw_unit_info_dlg
static void redraw_unit_info_dlg(void)
Definition helpdlg.c:604
change_tech_callback
static int change_tech_callback(struct widget *pwidget)
Definition helpdlg.c:1029
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:1133
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:1414
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:592
popup_unit_info
void popup_unit_info(Unit_type_id type_id)
Definition helpdlg.c:632
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:1656
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:86
COLOR_THEME_HELPDLG_TEXT
@ COLOR_THEME_HELPDLG_TEXT
Definition themecolors.h:90
COLOR_THEME_HELPDLG_LINE3
@ COLOR_THEME_HELPDLG_LINE3
Definition themecolors.h:89
COLOR_THEME_CITYDLG_LUX
@ COLOR_THEME_CITYDLG_LUX
Definition themecolors.h:59
COLOR_THEME_HELPDLG_LINE
@ COLOR_THEME_HELPDLG_LINE
Definition themecolors.h:87
COLOR_THEME_HELPDLG_LINE2
@ COLOR_THEME_HELPDLG_LINE2
Definition themecolors.h:88
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:3268
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:1015
movement.h
universal_name_translation
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
Definition requirements.c:6755
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:500
unit_type::obsoleted_by
const struct unit_type * obsoleted_by
Definition unittype.h:529
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::data
union widget::@192 data
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
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
cat_snprintf
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:1000
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:290
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:248
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:244
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:852
unit_type_iterate_end
#define unit_type_iterate_end
Definition unittype.h:859
U_NOT_OBSOLETED
#define U_NOT_OBSOLETED
Definition unittype.h:528