51#define SPECLIST_TAG option_dialog
52#define SPECLIST_TYPE struct option_dialog
54#define option_dialogs_iterate(pdialog) \
55 TYPED_LIST_ITERATE(struct option_dialog, option_dialogs, pdialog)
56#define option_dialogs_iterate_end LIST_ITERATE_END
88 bool reorder_notebook);
101 gint response_id, gpointer data)
105 switch (response_id) {
107 gtk_window_destroy(GTK_WINDOW(dialog));
111 gtk_window_destroy(GTK_WINDOW(dialog));
137 gtk_window_get_default_size(GTK_WINDOW(
object),
141 if (NULL != pdialog->
shell) {
143 pdialog->
shell = NULL;
157 if (NULL != pdialog) {
174 if (NULL != pdialog) {
191 if (NULL != pdialog) {
208 GtkEventController *controller = GTK_EVENT_CONTROLLER(gesture);
209 GtkWidget *parent = gtk_event_controller_get_widget(controller);
213 GdkRectangle rect = { .x = x, .y = y, .width = 1, .height = 1};
219 group = G_ACTION_GROUP(g_simple_action_group_new());
223 act = g_simple_action_new(
"refresh", NULL);
224 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
229 act = g_simple_action_new(
"unit_reset", NULL);
230 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
235 act = g_simple_action_new(
"units_apply", NULL);
236 g_action_map_add_action(G_ACTION_MAP(group), G_ACTION(act));
239 g_menu_item_new(
_(
"Apply the changes for this option"),
242 opt_popover = gtk_popover_menu_new_from_model(G_MENU_MODEL(menu));
244 gtk_widget_insert_action_group(
opt_popover,
"win", group);
247 gtk_popover_set_pointing_to(GTK_POPOVER(
opt_popover), &rect);
275 GdkRGBA *
color = (GdkRGBA *) data;
278 gdk_rgba_free(
color);
286 const GdkRGBA *new_color)
288 GdkRGBA *current_color = g_object_get_data(G_OBJECT(button),
"color");
291 if (NULL == new_color) {
292 if (NULL != current_color) {
293 g_object_set_data(G_OBJECT(button),
"color", NULL);
294 gtk_button_set_child(button, NULL);
300 if (NULL != current_color) {
302 *current_color = *new_color;
305 current_color = gdk_rgba_copy(new_color);
306 g_object_set_data_full(G_OBJECT(button),
"color", current_color,
309 gtk_button_set_child(button, NULL);
313 cairo_surface_t *surface = cairo_image_surface_create(
314 CAIRO_FORMAT_RGB24, 16, 16);
315 cairo_t *cr = cairo_create(surface);
316 gdk_cairo_set_source_rgba(cr, current_color);
319 pixbuf = gdk_pixbuf_get_from_surface(surface, 0, 0, 16, 16);
320 cairo_surface_destroy(surface);
322 child = gtk_image_new_from_pixbuf(pixbuf);
323 gtk_button_set_child(GTK_BUTTON(button), child);
324 gtk_widget_show(child);
325 g_object_unref(G_OBJECT(pixbuf));
333 gint res, gpointer data)
335 if (res == GTK_RESPONSE_REJECT) {
338 }
else if (res == GTK_RESPONSE_OK) {
340 GtkColorChooser *chooser =
341 GTK_COLOR_CHOOSER(g_object_get_data(G_OBJECT(dialog),
"chooser"));
344 gtk_color_chooser_get_rgba(chooser, &new_color);
348 gtk_window_destroy(GTK_WINDOW(dialog));
356 GtkWidget *dialog, *chooser;
357 GdkRGBA *current_color = g_object_get_data(G_OBJECT(button),
"color");
359 dialog = gtk_dialog_new_with_buttons(
_(
"Select a color"), NULL,
361 _(
"_Cancel"), GTK_RESPONSE_CANCEL,
362 _(
"C_lear"), GTK_RESPONSE_REJECT,
363 _(
"_OK"), GTK_RESPONSE_OK, NULL);
365 g_signal_connect(dialog,
"response",
368 chooser = gtk_color_chooser_widget_new();
369 g_object_set_data(G_OBJECT(dialog),
"chooser", chooser);
370 gtk_box_insert_child_after(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
373 gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(chooser), current_color);
376 gtk_widget_show(dialog);
391 pdialog->
shell = gtk_dialog_new_with_buttons(
name, NULL, 0,
398 pdialog->
notebook = gtk_notebook_new();
411 gtk_window_set_default_size(GTK_WINDOW(pdialog->
shell),
414 g_signal_connect(pdialog->
shell,
"response",
416 g_signal_connect(pdialog->
shell,
"destroy",
419 gtk_box_insert_child_after(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(pdialog->
shell))),
430 gtk_widget_show(pdialog->
shell);
452 pdialog->
shell = NULL;
453 gtk_window_destroy(GTK_WINDOW(
shell));
466 GObject *obj1 = G_OBJECT(*(GtkWidget **) w1);
467 GObject *obj2 = G_OBJECT(*(GtkWidget **) w2);
469 return (GPOINTER_TO_INT(g_object_get_data(obj1,
"category"))
470 - GPOINTER_TO_INT(g_object_get_data(obj2,
"category")));
479 const int pages_num = gtk_notebook_get_n_pages(
notebook);
482 GtkWidget *pages[pages_num];
485 for (i = 0; i < pages_num; i++) {
486 pages[i] = gtk_notebook_get_nth_page(
notebook, i);
489 for (i = 0; i < pages_num; i++) {
490 gtk_notebook_reorder_child(
notebook, pages[i], i);
499 void (*option_action)
505 option_action(poption);
514 bool reorder_notebook)
517 GtkWidget *main_hbox, *label, *w = NULL;
520 GtkEventController *controller;
525 if (NULL == pdialog->
vboxes[category]) {
528 sw = gtk_scrolled_window_new();
529 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
531 GTK_POLICY_AUTOMATIC);
532 gtk_scrolled_window_set_propagate_natural_height(GTK_SCROLLED_WINDOW(sw),
TRUE);
533 g_object_set_data(G_OBJECT(sw),
"category", GINT_TO_POINTER(category));
534 gtk_notebook_append_page(GTK_NOTEBOOK(pdialog->
notebook), sw,
535 gtk_label_new_with_mnemonic
538 if (reorder_notebook) {
542 pdialog->
vboxes[category] = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
543 gtk_widget_set_margin_bottom(pdialog->
vboxes[category], 8);
544 gtk_widget_set_margin_end(pdialog->
vboxes[category], 8);
545 gtk_widget_set_margin_start(pdialog->
vboxes[category], 8);
546 gtk_widget_set_margin_top(pdialog->
vboxes[category], 8);
547 gtk_widget_set_hexpand(pdialog->
vboxes[category],
TRUE);
548 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), pdialog->
vboxes[category]);
554 main_hbox = gtk_grid_new();
556 gtk_widget_set_margin_bottom(label, 2);
557 gtk_widget_set_margin_end(label, 2);
558 gtk_widget_set_margin_start(label, 2);
559 gtk_widget_set_margin_top(label, 2);
560 gtk_grid_attach(GTK_GRID(main_hbox), label, main_col++, 0, 1, 1);
562 gesture = gtk_gesture_click_new();
563 gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture), 3);
564 controller = GTK_EVENT_CONTROLLER(gesture);
565 g_signal_connect(controller,
"pressed",
567 gtk_widget_add_controller(main_hbox, controller);
568 gtk_box_append(GTK_BOX(pdialog->
vboxes[category]), main_hbox);
572 w = gtk_check_button_new();
579 w = gtk_spin_button_new_with_range(min, max,
MAX((max - min) / 50, 1));
587 if (NULL != values) {
588 w = gtk_combo_box_text_new_with_entry();
590 gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(w), value);
603 GtkCellRenderer *renderer;
607 model = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
608 w = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
609 g_object_unref(model);
611 renderer = gtk_cell_renderer_text_new();
612 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(w), renderer,
FALSE);
613 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(w), renderer,
616 gtk_list_store_append(model, &iter);
617 gtk_list_store_set(model, &iter, 0, i, 1,
_(
str), -1);
625 GtkWidget *grid, *check;
629 w = gtk_frame_new(NULL);
630 grid = gtk_grid_new();
631 gtk_grid_set_column_spacing(GTK_GRID(grid), 4);
632 gtk_grid_set_row_homogeneous(GTK_GRID(grid),
TRUE);
633 gtk_frame_set_child(GTK_FRAME(w), grid);
635 check = gtk_check_button_new();
636 gtk_grid_attach(GTK_GRID(grid), check, 0, i, 1, 1);
638 gtk_grid_attach(GTK_GRID(grid), label, 1, i, 1, 1);
641 g_object_set_data_full(G_OBJECT(w),
"check_buttons",
list,
642 (GDestroyNotify) g_list_free);
647 w = gtk_font_button_new();
648 g_object_set(G_OBJECT(w),
"use-font",
TRUE, NULL);
657 gtk_grid_set_column_spacing(GTK_GRID(w), 4);
658 gtk_grid_set_row_homogeneous(GTK_GRID(w),
TRUE);
661 button = gtk_button_new();
662 gtk_grid_attach(GTK_GRID(w), button, grid_col++, 0, 1, 1);
663 gtk_widget_set_tooltip_text(GTK_WIDGET(button),
664 _(
"Select the text color"));
665 g_object_set_data(G_OBJECT(w),
"fg_button", button);
666 g_signal_connect(button,
"clicked",
670 button = gtk_button_new();
671 gtk_grid_attach(GTK_GRID(w), button, grid_col++, 0, 1, 1);
672 gtk_widget_set_tooltip_text(GTK_WIDGET(button),
673 _(
"Select the background color"));
674 g_object_set_data(G_OBJECT(w),
"bg_button", button);
675 g_signal_connect(button,
"clicked",
681 log_error(
"Option type %s (%d) not supported yet.",
689 log_error(
"Failed to create a widget for option %d \"%s\".",
692 g_object_set_data(G_OBJECT(w),
"main_widget", main_hbox);
693 g_object_set_data(G_OBJECT(w),
"parent_of_main", pdialog->
vboxes[category]);
694 gtk_widget_set_hexpand(w,
TRUE);
695 gtk_widget_set_halign(w, GTK_ALIGN_END);
696 gtk_grid_attach(GTK_GRID(main_hbox), w, main_col++, 0, 1, 1);
699 gtk_widget_show(main_hbox);
713 if (NULL !=
object) {
717 gtk_box_remove(GTK_BOX(g_object_get_data(
object,
"parent_of_main")),
718 GTK_WIDGET(g_object_get_data(
object,
"main_widget")));
722 gtk_notebook_remove_page(GTK_NOTEBOOK(pdialog->
notebook), category);
723 pdialog->
vboxes[category] = NULL;
734 gtk_check_button_set_active(GTK_CHECK_BUTTON
758 GtkWidget *child = gtk_combo_box_get_child(GTK_COMBO_BOX(wdg));
760 gtk_entry_buffer_set_text(gtk_entry_get_buffer(GTK_ENTRY(child)),
string, -1);
762 gtk_entry_buffer_set_text(gtk_entry_get_buffer(GTK_ENTRY(wdg)),
string, -1);
773 GtkTreeModel *model = gtk_combo_box_get_model(combo);
777 if (gtk_tree_model_get_iter_first(model, &iter)) {
779 gtk_tree_model_get(model, &iter, 0, &i, -1);
781 gtk_combo_box_set_active_iter(combo, &iter);
784 }
while (gtk_tree_model_iter_next(model, &iter));
787 log_error(
"Didn't find the value %d for option \"%s\" (nb %d).",
798 GList *iter = g_object_get_data(data,
"check_buttons");
801 for (bit = 0; NULL != iter; iter = g_list_next(iter), bit++) {
802 gtk_check_button_set_active(GTK_CHECK_BUTTON(iter->data),
813 gtk_font_chooser_set_font(GTK_FONT_CHOOSER
827 if (NULL !=
color.foreground
828 &&
'\0' !=
color.foreground[0]
829 && gdk_rgba_parse(&gdk_color,
color.foreground)) {
839 if (NULL !=
color.background
840 &&
'\0' !=
color.background[0]
841 && gdk_rgba_parse(&gdk_color,
color.background)) {
879 log_error(
"Option type %s (%d) not supported yet.",
917 log_error(
"Option type %s (%d) not supported yet.",
934 (GTK_CHECK_BUTTON(w)));
939 (GTK_SPIN_BUTTON(w)));
945 gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(w)));
948 gtk_entry_get_buffer(GTK_ENTRY(w))));
957 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(w), &iter)) {
961 gtk_tree_model_get(gtk_combo_box_get_model(GTK_COMBO_BOX(w)),
962 &iter, 0, &value, -1);
969 GList *iter = g_object_get_data(G_OBJECT(w),
"check_buttons");
973 for (bit = 0; NULL != iter; iter = g_list_next(iter), bit++) {
974 if (gtk_check_button_get_active(GTK_CHECK_BUTTON(iter->data))) {
984 (GTK_FONT_CHOOSER(w)));
989 gchar *fg_color_text = NULL, *bg_color_text = NULL;
994 button = g_object_get_data(G_OBJECT(w),
"fg_button");
995 color = g_object_get_data(button,
"color");
996 if (
color) fg_color_text = gdk_rgba_to_string(
color);
999 button = g_object_get_data(G_OBJECT(w),
"bg_button");
1000 color = g_object_get_data(button,
"color");
1001 if (
color) bg_color_text = gdk_rgba_to_string(
color);
1005 g_free(fg_color_text);
1006 g_free(bg_color_text);
1011 log_error(
"Option type %s (%d) not supported yet.",
1025 if (NULL != pdialog) {
1039 if (NULL != pdialog) {
1051 if (strcmp(
option_name(poption),
"aifill") == 0) {
1053 }
else if (strcmp(
option_name(poption),
"nationset") == 0) {
1066 if (NULL != pdialog) {
1080 if (NULL != pdialog) {
1094 if (NULL != pdialog) {
static struct fc_sockaddr_list * list
static struct ft_color ft_color_construct(const char *foreground, const char *background)
void nationset_sync_to_server(const char *nationset)
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
static struct gui_dialog * shell
static void option_dialog_destroy_callback(GtkWidget *object, gpointer data)
static void color_selector_response_callback(GtkDialog *dialog, gint res, gpointer data)
static struct option_dialog * option_dialog_get(const struct option_set *poptset)
void option_gui_remove(struct option *poption)
static void option_dialog_option_refresh(struct option *poption)
void option_dialog_popdown(const struct option_set *poptset)
static void option_dialog_option_color_set(struct option *poption, struct ft_color color)
static void option_color_set_button_color(GtkButton *button, const GdkRGBA *new_color)
static void option_dialog_option_add(struct option_dialog *pdialog, struct option *poption, bool reorder_notebook)
#define option_dialogs_iterate_end
static void option_dialog_option_bitwise_set(struct option *poption, unsigned value)
static void option_dialog_destroy(struct option_dialog *pdialog)
static void option_dialog_option_bool_set(struct option *poption, bool value)
static void option_dialog_option_remove(struct option_dialog *pdialog, struct option *poption)
void option_gui_add(struct option *poption)
static void option_color_select_callback(GtkButton *button, gpointer data)
static void option_dialog_option_int_set(struct option *poption, int value)
static void option_dialog_reponse_callback(GtkDialog *dialog, gint response_id, gpointer data)
#define option_dialogs_iterate(pdialog)
static void option_gui_update_extra(struct option *poption)
static void option_apply_callback(GtkMenuItem *menuitem, gpointer data)
static void option_color_destroy_notify(gpointer data)
static void option_dialog_option_font_set(struct option *poption, const char *font)
void option_gui_update(struct option *poption)
static int option_dialog_pages_sort_func(const void *w1, const void *w2)
void option_dialog_popup(const char *name, const struct option_set *poptset)
static void option_dialog_reorder_notebook(struct option_dialog *pdialog)
static void option_dialog_option_apply(struct option *poption)
static gboolean option_button_press_callback(GtkWidget *widget, GdkEventButton *event, gpointer data)
static void option_dialog_option_reset(struct option *poption)
static void option_reset_callback(GtkMenuItem *menuitem, gpointer data)
static void option_dialog_foreach(struct option_dialog *pdialog, void(*option_action)(struct option *))
static void option_dialog_option_str_set(struct option *poption, const char *string)
static struct option_dialog_list * option_dialogs
static void option_dialog_option_enum_set(struct option *poption, int value)
static void option_refresh_callback(GtkMenuItem *menuitem, gpointer data)
void ai_fill_changed_by_server(int aifill)
static int opt_dlog_height
static int opt_dlog_width
#define menu_item_append_unref(menu, item)
static GtkWidget * opt_popover
static struct option_dialog * option_dialog_new(void)
#define fc_assert_ret(condition)
#define fc_assert(condition)
#define log_error(message,...)
#define fc_calloc(n, esz)
const struct strvec * option_str_values(const struct option *poption)
unsigned option_bitwise_def(const struct option *poption)
int option_int_min(const struct option *poption)
bool option_bool_def(const struct option *poption)
const char * option_font_def(const struct option *poption)
const struct option_set * server_optset
const char * option_description(const struct option *poption)
const char * option_help_text(const struct option *poption)
struct ft_color option_color_get(const struct option *poption)
int option_enum_get_int(const struct option *poption)
int option_number(const struct option *poption)
int option_category(const struct option *poption)
bool option_str_set(struct option *poption, const char *str)
const char * option_name(const struct option *poption)
int option_int_get(const struct option *poption)
bool option_color_set(struct option *poption, struct ft_color color)
bool option_bool_set(struct option *poption, bool val)
bool option_is_changeable(const struct option *poption)
void option_set_gui_data(struct option *poption, void *data)
const char * option_str_get(const struct option *poption)
void * option_get_gui_data(const struct option *poption)
bool option_enum_set_int(struct option *poption, int val)
bool option_bool_get(const struct option *poption)
int optset_category_number(const struct option_set *poptset)
enum option_type option_type(const struct option *poption)
const char * option_enum_int_to_str(const struct option *poption, int val)
const struct option_set * option_optset(const struct option *poption)
const char * option_str_def(const struct option *poption)
int option_int_max(const struct option *poption)
bool option_font_set(struct option *poption, const char *font)
void options_save(option_save_log_callback log_cb)
const struct strvec * option_bitwise_values(const struct option *poption)
bool option_bitwise_set(struct option *poption, unsigned val)
const char * option_font_get(const struct option *poption)
void desired_settable_options_update(void)
struct ft_color option_color_def(const struct option *poption)
unsigned option_bitwise_get(const struct option *poption)
int option_enum_def_int(const struct option *poption)
bool option_int_set(struct option *poption, int val)
const char * option_category_name(const struct option *poption)
int option_int_def(const struct option *poption)
#define options_iterate(poptset, poption)
#define options_iterate_end
const char * strvec_get(const struct strvec *psv, size_t svindex)
size_t strvec_size(const struct strvec *psv)
#define strvec_iterate(psv, str)
#define strvec_iterate_end
const struct option_set * poptset