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-5.0 */
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
68 GdkModifierType state, gpointer data);
69static void cma_del_preset_callback(GtkWidget *w, gpointer data);
70static void cma_preset_remove(struct cma_dialog *pdialog, int preset_index);
71static void cma_preset_remove_response(GtkWidget *w, gint response,
72 gpointer data);
73
74static void cma_add_preset_callback(GtkWidget *w, gpointer data);
75static void cma_preset_add_popup_callback(gpointer data, gint response,
76 const char *input);
77
78static void cma_active_callback(GtkWidget *w, gpointer data);
80 guint position,
82 gpointer data);
83
84static void hscale_changed(GtkWidget *get, gpointer data);
85static void set_hscales(const struct cm_parameter *const parameter,
86 struct cma_dialog *pdialog);
87
88#define FC_TYPE_PRESET_ROW (fc_preset_row_get_type())
89
91
98
103
105
106/**********************************************************************/
110{
112
113 if (row->desc != nullptr) {
114 free(row->desc);
115 row->desc = nullptr;
116 }
117
119}
120
121/**********************************************************************/
124static void
131
132/**********************************************************************/
135static void
137{
138 self->desc = nullptr;
139}
140
141/**********************************************************************/
145{
146 FcPresetRow *result;
147
148 result = g_object_new(FC_TYPE_PRESET_ROW, nullptr);
149
150 return result;
151}
152
153/**********************************************************************/
156void cma_fe_init(void)
157{
159}
160
161/**********************************************************************/
164void cma_fe_done(void)
165{
167}
168
169/**********************************************************************/
173{
174 struct cma_dialog *pdialog = get_cma_dialog(pcity);
175
176 if (pdialog == NULL) {
177 /* A city which is being investigated doesn't contain cma dialog */
178 return;
179 }
180
182 pdialog->shell);
183}
184
185/**********************************************************************/
189{
190 struct cma_dialog *pdialog = (struct cma_dialog *) data;
191
193 free(pdialog);
194}
195
196/**********************************************************************/
200{
202 if (pdialog->pcity == pcity) {
203 return pdialog;
204 }
206
207 return NULL;
208}
209
210/**********************************************************************/
214 double x, double y)
215{
217 struct cma_dialog *pdialog
218 = (struct cma_dialog *) g_object_get_data(G_OBJECT(widget), "dialog");
219 int rnbr = get_column_view_row(pdialog->preset_list, y);
220
221 if (rnbr >= 0) {
222 if (n_press == 1) {
223 const struct cm_parameter *pparam;
224
226
227 /* Save the change */
229
230 if (cma_is_city_under_agent(pdialog->pcity, NULL)) {
231 cma_release_city(pdialog->pcity);
233 }
234 refresh_city_dialog(pdialog->pcity);
235 } else if (n_press == 2) {
236 struct cm_parameter param;
237
238 cmafec_get_fe_parameter(pdialog->pcity, &param);
239 cma_put_city_under_agent(pdialog->pcity, &param);
240 refresh_city_dialog(pdialog->pcity);
241 }
242 }
243
244 return FALSE;
245}
246
247/**********************************************************************/
254
255/**********************************************************************/
269
270/**********************************************************************/
279
280/**********************************************************************/
284{
285 struct cma_dialog *pdialog;
286 struct cm_parameter param;
287 GtkWidget *frame, *page, *hbox, *vbox, *label, *table;
288 GtkWidget *hscale, *button;
294 int shell_row = 0;
296
298 pdialog = fc_malloc(sizeof(struct cma_dialog));
299 pdialog->pcity = pcity;
300 pdialog->shell = gtk_grid_new();
305 gtk_widget_set_margin_end(pdialog->shell, 8);
306 gtk_widget_set_margin_top(pdialog->shell, 8);
308 g_signal_connect(pdialog->shell, "destroy",
310
312 gtk_grid_attach(GTK_GRID(pdialog->shell), page, 0, shell_row++, 1, 1);
313
316 gtk_box_append(GTK_BOX(page), vbox);
317
319 pdialog->selection
322 pdialog->preset_list = list;
323
326 nullptr);
328 nullptr);
329
332
333 g_object_set_data(G_OBJECT(pdialog->preset_list), "dialog", pdialog);
335 g_signal_connect(controller, "pressed",
338
340 _("For information on\n"
341 "the citizen governor and governor presets,\n"
342 "including sample presets,\n"
343 "see README.governor."));
344
346 "use-underline", TRUE,
347 "mnemonic-widget", list,
348 "label", _("Prese_ts:"),
349 "xalign", 0.0, "yalign", 0.5, NULL);
350 gtk_box_append(GTK_BOX(vbox), label);
352
353 g_signal_connect(pdialog->selection, "selection-changed",
356 g_signal_connect(controller, "key-pressed",
359
362
363 button = icon_label_button_new("document-new", _("Ne_w"));
364 gtk_box_append(GTK_BOX(hbox), button);
365 g_signal_connect(button, "clicked",
367 pdialog->add_preset_command = button;
368
369 pdialog->del_preset_command = icon_label_button_new("edit-delete",
370 _("_Delete"));
372 g_signal_connect(pdialog->del_preset_command, "clicked",
374
375 /* The right-hand side */
381 gtk_box_append(GTK_BOX(page), vbox);
382
383 /* Result */
384 if (!tiny) {
385 frame = gtk_frame_new(_("Results"));
388 gtk_box_append(GTK_BOX(vbox), frame);
389
390 pdialog->result_label =
391 gtk_label_new("food\n prod\n trade\n\n people\n grow\n prod\n name");
392 gtk_widget_set_name(pdialog->result_label, "city_label");
395 } else {
396 pdialog->result_label = NULL;
397 }
398
399 /* Minimal Surplus and Factor */
406
407 label = gtk_label_new(_("Minimal Surplus"));
410 gtk_grid_attach(GTK_GRID(table), label, 1, 0, 1, 1);
411 label = gtk_label_new(_("Factor"));
414 gtk_grid_attach(GTK_GRID(table), label, 2, 0, 1, 1);
415
418 gtk_grid_attach(GTK_GRID(table), label, 0, i + 1, 1, 1);
421
422 pdialog->minimal_surplus[i] = hscale =
429 if (layout != NULL) {
432 }
433
434 gtk_grid_attach(GTK_GRID(table), hscale, 1, i + 1, 1, 1);
437
439 "value-changed",
440 G_CALLBACK(hscale_changed), pdialog);
441
442 pdialog->factor[i] = hscale
447 if (layout != NULL) {
449 } else {
450 layout_width = 20;
451 }
453
454 gtk_grid_attach(GTK_GRID(table), hscale, 2, i + 1, 1, 1);
457
458 g_signal_connect(pdialog->factor[i], "value-changed",
459 G_CALLBACK(hscale_changed), pdialog);
461
462 /* Happy Surplus and Factor */
463 label = gtk_label_new(_("Celebrate"));
464 gtk_grid_attach(GTK_GRID(table), label, 0, O_LAST + 1, 1, 1);
467
471 FALSE);
472 gtk_grid_attach(GTK_GRID(table), pdialog->happy_button, 1, O_LAST + 1, 1, 1);
473
474 g_signal_connect(pdialog->happy_button, "toggled",
475 G_CALLBACK(hscale_changed), pdialog);
476
477 pdialog->factor[O_LAST] = hscale
482 if (layout != NULL) {
485 }
486
487 gtk_grid_attach(GTK_GRID(table), hscale, 2, O_LAST + 1, 1, 1);
490
492 "value-changed",
493 G_CALLBACK(hscale_changed), pdialog);
494
495 /* Maximize Growth */
496 label = gtk_label_new(_("Maximize growth"));
497 gtk_grid_attach(GTK_GRID(table), label, 0, O_LAST + 2, 1, 1);
500
504 FALSE);
505 gtk_grid_attach(GTK_GRID(table), pdialog->growth_button, 1, O_LAST + 2, 1, 1);
506
507 g_signal_connect(pdialog->growth_button, "toggled",
508 G_CALLBACK(hscale_changed), pdialog);
509
510 /* Buttons */
513
514 button = icon_label_button_new("help-browser", _("Help"));
515 g_signal_connect(button, "clicked",
517 gtk_box_append(GTK_BOX(hbox), button);
518
521 gtk_widget_set_name(pdialog->active_command, "comment_label");
523
525
527
528 update_cma_preset_list(pdialog);
529
530 /* Refresh is done in refresh_city_dialog() */
531
532 return pdialog;
533}
534
535/**********************************************************************/
538void refresh_cma_dialog(struct city *pcity, enum cma_refresh refresh)
539{
540 struct cm_result *result = cm_result_new(pcity);
541 struct cm_parameter param;
542 struct cma_dialog *pdialog = get_cma_dialog(pcity);
544
546
547 if (pdialog->result_label != NULL) {
548 /* Fill in result label */
551 cmafec_get_result_descr(pcity, result, &param));
552 }
553
554 /* If called from a hscale, we _don't_ want to do this */
555 if (refresh != DONT_REFRESH_HSCALES) {
556 set_hscales(&param, pdialog);
557 }
558
560
562
567 controlled);
568 g_signal_connect(pdialog->active_command, "clicked",
570
571 if (controlled) {
573 _("Governor Enabl_ed"));
574 } else {
576 _("Governor Disabl_ed"));
577 }
578
579 if (pdialog->result_label != NULL) {
581 }
582
583 cm_result_destroy(result);
584}
585
586/**********************************************************************/
589static void update_cma_preset_list(struct cma_dialog *pdialog)
590{
591 char buf[BUFFER_SIZE];
592 int i;
593
594 /* Fill preset list */
596
597 /* Append the presets */
598 if (cmafec_preset_num()) {
599 for (i = 0; i < cmafec_preset_num(); i++) {
601
603 row->desc = fc_strdup(buf);
604 g_list_store_append(pdialog->store, row);
606 }
607 }
608}
609
610/**********************************************************************/
614 guint position,
616 gpointer data)
617{
618 struct cma_dialog *pdialog = (struct cma_dialog *) data;
619 const struct cm_parameter *pparam;
621
623
624 /* Save the change */
626
627 if (cma_is_city_under_agent(pdialog->pcity, NULL)) {
628 cma_release_city(pdialog->pcity);
630 }
631 refresh_city_dialog(pdialog->pcity);
632}
633
634/**********************************************************************/
638{
639 struct cma_dialog *pdialog = (struct cma_dialog *) data;
640 const char *default_name;
642 int index;
643
644 if ((index = gtk_single_selection_get_selected(pdialog->selection)) >= 0) {
646 } else {
647 default_name = _("new preset");
648 }
649
651 _("Name new preset"),
652 _("What should we name the preset?"),
655}
656
657/**********************************************************************/
660static void cma_preset_add_popup_callback(gpointer data, gint response,
661 const char *input)
662{
663 struct cma_dialog *pdialog = (struct cma_dialog *) data;
664
665 if (pdialog) {
666 if (response == GTK_RESPONSE_OK) {
667 struct cm_parameter param;
668
669 cmafec_get_fe_parameter(pdialog->pcity, &param);
670 cmafec_preset_add(input, &param);
671 update_cma_preset_list(pdialog);
673 /* If this or other cities have this set as "custom" */
675 } /* else CANCEL or DELETE_EVENT */
676
677 pdialog->name_shell = NULL;
678 }
679}
680
681/**********************************************************************/
686 GdkModifierType state, gpointer data)
687{
688 struct cma_dialog *pdialog = (struct cma_dialog *) data;
689 int index;
690
691 if ((index = gtk_single_selection_get_selected(pdialog->selection)) < 0) {
692 return FALSE;
693 }
694
695 switch (keyval) {
696 case GDK_KEY_Delete:
697 cma_preset_remove(pdialog, index);
698 break;
699 case GDK_KEY_Insert:
701 break;
702 default:
703 return FALSE;
704 }
705
706 return TRUE;
707}
708
709/**********************************************************************/
713{
714 struct cma_dialog *pdialog = (struct cma_dialog *) data;
715 int index;
716
717 if ((index = gtk_single_selection_get_selected(pdialog->selection)) < 0) {
718 return;
719 }
720
721 cma_preset_remove(pdialog, index);
722}
723
724/**********************************************************************/
748
749/**********************************************************************/
753 gpointer data)
754{
755 struct cma_dialog *pdialog = (struct cma_dialog *) data;
756
757 if (response == GTK_RESPONSE_YES) {
758 cmafec_preset_remove(pdialog->id);
759 pdialog->id = -1;
760 update_cma_preset_list(pdialog);
762 /* if this or other cities have this set, reset to "custom" */
764 }
766
767 pdialog->preset_remove_shell = NULL;
768}
769
770/**********************************************************************/
774{
775 struct cma_dialog *pdialog = (struct cma_dialog *) data;
776
777 if (cma_is_city_under_agent(pdialog->pcity, NULL)) {
778 cma_release_city(pdialog->pcity);
779 } else {
780 struct cm_parameter param;
781
782 cmafec_get_fe_parameter(pdialog->pcity, &param);
783 cma_put_city_under_agent(pdialog->pcity, &param);
784 }
785 refresh_city_dialog(pdialog->pcity);
786}
787
788/**********************************************************************/
792static void set_hscales(const struct cm_parameter *const parameter,
793 struct cma_dialog *pdialog)
794{
795 allow_refreshes = 0;
798 parameter->minimal_surplus[i]);
799 gtk_range_set_value(GTK_RANGE(pdialog->factor[i]), parameter->factor[i]);
802 parameter->require_happy);
804 parameter->max_growth);
806 parameter->happy_factor);
807 allow_refreshes = 1;
808}
809
810/**********************************************************************/
813static void hscale_changed(GtkWidget *get, gpointer data)
814{
815 struct cma_dialog *pdialog = (struct cma_dialog *) data;
816 struct cm_parameter param;
817
818 if (!allow_refreshes) {
819 return;
820 }
821
822 cmafec_get_fe_parameter(pdialog->pcity, &param);
824 param.minimal_surplus[i] =
826 param.factor[i] =
827 (int) (gtk_range_get_value(GTK_RANGE(pdialog->factor[i])));
829 param.require_happy =
831 param.max_growth =
833 param.happy_factor =
835
836 /* Save the change */
837 cmafec_set_fe_parameter(pdialog->pcity, &param);
838
839 /* Refreshes the cma */
840 if (cma_is_city_under_agent(pdialog->pcity, NULL)) {
841 cma_release_city(pdialog->pcity);
842 cma_put_city_under_agent(pdialog->pcity, &param);
843 refresh_city_dialog(pdialog->pcity);
844 } else {
846 }
847}
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)
static struct ai_type * self
Definition classicai.c:46
bool can_client_issue_orders(void)
static struct fc_sockaddr_list * list
Definition clinet.c:102
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
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
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 PangoLayout * layout
Definition canvas.c:325
static gboolean button_press_callback(GtkTreeView *view, GdkEventButton *ev, gpointer data)
Definition cma_fe.c:143
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 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
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
static gboolean cma_preset_key_pressed(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data)
Definition cma_fe.c:632
static void fc_preset_row_class_init(FcPresetRowClass *klass)
Definition cma_fe.c:125
static void fc_preset_row_finalize(GObject *gobject)
Definition cma_fe.c:109
static FcPresetRow * fc_preset_row_new(void)
Definition cma_fe.c:144
static void preset_factory_setup(GtkSignalListItemFactory *self, GtkListItem *list_item, gpointer user_data)
Definition cma_fe.c:273
static void preset_factory_bind(GtkSignalListItemFactory *self, GtkListItem *list_item, gpointer user_data)
Definition cma_fe.c:258
static void fc_preset_row_init(FcPresetRow *self)
Definition cma_fe.c:136
#define FC_TYPE_PRESET_ROW
Definition cma_fe.c:88
int get_column_view_row(GtkWidget *cview, int y)
Definition gui_stuff.c:1182
#define HELP_CMA_ITEM
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
GObjectClass parent_class
Definition cma_fe.c:101
char * desc
Definition cma_fe.c:96
GObject parent_instance
Definition cma_fe.c:94
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