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