1 /**********************************************************************
2 Freeciv - Copyright (C) 1996-2005 - Freeciv Development Team
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 #ifdef HAVE_CONFIG_H
14 #include <fc_config.h>
15 #endif
16
17 #include <stdarg.h>
18
19 #include <gtk/gtk.h>
20
21 #include "support.h"
22
23 #include "gui_main.h"
24 #include "gui_stuff.h"
25
26 #include "choice_dialog.h"
27
28 /****************************************************************
29 Choice dialog: A dialog with a label and a list of buttons
30 placed vertically
31 ****************************************************************/
32
33 /***********************************************************************
34 Get the number of buttons in the choice dialog.
35 ***********************************************************************/
choice_dialog_get_number_of_buttons(GtkWidget * cd)36 int choice_dialog_get_number_of_buttons(GtkWidget *cd)
37 {
38 return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(cd), "nbuttons"));
39 }
40
41 /****************************************************************
42 Get nth button widget from dialog
43 *****************************************************************/
choice_dialog_get_nth_button(GtkWidget * cd,int button)44 static GtkWidget* choice_dialog_get_nth_button(GtkWidget *cd,
45 int button)
46 {
47 char button_name[512];
48 GtkWidget *b;
49
50 fc_snprintf(button_name, sizeof(button_name), "button%d", button);
51
52 b = g_object_get_data(G_OBJECT(cd), button_name);
53
54 return b;
55 }
56
57 /****************************************************************
58 Set sensitivity state of choice dialog button.
59 *****************************************************************/
choice_dialog_button_set_sensitive(GtkWidget * cd,int button,gboolean state)60 void choice_dialog_button_set_sensitive(GtkWidget *cd, int button,
61 gboolean state)
62 {
63 gtk_widget_set_sensitive(choice_dialog_get_nth_button(cd, button), state);
64 }
65
66 /****************************************************************
67 Set label for choice dialog button.
68 *****************************************************************/
choice_dialog_button_set_label(GtkWidget * cd,int number,const char * label)69 void choice_dialog_button_set_label(GtkWidget *cd, int number,
70 const char* label)
71 {
72 GtkWidget* button = choice_dialog_get_nth_button(cd, number);
73 gtk_button_set_label(GTK_BUTTON(button), label);
74 }
75
76 /****************************************************************
77 Set tool tip for choice dialog button.
78 *****************************************************************/
choice_dialog_button_set_tooltip(GtkWidget * cd,int number,const char * tool_tip)79 void choice_dialog_button_set_tooltip(GtkWidget *cd, int number,
80 const char* tool_tip)
81 {
82 GtkWidget* button = choice_dialog_get_nth_button(cd, number);
83 gtk_widget_set_tooltip_text(button, tool_tip);
84 }
85
86 /****************************************************************
87 Move the specified button to the end.
88 *****************************************************************/
choice_dialog_button_move_to_the_end(GtkWidget * cd,const int number)89 void choice_dialog_button_move_to_the_end(GtkWidget *cd,
90 const int number)
91 {
92 GtkWidget *button = choice_dialog_get_nth_button(cd, number);
93 GtkWidget *bbox = g_object_get_data(G_OBJECT(cd), "bbox");
94
95 gtk_box_reorder_child(GTK_BOX(bbox), button, -1);
96 }
97
98 /****************************************************************
99 Create choice dialog
100 *****************************************************************/
choice_dialog_start(GtkWindow * parent,const gchar * name,const gchar * text)101 GtkWidget *choice_dialog_start(GtkWindow *parent, const gchar *name,
102 const gchar *text)
103 {
104 GtkWidget *dshell, *dlabel, *vbox, *bbox;
105
106 dshell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
107 setup_dialog(dshell, toplevel);
108 gtk_window_set_position (GTK_WINDOW(dshell), GTK_WIN_POS_MOUSE);
109
110 gtk_window_set_title(GTK_WINDOW(dshell), name);
111
112 gtk_window_set_transient_for(GTK_WINDOW(dshell), parent);
113 gtk_window_set_destroy_with_parent(GTK_WINDOW(dshell), TRUE);
114
115 vbox = gtk_vbox_new(FALSE, 5);
116 gtk_container_add(GTK_CONTAINER(dshell),vbox);
117
118 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
119
120 dlabel = gtk_label_new(text);
121 gtk_container_add(GTK_CONTAINER(vbox), dlabel);
122
123 bbox = gtk_vbutton_box_new();
124 gtk_box_set_spacing(GTK_BOX(bbox), 2);
125 gtk_container_add(GTK_CONTAINER(vbox), bbox);
126
127 g_object_set_data(G_OBJECT(dshell), "bbox", bbox);
128 g_object_set_data(G_OBJECT(dshell), "nbuttons", GINT_TO_POINTER(0));
129 g_object_set_data(G_OBJECT(dshell), "hide", GINT_TO_POINTER(FALSE));
130
131 gtk_widget_show(vbox);
132 gtk_widget_show(dlabel);
133
134 return dshell;
135 }
136
137 /****************************************************************
138 Choice dialog has been clicked and primary handling has
139 taken place already.
140 *****************************************************************/
choice_dialog_clicked(GtkWidget * w,gpointer data)141 static void choice_dialog_clicked(GtkWidget *w, gpointer data)
142 {
143 if (g_object_get_data(G_OBJECT(data), "hide")) {
144 gtk_widget_hide(GTK_WIDGET(data));
145 } else {
146 gtk_widget_destroy(GTK_WIDGET(data));
147 }
148 }
149
150 /****************************************************************
151 Add button to choice dialog.
152 *****************************************************************/
choice_dialog_add(GtkWidget * dshell,const gchar * label,GCallback handler,gpointer data,bool meta,const gchar * tool_tip)153 void choice_dialog_add(GtkWidget *dshell, const gchar *label,
154 GCallback handler, gpointer data,
155 bool meta, const gchar *tool_tip)
156 {
157 GtkWidget *button, *bbox;
158 char name[512];
159 int nbuttons;
160
161 bbox = g_object_get_data(G_OBJECT(dshell), "bbox");
162 nbuttons = choice_dialog_get_number_of_buttons(dshell);
163 g_object_set_data(G_OBJECT(dshell), "nbuttons", GINT_TO_POINTER(nbuttons+1));
164
165 fc_snprintf(name, sizeof(name), "button%d", nbuttons);
166
167 button = gtk_button_new_from_stock(label);
168 gtk_container_add(GTK_CONTAINER(bbox), button);
169 g_object_set_data(G_OBJECT(dshell), name, button);
170
171 if (handler) {
172 g_signal_connect(button, "clicked", handler, data);
173 }
174
175 if (!meta) {
176 /* This button makes the choice. */
177 g_signal_connect_after(button, "clicked",
178 G_CALLBACK(choice_dialog_clicked), dshell);
179 }
180
181 if (tool_tip != NULL) {
182 gtk_widget_set_tooltip_text(button, tool_tip);
183 }
184 }
185
186 /****************************************************************
187 Choice dialog construction ready
188 *****************************************************************/
choice_dialog_end(GtkWidget * dshell)189 void choice_dialog_end(GtkWidget *dshell)
190 {
191 GtkWidget *bbox;
192
193 bbox = g_object_get_data(G_OBJECT(dshell), "bbox");
194
195 gtk_widget_show_all(bbox);
196 gtk_widget_show(dshell);
197 }
198
199 /****************************************************************
200 Set hide property of choice dialog
201 *****************************************************************/
choice_dialog_set_hide(GtkWidget * dshell,gboolean setting)202 void choice_dialog_set_hide(GtkWidget *dshell, gboolean setting)
203 {
204 g_object_set_data(G_OBJECT(dshell), "hide", GINT_TO_POINTER(setting));
205 }
206
207 /****************************************************************
208 Open new choice dialog.
209 *****************************************************************/
popup_choice_dialog(GtkWindow * parent,const gchar * dialogname,const gchar * text,...)210 GtkWidget *popup_choice_dialog(GtkWindow *parent, const gchar *dialogname,
211 const gchar *text, ...)
212 {
213 GtkWidget *dshell;
214 va_list args;
215 gchar *name;
216
217 dshell = choice_dialog_start(parent, dialogname, text);
218
219 va_start(args, text);
220
221 while ((name = va_arg(args, gchar *))) {
222 GCallback handler;
223 gpointer data;
224
225 handler = va_arg(args, GCallback);
226 data = va_arg(args, gpointer);
227
228 choice_dialog_add(dshell, name, handler, data, FALSE, NULL);
229 }
230
231 va_end(args);
232
233 choice_dialog_end(dshell);
234
235 return dshell;
236 }
237