1
2 /*
3 * The Real SoundTracker - GUI support routines (header)
4 *
5 * Copyright (C) 1998-2019 Michael Krause
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22 #ifndef _GUI_SUBS_H
23 #define _GUI_SUBS_H
24
25 #include <gtk/gtk.h>
26
27 /* values for status bar messages */
28 enum {
29 STATUS_IDLE = 0,
30 STATUS_PLAYING_SONG,
31 STATUS_PLAYING_PATTERN,
32 STATUS_LOADING_MODULE,
33 STATUS_MODULE_LOADED,
34 STATUS_SAVING_MODULE,
35 STATUS_MODULE_SAVED,
36 STATUS_LOADING_SAMPLE,
37 STATUS_SAMPLE_LOADED,
38 STATUS_SAVING_SAMPLE,
39 STATUS_SAMPLE_SAVED,
40 STATUS_LOADING_INSTRUMENT,
41 STATUS_INSTRUMENT_LOADED,
42 STATUS_SAVING_INSTRUMENT,
43 STATUS_INSTRUMENT_SAVED,
44 STATUS_SAVING_SONG,
45 STATUS_SONG_SAVED,
46 };
47
48 struct menu_callback {
49 const gchar* widget_name;
50 void (*fn)();
51 gpointer data;
52 };
53
54 extern const gint SIZES_MENU_TOOLBOX[];
55 extern const gint SIZES_MENU[];
56
57 typedef struct
58 {
59 const gchar *gui_name, *file_name;
60 const gint* sizes; /* 0-terminated */
61 } icon_set;
62
63 int find_current_toggle(GtkWidget** widgets,
64 int count);
65
66 void add_empty_hbox(GtkWidget* tobox);
67 void add_empty_vbox(GtkWidget* tobox);
68
69 void make_radio_group_full_num(const char* labels[],
70 GtkWidget* tobox,
71 GtkWidget* saveptr[],
72 gint t1,
73 gint t2,
74 void (*sigfunc)(),
75 gpointer data,
76 gboolean end,
77 guint num);
78
79 #define make_radio_group_full_ext(labels, tobox, saveptr, t1, t2, sigfunc, data, end) \
80 make_radio_group_full_num(labels, tobox, saveptr, t1, t2, sigfunc, data, end, sizeof(labels) / sizeof(labels[0]))
81
82 #define make_radio_group_full(labels, tobox, saveptr, t1, t2, sigfunc, data) \
83 make_radio_group_full_num(labels, tobox, saveptr, t1, t2, sigfunc, data, FALSE, sizeof(labels) / sizeof(labels[0]))
84
85 #define make_radio_group(labels, tobox, saveptr, t1, t2, sigfunc) \
86 make_radio_group_full_num(labels, tobox, saveptr, t1, t2, sigfunc, NULL, FALSE, sizeof(labels) / sizeof(labels[0]))
87
88 GtkWidget*
89 make_labelled_radio_group_box_full_num(const char* title,
90 const char* labels[],
91 GtkWidget* saveptr[],
92 void (*sigfunc)(),
93 gpointer data,
94 guint num);
95
96 #define make_labelled_radio_group_box_full(title, labels, saveptr, sigfunc, data) \
97 make_labelled_radio_group_box_full_num(title, labels, saveptr, sigfunc, data, sizeof(labels) / sizeof(labels[0]))
98
99 #define make_labelled_radio_group_box(title, labels, saveptr, sigfunc) \
100 make_labelled_radio_group_box_full_num(title, labels, saveptr, sigfunc, NULL, sizeof(labels) / sizeof(labels[0]))
101
102 GtkWidget*
103 gui_labelled_spin_button_new(const char* title,
104 int min,
105 int max,
106 GtkWidget** spin,
107 void (*callback)(),
108 void* callbackdata,
109 gboolean in_mainwindow,
110 gint* handler_id);
111
112 static inline gint
gui_put_labelled_spin_button(GtkWidget * destbox,const char * title,int min,int max,GtkWidget ** spin,void (* callback)(),void * callbackdata,gboolean in_mainwindow)113 gui_put_labelled_spin_button(GtkWidget* destbox,
114 const char* title,
115 int min,
116 int max,
117 GtkWidget** spin,
118 void (*callback)(),
119 void* callbackdata,
120 gboolean in_mainwindow)
121 {
122 gint handler_id;
123 GtkWidget *hbox = gui_labelled_spin_button_new(title, min, max, spin,
124 callback, callbackdata, in_mainwindow, &handler_id);
125
126 gtk_box_pack_start(GTK_BOX(destbox), hbox, FALSE, TRUE, 0);
127 return handler_id;
128 }
129
130 static inline void
gui_set_radio_active(GtkWidget ** radiobutton,guint i)131 gui_set_radio_active(GtkWidget** radiobutton, guint i)
132 {
133 if (gtk_widget_is_sensitive(radiobutton[i]))
134 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobutton[i]), TRUE);
135 }
136
137 GtkWidget*
138 gui_subs_create_slider_full(const gchar* title,
139 const gdouble min,
140 const gdouble max,
141 void (*changedfunc)(),
142 GtkAdjustment** adj,
143 gboolean in_mainwindow,
144 gint* tag);
145
146 static inline GtkWidget*
gui_subs_create_slider(const gchar * title,const gdouble min,const gdouble max,void (* changedfunc)(),GtkAdjustment ** adj,gboolean in_mainwindow)147 gui_subs_create_slider(const gchar* title,
148 const gdouble min,
149 const gdouble max,
150 void (*changedfunc)(),
151 GtkAdjustment** adj,
152 gboolean in_mainwindow)
153 {
154 return gui_subs_create_slider_full(title, min, max, changedfunc, adj, in_mainwindow, NULL);
155 }
156
157 GtkWidget* gui_combo_new(GtkListStore* ls);
158
159 gboolean gui_set_active_combo_item(GtkWidget* combobox,
160 GtkTreeModel* model,
161 guint item);
162
163 void gui_combo_box_prepend_text_or_set_active(GtkComboBoxText* combobox,
164 const gchar* text,
165 gboolean force_active);
166
167 GtkWidget* gui_list_in_scrolled_window_full(const int n,
168 const gchar* const* tp,
169 GtkWidget* hbox,
170 GType* types,
171 const gfloat* alignments,
172 const gboolean* expands,
173 GtkSelectionMode mode,
174 gboolean expand,
175 gboolean fill,
176 GtkWidget** scrolledwindow,
177 GtkPolicyType hpolicy,
178 GtkPolicyType vpolicy);
179
gui_list_in_scrolled_window(const int n,const gchar * const * tp,GtkWidget * hbox,GType * types,const gfloat * alignments,const gboolean * expands,GtkSelectionMode mode,gboolean expand,gboolean fill)180 static inline GtkWidget* gui_list_in_scrolled_window(const int n,
181 const gchar* const* tp,
182 GtkWidget* hbox,
183 GType* types,
184 const gfloat* alignments,
185 const gboolean* expands,
186 GtkSelectionMode mode,
187 gboolean expand,
188 gboolean fill)
189 {
190 return gui_list_in_scrolled_window_full(n, tp, hbox, types,
191 alignments, expands, mode, expand, fill, NULL,
192 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
193 }
194
195 GtkWidget* gui_stringlist_in_scrolled_window(const int n,
196 const gchar* const* tp,
197 GtkWidget* hbox, gboolean expandfill);
198
199 void gui_list_clear(GtkWidget* list);
200 void gui_list_clear_with_model(GtkTreeModel* model);
201 GtkTreeModel* gui_list_freeze(GtkWidget* list);
202 void gui_list_thaw(GtkWidget* list,
203 GtkTreeModel* model);
204
205 #define GUI_GET_LIST_STORE(list) GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list)))
206
207 void gui_list_handle_selection(GtkWidget* list,
208 GCallback handler,
209 gpointer data);
210 gint gui_list_get_selection_index(GtkTreeSelection* sel);
211
212 static inline gboolean
gui_list_get_iter(guint n,GtkListStore * tree_model,GtkTreeIter * iter)213 gui_list_get_iter(guint n, GtkListStore* tree_model, GtkTreeIter* iter)
214 {
215 gchar* path;
216 gboolean result;
217
218 path = g_strdup_printf("%u", n);
219 result = gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(tree_model), iter, path);
220 g_free(path);
221 return result;
222 }
223
224 void gui_string_list_set_text(GtkWidget* list,
225 guint row,
226 guint col,
227 const gchar* string);
228
229 void gui_list_select(GtkWidget* list,
230 guint row,
231 gboolean use_align,
232 gfloat align);
233
234 GtkWidget* gui_button(GtkWidget* win,
235 char* stock,
236 void* callback,
237 gpointer userdata,
238 GtkWidget* box);
239
240 gboolean gui_delete_noop(void);
241 void gui_set_escape_close(GtkWidget* window);
242 gboolean gui_ok_cancel_modal(GtkWidget* window, const gchar* text);
243 void gui_errno_dialog (GtkWidget* window, const gchar* text, const int err);
244 void gui_message_dialog(GtkWidget** dialog, const gchar* text, GtkMessageType type, const gchar* title, gboolean need_update);
245 #define gui_warning_dialog(dialog, text, need_update) gui_message_dialog(dialog, text, GTK_MESSAGE_WARNING, N_("Warning"), need_update)
246 #define gui_error_dialog(dialog, text, need_update) gui_message_dialog(dialog, text, GTK_MESSAGE_ERROR, N_("Error!"), need_update)
247 #define gui_info_dialog(dialog, text, need_update) gui_message_dialog(dialog, text, GTK_MESSAGE_INFO, N_("Information"), need_update)
248 void gui_dialog_adjust(GtkWidget* dialog, gint default_id);
249 FILE* gui_fopen(const gchar* name, const gchar* utf_name, const gchar* mode);
250 void gui_oom_error(void);
251
252 static inline void
gui_dialog_connect(GtkWidget * dialog,GCallback resp_cb)253 gui_dialog_connect(GtkWidget* dialog, GCallback resp_cb)
254 {
255 g_signal_connect(dialog, "delete_event",
256 G_CALLBACK(gui_delete_noop), NULL);
257 g_signal_connect(dialog, "response",
258 resp_cb ? resp_cb : G_CALLBACK(gtk_widget_hide), NULL);
259 }
260
261 static inline void
gui_dialog_connect_data(GtkWidget * dialog,GCallback resp_cb,gpointer data)262 gui_dialog_connect_data(GtkWidget* dialog, GCallback resp_cb, gpointer data)
263 {
264 g_signal_connect(dialog, "delete_event",
265 G_CALLBACK(gui_delete_noop), NULL);
266 g_signal_connect(dialog, "response",
267 resp_cb ? resp_cb : G_CALLBACK(gtk_widget_hide), data);
268 }
269
270 gchar* gui_filename_to_utf8(const gchar* old_name);
271 gchar* gui_filename_from_utf8(const gchar* old_name);
272
273 GtkBuilder* gui_builder_from_file(const gchar* name, const struct menu_callback cb[]);
274
275 gint gui_get_text_entry(int length,
276 void (*changedfunc)(),
277 GtkWidget** widget);
278 GtkWidget* gui_get_widget(GtkBuilder *builder, const gchar* name, const gchar* file);
279 void gui_popup_menu_attach(GtkWidget* menu, GtkWidget* widget, gpointer* user_data);
280 void gui_get_pixel_size(GtkWidget* w, const char* text, gint* width, gint* height);
281 GdkPixbuf* gui_pixbuf_new_from_file(const gchar* path);
282 /* icon_set should be NULL-terminated */
283 void gui_add_icons(const icon_set* icons);
284
285 static inline void
_gui_block_signals(GObject * objs[],const gint tags[],const gint number,gboolean block)286 _gui_block_signals(GObject* objs[], const gint tags[], const gint number, gboolean block)
287 {
288 gint i;
289
290 for (i = 0; i < number; i++)
291 (block ? g_signal_handler_block : g_signal_handler_unblock)(objs[i], tags[i]);
292 }
293 #define gui_block_signals(objs, tags, block)\
294 _gui_block_signals((GObject **)objs, tags, sizeof(objs) / sizeof(objs[0]), block)
295
296 #endif /* _GUI_SUBS_H */
297