1 /*
2 * KCemu -- The emulator for the KC85 homecomputer series and much more.
3 * Copyright (C) 1997-2010 Torsten Paul
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <string>
21
22 #include "kc/kc.h"
23
24 #include "ui/gtk/window.h"
25
26 #include "ui/gtk/cmd.h"
27
28 using namespace std;
29
30 bool UI_Gtk_Window::_static_init = false;
31 string UI_Gtk_Window::_icon_path;
32 string UI_Gtk_Window::_image_path;
33
UI_Gtk_Window(void)34 UI_Gtk_Window::UI_Gtk_Window(void)
35 {
36 static_init();
37
38 _window = 0;
39 _visible = false;
40 _gtk_builder = NULL;
41 _help_args = new CMD_Args();
42 }
43
UI_Gtk_Window(const char * ui_xml_file)44 UI_Gtk_Window::UI_Gtk_Window(const char *ui_xml_file)
45 {
46 static_init();
47
48 _window = 0;
49 _visible = false;
50 _help_args = new CMD_Args();
51
52 string ui_xml_file_path = _image_path + ui_xml_file;
53 _gtk_builder = gtk_builder_new();
54 gtk_builder_set_translation_domain(_gtk_builder, PACKAGE);
55 gtk_builder_add_from_file(_gtk_builder, ui_xml_file_path.c_str(), NULL);
56 }
57
~UI_Gtk_Window(void)58 UI_Gtk_Window::~UI_Gtk_Window(void)
59 {
60 delete _help_args;
61 }
62
63 void
static_init(void)64 UI_Gtk_Window::static_init(void)
65 {
66 if (_static_init)
67 return;
68
69 _static_init = true;
70
71 string datadir(kcemu_datadir);
72 _icon_path = datadir + "/icons/";
73 _image_path = datadir + "/images/";
74
75 GtkSettings *settings = gtk_settings_get_default();
76 gtk_settings_set_long_property(settings, "gtk-can-change-accels", 1, "UI_Gtk_Window::static_init");
77 gtk_settings_set_string_property(settings, "gtk-menu-bar-accel", "", "UI_Gtk_Window::static_init");
78
79 GdkPixbuf *pixbuf16 = get_icon("kcemu-winicon_16x16.png");
80 GdkPixbuf *pixbuf32 = get_icon("kcemu-winicon_32x32.png");
81 GdkPixbuf *pixbuf48 = get_icon("kcemu-winicon_48x48.png");
82
83 GList *icon_list = NULL;
84 if (pixbuf16 != NULL)
85 icon_list = g_list_append(icon_list, pixbuf16);
86 if (pixbuf32 != NULL)
87 icon_list = g_list_append(icon_list, pixbuf32);
88 if (pixbuf48 != NULL)
89 icon_list = g_list_append(icon_list, pixbuf48);
90
91 if (icon_list != NULL)
92 gtk_window_set_default_icon_list(icon_list);
93 }
94
95 void
show(void)96 UI_Gtk_Window::show(void)
97 {
98 if (_visible)
99 return;
100
101 if (_window == NULL)
102 init();
103
104 gtk_widget_show(_window);
105 _visible = true;
106 }
107
108 void
hide(void)109 UI_Gtk_Window::hide(void)
110 {
111 if (!_visible)
112 return;
113
114 gtk_widget_hide(_window);
115 _visible = false;
116 }
117
118 void
toggle(void)119 UI_Gtk_Window::toggle(void)
120 {
121 if (_visible)
122 hide();
123 else
124 show();
125 }
126
127 bool
is_visible(void)128 UI_Gtk_Window::is_visible(void)
129 {
130 return _visible;
131 }
132
133 GtkWidget *
get_window(void)134 UI_Gtk_Window::get_window(void)
135 {
136 return _window;
137 }
138
139 GdkPixbuf *
get_pixbuf(string path)140 UI_Gtk_Window::get_pixbuf(string path)
141 {
142 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path.c_str(), NULL);
143 return pixbuf;
144 }
145
146 GdkPixbuf *
get_icon(const char * name)147 UI_Gtk_Window::get_icon(const char *name)
148 {
149 return get_pixbuf(_icon_path + name);
150 }
151
152 GdkPixbuf *
get_image(const char * name)153 UI_Gtk_Window::get_image(const char *name)
154 {
155 return get_pixbuf(_image_path + name);
156 }
157
158 GtkWidget *
get_widget_or_null(const char * name)159 UI_Gtk_Window::get_widget_or_null(const char *name)
160 {
161 g_assert(_gtk_builder != NULL);
162
163 GtkWidget *widget = GTK_WIDGET(gtk_builder_get_object(_gtk_builder, name));
164 return widget;
165 }
166
167 GtkWidget *
get_widget(const char * name)168 UI_Gtk_Window::get_widget(const char *name)
169 {
170 GtkWidget *widget = get_widget_or_null(name);
171
172 if (widget == NULL)
173 g_error("widget with name '%s' not found!", name);
174
175 return widget;
176 }
177
178 GtkWidget *
get_widget(const char * name,int nr)179 UI_Gtk_Window::get_widget(const char *name, int nr)
180 {
181 char widget_name[80];
182 snprintf(widget_name, sizeof(widget_name), "%s%d", name, nr);
183 return get_widget(widget_name);
184 }
185
186 GtkCellRenderer *
bind_list_model_column(GtkComboBox * combobox,int column,...)187 UI_Gtk_Window::bind_list_model_column(GtkComboBox *combobox, int column, ...)
188 {
189 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
190 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE);
191 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), renderer, "text", column, NULL);
192
193 va_list ap;
194 va_start(ap, column);
195
196 while (242) {
197 const char *attr = va_arg(ap, const char *);
198 if (attr == NULL)
199 break;
200
201 int index = va_arg(ap, int);
202 gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combobox), renderer, attr, index);
203 }
204
205 va_end(ap);
206
207 return renderer;
208 }
209
210 GtkCellRenderer *
add_text_renderer(GtkTreeView * treeview,GtkTreeViewColumn * column,const char * title,...)211 UI_Gtk_Window::add_text_renderer(GtkTreeView *treeview, GtkTreeViewColumn *column, const char *title, ...) {
212 GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
213
214 gtk_tree_view_column_set_title(column, title);
215 gtk_tree_view_column_pack_end(column, renderer, TRUE);
216 gtk_tree_view_column_set_resizable(column, TRUE);
217 gtk_tree_view_column_set_expand(column, TRUE);
218
219 va_list ap;
220 va_start(ap, title);
221
222 while (242) {
223 const char *attr = va_arg(ap, const char *);
224 if (attr == NULL)
225 break;
226
227 int index = va_arg(ap, int);
228 gtk_tree_view_column_add_attribute(column, renderer, attr, index);
229 }
230
231 va_end(ap);
232
233 return renderer;
234 }
235
236 GtkCellRenderer *
add_icon_renderer(GtkTreeView * treeview,GtkTreeViewColumn * column,const char * title,...)237 UI_Gtk_Window::add_icon_renderer(GtkTreeView *treeview, GtkTreeViewColumn *column, const char *title, ...) {
238 GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
239
240 gtk_tree_view_column_set_title(column, title);
241 gtk_tree_view_column_pack_start(column, renderer, FALSE);
242 gtk_tree_view_column_set_resizable(column, FALSE);
243 gtk_tree_view_column_set_expand(column, FALSE);
244
245 va_list ap;
246 va_start(ap, title);
247
248 while (242) {
249 const char *attr = va_arg(ap, const char *);
250 if (attr == NULL)
251 break;
252
253 int index = va_arg(ap, int);
254 gtk_tree_view_column_add_attribute(column, renderer, attr, index);
255 }
256
257 va_end(ap);
258
259 return renderer;
260 }
261
262 void
sf_help(GtkWidget * widget,gpointer data)263 UI_Gtk_Window::sf_help(GtkWidget *widget, gpointer data)
264 {
265 UI_Gtk_Window *w = (UI_Gtk_Window *)data;
266
267 char *help_topic = (char *)g_object_get_data(G_OBJECT(widget), "help-topic");
268 if (help_topic == NULL)
269 return;
270
271 w->_help_args->set_string_arg("help-topic", help_topic);
272
273 CMD_EXEC_ARGS("ui-help-window-show", w->_help_args);
274 }
275
276 void
sf_help_recursive(GtkWidget * widget,gpointer data)277 UI_Gtk_Window::sf_help_recursive(GtkWidget *widget, gpointer data)
278 {
279 UI_Gtk_Window *w = (UI_Gtk_Window *)data;
280
281 while (widget != NULL)
282 {
283 char *help_topic = (char *)g_object_get_data(G_OBJECT(widget), "help-topic");
284 if (help_topic != NULL)
285 {
286 w->_help_args->set_string_arg("help-topic", help_topic);
287 CMD_EXEC_ARGS("ui-help-window-show", w->_help_args);
288 break;
289 }
290
291 widget = gtk_widget_get_parent(widget);
292 }
293 }
294
295 void
init_dialog(const char * close_button_func,const char * help_topic)296 UI_Gtk_Window::init_dialog(const char *close_button_func, const char *help_topic)
297 {
298 g_object_set_data(G_OBJECT(_window), "help-topic", (gpointer)help_topic);
299
300 if (close_button_func != NULL)
301 {
302 GtkWidget *button_close = get_widget("dialog_button_close");
303 g_assert(GTK_IS_BUTTON(button_close));
304
305 g_signal_connect(G_OBJECT(button_close), "clicked",
306 G_CALLBACK(cmd_exec_sf),
307 (gpointer)close_button_func);
308
309 GTK_WIDGET_SET_FLAGS(button_close, GTK_CAN_DEFAULT);
310 gtk_widget_grab_default(button_close);
311 }
312
313 if (help_topic != NULL)
314 {
315 GtkWidget *button_help = get_widget("dialog_button_help");
316 g_assert(GTK_IS_BUTTON(button_help));
317
318 g_object_set_data(G_OBJECT(button_help), "help-topic", (gpointer)help_topic);
319
320 g_signal_connect(G_OBJECT(button_help), "clicked", G_CALLBACK(sf_help), (gpointer)this);
321 }
322
323 GtkWidget *header_label = get_widget("header_label");
324 g_assert(GTK_IS_LABEL(header_label));
325
326 PangoFontDescription *font_desc = pango_font_description_from_string("Sans 16");
327 gtk_widget_modify_font(header_label, font_desc);
328 pango_font_description_free(font_desc);
329 }
330