Freeciv-3.3
Loading...
Searching...
No Matches
cma_fe.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2001 - R. Falke, M. Kaufman
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 <gdk/gdkkeysyms.h>
19
20/* utility */
21#include "fcintl.h"
22#include "log.h"
23#include "mem.h"
24#include "support.h"
25
26/* common */
27#include "events.h"
28#include "game.h"
29
30/* client */
31#include "chatline_g.h"
32#include "citydlg_g.h"
33#include "client_main.h"
34#include "cma_fec.h"
35#include "messagewin_g.h"
36#include "options.h"
37
38/* client/gui-gtk-3.22 */
39#include "cityrep.h"
40#include "dialogs.h"
41#include "gui_main.h"
42#include "gui_stuff.h"
43#include "helpdlg.h"
44#include "inputdlg.h"
45
46#include "cma_fe.h"
47
48#define BUFFER_SIZE 64
49
50#define SPECLIST_TAG dialog
51#define SPECLIST_TYPE struct cma_dialog
52#include "speclist.h"
53
54#define dialog_list_iterate(dialoglist, pdialog) \
55 TYPED_LIST_ITERATE(struct cma_dialog, dialoglist, pdialog)
56#define dialog_list_iterate_end LIST_ITERATE_END
57
58static struct dialog_list *dialog_list;
59
60static int allow_refreshes = 1;
61
62static struct cma_dialog *get_cma_dialog(struct city *pcity);
63
64static void update_cma_preset_list(struct cma_dialog *pdialog);
65
67 gpointer data);
68static void cma_del_preset_callback(GtkWidget *w, gpointer data);
69static void cma_preset_remove(struct cma_dialog *pdialog, int preset_index);
70static void cma_preset_remove_response(GtkWidget *w, gint response,
71 gpointer data);
72
73static void cma_add_preset_callback(GtkWidget *w, gpointer data);
74static void cma_preset_add_popup_callback(gpointer data, gint response,
75 const char *input);
76
77static void cma_active_callback(GtkWidget *w, gpointer data);
80
81static void hscale_changed(GtkWidget *get, gpointer data);
82static void set_hscales(const struct cm_parameter *const parameter,
83 struct cma_dialog *pdialog);
84
85/**********************************************************************/
88void cma_fe_init(void)
89{
91}
92
93/**********************************************************************/
100
101/**********************************************************************/
105{
106 struct cma_dialog *pdialog = get_cma_dialog(pcity);
107
108 if (pdialog == NULL) {
109 /* A city which is being investigated doesn't contain cma dialog */
110 return;
111 }
112 gtk_widget_destroy(pdialog->shell);
113}
114
115/**********************************************************************/
119{
120 struct cma_dialog *pdialog = (struct cma_dialog *) data;
121
123 free(pdialog);
124}
125
126/**********************************************************************/
130{
132 if (pdialog->pcity == pcity) {
133 return pdialog;
134 }
136
137 return NULL;
138}
139
140/**********************************************************************/
144 gpointer data)
145{
146 GtkTreePath *path;
148
150 ev->x, ev->y, &path, &column, NULL, NULL)) {
151 if (ev->type == GDK_BUTTON_PRESS) {
153 } else if (ev->type == GDK_2BUTTON_PRESS) {
154 struct cma_dialog *pdialog = (struct cma_dialog *) data;
155 struct cm_parameter param;
156
157 cmafec_get_fe_parameter(pdialog->pcity, &param);
158 cma_put_city_under_agent(pdialog->pcity, &param);
159 refresh_city_dialog(pdialog->pcity);
160 }
161 }
162 gtk_tree_path_free(path);
163
164 return FALSE;
165}
166
167/**********************************************************************/
174
175/**********************************************************************/
179 GtkTreeModel *model, GtkTreeIter *it, gpointer data)
180{
181 struct cma_dialog *pdialog = (struct cma_dialog *) data;
182 char *s1;
183 const char *s2;
184 int i1, i2;
185 struct cm_parameter param;
186 GtkTreePath *path;
187
188 gtk_tree_model_get(model, it, 0, &s1, -1);
189 if (s1 == NULL) {
190 return;
191 }
192 path = gtk_tree_model_get_path(model, it);
193 i1 = gtk_tree_path_get_indices(path)[0];
194 gtk_tree_path_free(path);
195
196 cmafec_get_fe_parameter(pdialog->pcity, &param);
197 s2 = cmafec_get_short_descr(&param);
199
200 if (!strcmp(s1, s2) && i1 == i2) {
202 "weight", PANGO_WEIGHT_BOLD, NULL);
203 } else {
205 "weight", PANGO_WEIGHT_NORMAL, NULL);
206 }
207
208 g_free(s1);
209}
210
211/**********************************************************************/
215{
216 struct cma_dialog *pdialog;
217 struct cm_parameter param;
218 GtkWidget *frame, *page, *hbox, *label, *table;
219 GtkWidget *vbox, *sw, *hscale, *button;
220 GtkListStore *store;
225
227 pdialog = fc_malloc(sizeof(struct cma_dialog));
228 pdialog->pcity = pcity;
229 pdialog->shell = gtk_grid_new();
234 g_signal_connect(pdialog->shell, "destroy",
236
237 page = gtk_grid_new();
239 gtk_container_add(GTK_CONTAINER(pdialog->shell), page);
240
241 vbox = gtk_grid_new();
245 gtk_container_add(GTK_CONTAINER(page), vbox);
246
252
254 pdialog->store = store;
255
259 g_object_unref(store);
261 pdialog->preset_list = view;
263
264 g_signal_connect(pdialog->preset_list, "button_press_event",
266
268 _("For information on\n"
269 "the citizen governor and governor presets,\n"
270 "including sample presets,\n"
271 "see README.governor."));
272
275 "text", 0, NULL);
278 pdialog, NULL);
279
281 "use-underline", TRUE,
282 "mnemonic-widget", view,
283 "label", _("Prese_ts:"),
284 "xalign", 0.0, "yalign", 0.5, NULL);
285 gtk_container_add(GTK_CONTAINER(vbox), label);
286
289
290 g_signal_connect(view, "row_activated",
292 g_signal_connect(view, "key-press-event",
294
298
299 button = icon_label_button_new("document-new", _("Ne_w"));
301 g_signal_connect(button, "clicked",
303 pdialog->add_preset_command = button;
304
305 pdialog->del_preset_command = icon_label_button_new("edit-delete",
306 _("_Delete"));
308 g_signal_connect(pdialog->del_preset_command, "clicked",
310
311 /* the right-hand side */
312
313 vbox = gtk_grid_new();
314 g_object_set(vbox, "margin", 2, NULL);
317 gtk_container_add(GTK_CONTAINER(page), vbox);
318
319 /* Result */
320 if (!tiny) {
321 frame = gtk_frame_new(_("Results"));
324 gtk_container_add(GTK_CONTAINER(vbox), frame);
325
326 pdialog->result_label =
327 gtk_label_new("food\n prod\n trade\n\n people\n grow\n prod\n name");
328 gtk_widget_set_name(pdialog->result_label, "city_label");
331 } else {
332 pdialog->result_label = NULL;
333 }
334
335 /* Minimal Surplus and Factor */
336
338 g_object_set(table, "margin", 2, NULL);
340
341 label = gtk_label_new(_("Minimal Surplus"));
344 gtk_grid_attach(GTK_GRID(table), label, 1, 0, 1, 1);
345 label = gtk_label_new(_("Factor"));
348 gtk_grid_attach(GTK_GRID(table), label, 2, 0, 1, 1);
349
352 gtk_grid_attach(GTK_GRID(table), label, 0, i + 1, 1, 1);
355
356 pdialog->minimal_surplus[i] = hscale =
365
366 gtk_grid_attach(GTK_GRID(table), hscale, 1, i + 1, 1, 1);
369
371 "value-changed",
372 G_CALLBACK(hscale_changed), pdialog);
373
374 pdialog->factor[i] = hscale =
381
382 gtk_grid_attach(GTK_GRID(table), hscale, 2, i + 1, 1, 1);
385
386 g_signal_connect(pdialog->factor[i], "value-changed",
387 G_CALLBACK(hscale_changed), pdialog);
389
390 /* Happy Surplus and Factor */
391 label = gtk_label_new(_("Celebrate"));
392 gtk_grid_attach(GTK_GRID(table), label, 0, O_LAST + 1, 1, 1);
395
399 FALSE);
400 gtk_grid_attach(GTK_GRID(table), pdialog->happy_button, 1, O_LAST + 1, 1, 1);
401
402 g_signal_connect(pdialog->happy_button, "toggled",
403 G_CALLBACK(hscale_changed), pdialog);
404
405 pdialog->factor[O_LAST] = hscale =
412
413 gtk_grid_attach(GTK_GRID(table), hscale, 2, O_LAST + 1, 1, 1);
416
418 "value-changed",
419 G_CALLBACK(hscale_changed), pdialog);
420
421 /* Maximize Growth */
422 label = gtk_label_new(_("Maximize growth"));
423 gtk_grid_attach(GTK_GRID(table), label, 0, O_LAST + 2, 1, 1);
426
430 FALSE);
431 gtk_grid_attach(GTK_GRID(table), pdialog->growth_button, 1, O_LAST + 2, 1, 1);
432
433 g_signal_connect(pdialog->growth_button, "toggled",
434 G_CALLBACK(hscale_changed), pdialog);
435
436 /* Buttons */
440
441 button = icon_label_button_new("help-browser", _("Help"));
442 g_signal_connect(button, "clicked",
446 button, TRUE);
447
452 gtk_widget_set_name(pdialog->active_command, "comment_label");
454
455 gtk_widget_show_all(pdialog->shell);
456
458
459 update_cma_preset_list(pdialog);
460
462
463 /* refresh is done in refresh_city_dialog */
464
465 return pdialog;
466}
467
468/**********************************************************************/
471void refresh_cma_dialog(struct city *pcity, enum cma_refresh refresh)
472{
473 struct cm_result *result = cm_result_new(pcity);
474 struct cm_parameter param;
475 struct cma_dialog *pdialog = get_cma_dialog(pcity);
477
479
480 if (pdialog->result_label != NULL) {
481 /* fill in result label */
484 cmafec_get_result_descr(pcity, result, &param));
485 }
486
487 /* if called from a hscale, we _don't_ want to do this */
488 if (refresh != DONT_REFRESH_HSCALES) {
489 set_hscales(&param, pdialog);
490 }
491
493
495
500 controlled);
501 g_signal_connect(pdialog->active_command, "clicked",
503
504 if (controlled) {
506 _("Governor Enabl_ed"));
507 } else {
509 _("Governor Disabl_ed"));
510 }
511
512 if (pdialog->result_label != NULL) {
514 }
515
516 cm_result_destroy(result);
517}
518
519/**********************************************************************/
522static void update_cma_preset_list(struct cma_dialog *pdialog)
523{
524 char buf[BUFFER_SIZE];
525 GtkTreeIter it;
526 int i;
527
528 /* Fill preset list */
529 gtk_list_store_clear(pdialog->store);
530
531 /* Append the presets */
532 if (cmafec_preset_num()) {
533 for (i = 0; i < cmafec_preset_num(); i++) {
535 gtk_list_store_append(pdialog->store, &it);
536 gtk_list_store_set(pdialog->store, &it, 0, buf, -1);
537 }
538 }
539}
540
541/**********************************************************************/
546{
547 struct cma_dialog *pdialog = (struct cma_dialog *) data;
548 int preset_index;
549 const struct cm_parameter *pparam;
550
552
554
555 /* Save the change */
557
558 if (cma_is_city_under_agent(pdialog->pcity, NULL)) {
559 cma_release_city(pdialog->pcity);
561 }
562 refresh_city_dialog(pdialog->pcity);
563}
564
565/**********************************************************************/
569{
570 struct cma_dialog *pdialog = (struct cma_dialog *) data;
571 const char *default_name;
573 int index;
574
575 if ((index = gtk_tree_selection_get_row(pdialog->selection)) != -1) {
577 } else {
578 default_name = _("new preset");
579 }
580
582 _("Name new preset"),
583 _("What should we name the preset?"),
586}
587
588/**********************************************************************/
591static void cma_preset_add_popup_callback(gpointer data, gint response,
592 const char *input)
593{
594 struct cma_dialog *pdialog = (struct cma_dialog *) data;
595
596 if (pdialog) {
597 if (response == GTK_RESPONSE_OK) {
598 struct cm_parameter param;
599
600 cmafec_get_fe_parameter(pdialog->pcity, &param);
601 cmafec_preset_add(input, &param);
602 update_cma_preset_list(pdialog);
604 /* If this or other cities have this set as "custom" */
606 } /* else CANCEL or DELETE_EVENT */
607
608 pdialog->name_shell = NULL;
609 }
610}
611
612/**********************************************************************/
616 gpointer data)
617{
618 struct cma_dialog *pdialog = (struct cma_dialog *) data;
619 int index;
620
621 if ((index = gtk_tree_selection_get_row(pdialog->selection)) == -1) {
622 return FALSE;
623 }
624
625 if (ev->type == GDK_KEY_PRESS) {
626 switch (ev->keyval) {
627 case GDK_KEY_Delete:
628 cma_preset_remove(pdialog, index);
629 break;
630 case GDK_KEY_Insert:
632 break;
633 default:
634 return FALSE;
635 }
636 return TRUE;
637 }
638 return FALSE;
639}
640
641/**********************************************************************/
645{
646 struct cma_dialog *pdialog = (struct cma_dialog *) data;
647 int index;
648
649 if ((index = gtk_tree_selection_get_row(pdialog->selection)) == -1) {
650 return;
651 }
652
653 cma_preset_remove(pdialog, index);
654}
655
656/**********************************************************************/
680
681/**********************************************************************/
685 gpointer data)
686{
687 struct cma_dialog *pdialog = (struct cma_dialog *) data;
688
689 if (response == GTK_RESPONSE_YES) {
690 cmafec_preset_remove(pdialog->id);
691 pdialog->id = -1;
692 update_cma_preset_list(pdialog);
694 /* if this or other cities have this set, reset to "custom" */
696 }
698
699 pdialog->preset_remove_shell = NULL;
700}
701
702/**********************************************************************/
706{
707 struct cma_dialog *pdialog = (struct cma_dialog *) data;
708
709 if (cma_is_city_under_agent(pdialog->pcity, NULL)) {
710 cma_release_city(pdialog->pcity);
711 } else {
712 struct cm_parameter param;
713
714 cmafec_get_fe_parameter(pdialog->pcity, &param);
715 cma_put_city_under_agent(pdialog->pcity, &param);
716 }
717 refresh_city_dialog(pdialog->pcity);
718}
719
720/**********************************************************************/
724static void set_hscales(const struct cm_parameter *const parameter,
725 struct cma_dialog *pdialog)
726{
727 allow_refreshes = 0;
730 parameter->minimal_surplus[i]);
731 gtk_range_set_value(GTK_RANGE(pdialog->factor[i]), parameter->factor[i]);
734 parameter->require_happy);
736 parameter->max_growth);
738 parameter->happy_factor);
739 allow_refreshes = 1;
740}
741
742/**********************************************************************/
745static void hscale_changed(GtkWidget *get, gpointer data)
746{
747 struct cma_dialog *pdialog = (struct cma_dialog *) data;
748 struct cm_parameter param;
749
750 if (!allow_refreshes) {
751 return;
752 }
753
754 cmafec_get_fe_parameter(pdialog->pcity, &param);
756 param.minimal_surplus[i] =
758 param.factor[i] =
759 (int) (gtk_range_get_value(GTK_RANGE(pdialog->factor[i])));
761 param.require_happy =
763 ? TRUE : FALSE);
764 param.max_growth =
766 ? TRUE : FALSE);
767 param.happy_factor =
769
770 /* Save the change */
771 cmafec_set_fe_parameter(pdialog->pcity, &param);
772
773 /* Refreshes the cma */
774 if (cma_is_city_under_agent(pdialog->pcity, NULL)) {
775 cma_release_city(pdialog->pcity);
776 cma_put_city_under_agent(pdialog->pcity, &param);
777 refresh_city_dialog(pdialog->pcity);
778 } else {
780 }
781}
const char * get_output_name(Output_type_id output)
Definition city.c:629
#define output_type_iterate(output)
Definition city.h:842
#define output_type_iterate_end
Definition city.h:848
void refresh_city_dialog(struct city *pcity)
void city_report_dialog_update(void)
bool can_client_issue_orders(void)
struct cm_result * cm_result_new(struct city *pcity)
Definition cm.c:345
void cm_result_from_main_map(struct cm_result *result, const struct city *pcity)
Definition cm.c:2261
void cm_result_destroy(struct cm_result *result)
Definition cm.c:368
bool cma_is_city_under_agent(const struct city *pcity, struct cm_parameter *parameter)
Definition cma_core.c:552
void cma_put_city_under_agent(struct city *pcity, const struct cm_parameter *const parameter)
Definition cma_core.c:524
void cma_release_city(struct city *pcity)
Definition cma_core.c:542
const char * cmafec_get_short_descr(const struct cm_parameter *const parameter)
Definition cma_fec.c:236
void cmafec_set_fe_parameter(struct city *pcity, const struct cm_parameter *const parameter)
Definition cma_fec.c:105
char * cmafec_preset_get_descr(int idx)
Definition cma_fec.c:169
const char * cmafec_get_result_descr(struct city *pcity, const struct cm_result *result, const struct cm_parameter *const parameter)
Definition cma_fec.c:322
const struct cm_parameter * cmafec_preset_get_parameter(int idx)
Definition cma_fec.c:182
void cmafec_preset_add(const char *descr_name, struct cm_parameter *pparam)
Definition cma_fec.c:136
int cmafec_preset_get_index_of_parameter(const struct cm_parameter *const parameter)
Definition cma_fec.c:196
void cmafec_preset_remove(int idx)
Definition cma_fec.c:153
int cmafec_preset_num(void)
Definition cma_fec.c:213
void cmafec_get_fe_parameter(struct city *pcity, struct cm_parameter *dest)
Definition cma_fec.c:115
char * incite_cost
Definition comments.c:76
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
@ O_LAST
Definition fc_types.h:101
#define _(String)
Definition fcintl.h:67
static gboolean button_press_callback(GtkTreeView *view, GdkEventButton *ev, gpointer data)
Definition cma_fe.c:143
static gboolean cma_preset_key_pressed_callback(GtkWidget *w, GdkEventKey *ev, gpointer data)
Definition cma_fe.c:615
static void cma_preset_remove(struct cma_dialog *pdialog, int preset_index)
Definition cma_fe.c:659
void close_cma_dialog(struct city *pcity)
Definition cma_fe.c:104
struct cma_dialog * create_cma_dialog(struct city *pcity, bool tiny)
Definition cma_fe.c:214
void refresh_cma_dialog(struct city *pcity, enum cma_refresh refresh)
Definition cma_fe.c:471
static void cma_del_preset_callback(GtkWidget *w, gpointer data)
Definition cma_fe.c:644
static void cma_dialog_destroy_callback(GtkWidget *w, gpointer data)
Definition cma_fe.c:118
void cma_fe_init(void)
Definition cma_fe.c:88
static void cma_add_preset_callback(GtkWidget *w, gpointer data)
Definition cma_fe.c:568
static void help_callback(GtkWidget *w, gpointer data)
Definition cma_fe.c:170
static void update_cma_preset_list(struct cma_dialog *pdialog)
Definition cma_fe.c:522
#define BUFFER_SIZE
Definition cma_fe.c:48
#define dialog_list_iterate_end
Definition cma_fe.c:56
static void hscale_changed(GtkWidget *get, gpointer data)
Definition cma_fe.c:745
static void cell_data_func(GtkTreeViewColumn *col, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *it, gpointer data)
Definition cma_fe.c:178
static void cma_preset_add_popup_callback(gpointer data, gint response, const char *input)
Definition cma_fe.c:591
static struct cma_dialog * get_cma_dialog(struct city *pcity)
Definition cma_fe.c:129
#define dialog_list_iterate(dialoglist, pdialog)
Definition cma_fe.c:54
static struct dialog_list * dialog_list
Definition cma_fe.c:58
static void cma_preset_remove_response(GtkWidget *w, gint response, gpointer data)
Definition cma_fe.c:684
static void cma_activate_preset_callback(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data)
Definition cma_fe.c:544
static void cma_active_callback(GtkWidget *w, gpointer data)
Definition cma_fe.c:705
static void set_hscales(const struct cm_parameter *const parameter, struct cma_dialog *pdialog)
Definition cma_fe.c:724
void cma_fe_done(void)
Definition cma_fe.c:96
static int allow_refreshes
Definition cma_fe.c:60
cma_refresh
Definition cma_fe.h:25
@ DONT_REFRESH_HSCALES
Definition cma_fe.h:28
#define GUI_GTK_OPTION(optname)
Definition gui_main.h:25
void gtk_tree_view_focus(GtkTreeView *view)
Definition gui_stuff.c:236
gint gtk_tree_selection_get_row(GtkTreeSelection *selection)
Definition gui_stuff.c:215
GtkWidget * icon_label_button_new(const gchar *icon_name, const gchar *label_text)
Definition gui_stuff.c:76
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:287
void popup_help_dialog_string(const char *item)
Definition helpdlg.c:212
GtkWidget * input_dialog_create(GtkWindow *parent, const char *dialogname, const char *text, const char *postinputtest, input_dialog_callback_t response_callback, gpointer response_cli_data)
Definition inputdlg.c:66
#define HELP_CMA_ITEM
#define fc_malloc(sz)
Definition mem.h:34
Definition city.h:317
int factor[O_LAST]
Definition cm.h:47
bool max_growth
Definition cm.h:42
bool require_happy
Definition cm.h:43
int minimal_surplus[O_LAST]
Definition cm.h:41
int happy_factor
Definition cm.h:48
Definition cm.h:52
GtkWidget * preset_list
Definition cma_fe.h:36
GtkWidget * active_command
Definition cma_fe.h:40
GtkWidget * factor[O_LAST+1]
Definition cma_fe.h:44
GtkWidget * shell
Definition cma_fe.h:33
GtkWidget * happy_button
Definition cma_fe.h:42
GtkWidget * del_preset_command
Definition cma_fe.h:39
GtkWidget * growth_button
Definition cma_fe.h:43
GtkWidget * result_label
Definition cma_fe.h:37
GtkWidget * add_preset_command
Definition cma_fe.h:38
GtkWidget * minimal_surplus[O_LAST]
Definition cma_fe.h:41
GtkListStore * store
Definition cma_fe.h:46
GtkWidget * name_shell
Definition cma_fe.h:34
GtkWidget * preset_remove_shell
Definition cma_fe.h:35
int id
Definition cma_fe.h:47
struct city * pcity
Definition cma_fe.h:32
GtkTreeSelection * selection
Definition cma_fe.h:45
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:777
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47