1 /*****************************************************************
2 * gmerlin - a general purpose multimedia framework and applications
3 *
4 * Copyright (c) 2001 - 2011 Members of the Gmerlin project
5 * gmerlin-general@lists.sourceforge.net
6 * http://gmerlin.sourceforge.net
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * *****************************************************************/
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <gtk/gtk.h>
25
26 #include <gmerlin/tree.h>
27 #include <gmerlin/utils.h>
28
29 #include <gui_gtk/tree.h>
30 #include <gui_gtk/gtkutils.h>
31
32 /* This is missing in the gtk headers */
33
34 extern void
35 gtk_decorated_window_move_resize_window(GtkWindow*, int, int, int, int);
36
37 struct bg_gtk_album_window_s
38 {
39 bg_gtk_album_widget_t * widget;
40 bg_gtk_tree_widget_t * tree_widget;
41 GtkWidget * window;
42
43 int x, y, width, height;
44
45 bg_cfg_section_t * cfg_section;
46
47 /* Notebook stuff */
48
49 GtkWidget * tab_close_button;
50 GtkWidget * tab_label;
51 GtkWidget * tab_widget;
52
53 GtkWidget * notebook;
54 int name_len;
55 GtkAccelGroup * accel_group;
56 };
57
58 /* Configuration stuff */
59
60 static const bg_parameter_info_t parameters[] =
61 {
62 {
63 .name = "x",
64 .long_name = "X",
65 .type = BG_PARAMETER_INT,
66 .val_default = { .val_i = 100 }
67 },
68 {
69 .name = "y",
70 .long_name = "Y",
71 .type = BG_PARAMETER_INT,
72 .val_default = { .val_i = 100 }
73 },
74 {
75 .name = "width",
76 .long_name = "Width",
77 .type = BG_PARAMETER_INT,
78 .val_default = { .val_i = 200 }
79 },
80 {
81 .name = "height",
82 .long_name = "Height",
83 .type = BG_PARAMETER_INT,
84 .val_default = { .val_i = 300 }
85 },
86 { /* End of parameters */ }
87 };
88
set_parameter(void * data,const char * name,const bg_parameter_value_t * val)89 static void set_parameter(void * data, const char * name,
90 const bg_parameter_value_t * val)
91 {
92 bg_gtk_album_window_t * win;
93 win = (bg_gtk_album_window_t*)data;
94 if(!name)
95 return;
96 else if(!strcmp(name, "x"))
97 {
98 win->x = val->val_i;
99 }
100 else if(!strcmp(name, "y"))
101 {
102 win->y = val->val_i;
103 }
104 else if(!strcmp(name, "width"))
105 {
106 win->width = val->val_i;
107 }
108 else if(!strcmp(name, "height"))
109 {
110 win->height = val->val_i;
111 }
112 }
113
get_parameter(void * data,const char * name,bg_parameter_value_t * val)114 static int get_parameter(void * data, const char * name,
115 bg_parameter_value_t * val)
116 {
117 bg_gtk_album_window_t * win;
118 win = (bg_gtk_album_window_t*)data;
119 if(!name)
120 return 1;
121 else if(!strcmp(name, "x"))
122 {
123 val->val_i = win->x;
124 return 1;
125 }
126 else if(!strcmp(name, "y"))
127 {
128 val->val_i = win->y;
129 return 1;
130 }
131 else if(!strcmp(name, "width"))
132 {
133 val->val_i = win->width;
134 return 1;
135 }
136 else if(!strcmp(name, "height"))
137 {
138 val->val_i = win->height;
139 return 1;
140 }
141 return 0;
142 }
143
delete_callback(GtkWidget * w,GdkEventAny * event,gpointer data)144 static gboolean delete_callback(GtkWidget * w, GdkEventAny * event,
145 gpointer data)
146 {
147 bg_gtk_album_window_t * win;
148 win = (bg_gtk_album_window_t*)data;
149 bg_gtk_album_window_destroy(win, 1);
150 return TRUE;
151 }
152
close_callback(GtkWidget * w,gpointer data)153 static void close_callback(GtkWidget * w, gpointer data)
154 {
155 bg_gtk_album_window_t * win;
156 win = (bg_gtk_album_window_t*)data;
157 bg_gtk_album_window_destroy(win, 1);
158 }
159
widget_close_callback(bg_gtk_album_widget_t * w,gpointer data)160 static void widget_close_callback(bg_gtk_album_widget_t * w, gpointer data)
161 {
162 bg_gtk_album_window_t * win;
163 win = (bg_gtk_album_window_t*)data;
164 bg_gtk_album_window_destroy(win, 1);
165 }
166
167
name_change_callback(bg_album_t * a,const char * name,void * data)168 static void name_change_callback(bg_album_t * a,
169 const char * name,
170 void * data)
171 {
172 bg_gtk_album_window_t * win = (bg_gtk_album_window_t *)data;
173 win->name_len = strlen(name);
174 if(win->notebook)
175 {
176 gtk_label_set_text(GTK_LABEL(win->tab_label), name);
177 }
178 else if(win->window)
179 {
180 gtk_window_set_title(GTK_WINDOW(win->window), name);
181 }
182 }
183
184 bg_gtk_album_window_t *
bg_gtk_album_window_create(bg_album_t * album,bg_gtk_tree_widget_t * tree_widget,GtkAccelGroup * accel_group)185 bg_gtk_album_window_create(bg_album_t * album,
186 bg_gtk_tree_widget_t * tree_widget, GtkAccelGroup * accel_group)
187 {
188
189 bg_gtk_album_window_t * ret;
190 ret = calloc(1, sizeof(*ret));
191 ret->tree_widget = tree_widget;
192
193 ret->accel_group = accel_group;
194
195 bg_album_set_name_change_callback(album, name_change_callback, ret);
196
197 ret->widget = bg_gtk_album_widget_create(album, ret->window);
198 bg_gtk_album_widget_set_close_callback(ret->widget,
199 widget_close_callback,
200 ret);
201
202
203 g_object_ref(G_OBJECT(bg_gtk_album_widget_get_widget(ret->widget)));
204
205 /* Set config stuff */
206
207 ret->cfg_section =
208 bg_cfg_section_find_subsection(bg_album_get_cfg_section(album), "gtk_albumwindow");
209
210 bg_cfg_section_apply(ret->cfg_section, parameters, set_parameter, ret);
211
212 return ret;
213 }
214
bg_gtk_album_window_destroy(bg_gtk_album_window_t * w,int notify)215 void bg_gtk_album_window_destroy(bg_gtk_album_window_t * w, int notify)
216 {
217 int page_num;
218
219 /* Get the window coordinates */
220
221 if(w->window && w->window->window)
222 {
223 gdk_window_get_geometry(w->window->window,
224 NULL, NULL, &w->width, &w->height,
225 NULL);
226
227 gdk_window_get_root_origin(w->window->window, &w->x, &w->y);
228
229 bg_cfg_section_get(w->cfg_section, parameters, get_parameter, w);
230 }
231
232 bg_gtk_album_widget_put_config(w->widget);
233
234 if(w->tree_widget && notify)
235 {
236 bg_gtk_tree_widget_close_album(w->tree_widget, w);
237 }
238 if(w->window)
239 gtk_widget_destroy(w->window);
240
241 if(w->notebook)
242 {
243 page_num = gtk_notebook_page_num(GTK_NOTEBOOK(w->notebook), bg_gtk_album_widget_get_widget(w->widget));
244 gtk_notebook_remove_page(GTK_NOTEBOOK(w->notebook), page_num);
245 }
246
247 if(w->widget)
248 {
249 bg_album_set_name_change_callback(bg_gtk_album_widget_get_album(w->widget),
250 NULL, NULL);
251
252 g_object_unref(G_OBJECT(bg_gtk_album_widget_get_widget(w->widget)));
253 bg_gtk_album_widget_destroy(w->widget);
254 }
255 free(w);
256 }
257
bg_gtk_album_window_get_album(bg_gtk_album_window_t * w)258 bg_album_t * bg_gtk_album_window_get_album(bg_gtk_album_window_t*w)
259 {
260 return bg_gtk_album_widget_get_album(w->widget);
261 }
262
bg_gtk_album_window_raise(bg_gtk_album_window_t * w)263 void bg_gtk_album_window_raise(bg_gtk_album_window_t* w)
264 {
265 int page_num;
266
267 if(w->window && w->window->window)
268 gtk_window_present(GTK_WINDOW(w->window));
269
270 else if(w->notebook)
271 {
272 page_num = gtk_notebook_page_num(GTK_NOTEBOOK(w->notebook), bg_gtk_album_widget_get_widget(w->widget));
273 gtk_notebook_set_current_page(GTK_NOTEBOOK(w->notebook), page_num);
274
275 }
276 }
277
278
279
create_close_button(bg_gtk_album_window_t * w)280 static GtkWidget * create_close_button(bg_gtk_album_window_t * w)
281 {
282 GtkWidget * button;
283 GtkWidget * image;
284 char * path;
285 path = bg_search_file_read("icons", "tab_close.png");
286 if(path)
287 {
288 image = gtk_image_new_from_file(path);
289 free(path);
290 }
291 else
292 image = gtk_image_new();
293
294 gtk_widget_show(image);
295 button = gtk_button_new();
296 gtk_container_add(GTK_CONTAINER(button), image);
297
298 g_signal_connect(G_OBJECT(button), "clicked",
299 G_CALLBACK(close_callback), w);
300
301 gtk_widget_show(button);
302 return button;
303 }
304
305
bg_gtk_album_window_attach(bg_gtk_album_window_t * w,GtkWidget * notebook)306 void bg_gtk_album_window_attach(bg_gtk_album_window_t * w, GtkWidget * notebook)
307 {
308 const char * name;
309 int page_num;
310
311 bg_album_t * album;
312
313 /* Remove widget from container and delete window */
314
315 if(w->window)
316 {
317 gtk_container_remove(GTK_CONTAINER(w->window), bg_gtk_album_widget_get_widget(w->widget));
318 gtk_widget_destroy(w->window);
319 w->window = NULL;
320 }
321 /* Attach stuff to notebook */
322
323 album = bg_gtk_album_widget_get_album(w->widget);
324
325 name = bg_album_get_label(album);
326
327 w->tab_label = gtk_label_new(name);
328 w->name_len = strlen(name);
329
330 gtk_widget_show(w->tab_label);
331
332 w->tab_close_button = create_close_button(w);
333 w->tab_widget = gtk_hbox_new(0, 2);
334 bg_gtk_box_pack_start_defaults(GTK_BOX(w->tab_widget), w->tab_label);
335 gtk_box_pack_start(GTK_BOX(w->tab_widget), w->tab_close_button, FALSE, FALSE, 0);
336 gtk_widget_show(w->tab_widget);
337
338 page_num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
339 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), bg_gtk_album_widget_get_widget(w->widget),
340 w->tab_widget);
341 gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), page_num);
342
343 #if 0
344 #if GTK_CHECK_VERSION(2,20,0)
345 g_object_set(notebook, "tab-fill", FALSE, NULL);
346 #else
347 gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(notebook),
348 bg_gtk_album_widget_get_widget(w->widget),
349 FALSE, FALSE, GTK_PACK_START);
350 #endif
351 #endif
352 gtk_notebook_set_menu_label_text(GTK_NOTEBOOK(notebook),
353 bg_gtk_album_widget_get_widget(w->widget),
354 bg_album_get_label(album));
355
356
357 w->notebook = notebook;
358 if(bg_album_is_current(album))
359 bg_gtk_album_window_set_current(w, 1);
360 }
361
bg_gtk_album_window_detach(bg_gtk_album_window_t * w)362 void bg_gtk_album_window_detach(bg_gtk_album_window_t * w)
363 {
364 int page_num;
365 bg_album_t * album;
366
367 album = bg_gtk_album_widget_get_album(w->widget);
368
369 if(w->notebook)
370 {
371 page_num = gtk_notebook_page_num(GTK_NOTEBOOK(w->notebook), bg_gtk_album_widget_get_widget(w->widget));
372 gtk_notebook_remove_page(GTK_NOTEBOOK(w->notebook), page_num);
373 w->notebook = NULL;
374 }
375
376 w->window = bg_gtk_window_new(GTK_WINDOW_TOPLEVEL);
377 gtk_window_add_accel_group(GTK_WINDOW (w->window), w->accel_group);
378 gtk_window_add_accel_group(GTK_WINDOW (w->window), bg_gtk_album_widget_get_accel_group(w->widget));
379
380 g_signal_connect(G_OBJECT(w->window), "delete-event",
381 G_CALLBACK(delete_callback),
382 w);
383 gtk_window_set_title(GTK_WINDOW(w->window), bg_album_get_label(album));
384
385 gtk_container_add(GTK_CONTAINER(w->window),
386 bg_gtk_album_widget_get_widget(w->widget));
387
388 gtk_widget_show(w->window);
389
390 gtk_decorated_window_move_resize_window(GTK_WINDOW(w->window),
391 w->x, w->y, w->width, w->height);
392
393 }
394
bg_gtk_album_window_set_current(bg_gtk_album_window_t * w,int current)395 void bg_gtk_album_window_set_current(bg_gtk_album_window_t * w, int current)
396 {
397 PangoAttribute *attr;
398 PangoAttrList *attr_list;
399
400
401 if(!w->notebook)
402 return;
403 attr_list = pango_attr_list_new();
404 attr = pango_attr_weight_new(current ? PANGO_WEIGHT_BOLD: PANGO_WEIGHT_NORMAL);
405 attr->start_index = 0;
406 attr->end_index = w->name_len;
407
408 pango_attr_list_insert(attr_list,attr);
409 gtk_label_set_attributes(GTK_LABEL(w->tab_label), attr_list);
410 pango_attr_list_unref(attr_list);
411 }
412
bg_gtk_album_window_goto_current(bg_gtk_album_window_t * w)413 void bg_gtk_album_window_goto_current(bg_gtk_album_window_t * w)
414 {
415 bg_gtk_album_window_raise(w);
416 bg_gtk_album_widget_goto_current(w->widget);
417 }
418
bg_gtk_album_window_get_accel_group(bg_gtk_album_window_t * w)419 GtkAccelGroup * bg_gtk_album_window_get_accel_group(bg_gtk_album_window_t * w)
420 {
421 return bg_gtk_album_widget_get_accel_group(w->widget);
422 }
423