Freeciv-3.3: /fast/freeciv/nightly/main/client/gui-gtk-4.0/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#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <math.h> /* sqrt */
22
23#include <gtk/gtk.h>
24
25/* utility */
26#include "fcintl.h"
27#include "mem.h"
28#include "shared.h"
29#include "support.h"
30
31/* common */
32#include "city.h"
33#include "game.h"
34#include "government.h"
35#include "movement.h"
36#include "nation.h"
37#include "specialist.h"
38#include "tech.h"
39#include "unit.h"
40#include "map.h"
41#include "research.h"
42#include "version.h"
43
44/* client */
45#include "client_main.h"
46#include "climisc.h"
47#include "helpdata.h"
48#include "options.h"
49#include "tilespec.h"
50
51/* client/gui-gtk-4.0 */
52#include "colors.h"
53#include "graphics.h"
54#include "gui_main.h"
55#include "gui_stuff.h"
56
57#include "helpdlg.h"
58
59#define TECH_TREE_DEPTH 20
60
61/*
62 * Globals.
63 */
64 static GtkWidget *help_dialog_shell;
65 static GtkWidget *help_view_sw;
66
67 static GtkWidget *help_view;
68
69 static GtkWidget *help_frame;
70 static GtkTextBuffer *help_text;
71 static GtkWidget *help_text_sw;
72 static GtkWidget *help_vbox;
73 static GtkWidget *help_tile;
74 static GtkWidget *help_box;
75 static GtkWidget *help_itable;
76 static GtkWidget *help_wtable;
77 static GtkWidget *help_utable;
78 static GtkWidget *help_ttable;
79 static GtkWidget *help_etable;
80 static GtkWidget *help_tree;
81 static GtkTreeStore *tstore;
82
83 static GtkWidget *help_tree_sw;
84 static GtkWidget *help_tree_expand;
85 static GtkWidget *help_tree_collapse;
86 static GtkWidget *help_tree_buttons_hbox;
87 static GtkWidget *help_ilabel[6];
88 static GtkWidget *help_wlabel[6];
89 static GtkWidget *help_ulabel[5][5];
90 static GtkWidget *help_tlabel[2][5];
91 static GtkWidget *help_elabel[6];
92
93 static bool help_advances[A_LAST];
94
95 static GPtrArray *help_history;
96 static int help_history_pos;
97
98struct help_page_selection
99{
100 enum { HPAGE_SRC_ENUM, HPAGE_SRC_REQ } type;
101 union {
102 enum help_page_type page;
103 const struct requirement *req;
104 } u;
105};
106
107 static const char *help_ilabel_name[6] =
108{ N_("Base Cost:"), NULL, N_("Upkeep:"), NULL, N_("Requirement:"), NULL };
109 static struct help_page_selection help_impr_req;
110
111 static const char *help_wlabel_name[6] =
112{ N_("Base Cost:"), NULL, N_("Requirement:"), NULL, N_("Obsolete by:"), NULL };
113 static struct help_page_selection help_wndr_req;
114
115 static struct help_page_selection page_selections[HELP_LAST];
116
117 static const char *help_ulabel_name[5][5] =
118{
119 { N_("Cost:"), NULL, NULL, N_("Attack:"), NULL },
120 { N_("Defense:"), NULL, NULL, N_("Move:"), NULL },
121 { N_("Firepower:"), NULL, NULL, N_("Hitpoints:"), NULL },
122 { N_("Basic Upkeep:"), NULL, NULL, N_("Vision:"), NULL },
123 { N_("Requirement:"), NULL, NULL, N_("Obsolete by:"), NULL }
124};
125
126 static const char *help_tlabel_name[2][5] =
127{
128 { N_("Move/Defense:"), NULL, NULL, N_("Food/Res/Trade:"), NULL },
129 { N_("Resources:"), NULL, NULL, NULL, NULL }
130};
131
132 static const char *help_elabel_name[6] =
133/* TRANS: Label for build cost for extras in help. Will be followed by
134 * something like "3 MP" (where MP = Movement Points) */
135{ N_("Build:"), NULL,
136/* TRANS: Extra conflicts in help. Will be followed by a list of extras
137 * that can't be built on the same tile as this one. */
138 N_("Conflicts with:"), NULL,
139/* TRANS: Extra bonus in help. Will be followed by food/production/trade
140 * stats like "0/0/+1", "0/+50%/0" */
141 N_("Bonus (F/P/T):"), NULL };
142
143#define REQ_LABEL_NONE _("?tech:None")
144#define REQ_LABEL_NEVER _("(Never)")
145
146static void create_help_dialog(void);
147static void help_update_dialog(const struct help_item *pitem);
148
149static void select_help_item_string(const char *item,
150 enum help_page_type htype);
151static void help_command_update(void);
152static void help_command_callback(GtkWidget *w, gint response_id);
153
154/**********************************************************************/
157 void help_system_init(void)
158{
159 enum help_page_type page;
160
161 for (page = 0; page < HELP_LAST; page++) {
162 page_selections[page].type = HPAGE_SRC_ENUM;
163 page_selections[page].u.page = page;
164 }
165
166 help_impr_req.type = HPAGE_SRC_REQ;
167 help_wndr_req.type = HPAGE_SRC_REQ;
168}
169
170/**********************************************************************/
173 static void set_title_topic(char *topic)
174{
175 if (strcmp(topic, _(HELP_ABOUT_ITEM)) == 0) {
176 gtk_frame_set_label(GTK_FRAME(help_frame), freeciv_name_version());
177 } else {
178 gtk_frame_set_label(GTK_FRAME(help_frame), topic);
179 }
180}
181
182/**********************************************************************/
185 void popdown_help_dialog(void)
186{
187 if (help_dialog_shell) {
188 gtk_window_destroy(GTK_WINDOW(help_dialog_shell));
189 }
190}
191
192/**********************************************************************/
195 void popup_help_dialog_typed(const char *item, enum help_page_type htype)
196{
197 if (!help_dialog_shell) {
198 create_help_dialog();
199 }
200 gtk_window_present(GTK_WINDOW(help_dialog_shell));
201
202 select_help_item_string(item, htype);
203}
204
205/**********************************************************************/
209 void popup_help_dialog_string(const char *item)
210{
211 popup_help_dialog_typed(Q_(item), HELP_ANY);
212}
213
214/**********************************************************************/
223 static void create_tech_tree(int tech, int levels, GtkTreeIter *parent)
224{
225 const struct research *presearch;
226 int bg;
227 int turns_to_tech;
228 bool original;
229 GtkTreeIter l;
230 GValue value = { 0, };
231 enum tech_state state;
232
233 if (advance_required(tech, AR_ONE) == A_LAST
234 && advance_required(tech, AR_TWO) == A_LAST) {
235 bg = COLOR_REQTREE_UNKNOWN;
236
237 gtk_tree_store_append(tstore, &l, parent);
238 help_advances[tech] = TRUE;
239
240 g_value_init(&value, G_TYPE_STRING);
241 g_value_set_static_string(&value, _("Removed"));
242 gtk_tree_store_set_value(tstore, &l, 0, &value);
243 g_value_unset(&value);
244
245 gtk_tree_store_set(tstore, &l,
246 1, -1,
247 2, tech,
248 3, &get_color(tileset, bg)->color
249 -1);
250 return;
251 }
252
253 presearch = research_get(client_player());
254
255 state = research_invention_state(presearch, tech);
256 if (tech_state_is_valid(state)) {
257 switch (state) {
258 case TECH_UNKNOWN:
259 bg = COLOR_REQTREE_UNKNOWN;
260 break;
261 case TECH_KNOWN:
262 bg = COLOR_REQTREE_KNOWN;
263 break;
264 case TECH_PREREQS_KNOWN:
265 bg = COLOR_REQTREE_PREREQS_KNOWN;
266 break;
267 }
268 } else {
269 bg = COLOR_REQTREE_BACKGROUND;
270 }
271 turns_to_tech = research_goal_unknown_techs(presearch, tech);
272
273 /* l is the original in the tree. */
274 original = !help_advances[tech];
275
276 gtk_tree_store_append(tstore, &l, parent);
277 help_advances[tech] = TRUE;
278
279 g_value_init(&value, G_TYPE_STRING);
280 g_value_set_static_string(&value,
281 research_advance_name_translation(presearch,
282 tech));
283 gtk_tree_store_set_value(tstore, &l, 0, &value);
284 g_value_unset(&value);
285
286 gtk_tree_store_set(tstore, &l,
287 1, turns_to_tech,
288 2, tech,
289 3, &get_color(tileset, bg)->color,
290 -1);
291
292 if (--levels <= 0) {
293 return;
294 }
295
296 if (original) {
297 /* Only add children to orginals */
298 if (advance_required(tech, AR_ONE) != A_NONE)
299 create_tech_tree(advance_required(tech, AR_ONE), levels, &l);
300 if (advance_required(tech, AR_TWO) != A_NONE)
301 create_tech_tree(advance_required(tech, AR_TWO), levels, &l);
302 }
303}
304
305/**********************************************************************/
308 static void help_tech_tree_activated_callback(GtkTreeView *view,
309 GtkTreePath *path,
310 GtkTreeViewColumn *col,
311 gpointer data)
312{
313 GtkTreeIter it;
314 gint tech;
315
316 gtk_tree_model_get_iter(GTK_TREE_MODEL(tstore), &it, path);
317 gtk_tree_model_get(GTK_TREE_MODEL(tstore), &it, 2, &tech, -1);
318 select_help_item_string(advance_name_translation(advance_by_number(tech)),
319 HELP_TECH);
320}
321
322/**********************************************************************/
325 static void help_tech_tree_expand_callback(GtkWidget *w, gpointer data)
326{
327 gtk_tree_view_expand_all(GTK_TREE_VIEW(data));
328}
329
330/**********************************************************************/
333 static void help_tech_tree_collapse_callback(GtkWidget *w, gpointer data)
334{
335 gtk_tree_view_collapse_all(GTK_TREE_VIEW(data));
336}
337
338/**********************************************************************/
341 static void help_hyperlink_callback(GtkWidget *w)
342{
343 const char *s;
344 struct help_page_selection *select;
345 enum help_page_type type = HELP_LAST;
346
347 s = gtk_label_get_text(GTK_LABEL(w));
348 select = (struct help_page_selection *)(g_object_get_data(G_OBJECT(w),
349 "page_type"));
350
351 switch (select->type) {
352 case HPAGE_SRC_ENUM:
353 type = select->u.page;
354 break;
355 case HPAGE_SRC_REQ:
356 type = help_type_by_requirement(select->u.req);
357 break;
358 }
359
360 if (type == HELP_LAST) {
361 return;
362 }
363
364 /* FIXME: May be able to skip, or may need to modify, advances[A_NONE]
365 below, depending on which i18n is done elsewhere.
366 */
367 if (strcmp(s, REQ_LABEL_NEVER) != 0
368 && strcmp(s, skip_intl_qualifier_prefix(REQ_LABEL_NONE)) != 0
369 && strcmp(s, advance_name_translation(advance_by_number(A_NONE))) != 0) {
370 select_help_item_string(s, type);
371 }
372}
373
374/**********************************************************************/
377 static GtkWidget *help_hyperlink_new(GtkWidget *label,
378 struct help_page_selection *select)
379{
380 GtkWidget *button;
381
382 button = gtk_button_new();
383 gtk_button_set_has_frame(GTK_BUTTON(button), FALSE);
384 gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
385 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
386 gtk_widget_set_name(label, "help_link");
387 gtk_button_set_child(GTK_BUTTON(button), label);
388 gtk_widget_set_visible(button, TRUE);
389 g_signal_connect_swapped(button, "clicked",
390 G_CALLBACK(help_hyperlink_callback), label);
391 g_object_set_data(G_OBJECT(label), "page_type", select);
392
393 return button;
394}
395
396/**********************************************************************/
399 static GtkWidget *help_hyperlink_new_page(GtkWidget *label,
400 enum help_page_type page)
401{
402 return help_hyperlink_new(label, &(page_selections[page]));
403}
404
405/**********************************************************************/
408 static GtkWidget *help_slink_new(const gchar *txt,
409 struct help_page_selection *select)
410{
411 GtkWidget *button, *label;
412
413 label = gtk_label_new(txt);
414 gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
415 gtk_widget_set_valign(label, GTK_ALIGN_CENTER);
416 button = help_hyperlink_new(label, select);
417
418 return button;
419}
420
421/**********************************************************************/
424 static GtkWidget *help_slink_new_page(const gchar *txt,
425 enum help_page_type page)
426{
427 return help_slink_new(txt, &(page_selections[page]));
428}
429
430/**********************************************************************/
433 static void help_box_hide(void)
434{
435 gtk_widget_set_visible(help_box, FALSE);
436
437 gtk_widget_set_visible(help_tile, FALSE);
438
439 gtk_widget_set_visible(help_itable, FALSE);
440 gtk_widget_set_visible(help_wtable, FALSE);
441 gtk_widget_set_visible(help_utable, FALSE);
442 gtk_widget_set_visible(help_ttable, FALSE);
443 gtk_widget_set_visible(help_etable, FALSE);
444
445 gtk_widget_set_visible(help_vbox, FALSE);
446 gtk_widget_set_visible(help_text_sw, FALSE);
447
448 gtk_widget_set_visible(help_tree_sw, FALSE);
449 gtk_widget_set_visible(help_tree_buttons_hbox, FALSE);
450}
451
452/**********************************************************************/
455 static void help_box_add(GtkWidget *wdg)
456{
457 gtk_box_append(GTK_BOX(help_vbox), wdg);
458}
459
460/**********************************************************************/
463 static void help_box_clear(void)
464{
465 GtkWidget *child = gtk_widget_get_first_child(help_vbox);
466
467 while (child != NULL) {
468 gtk_box_remove(GTK_BOX(help_vbox), child);
469 child = gtk_widget_get_first_child(help_vbox);
470 }
471}
472
473/**********************************************************************/
476 static void help_destroy_callback(GtkWidget *w, gpointer data)
477{
478 g_ptr_array_free(help_history, TRUE);
479 help_dialog_shell = NULL;
480}
481
482/**********************************************************************/
485 static void activated_topic(GtkTreeView *view, gpointer data)
486{
487 GtkTreePath *path;
488 GtkTreeViewColumn *col;
489 GtkTreeModel *model;
490 GtkTreeIter it;
491 struct help_item *pitem;
492
493 model = gtk_tree_view_get_model(view);
494
495 if (model == NULL) {
496 return;
497 }
498
499 gtk_tree_view_get_cursor(view, &path, &col);
500 gtk_tree_model_get_iter(model, &it, path);
501 gtk_tree_path_free(path);
502
503 if (path == NULL) {
504 return;
505 }
506
507 gtk_tree_model_get(model, &it, 1, &pitem, -1);
508
509 if (help_history_pos >= 0
510 && g_ptr_array_index(help_history, help_history_pos) == (gpointer) pitem) {
511 return;
512 }
513
514 help_update_dialog(pitem);
515
516 /* Add to history. */
517 if (help_history_pos < help_history-> len - 1) {
518 g_ptr_array_set_size(help_history, help_history_pos + 1);
519 }
520 help_history_pos++;
521
522 g_ptr_array_add(help_history, (gpointer)pitem);
523 help_command_update();
524}
525
526/**********************************************************************/
529 static void create_help_dialog(void)
530{
531 GtkWidget *hbox;
532 GtkWidget *button;
533 GtkWidget *text;
534 int i, j;
535 GtkCellRenderer *rend;
536 GtkTreeViewColumn *col;
537 GArray *array;
538 GtkTreeStore *store;
539 GtkTreeSelection *selection;
540 GtkWidget *tile_sw;
541
542 help_history = g_ptr_array_new();
543 help_history_pos = -1;
544
545 help_dialog_shell = gtk_dialog_new_with_buttons(_("Freeciv Help Browser"),
546 NULL,
547 0,
548 _("_Back"),
549 1,
550 _("_Forward"),
551 2,
552 _("_Close"),
553 GTK_RESPONSE_CLOSE,
554 NULL);
555 setup_dialog(help_dialog_shell, toplevel);
556 gtk_dialog_set_default_response(GTK_DIALOG(help_dialog_shell),
557 GTK_RESPONSE_CLOSE);
558 gtk_widget_set_name(help_dialog_shell, "Freeciv");
559
560 g_signal_connect(help_dialog_shell, "response",
561 G_CALLBACK(help_command_callback), NULL);
562 g_signal_connect(help_dialog_shell, "destroy",
563 G_CALLBACK(help_destroy_callback), NULL);
564
565 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
566 gtk_box_append(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(help_dialog_shell))),
567 hbox);
568 gtk_widget_set_visible(hbox, TRUE);
569
570 /* Build tree store. */
571 store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
572
573 array = g_array_new(FALSE, FALSE, sizeof(GtkTreeIter));
574 help_items_iterate(pitem) {
575 GtkTreeIter *it, *parent;
576 const char *s;
577 int depth;
578
579 for (s = pitem->topic; *s == ' '; s++) {
580 /* Nothing */
581 }
582 depth = s - pitem->topic;
583
584 array = g_array_set_size(array, depth+1);
585
586 if (depth > 0) {
587 parent = &g_array_index(array, GtkTreeIter, depth-1);
588 } else {
589 parent = NULL;
590 }
591
592 it = &g_array_index(array, GtkTreeIter, depth);
593 gtk_tree_store_append(store, it, parent);
594
595 gtk_tree_store_set(store, it, 0, pitem->topic, 1, pitem, -1);
596 } help_items_iterate_end;
597
598 /* Create tree view. */
599 help_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
600 g_object_unref(store);
601 gtk_tree_view_columns_autosize(GTK_TREE_VIEW(help_view));
602 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(help_view), FALSE);
603
604 g_signal_connect(help_view, "cursor-changed",
605 G_CALLBACK(activated_topic), NULL);
606
607 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(help_view));
608 gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
609
610 rend = gtk_cell_renderer_text_new();
611 col = gtk_tree_view_column_new_with_attributes(NULL, rend, "text", 0, NULL);
612 gtk_tree_view_append_column(GTK_TREE_VIEW(help_view), col);
613
614 help_view_sw = gtk_scrolled_window_new();
615 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(help_view_sw),
616 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
617 gtk_widget_set_size_request(help_view_sw, 190, -1);
618 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(help_view_sw), help_view);
619 gtk_widget_set_visible(help_view, TRUE);
620 gtk_box_append(GTK_BOX(hbox), help_view_sw);
621 gtk_widget_set_visible(help_view_sw, TRUE);
622
623 help_frame = gtk_frame_new("");
624 gtk_box_append(GTK_BOX(hbox), help_frame);
625 gtk_widget_set_hexpand(help_frame, TRUE);
626 gtk_widget_set_visible(help_frame, TRUE);
627
628 help_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
629 gtk_frame_set_child(GTK_FRAME(help_frame), help_box);
630
631 help_tile = gtk_picture_new();
632 gtk_picture_set_can_shrink(GTK_PICTURE(help_tile), FALSE);
633 gtk_widget_set_valign(help_tile, GTK_ALIGN_CENTER);
634 gtk_widget_set_halign(help_tile, GTK_ALIGN_CENTER);
635 tile_sw = gtk_scrolled_window_new();
636 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(tile_sw),
637 GTK_POLICY_NEVER,
638 GTK_POLICY_NEVER);
639 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(tile_sw), help_tile);
640 gtk_box_append(GTK_BOX(help_box), tile_sw);
641
642 help_itable = gtk_grid_new();
643 gtk_box_append(GTK_BOX(help_box), help_itable);
644
645 for (i = 0; i < 6; i++) {
646 help_ilabel[i] =
647 gtk_label_new(help_ilabel_name[i] != NULL ? _(help_ilabel_name[i]) : "");
648 gtk_widget_set_hexpand(help_ilabel[i], TRUE);
649
650 if (i == 5) {
651 button = help_hyperlink_new(help_ilabel[i], &help_impr_req);
652 gtk_grid_attach(GTK_GRID(help_itable), button, i, 0, 1, 1);
653 } else {
654 gtk_grid_attach(GTK_GRID(help_itable), help_ilabel[i], i, 0, 1, 1);
655 gtk_widget_set_name(help_ilabel[i], "help_label");
656 }
657
658 gtk_widget_set_visible(help_ilabel[i], TRUE);
659 }
660
661 help_wtable = gtk_grid_new();
662 gtk_box_append(GTK_BOX(help_box), help_wtable);
663
664 for (i = 0; i < 6; i++) {
665 help_wlabel[i] =
666 gtk_label_new(help_wlabel_name[i] ? _(help_wlabel_name[i]) : "");
667 gtk_widget_set_hexpand(help_wlabel[i], TRUE);
668
669 if (i == 3 || i == 5) {
670 button = help_hyperlink_new(help_wlabel[i], &help_wndr_req);
671 gtk_grid_attach(GTK_GRID(help_wtable), button, i, 0, 1, 1);
672 } else {
673 gtk_grid_attach(GTK_GRID(help_wtable), help_wlabel[i], i, 0, 1, 1);
674 gtk_widget_set_name(help_wlabel[i], "help_label");
675 }
676
677 gtk_widget_set_visible(help_wlabel[i], TRUE);
678 }
679
680 help_utable = gtk_grid_new();
681 gtk_box_append(GTK_BOX(help_box), help_utable);
682
683 for (i = 0; i < 5; i++) {
684 for (j = 0; j < 5; j++) {
685 help_ulabel[j][i] =
686 gtk_label_new(help_ulabel_name[j][i] ? _(help_ulabel_name[j][i]) : "");
687 gtk_widget_set_hexpand(help_ulabel[j][i], TRUE);
688
689 if (j == 4 && (i == 1 || i == 4)) {
690 if (i == 1) {
691 button = help_hyperlink_new_page(help_ulabel[j][i], HELP_TECH);
692 } else {
693 button = help_hyperlink_new_page(help_ulabel[j][i], HELP_UNIT);
694 }
695
696 gtk_grid_attach(GTK_GRID(help_utable), button, i, j, 1, 1);
697 } else {
698 gtk_grid_attach(GTK_GRID(help_utable), help_ulabel[j][i],
699 i, j, 1, 1);
700 gtk_widget_set_name(help_ulabel[j][i], "help_label");
701 }
702
703 gtk_widget_set_visible(help_ulabel[j][i], TRUE);
704 }
705 }
706
707 help_ttable = gtk_grid_new();
708 gtk_box_append(GTK_BOX(help_box), help_ttable);
709
710 for (j = 0; j < 2; j++) {
711 for (i = 0; i < 5; i++) {
712 help_tlabel[j][i] =
713 gtk_label_new(help_tlabel_name[j][i] ? _(help_tlabel_name[j][i]) : "");
714 gtk_widget_set_hexpand(help_tlabel[j][i], TRUE);
715 gtk_widget_set_name(help_tlabel[j][i], "help_label");
716
717 /* Ugly (but these numbers are hardcoded in help_update_terrain() too) */
718 if (j == 1 && i == 1) {
719 /* Extra wide cell for terrain specials */
720 gtk_grid_attach(GTK_GRID(help_ttable), help_tlabel[j][i],
721 i, j, 4, 1);
722 gtk_widget_set_visible(help_tlabel[j][i], TRUE);
723 break; /* Skip rest of row */
724 } else {
725 gtk_grid_attach(GTK_GRID(help_ttable), help_tlabel[j][i],
726 i, j, 1, 1);
727 gtk_widget_set_visible(help_tlabel[j][i], TRUE);
728 }
729 }
730 }
731
732 help_etable = gtk_grid_new();
733 gtk_box_append(GTK_BOX(help_box), help_etable);
734
735 for (i = 0; i < 6; i++) {
736 help_elabel[i]
737 = gtk_label_new(help_elabel_name[i] ? _(help_elabel_name[i]) : "");
738 gtk_widget_set_hexpand(help_elabel[i], TRUE);
739 gtk_grid_attach(GTK_GRID(help_etable), help_elabel[i], i % 4, i / 4, 1, 1);
740 gtk_widget_set_name(help_elabel[i], "help_label");
741 gtk_widget_set_visible(help_elabel[i], TRUE);
742 }
743
744 help_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1);
745 gtk_widget_set_margin_start(help_vbox, 5);
746 gtk_widget_set_margin_end(help_vbox, 5);
747 gtk_widget_set_margin_top(help_vbox, 5);
748 gtk_widget_set_margin_bottom(help_vbox, 5);
749 gtk_box_append(GTK_BOX(help_box), help_vbox);
750
751 text = gtk_text_view_new();
752 gtk_widget_set_hexpand(text, TRUE);
753 gtk_widget_set_vexpand(text, TRUE);
754 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text), FALSE);
755 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
756 gtk_widget_set_margin_start(text, 5);
757 gtk_widget_set_margin_end(text, 5);
758 gtk_widget_set_margin_top(text, 5);
759 gtk_widget_set_margin_bottom(text, 5);
760 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
761 gtk_widget_set_name(text, "help_text");
762 help_text = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
763 gtk_widget_set_visible(text, TRUE);
764
765 help_text_sw = gtk_scrolled_window_new();
766 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(help_text_sw),
767 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
768 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(help_text_sw), text);
769 gtk_box_append(GTK_BOX(help_box), help_text_sw);
770
771 /* Build tech store. */
772 tstore = gtk_tree_store_new(4,
773 G_TYPE_STRING, /* Tech name */
774 G_TYPE_INT, /* Turns to tech */
775 G_TYPE_INT, /* Tech id */
776 GDK_TYPE_RGBA); /* Color */
777 help_tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(tstore));
778 gtk_widget_set_hexpand(help_tree, TRUE);
779 gtk_widget_set_vexpand(help_tree, TRUE);
780 g_object_unref(tstore);
781 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(help_tree), FALSE);
782
783 g_signal_connect(help_tree, "row_activated",
784 G_CALLBACK(help_tech_tree_activated_callback), NULL);
785
786
787 col = gtk_tree_view_column_new();
788
789 rend = gtk_cell_renderer_text_new();
790 g_object_set(rend, "weight", PANGO_WEIGHT_BOLD, NULL);
791 gtk_tree_view_column_pack_start(col, rend, TRUE);
792 gtk_tree_view_column_set_attributes(col, rend,
793 "text", 0,
794 "background-rgba", 3,
795 NULL);
796 rend = gtk_cell_renderer_text_new();
797 g_object_set(rend, "weight", PANGO_WEIGHT_BOLD, "xalign", 1.0, NULL);
798 gtk_tree_view_column_pack_start(col, rend, FALSE);
799 gtk_tree_view_column_set_attributes(col, rend,
800 "text", 1,
801 "background-rgba", 3,
802 NULL);
803
804 gtk_tree_view_append_column(GTK_TREE_VIEW(help_tree), col);
805
806 help_tree_sw = gtk_scrolled_window_new();
807 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(help_tree_sw),
808 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
809 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(help_tree_sw), help_tree);
810 gtk_widget_set_size_request(help_tree_sw, -1, 200);
811 gtk_widget_set_visible(help_tree, TRUE);
812 gtk_box_append(GTK_BOX(help_box), help_tree_sw);
813
814 help_tree_expand = gtk_button_new_with_label(_("Expand All"));
815 help_tree_collapse = gtk_button_new_with_label(_("Collapse All"));
816
817 g_signal_connect(help_tree_expand, "clicked",
818 G_CALLBACK(help_tech_tree_expand_callback), help_tree);
819 g_signal_connect(help_tree_collapse, "clicked",
820 G_CALLBACK(help_tech_tree_collapse_callback), help_tree);
821
822 help_tree_buttons_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
823 gtk_box_append(GTK_BOX(help_tree_buttons_hbox), help_tree_expand);
824 gtk_box_append(GTK_BOX(help_tree_buttons_hbox), help_tree_collapse);
825 gtk_box_append(GTK_BOX(help_box), help_tree_buttons_hbox);
826 gtk_widget_set_visible(help_tree_buttons_hbox, TRUE);
827}
828
829/**********************************************************************/
832 static void set_help_tile_from_sprite(struct sprite *spr)
833{
834 if (spr == nullptr) {
835 return;
836 }
837
838 picture_set_from_surface(GTK_PICTURE(help_tile), spr->surface);
839 gtk_widget_set_visible(help_tile, TRUE);
840}
841
842/**********************************************************************/
845 static void set_help_tile_from_terrain(struct terrain *pterr)
846{
847 struct canvas canvas = FC_STATIC_CANVAS_INIT;
848 cairo_t *cr;
849 int i;
850
851 canvas.surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
852 tileset_tile_width(tileset),
853 tileset_tile_height(tileset));
854
855 cr = cairo_create(canvas.surface);
856 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
857 cairo_paint(cr);
858 cairo_destroy(cr);
859
860 for (i = 0; i < 3; i++) {
861 struct drawn_sprite sprs[80];
862 int count = fill_basic_terrain_layer_sprite_array(tileset, sprs,
863 i, pterr);
864
865 put_drawn_sprites(&canvas, 1.0, 0, 0, count, sprs, FALSE);
866 }
867
868 picture_set_from_surface(GTK_PICTURE(help_tile), canvas.surface);
869 gtk_widget_set_visible(help_tile, TRUE);
870 cairo_surface_destroy(canvas.surface);
871}
872
873/**********************************************************************/
876 static void set_help_tile_from_extra(const struct extra_type *pextra)
877{
878 struct canvas canvas = FC_STATIC_CANVAS_INIT;
879 cairo_t *cr;
880 struct drawn_sprite sprs[80];
881 int count;
882
883 canvas.surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
884 tileset_tile_width(tileset),
885 tileset_tile_height(tileset));
886
887 cr = cairo_create(canvas.surface);
888 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
889 cairo_paint(cr);
890 cairo_destroy(cr);
891
892 count = fill_basic_extra_sprite_array(tileset, sprs, pextra);
893
894 put_drawn_sprites(&canvas, 1.0, 0, 0, count, sprs, FALSE);
895
896 picture_set_from_surface(GTK_PICTURE(help_tile), canvas.surface);
897 gtk_widget_set_visible(help_tile, TRUE);
898 cairo_surface_destroy(canvas.surface);
899}
900
901/**********************************************************************/
904 static void help_update_improvement(const struct help_item *pitem,
905 char *title)
906{
907 char buf[8192];
908 struct impr_type *imp = improvement_by_translated_name(title);
909
910 if (imp != NULL && !is_great_wonder(imp)) {
911 const char *req = skip_intl_qualifier_prefix(REQ_LABEL_NONE);
912 char req_buf[512];
913
914 sprintf(buf, "%d", impr_base_build_shield_cost(imp));
915 gtk_label_set_text(GTK_LABEL(help_ilabel[1]), buf);
916 sprintf(buf, "%d", imp->upkeep);
917 gtk_label_set_text(GTK_LABEL(help_ilabel[3]), buf);
918
919 /* FIXME: this should show ranges, negated reqs, and all the
920 * MAX_NUM_REQS reqs.
921 * Currently it's limited to 1 req but this code is partially prepared
922 * to be extended. Remember MAX_NUM_REQS is a compile-time
923 * definition. */
924 help_impr_req.u.req = NULL;
925 requirement_vector_iterate(&imp->reqs, preq) {
926 if (!preq->present) {
927 continue;
928 }
929 req = universal_name_translation(&preq->source, req_buf, sizeof(req_buf));
930 help_impr_req.u.req = preq;
931 break;
932 } requirement_vector_iterate_end;
933 gtk_label_set_text(GTK_LABEL(help_ilabel[5]), req);
934/* create_tech_tree(help_improvement_tree, 0, imp->tech_req, 3); */
935 } else {
936 gtk_label_set_text(GTK_LABEL(help_ilabel[1]), "0");
937 gtk_label_set_text(GTK_LABEL(help_ilabel[3]), "0");
938 gtk_label_set_text(GTK_LABEL(help_ilabel[5]), REQ_LABEL_NEVER);
939/* create_tech_tree(help_improvement_tree, 0, advance_count(), 3); */
940 }
941
942 set_help_tile_from_sprite(get_building_sprite(tileset, imp));
943
944 gtk_widget_set_visible(help_itable, TRUE);
945
946 helptext_building(buf, sizeof(buf), client_player(), pitem->text, imp);
947 gtk_text_buffer_set_text(help_text, buf, -1);
948 gtk_widget_set_visible(help_text_sw, TRUE);
949}
950
951/**********************************************************************/
954 static void help_update_wonder(const struct help_item *pitem,
955 char *title)
956{
957 char buf[8192];
958 struct impr_type *imp = improvement_by_translated_name(title);
959
960 if (imp != NULL && is_great_wonder(imp)) {
961 int i;
962 char req_buf[512];
963
964 sprintf(buf, "%d", impr_base_build_shield_cost(imp));
965 gtk_label_set_text(GTK_LABEL(help_wlabel[1]), buf);
966
967 /* FIXME: this should show ranges, negated reqs, and all the
968 * MAX_NUM_REQS reqs.
969 * Currently it's limited to 1 req but this code is partially prepared
970 * to be extended. Remember MAX_NUM_REQS is a compile-time
971 * definition. */
972 i = 0;
973 help_wndr_req.u.req = NULL;
974 requirement_vector_iterate(&imp->reqs, preq) {
975 if (!preq->present) {
976 continue;
977 }
978 gtk_label_set_text(GTK_LABEL(help_wlabel[3 + i]),
979 universal_name_translation(&preq->source,
980 req_buf, sizeof(req_buf)));
981 help_wndr_req.u.req = preq;
982 i++;
983 break;
984 } requirement_vector_iterate_end;
985
986 gtk_label_set_text(GTK_LABEL(help_wlabel[5]), REQ_LABEL_NEVER);
987 requirement_vector_iterate(&imp->obsolete_by, pobs) {
988 if (pobs->source.kind == VUT_ADVANCE && pobs->present) {
989 gtk_label_set_text(GTK_LABEL(help_wlabel[5]),
990 advance_name_translation
991 (pobs->source.value.advance));
992
993 break;
994 }
995 } requirement_vector_iterate_end;
996
997/* create_tech_tree(help_improvement_tree, 0, imp->tech_req, 3); */
998 } else {
999 /* Can't find wonder */
1000 gtk_label_set_text(GTK_LABEL(help_wlabel[1]), "0");
1001 gtk_label_set_text(GTK_LABEL(help_wlabel[3]), REQ_LABEL_NEVER);
1002 gtk_label_set_text(GTK_LABEL(help_wlabel[5]), skip_intl_qualifier_prefix(REQ_LABEL_NONE));
1003/* create_tech_tree(help_improvement_tree, 0, advance_count(), 3); */
1004 }
1005
1006 set_help_tile_from_sprite(get_building_sprite(tileset, imp));
1007
1008 gtk_widget_set_visible(help_wtable, TRUE);
1009
1010 helptext_building(buf, sizeof(buf), client_player(), pitem->text, imp);
1011 gtk_text_buffer_set_text(help_text, buf, -1);
1012 gtk_widget_set_visible(help_text_sw, TRUE);
1013}
1014
1015/**********************************************************************/
1018 static void help_update_unit_type(const struct help_item *pitem,
1019 char *title)
1020{
1021 char buf[8192];
1022 struct unit_type *utype = unit_type_by_translated_name(title);
1023
1024 if (utype != NULL) {
1025 sprintf(buf, "%d", utype_build_shield_cost_base(utype));
1026 gtk_label_set_text(GTK_LABEL(help_ulabel[0][1]), buf);
1027 sprintf(buf, "%d", utype->attack_strength);
1028 gtk_label_set_text(GTK_LABEL(help_ulabel[0][4]), buf);
1029 sprintf(buf, "%d", utype->defense_strength);
1030 gtk_label_set_text(GTK_LABEL(help_ulabel[1][1]), buf);
1031 sprintf(buf, "%s", move_points_text(utype->move_rate, TRUE));
1032 gtk_label_set_text(GTK_LABEL(help_ulabel[1][4]), buf);
1033 sprintf(buf, "%d", utype->firepower);
1034 gtk_label_set_text(GTK_LABEL(help_ulabel[2][1]), buf);
1035 sprintf(buf, "%d", utype->hp);
1036 gtk_label_set_text(GTK_LABEL(help_ulabel[2][4]), buf);
1037 gtk_label_set_text(GTK_LABEL(help_ulabel[3][1]),
1038 helptext_unit_upkeep_str(utype));
1039 sprintf(buf, "%d", (int)sqrt((double)utype->vision_radius_sq));
1040 gtk_label_set_text(GTK_LABEL(help_ulabel[3][4]), buf);
1041 gtk_label_set_text(GTK_LABEL(help_ulabel[4][1]),
1042 advance_name_translation(utype_primary_tech_req(utype)));
1043
1044#if 0
1045 create_tech_tree(help_improvement_tree, 0,
1046 advance_number(utype->require_advance), 3);
1047#endif
1048
1049 if (U_NOT_OBSOLETED == utype->obsoleted_by) {
1050 gtk_label_set_text(GTK_LABEL(help_ulabel[4][4]),
1051 skip_intl_qualifier_prefix(REQ_LABEL_NONE));
1052 } else {
1053 gtk_label_set_text(GTK_LABEL(help_ulabel[4][4]),
1054 utype_name_translation(utype->obsoleted_by));
1055 }
1056
1057 helptext_unit(buf, sizeof(buf), client_player(), pitem->text, utype);
1058
1059 gtk_text_buffer_set_text(help_text, buf, -1);
1060 gtk_widget_set_visible(help_text_sw, TRUE);
1061
1062 set_help_tile_from_sprite(get_unittype_sprite(tileset, utype,
1063 ACTIVITY_LAST,
1064 direction8_invalid()));
1065 } else {
1066 gtk_label_set_text(GTK_LABEL(help_ulabel[0][1]), "0");
1067 gtk_label_set_text(GTK_LABEL(help_ulabel[0][4]), "0");
1068 gtk_label_set_text(GTK_LABEL(help_ulabel[1][1]), "0");
1069 gtk_label_set_text(GTK_LABEL(help_ulabel[1][4]), "0");
1070 gtk_label_set_text(GTK_LABEL(help_ulabel[2][1]), "0");
1071 gtk_label_set_text(GTK_LABEL(help_ulabel[2][4]), "0");
1072 gtk_label_set_text(GTK_LABEL(help_ulabel[3][1]), "0");
1073 gtk_label_set_text(GTK_LABEL(help_ulabel[3][4]), "0");
1074
1075 gtk_label_set_text(GTK_LABEL(help_ulabel[4][1]), REQ_LABEL_NEVER);
1076/* create_tech_tree(help_improvement_tree, 0, A_LAST, 3); */
1077 gtk_label_set_text(GTK_LABEL(help_ulabel[4][4]),
1078 skip_intl_qualifier_prefix(REQ_LABEL_NONE));
1079
1080 gtk_text_buffer_set_text(help_text, buf, -1);
1081 gtk_widget_set_visible(help_text_sw, TRUE);
1082 }
1083
1084 gtk_widget_set_visible(help_utable, TRUE);
1085}
1086
1087/**********************************************************************/
1090 static char *fc_chomp(char *str, size_t len)
1091{
1092 gchar *i;
1093
1094 if (str == NULL || !*str) {
1095 return str;
1096 }
1097
1098 i = str + len;
1099 for (i = g_utf8_find_prev_char(str, i);
1100 (i != NULL && g_unichar_isspace(g_utf8_get_char(i)));
1101 i = g_utf8_find_prev_char(str, i)) {
1102 *i = '\0';
1103 }
1104
1105 return str;
1106}
1107
1108/**********************************************************************/
1111 static void help_update_tech(const struct help_item *pitem, char *title)
1112{
1113 int j;
1114 GtkWidget *w, *hbox;
1115 char buf[8192];
1116 struct advance *padvance = advance_by_translated_name(title);
1117
1118 if (is_regular_advance(padvance)) {
1119 GtkTextBuffer *txt;
1120 size_t len;
1121 Tech_type_id i = advance_number(padvance);
1122
1123 help_box_clear();
1124
1125 for (j = 0; j < ARRAY_SIZE(help_advances); j++) {
1126 help_advances[j] = FALSE;
1127 }
1128
1129 gtk_tree_store_clear(tstore);
1130 create_tech_tree(i, TECH_TREE_DEPTH, NULL);
1131 gtk_widget_set_visible(help_tree_sw, TRUE);
1132 gtk_widget_set_visible(help_tree_buttons_hbox, TRUE);
1133
1134 helptext_advance(buf, sizeof(buf), client.conn.playing, pitem->text, i);
1135 len = strlen(buf);
1136 fc_chomp(buf, len);
1137
1138 set_help_tile_from_sprite(get_tech_sprite(tileset, i));
1139
1140 w = gtk_text_view_new();
1141 gtk_widget_set_hexpand(w, TRUE);
1142 gtk_widget_set_vexpand(w, TRUE);
1143 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(w), FALSE);
1144 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(w), GTK_WRAP_WORD);
1145 gtk_widget_set_name(w, "help_text");
1146 gtk_widget_set_margin_start(w, 5);
1147 gtk_widget_set_margin_end(w, 5);
1148 gtk_widget_set_margin_top(w, 5);
1149 gtk_widget_set_margin_bottom(w, 5);
1150 gtk_text_view_set_editable(GTK_TEXT_VIEW(w), FALSE);
1151 help_box_add(w);
1152 gtk_widget_set_visible(w, TRUE);
1153
1154 txt = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
1155 if (txt != nullptr) {
1156 gtk_text_buffer_set_text(txt, buf, -1);
1157 }
1158
1159 w = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
1160 gtk_widget_set_margin_bottom(w, 5);
1161 gtk_widget_set_margin_end(w, 5);
1162 gtk_widget_set_margin_start(w, 5);
1163 gtk_widget_set_margin_top(w, 5);
1164 gtk_widget_set_hexpand(w, TRUE);
1165 gtk_widget_set_vexpand(w, TRUE);
1166 help_box_add(w);
1167 gtk_widget_set_visible(w, TRUE);
1168
1169 governments_iterate(pgov) {
1170 /* FIXME: need a more general mechanism for this, since this
1171 * helptext needs to be shown in all possible req source types. */
1172 requirement_vector_iterate(&pgov->reqs, preq) {
1173 if (VUT_ADVANCE == preq->source.kind
1174 && preq->source.value.advance == padvance) {
1175 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
1176 help_box_add(hbox);
1177 w = gtk_label_new(_("Allows"));
1178 gtk_box_append(GTK_BOX(hbox), w);
1179 w = help_slink_new_page(government_name_translation(pgov),
1180 HELP_GOVERNMENT);
1181 gtk_box_append(GTK_BOX(hbox), w);
1182 gtk_widget_set_visible(hbox, TRUE);
1183 }
1184 } requirement_vector_iterate_end;
1185 } governments_iterate_end;
1186
1187 improvement_iterate(pimprove) {
1188 if (valid_improvement(pimprove)) {
1189 requirement_vector_iterate(&pimprove->reqs, preq) {
1190 if (VUT_ADVANCE == preq->source.kind
1191 && preq->source.value.advance == padvance) {
1192 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
1193 help_box_add(hbox);
1194 w = gtk_label_new(_("Allows"));
1195 gtk_box_append(GTK_BOX(hbox), w);
1196 w = help_slink_new_page(improvement_name_translation(pimprove),
1197 is_great_wonder(pimprove)
1198 ? HELP_WONDER
1199 : HELP_IMPROVEMENT);
1200 gtk_box_append(GTK_BOX(hbox), w);
1201 gtk_widget_set_visible(hbox, TRUE);
1202 }
1203 } requirement_vector_iterate_end;
1204 requirement_vector_iterate(&pimprove->obsolete_by, pobs) {
1205 if (pobs->source.kind == VUT_ADVANCE
1206 && pobs->source.value.advance == padvance
1207 && pobs->present) {
1208 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
1209 help_box_add(hbox);
1210 w = gtk_label_new(_("Obsoletes"));
1211 gtk_box_append(GTK_BOX(hbox), w);
1212 w = help_slink_new_page(improvement_name_translation(pimprove),
1213 is_great_wonder(pimprove)
1214 ? HELP_WONDER
1215 : HELP_IMPROVEMENT);
1216 gtk_box_append(GTK_BOX(hbox), w);
1217 gtk_widget_set_visible(hbox, TRUE);
1218 }
1219 } requirement_vector_iterate_end;
1220 }
1221 } improvement_iterate_end;
1222
1223 unit_type_iterate(punittype) {
1224 if (!is_tech_req_for_utype(punittype, padvance)) {
1225 continue;
1226 }
1227
1228 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
1229 help_box_add(hbox);
1230 w = gtk_label_new(_("Allows"));
1231 gtk_box_append(GTK_BOX(hbox), w);
1232 w = help_slink_new_page(utype_name_translation(punittype), HELP_UNIT);
1233 gtk_box_append(GTK_BOX(hbox), w);
1234 gtk_widget_set_visible(hbox, TRUE);
1235 } unit_type_iterate_end;
1236
1237 advance_iterate_all(ptest) {
1238 if (padvance == advance_requires(ptest, AR_ONE)) {
1239 if (advance_by_number(A_NONE) == advance_requires(ptest, AR_TWO)) {
1240 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
1241 help_box_add(hbox);
1242 w = gtk_label_new(_("Allows"));
1243 gtk_box_append(GTK_BOX(hbox), w);
1244 w = help_slink_new_page(advance_name_translation(ptest), HELP_TECH);
1245 gtk_box_append(GTK_BOX(hbox), w);
1246 gtk_widget_set_visible(hbox, TRUE);
1247 } else {
1248 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
1249 help_box_add(hbox);
1250 w = gtk_label_new(_("Allows"));
1251 gtk_box_append(GTK_BOX(hbox), w);
1252 w = help_slink_new_page(advance_name_translation(ptest), HELP_TECH);
1253 gtk_box_append(GTK_BOX(hbox), w);
1254 w = gtk_label_new(_("with"));
1255 gtk_box_append(GTK_BOX(hbox), w);
1256 w = help_slink_new_page(advance_name_translation(advance_requires(ptest,
1257 AR_TWO)),
1258 HELP_TECH);
1259 gtk_box_append(GTK_BOX(hbox), w);
1260 w = gtk_label_new(Q_("?techhelp:"));
1261 gtk_box_append(GTK_BOX(hbox), w);
1262 gtk_widget_set_visible(hbox, TRUE);
1263 }
1264 }
1265 if (padvance == advance_requires(ptest, AR_TWO)) {
1266 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
1267 help_box_add(hbox);
1268 w = gtk_label_new(_("Allows"));
1269 gtk_box_append(GTK_BOX(hbox), w);
1270 w = help_slink_new_page(advance_name_translation(ptest), HELP_TECH);
1271 gtk_box_append(GTK_BOX(hbox), w);
1272 w = gtk_label_new(_("with"));
1273 gtk_box_append(GTK_BOX(hbox), w);
1274 w = help_slink_new_page(advance_name_translation(advance_requires(ptest,
1275 AR_ONE)),
1276 HELP_TECH);
1277 gtk_box_append(GTK_BOX(hbox), w);
1278 w = gtk_label_new(Q_("?techhelp:"));
1279 gtk_box_append(GTK_BOX(hbox), w);
1280 gtk_widget_set_visible(hbox, TRUE);
1281 }
1282 } advance_iterate_all_end;
1283
1284 gtk_widget_set_visible(help_vbox, TRUE);
1285 }
1286}
1287
1288/**********************************************************************/
1291 static void add_act_help_for_terrain(const char *act_label,
1292 const char *result_link_label,
1293 enum help_page_type result_link_type,
1294 const char *descr_label)
1295{
1296 GtkWidget *w;
1297 GtkWidget *hbox;
1298
1299 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
1300 help_box_add(hbox);
1301 w = gtk_label_new(act_label);
1302 gtk_box_append(GTK_BOX(hbox), w);
1303 w = help_slink_new_page(result_link_label, result_link_type);
1304 gtk_box_append(GTK_BOX(hbox), w);
1305 w = gtk_label_new(descr_label);
1306 gtk_box_append(GTK_BOX(hbox), w);
1307
1308 gtk_widget_set_visible(hbox, TRUE);
1309}
1310
1311/**********************************************************************/
1314 static void help_extras_of_act_for_terrain(struct terrain *pterr,
1315 enum unit_activity act,
1316 char *label)
1317{
1318 enum extra_cause cause = activity_to_extra_cause(act);
1319
1320 extra_type_by_cause_iterate(cause, pextra) {
1321 if (pextra->buildable
1322 && requirement_fulfilled_by_terrain(pterr, &(pextra->reqs))) {
1323 add_act_help_for_terrain(label,
1324 extra_name_translation(pextra), HELP_EXTRA,
1325 helptext_extra_for_terrain_str(pextra, pterr,
1326 act));
1327 }
1328 } extra_type_by_cause_iterate_end;
1329}
1330
1331/**********************************************************************/
1334 static void help_update_terrain(const struct help_item *pitem,
1335 char *title)
1336{
1337 char buf[8192];
1338 struct terrain *pterrain = terrain_by_translated_name(title);
1339
1340 if (pterrain != NULL) {
1341 struct universal for_terr = { .kind = VUT_TERRAIN, .value = { .terrain = pterrain }};
1342
1343 set_help_tile_from_terrain(pterrain);
1344
1345 {
1346 /* 25 => "1.25"; 50 => "1.5"; 100 => "2.0" */
1347 int defbonus = pterrain->defense_bonus + 100;
1348 int frac = defbonus % 100;
1349
1350 if ((frac % 10) == 0) {
1351 frac /= 10;
1352 }
1353 sprintf(buf, "%d/%d.%d",
1354 pterrain->movement_cost, defbonus / 100, frac);
1355 }
1356 gtk_label_set_text(GTK_LABEL(help_tlabel[0][1]), buf);
1357
1358 sprintf(buf, "%d/%d/%d",
1359 pterrain->output[O_FOOD],
1360 pterrain->output[O_SHIELD],
1361 pterrain->output[O_TRADE]);
1362 gtk_label_set_text(GTK_LABEL(help_tlabel[0][4]), buf);
1363
1364 buf[0] = '\0';
1365 if (*(pterrain->resources)) {
1366 struct extra_type **r;
1367
1368 /* TODO: include resource frequency information */
1369 for (r = pterrain->resources; *r; r++) {
1370 /* TRANS: " Whales (2/1/2)," */
1371 sprintf (buf + strlen (buf), " %s (%d/%d/%d),",
1372 extra_name_translation(*r),
1373 pterrain->output[O_FOOD] + (*r)->data.resource->output[O_FOOD],
1374 pterrain->output[O_SHIELD] + (*r)->data.resource->output[O_SHIELD],
1375 pterrain->output[O_TRADE] + (*r)->data.resource->output[O_TRADE]);
1376 }
1377 buf[strlen (buf) - 1] = '.';
1378 } else {
1379 /* TRANS: "Resources: (none)" */
1380 sprintf (buf + strlen (buf), _("(none)"));
1381 }
1382 gtk_label_set_text(GTK_LABEL(help_tlabel[1][1]), buf);
1383
1384 help_box_clear();
1385
1386 if (pterrain->cultivate_result != T_NONE
1387 && action_id_univs_not_blocking(ACTION_CULTIVATE,
1388 NULL, &for_terr)) {
1389 fc_snprintf(buf, sizeof(buf),
1390 PL_("%d turn", "%d turns", pterrain->cultivate_time),
1391 pterrain->cultivate_time);
1392 add_act_help_for_terrain(_("Cultivate Rslt/Time"),
1393 terrain_name_translation(pterrain->cultivate_result),
1394 HELP_TERRAIN, buf);
1395 }
1396
1397 if (pterrain->plant_result != T_NONE
1398 && action_id_univs_not_blocking(ACTION_PLANT, NULL, &for_terr)) {
1399 fc_snprintf(buf, sizeof(buf),
1400 PL_("%d turn", "%d turns", pterrain->plant_time),
1401 pterrain->plant_time);
1402 add_act_help_for_terrain(_("Plant Rslt/Time"),
1403 terrain_name_translation(pterrain->plant_result),
1404 HELP_TERRAIN, buf);
1405 }
1406
1407 if (pterrain->transform_result != T_NONE
1408 && action_id_univs_not_blocking(ACTION_TRANSFORM_TERRAIN,
1409 NULL, &for_terr)) {
1410 fc_snprintf(buf, sizeof(buf),
1411 PL_("%d turn", "%d turns", pterrain->transform_time),
1412 pterrain->transform_time);
1413 add_act_help_for_terrain(_("Trans. Rslt/Time"),
1414 terrain_name_translation(pterrain->transform_result),
1415 HELP_TERRAIN, buf);
1416 }
1417
1418 if (action_id_univs_not_blocking(ACTION_IRRIGATE, NULL, &for_terr)) {
1419 help_extras_of_act_for_terrain(pterrain, ACTIVITY_IRRIGATE,
1420 _("Build as irrigation"));
1421 }
1422 if (action_id_univs_not_blocking(ACTION_MINE, NULL, &for_terr)) {
1423 help_extras_of_act_for_terrain(pterrain, ACTIVITY_MINE,
1424 _("Build as mine"));
1425 }
1426 if (action_id_univs_not_blocking(ACTION_ROAD, NULL, &for_terr)) {
1427 help_extras_of_act_for_terrain(pterrain, ACTIVITY_GEN_ROAD,
1428 _("Build as road"));
1429 }
1430 if (action_id_univs_not_blocking(ACTION_BASE, NULL, &for_terr)) {
1431 help_extras_of_act_for_terrain(pterrain, ACTIVITY_BASE,
1432 _("Build as base"));
1433 }
1434 gtk_widget_set_visible(help_vbox, TRUE);
1435 }
1436
1437 helptext_terrain(buf, sizeof(buf), client.conn.playing,
1438 pitem->text, pterrain);
1439
1440 gtk_text_buffer_set_text(help_text, buf, -1);
1441 gtk_widget_set_visible(help_text_sw, TRUE);
1442
1443 gtk_widget_set_visible(help_ttable, TRUE);
1444}
1445
1446/**********************************************************************/
1449 static void help_update_extra(const struct help_item *pitem, char *title)
1450{
1451 char buf[8192];
1452 struct extra_type *pextra = extra_type_by_translated_name(title);
1453
1454 buf[0] = '\0';
1455 if (pextra == NULL) {
1456 strcat(buf, pitem->text);
1457 } else {
1458 struct road_type *proad = extra_road_get(pextra);
1459 bool is_resource = is_extra_caused_by(pextra, EC_RESOURCE);
1460
1461 set_help_tile_from_extra(pextra);
1462
1463 /* Cost to build */
1464 if (pextra->buildable) {
1465 if (pextra->build_time != 0) {
1466 /* TRANS: "MP" = movement points */
1467 sprintf(buf, _("%d MP"), pextra->build_time);
1468 } else {
1469 /* TRANS: Build time depends on terrain. */
1470 sprintf(buf, _("Terrain specific"));
1471 }
1472 } else {
1473 sprintf(buf, "-");
1474 }
1475 gtk_label_set_text(GTK_LABEL(help_elabel[1]), buf);
1476 /* Conflicting extras */
1477 buf[0] = '\0';
1478 if (is_resource) {
1479 /* TRANS: (Resource extra) Conflicts with: */
1480 strcat(buf, _("Other Resources"));
1481 }
1482 extra_type_iterate(pextra2) {
1483 if (!can_extras_coexist(pextra, pextra2)
1484 && (!is_resource || !is_extra_caused_by(pextra2, EC_RESOURCE))) {
1485 if (buf[0] != '\0') {
1486 strcat(buf, "/");
1487 }
1488 strcat(buf, extra_name_translation(pextra2));
1489 }
1490 } extra_type_iterate_end;
1491 /* TRANS: "Conflicts with: (none)" (extras) */
1492 gtk_label_set_text(GTK_LABEL(help_elabel[3]), buf[0] ? buf : _("(none)"));
1493
1494 /* Bonus */
1495 if (proad != nullptr) {
1496 const char *bonus = nullptr;
1497
1498 output_type_iterate(o) {
1499 if (proad->tile_incr[o] > 0) {
1500 /* TRANS: Road bonus depends on terrain. */
1501 bonus = _("Terrain specific");
1502 break;
1503 }
1504 } output_type_iterate_end;
1505 if (bonus == nullptr) {
1506 bonus = helptext_road_bonus_str(nullptr, proad);
1507
1508 if (bonus == nullptr) {
1509 /* TRANS: No output bonus from a road */
1510 bonus = Q_("?bonus:None");
1511 }
1512 }
1513 gtk_label_set_text(GTK_LABEL(help_elabel[5]), bonus);
1514 } else {
1515 gtk_label_set_text(GTK_LABEL(help_elabel[5]), Q_("?bonus:None"));
1516 }
1517
1518 helptext_extra(buf, sizeof(buf), client.conn.playing, pitem->text, pextra);
1519 }
1520 gtk_widget_set_visible(help_etable, TRUE);
1521
1522 gtk_text_buffer_set_text(help_text, buf, -1);
1523 gtk_widget_set_visible(help_text_sw, TRUE);
1524}
1525
1526/**********************************************************************/
1529 static void help_update_goods(const struct help_item *pitem,
1530 char *title)
1531{
1532 char buf[8192];
1533 struct goods_type *pgood = goods_by_translated_name(title);
1534
1535 if (pgood == nullptr) {
1536 strcat(buf, pitem->text);
1537 } else {
1538 helptext_goods(buf, sizeof(buf), client.conn.playing, pitem->text,
1539 pgood);
1540 }
1541
1542 gtk_text_buffer_set_text(help_text, buf, -1);
1543 gtk_widget_set_visible(help_text_sw, TRUE);
1544}
1545
1546/**********************************************************************/
1549 static void help_update_specialist(const struct help_item *pitem,
1550 char *title)
1551{
1552 char buf[8192];
1553 struct specialist *pspec = specialist_by_translated_name(title);
1554
1555 if (pspec == nullptr) {
1556 strcat(buf, pitem->text);
1557 } else {
1558 helptext_specialist(buf, sizeof(buf), client.conn.playing, pitem->text,
1559 pspec);
1560 }
1561
1562 gtk_text_buffer_set_text(help_text, buf, -1);
1563 gtk_widget_set_visible(help_text_sw, TRUE);
1564}
1565
1566/**********************************************************************/
1569 static void help_update_government(const struct help_item *pitem,
1570 char *title)
1571{
1572 char buf[8192];
1573 struct government *gov = government_by_translated_name(title);
1574
1575 if (gov == nullptr) {
1576 strcat(buf, pitem->text);
1577 } else {
1578 helptext_government(buf, sizeof(buf), client.conn.playing,
1579 pitem->text, gov);
1580 }
1581
1582 gtk_text_buffer_set_text(help_text, buf, -1);
1583 gtk_widget_set_visible(help_text_sw, TRUE);
1584}
1585
1586/**********************************************************************/
1589 static void help_update_nation(const struct help_item *pitem, char *title,
1590 struct nation_type *pnation)
1591{
1592 char buf[4096];
1593
1594 if (pnation == nullptr) {
1595 strcat(buf, pitem->text);
1596 } else {
1597 helptext_nation(buf, sizeof(buf), pnation, pitem->text);
1598
1599 set_help_tile_from_sprite(get_nation_flag_sprite(tileset, pnation));
1600 }
1601
1602 gtk_text_buffer_set_text(help_text, buf, -1);
1603 gtk_widget_set_visible(help_text_sw, TRUE);
1604}
1605
1606/**********************************************************************/
1609 static void help_update_dialog(const struct help_item *pitem)
1610{
1611 char *top;
1612
1613 /* Figure out what kind of item is required for pitem ingo */
1614
1615 for (top = pitem->topic; *top == ' '; top++) {
1616 /* Nothing */
1617 }
1618
1619 help_box_hide();
1620 gtk_text_buffer_set_text(help_text, "", -1);
1621
1622 switch (pitem->type) {
1623 case HELP_IMPROVEMENT:
1624 help_update_improvement(pitem, top);
1625 break;
1626 case HELP_WONDER:
1627 help_update_wonder(pitem, top);
1628 break;
1629 case HELP_UNIT:
1630 help_update_unit_type(pitem, top);
1631 break;
1632 case HELP_TECH:
1633 help_update_tech(pitem, top);
1634 break;
1635 case HELP_TERRAIN:
1636 help_update_terrain(pitem, top);
1637 break;
1638 case HELP_EXTRA:
1639 help_update_extra(pitem, top);
1640 break;
1641 case HELP_GOODS:
1642 help_update_goods(pitem, top);
1643 break;
1644 case HELP_SPECIALIST:
1645 help_update_specialist(pitem, top);
1646 break;
1647 case HELP_GOVERNMENT:
1648 help_update_government(pitem, top);
1649 break;
1650 case HELP_NATIONS:
1651 help_update_nation(pitem, top, nation_by_translated_plural(top));
1652 break;
1653 case HELP_TEXT:
1654 default:
1655 /* It was a pure text item */
1656 gtk_text_buffer_set_text(help_text, pitem->text, -1);
1657 gtk_widget_set_visible(help_text_sw, TRUE);
1658 break;
1659 }
1660 set_title_topic(pitem->topic);
1661
1662 gtk_widget_set_visible(help_box, TRUE);
1663}
1664
1665/**********************************************************************/
1668 static void help_item_zoom(GtkTreePath *path)
1669{
1670 GtkTreeModel *model;
1671 GtkTreeIter it, child, item;
1672 GtkTreeSelection *selection;
1673
1674 model = gtk_tree_view_get_model(GTK_TREE_VIEW(help_view));
1675 gtk_tree_model_get_iter(model, &item, path);
1676
1677 for (child = item; gtk_tree_model_iter_parent(model, &it, &child); child = it) {
1678 GtkTreePath *it_path;
1679
1680 it_path = gtk_tree_model_get_path(model, &it);
1681 gtk_tree_view_expand_row(GTK_TREE_VIEW(help_view), it_path, TRUE);
1682 gtk_tree_path_free(it_path);
1683 }
1684
1685 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(help_view));
1686 gtk_tree_selection_select_iter(selection, &item);
1687 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(help_view), path, NULL,
1688 TRUE, 0.0, 0.0);
1689}
1690
1691/**********************************************************************/
1694 static GtkTreePath *help_item_path(const struct help_item *pitem)
1695{
1696 GtkTreePath *path;
1697 bool next;
1698
1699 path = gtk_tree_path_new_first();
1700 next = FALSE;
1701 help_items_iterate(pitem2) {
1702 const char *s;
1703 int depth;
1704
1705 for (s = pitem2->topic; *s == ' '; s++) {
1706 /* Nothing */
1707 }
1708 depth = s - pitem2->topic + 1;
1709
1710 while (depth < gtk_tree_path_get_depth(path)) {
1711 gtk_tree_path_up(path);
1712 gtk_tree_path_next(path);
1713 next = FALSE;
1714 }
1715 while (depth > gtk_tree_path_get_depth(path)) {
1716 gtk_tree_path_down(path);
1717 next = FALSE;
1718 }
1719
1720 if (next) {
1721 gtk_tree_path_next(path);
1722 }
1723
1724 if (pitem == pitem2) {
1725 break;
1726 }
1727
1728 next = TRUE;
1729 } help_items_iterate_end;
1730
1731 return path;
1732}
1733
1734/**********************************************************************/
1737 static void select_help_item_string(const char *item, enum help_page_type htype)
1738{
1739 const struct help_item *pitem;
1740 int idx;
1741 GtkTreePath *path;
1742 GtkTreeViewColumn *col;
1743
1744 if (!(pitem = get_help_item_spec(item, htype, &idx))) {
1745 return;
1746 }
1747
1748 path = help_item_path(pitem);
1749 help_item_zoom(path);
1750
1751 col = gtk_tree_view_get_column(GTK_TREE_VIEW(help_view), 0);
1752 gtk_tree_view_set_cursor(GTK_TREE_VIEW(help_view), path, col, FALSE);
1753 gtk_tree_path_free(path);
1754}
1755
1756/**********************************************************************/
1759 static void help_command_update(void)
1760{
1761 GtkDialog *dialog = GTK_DIALOG(help_dialog_shell);
1762
1763 if (help_history_pos < 0) {
1764 gtk_dialog_set_response_sensitive(dialog, 1, FALSE);
1765 gtk_dialog_set_response_sensitive(dialog, 2, FALSE);
1766 } else {
1767 gtk_dialog_set_response_sensitive(dialog, 1, TRUE);
1768 gtk_dialog_set_response_sensitive(dialog, 2, TRUE);
1769
1770 if (help_history_pos == 0) {
1771 gtk_dialog_set_response_sensitive(dialog, 1, FALSE);
1772 }
1773 if (help_history_pos >= help_history->len - 1) {
1774 gtk_dialog_set_response_sensitive(dialog, 2, FALSE);
1775 }
1776 }
1777}
1778
1779/**********************************************************************/
1782 static void help_command_callback(GtkWidget *w, gint response_id)
1783{
1784 GtkTreePath *path;
1785 const struct help_item *pitem;
1786
1787 if (response_id == 1) {
1788 if (help_history_pos > 0) {
1789 help_history_pos--;
1790
1791 pitem = g_ptr_array_index(help_history, help_history_pos);
1792 path = help_item_path(pitem);
1793 help_item_zoom(path);
1794 help_update_dialog(pitem);
1795 help_command_update();
1796 }
1797 } else if (response_id == 2) {
1798 if (help_history_pos < help_history-> len - 1) {
1799 help_history_pos++;
1800
1801 pitem = g_ptr_array_index(help_history, help_history_pos);
1802 path = help_item_path(pitem);
1803 help_item_zoom(path);
1804 help_update_dialog(pitem);
1805 help_command_update();
1806 }
1807 } else {
1808 gtk_window_destroy(GTK_WINDOW(help_dialog_shell));
1809 }
1810}
action_id_univs_not_blocking
#define action_id_univs_not_blocking(act_id, act_uni, tgt_uni)
Definition actions.h:685
str
#define str
Definition astring.c:76
city.h
output_type_iterate
#define output_type_iterate(output)
Definition city.h:833
output_type_iterate_end
#define output_type_iterate_end
Definition city.h:839
client
struct civclient client
Definition client_main.c:150
client_main.h
client_player
#define client_player()
Definition client_main.h:106
climisc.h
get_color
struct color * get_color(const struct tileset *t, enum color_std stdcolor)
Definition colors_common.c:100
incite_cost
char * incite_cost
Definition comments.c:74
extra_type_by_translated_name
struct extra_type * extra_type_by_translated_name(const char *name)
Definition extras.c:235
activity_to_extra_cause
enum extra_cause activity_to_extra_cause(enum unit_activity act)
Definition extras.c:1076
can_extras_coexist
bool can_extras_coexist(const struct extra_type *pextra1, const struct extra_type *pextra2)
Definition extras.c:1003
extra_name_translation
const char * extra_name_translation(const struct extra_type *pextra)
Definition extras.c:194
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:315
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:321
is_extra_caused_by
#define is_extra_caused_by(e, c)
Definition extras.h:203
extra_road_get
#define extra_road_get(_e_)
Definition extras.h:191
extra_type_by_cause_iterate_end
#define extra_type_by_cause_iterate_end
Definition extras.h:339
extra_type_by_cause_iterate
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
Tech_type_id
int Tech_type_id
Definition fc_types.h:381
O_SHIELD
@ O_SHIELD
Definition fc_types.h:101
O_FOOD
@ O_FOOD
Definition fc_types.h:101
O_TRADE
@ O_TRADE
Definition fc_types.h:101
skip_intl_qualifier_prefix
const char * skip_intl_qualifier_prefix(const char *str)
Definition fcintl.c:48
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
N_
#define N_(String)
Definition fcintl.h:69
game.h
government_name_translation
const char * government_name_translation(const struct government *pgovern)
Definition government.c:143
government_by_translated_name
struct government * government_by_translated_name(const char *name)
Definition government.c:40
government.h
governments_iterate
#define governments_iterate(NAME_pgov)
Definition government.h:120
governments_iterate_end
#define governments_iterate_end
Definition government.h:123
FC_STATIC_CANVAS_INIT
#define FC_STATIC_CANVAS_INIT
Definition canvas.h:28
toplevel
GtkWidget * toplevel
Definition gui_main.c:125
setup_dialog
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:287
help_tree_sw
static GtkWidget * help_tree_sw
Definition helpdlg.c:83
set_title_topic
static void set_title_topic(char *topic)
Definition helpdlg.c:173
activated_topic
static void activated_topic(GtkTreeView *view, gpointer data)
Definition helpdlg.c:469
help_tree
static GtkWidget * help_tree
Definition helpdlg.c:80
help_tree_expand
static GtkWidget * help_tree_expand
Definition helpdlg.c:84
help_ulabel
static GtkWidget * help_ulabel[5][5]
Definition helpdlg.c:89
help_update_specialist
static void help_update_specialist(const struct help_item *pitem, char *title)
Definition helpdlg.c:1503
help_hyperlink_callback
static void help_hyperlink_callback(GtkWidget *w)
Definition helpdlg.c:345
help_elabel
static GtkWidget * help_elabel[6]
Definition helpdlg.c:91
help_etable
static GtkWidget * help_etable
Definition helpdlg.c:79
help_destroy_callback
static void help_destroy_callback(GtkWidget *w, gpointer data)
Definition helpdlg.c:460
set_help_tile_from_extra
static void set_help_tile_from_extra(const struct extra_type *pextra)
Definition helpdlg.c:848
help_frame
static GtkWidget * help_frame
Definition helpdlg.c:69
help_tech_tree_activated_callback
static void help_tech_tree_activated_callback(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
Definition helpdlg.c:312
help_update_tech
static void help_update_tech(const struct help_item *pitem, char *title)
Definition helpdlg.c:1074
help_item_zoom
static void help_item_zoom(GtkTreePath *path)
Definition helpdlg.c:1621
help_slink_new_page
static GtkWidget * help_slink_new_page(const gchar *txt, enum help_page_type page)
Definition helpdlg.c:427
help_tlabel
static GtkWidget * help_tlabel[2][5]
Definition helpdlg.c:90
help_item_path
static GtkTreePath * help_item_path(const struct help_item *pitem)
Definition helpdlg.c:1647
help_tree_collapse
static GtkWidget * help_tree_collapse
Definition helpdlg.c:85
help_update_nation
static void help_update_nation(const struct help_item *pitem, char *title, struct nation_type *pnation)
Definition helpdlg.c:1542
create_help_dialog
static void create_help_dialog(void)
Definition helpdlg.c:509
help_text
static GtkTextBuffer * help_text
Definition helpdlg.c:70
help_update_wonder
static void help_update_wonder(const struct help_item *pitem, char *title)
Definition helpdlg.c:926
help_hyperlink_new_page
static GtkWidget * help_hyperlink_new_page(GtkWidget *label, enum help_page_type page)
Definition helpdlg.c:402
help_dialog_shell
static GtkWidget * help_dialog_shell
Definition helpdlg.c:64
help_text_sw
static GtkWidget * help_text_sw
Definition helpdlg.c:71
help_history
static GPtrArray * help_history
Definition helpdlg.c:95
help_elabel_name
static const char * help_elabel_name[6]
Definition helpdlg.c:132
create_tech_tree
static void create_tech_tree(int tech, int levels, GtkTreeIter *parent)
Definition helpdlg.c:226
help_update_extra
static void help_update_extra(const struct help_item *pitem, char *title)
Definition helpdlg.c:1404
help_ilabel
static GtkWidget * help_ilabel[6]
Definition helpdlg.c:87
set_help_tile_from_sprite
static void set_help_tile_from_sprite(struct sprite *spr)
Definition helpdlg.c:804
help_wlabel_name
static const char * help_wlabel_name[6]
Definition helpdlg.c:111
help_ulabel_name
static const char * help_ulabel_name[5][5]
Definition helpdlg.c:117
help_tech_tree_collapse_callback
static void help_tech_tree_collapse_callback(GtkWidget *w, gpointer data)
Definition helpdlg.c:337
set_help_tile_from_terrain
static void set_help_tile_from_terrain(struct terrain *pterr)
Definition helpdlg.c:817
help_view
static GtkWidget * help_view
Definition helpdlg.c:67
help_update_goods
static void help_update_goods(const struct help_item *pitem, char *title)
Definition helpdlg.c:1483
help_system_init
void help_system_init(void)
Definition helpdlg.c:157
help_box_hide
static void help_box_hide(void)
Definition helpdlg.c:436
help_update_unit_type
static void help_update_unit_type(const struct help_item *pitem, char *title)
Definition helpdlg.c:990
popdown_help_dialog
void popdown_help_dialog(void)
Definition helpdlg.c:186
help_update_terrain
static void help_update_terrain(const struct help_item *pitem, char *title)
Definition helpdlg.c:1289
help_update_dialog
static void help_update_dialog(const struct help_item *pitem)
Definition helpdlg.c:1562
fc_chomp
static char * fc_chomp(char *str, size_t len)
Definition helpdlg.c:1054
popup_help_dialog_string
void popup_help_dialog_string(const char *item)
Definition helpdlg.c:212
help_history_pos
static int help_history_pos
Definition helpdlg.c:96
help_wndr_req
static struct help_page_selection help_wndr_req
Definition helpdlg.c:113
help_wlabel
static GtkWidget * help_wlabel[6]
Definition helpdlg.c:88
help_box
static GtkWidget * help_box
Definition helpdlg.c:74
help_extras_of_act_for_terrain
static void help_extras_of_act_for_terrain(struct terrain *pterr, enum unit_activity act, char *label)
Definition helpdlg.c:1269
popup_help_dialog_typed
void popup_help_dialog_typed(const char *item, enum help_page_type htype)
Definition helpdlg.c:196
REQ_LABEL_NEVER
#define REQ_LABEL_NEVER
Definition helpdlg.c:144
help_command_update
static void help_command_update(void)
Definition helpdlg.c:1711
page_selections
static struct help_page_selection page_selections[HELP_LAST]
Definition helpdlg.c:115
TECH_TREE_DEPTH
#define TECH_TREE_DEPTH
Definition helpdlg.c:59
help_tlabel_name
static const char * help_tlabel_name[2][5]
Definition helpdlg.c:126
help_impr_req
static struct help_page_selection help_impr_req
Definition helpdlg.c:109
REQ_LABEL_NONE
#define REQ_LABEL_NONE
Definition helpdlg.c:143
help_wtable
static GtkWidget * help_wtable
Definition helpdlg.c:76
help_slink_new
static GtkWidget * help_slink_new(const gchar *txt, struct help_page_selection *select)
Definition helpdlg.c:411
help_vbox
static GtkWidget * help_vbox
Definition helpdlg.c:72
help_tech_tree_expand_callback
static void help_tech_tree_expand_callback(GtkWidget *w, gpointer data)
Definition helpdlg.c:329
help_tile
static GtkWidget * help_tile
Definition helpdlg.c:73
help_hyperlink_new
static GtkWidget * help_hyperlink_new(GtkWidget *label, struct help_page_selection *select)
Definition helpdlg.c:380
help_update_government
static void help_update_government(const struct help_item *pitem, char *title)
Definition helpdlg.c:1523
help_ttable
static GtkWidget * help_ttable
Definition helpdlg.c:78
help_update_improvement
static void help_update_improvement(const struct help_item *pitem, char *title)
Definition helpdlg.c:876
help_ilabel_name
static const char * help_ilabel_name[6]
Definition helpdlg.c:107
help_tree_buttons_hbox
static GtkWidget * help_tree_buttons_hbox
Definition helpdlg.c:86
help_view_sw
static GtkWidget * help_view_sw
Definition helpdlg.c:65
select_help_item_string
static void select_help_item_string(const char *item, enum help_page_type htype)
Definition helpdlg.c:1689
help_advances
static bool help_advances[A_LAST]
Definition helpdlg.c:93
help_utable
static GtkWidget * help_utable
Definition helpdlg.c:77
help_itable
static GtkWidget * help_itable
Definition helpdlg.c:75
tstore
static GtkTreeStore * tstore
Definition helpdlg.c:81
add_act_help_for_terrain
static void add_act_help_for_terrain(const char *act_label, const char *result_link_label, enum help_page_type result_link_type, const char *descr_label)
Definition helpdlg.c:1246
help_command_callback
static void help_command_callback(GtkWidget *w, gint response_id)
Definition helpdlg.c:1734
title
const char * title
Definition repodlgs.c:1314
type
GType type
Definition repodlgs.c:1313
help_box_add
static void help_box_add(GtkWidget *wdg)
Definition helpdlg.c:455
help_box_clear
static void help_box_clear(void)
Definition helpdlg.c:463
picture_set_from_surface
void picture_set_from_surface(GtkPicture *pic, cairo_surface_t *surf)
Definition sprite.c:544
gui_stuff.h
colors.h
graphics.h
gui_main.h
helpdlg.h
helptext_government
void helptext_government(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, struct government *gov)
Definition helpdata.c:4304
helptext_advance
void helptext_advance(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, int i)
Definition helpdata.c:3263
help_type_by_requirement
enum help_page_type help_type_by_requirement(const struct requirement *req)
Definition helpdata.c:5169
helptext_extra
void helptext_extra(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, struct extra_type *pextra)
Definition helpdata.c:3758
helptext_goods
void helptext_goods(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, struct goods_type *pgood)
Definition helpdata.c:4223
helptext_road_bonus_str
const char * helptext_road_bonus_str(const struct terrain *pterrain, const struct road_type *proad)
Definition helpdata.c:3594
helptext_unit_upkeep_str
char * helptext_unit_upkeep_str(const struct unit_type *utype)
Definition helpdata.c:4966
helptext_extra_for_terrain_str
const char * helptext_extra_for_terrain_str(struct extra_type *pextra, struct terrain *pterrain, enum unit_activity act)
Definition helpdata.c:3724
helptext_specialist
void helptext_specialist(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, struct specialist *pspec)
Definition helpdata.c:4269
get_help_item_spec
const struct help_item * get_help_item_spec(const char *name, enum help_page_type htype, int *pos)
Definition helpdata.c:1288
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_terrain
void helptext_terrain(char *buf, size_t bufsz, struct player *pplayer, const char *user_text, struct terrain *pterrain)
Definition helpdata.c:3484
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
helptext_nation
void helptext_nation(char *buf, size_t bufsz, struct nation_type *pnation, const char *user_text)
Definition helpdata.c:5003
helpdata.h
help_items_iterate
#define help_items_iterate(pitem)
Definition helpdata.h:70
help_items_iterate_end
#define help_items_iterate_end
Definition helpdata.h:74
HELP_ABOUT_ITEM
#define HELP_ABOUT_ITEM
help_page_type
help_page_type
Definition helpdlg_g.h:20
HELP_ANY
@ HELP_ANY
Definition helpdlg_g.h:20
HELP_TERRAIN
@ HELP_TERRAIN
Definition helpdlg_g.h:21
HELP_EXTRA
@ HELP_EXTRA
Definition helpdlg_g.h:21
HELP_NATIONS
@ HELP_NATIONS
Definition helpdlg_g.h:24
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_SPECIALIST
@ HELP_SPECIALIST
Definition helpdlg_g.h:22
HELP_GOVERNMENT
@ HELP_GOVERNMENT
Definition helpdlg_g.h:22
HELP_GOODS
@ HELP_GOODS
Definition helpdlg_g.h:22
HELP_WONDER
@ HELP_WONDER
Definition helpdlg_g.h:21
HELP_TECH
@ HELP_TECH
Definition helpdlg_g.h:21
HELP_TEXT
@ HELP_TEXT
Definition helpdlg_g.h:20
valid_improvement
const struct impr_type * valid_improvement(const struct impr_type *pimprove)
Definition improvement.c:211
impr_base_build_shield_cost
int impr_base_build_shield_cost(const struct impr_type *pimprove)
Definition improvement.c:261
is_great_wonder
bool is_great_wonder(const struct impr_type *pimprove)
Definition improvement.c:772
improvement_by_translated_name
struct impr_type * improvement_by_translated_name(const char *name)
Definition improvement.c:352
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
map.h
put_drawn_sprites
void put_drawn_sprites(struct canvas *pcanvas, float zoom, int canvas_x, int canvas_y, int count, struct drawn_sprite *pdrawn, bool fog)
Definition mapview_common.c:1328
mem.h
move_points_text
const char * move_points_text(int mp, bool reduce)
Definition movement.c:1016
movement.h
nation_by_translated_plural
struct nation_type * nation_by_translated_plural(const char *name)
Definition nation.c:106
nation.h
options.h
len
int len
Definition packhand.c:127
universal_name_translation
const char * universal_name_translation(const struct universal *psource, char *buf, size_t bufsz)
Definition requirements.c:6962
requirement_fulfilled_by_terrain
#define requirement_fulfilled_by_terrain(_ter_, _rqs_)
Definition requirements.h:419
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
research_goal_unknown_techs
int research_goal_unknown_techs(const struct research *presearch, Tech_type_id goal)
Definition research.c:750
research_advance_name_translation
const char * research_advance_name_translation(const struct research *presearch, Tech_type_id tech)
Definition research.c:273
research_get
struct research * research_get(const struct player *pplayer)
Definition research.c:128
research_invention_state
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:619
research.h
shared.h
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
specialist_by_translated_name
struct specialist * specialist_by_translated_name(const char *name)
Definition specialist.c:130
specialist.h
advance
Definition tech.h:124
canvas
Definition canvas.h:22
canvas::surface
cairo_surface_t * surface
Definition canvas.h:23
civclient::conn
struct connection conn
Definition client_main.h:96
color
Definition colors.h:21
connection::playing
struct player * playing
Definition connection.h:151
drawn_sprite
Definition tilespec.h:112
extra_type
Definition extras.h:88
extra_type::buildable
bool buildable
Definition extras.h:116
extra_type::build_time
int build_time
Definition extras.h:118
goods_type
Definition traderoutes.h:187
government
Definition government.h:52
help_item
Definition helpdata.h:25
help_item::text
char * text
Definition helpdata.h:26
help_page_selection
Definition helpdlg.c:99
help_page_selection::u
union help_page_selection::@155 u
help_page_selection::page
enum help_page_type page
Definition helpdlg.c:102
help_page_selection::req
const struct requirement * req
Definition helpdlg.c:103
help_page_selection::HPAGE_SRC_REQ
@ HPAGE_SRC_REQ
Definition helpdlg.c:100
help_page_selection::HPAGE_SRC_ENUM
@ HPAGE_SRC_ENUM
Definition helpdlg.c:100
help_page_selection::type
enum help_page_selection::@154 type
impr_type
Definition improvement.h:50
item
Definition climisc.h:80
nation_type
Definition nation.h:98
requirement
Definition requirements.h:81
research
Definition research.h:39
road_type
Definition road.h:71
specialist
Definition specialist.h:29
sprite
Definition sprite.h:22
terrain
Definition terrain.h:75
terrain::cultivate_result
struct terrain * cultivate_result
Definition terrain.h:108
terrain::resources
struct extra_type ** resources
Definition terrain.h:97
terrain::plant_time
int plant_time
Definition terrain.h:112
terrain::plant_result
struct terrain * plant_result
Definition terrain.h:111
terrain::defense_bonus
int defense_bonus
Definition terrain.h:93
terrain::cultivate_time
int cultivate_time
Definition terrain.h:109
terrain::movement_cost
int movement_cost
Definition terrain.h:92
terrain::output
int output[O_LAST]
Definition terrain.h:95
terrain::transform_time
int transform_time
Definition terrain.h:124
terrain::transform_result
struct terrain * transform_result
Definition terrain.h:122
tileset
Definition tilespec.c:481
unit_type
Definition unittype.h:507
unit_type::defense_strength
int defense_strength
Definition unittype.h:523
unit_type::firepower
int firepower
Definition unittype.h:532
unit_type::obsoleted_by
const struct unit_type * obsoleted_by
Definition unittype.h:536
unit_type::vision_radius_sq
int vision_radius_sq
Definition unittype.h:529
unit_type::move_rate
int move_rate
Definition unittype.h:524
unit_type::hp
int hp
Definition unittype.h:531
unit_type::attack_strength
int attack_strength
Definition unittype.h:522
universal
Definition fc_types.h:908
universal::kind
enum universals_n kind
Definition fc_types.h:910
view
Definition mapview_common.h:36
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
support.h
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_by_translated_name
struct advance * advance_by_translated_name(const char *name)
Definition tech.c:185
advance_requires
struct advance * advance_requires(const struct advance *padvance, enum tech_req require)
Definition tech.c:136
advance_name_translation
const char * advance_name_translation(const struct advance *padvance)
Definition tech.c:300
advance_required
Tech_type_id advance_required(const Tech_type_id tech, enum tech_req require)
Definition tech.c:121
is_regular_advance
bool is_regular_advance(struct advance *padvance)
Definition tech.c:290
advance_number
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
tech.h
advance_iterate_all_end
#define advance_iterate_all_end
Definition tech.h:280
AR_TWO
@ AR_TWO
Definition tech.h:112
AR_ONE
@ AR_ONE
Definition tech.h:111
advance_iterate_all
#define advance_iterate_all(_p)
Definition tech.h:279
A_NONE
#define A_NONE
Definition tech.h:43
A_LAST
#define A_LAST
Definition tech.h:45
terrain_by_translated_name
struct terrain * terrain_by_translated_name(const char *name)
Definition terrain.c:202
terrain_name_translation
const char * terrain_name_translation(const struct terrain *pterrain)
Definition terrain.c:238
T_NONE
#define T_NONE
Definition terrain.h:61
get_building_sprite
struct sprite * get_building_sprite(const struct tileset *t, const struct impr_type *pimprove)
Definition tilespec.c:6801
fill_basic_extra_sprite_array
int fill_basic_extra_sprite_array(const struct tileset *t, struct drawn_sprite *sprs, const struct extra_type *pextra)
Definition tilespec.c:7222
fill_basic_terrain_layer_sprite_array
int fill_basic_terrain_layer_sprite_array(struct tileset *t, struct drawn_sprite *sprs, int layer, struct terrain *pterrain)
Definition tilespec.c:7189
tileset_tile_height
int tileset_tile_height(const struct tileset *t)
Definition tilespec.c:765
get_unittype_sprite
struct sprite * get_unittype_sprite(const struct tileset *t, const struct unit_type *punittype, enum unit_activity activity, enum direction8 facing)
Definition tilespec.c:6823
get_nation_flag_sprite
struct sprite * get_nation_flag_sprite(const struct tileset *t, const struct nation_type *pnation)
Definition tilespec.c:6774
tileset_tile_width
int tileset_tile_width(const struct tileset *t)
Definition tilespec.c:753
get_tech_sprite
struct sprite * get_tech_sprite(const struct tileset *t, Tech_type_id tech)
Definition tilespec.c:6792
tilespec.h
goods_by_translated_name
struct goods_type * goods_by_translated_name(const char *name)
Definition traderoutes.c:665
unit.h
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
unit_type_by_translated_name
struct unit_type * unit_type_by_translated_name(const char *name)
Definition unittype.c:1752
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
freeciv_name_version
const char * freeciv_name_version(void)
Definition version.c:35
version.h