Style browser now lists theme buttons.
[irreco.git] / irreco / trunk / src / core / irreco_button_browser_widget.c
blob55c029d47277cbeb8b1056850e25a6739d94edbd
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2008 Joni Kokko (t5kojo01@students.oamk.fi),
4 * Harri Vattulainen (t5vaha01@students.oamk.fi)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "irreco_button_browser_widget.h"
22 #include <hildon/hildon-banner.h>
24 G_DEFINE_TYPE (IrrecoButtonBrowserWidget, irreco_button_browser_widget, GTK_TYPE_VBOX)
26 /**
27 * @addtogroup IrrecoButtonBrowserWidget
29 * This widget helps selection of background.
31 * This widget allows background selection from themes
32 * @{
35 /**
36 * @file
37 * Source file of @ref IrrecoButtonBrowserWidget.
40 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
41 /* Prototypes */
42 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
44 static gboolean irreco_button_browser_widget_populate_themes(
45 IrrecoButtonBrowserWidget *self);
47 static gboolean irreco_button_browser_widget_loader_images(
48 IrrecoButtonBrowserWidget *self);
50 static void irreco_button_browser_widget_loader_start(IrrecoButtonBrowserWidget *self,
51 GSourceFunc function,
52 GtkTreeIter *parent_iter);
54 static void irreco_button_browser_widget_destroy_event(IrrecoButtonBrowserWidget *self,
55 gpointer user_data);
57 static void irreco_button_browser_widget_theme_selection_changed(
58 GtkTreeSelection * selection,
59 IrrecoButtonBrowserWidget *self);
61 static void irreco_button_browser_widget_image_selection_changed(
62 GtkTreeSelection * selection,
63 IrrecoButtonBrowserWidget *self);
65 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
66 /* Datatypes */
67 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
69 /** Loader states. */
70 enum
72 LOADER_STATE_INIT,
73 LOADER_STATE_LOOP,
74 LOADER_STATE_END,
75 LOADER_STATE_CLEANUP
78 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
79 /* Construction & Destruction */
80 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
82 /**
83 * @name Construction & Destruction
84 * @{
87 static void irreco_button_browser_widget_finalize (GObject *object)
89 IRRECO_ENTER
91 if (G_OBJECT_CLASS(irreco_button_browser_widget_parent_class)->finalize)
92 G_OBJECT_CLASS(irreco_button_browser_widget_parent_class)->finalize (object);
94 IRRECO_RETURN
97 static void irreco_button_browser_widget_class_init(IrrecoButtonBrowserWidgetClass *klass)
99 GObjectClass *object_class;
100 IRRECO_ENTER
102 object_class = G_OBJECT_CLASS (klass);
103 object_class->finalize = irreco_button_browser_widget_finalize;
105 IRRECO_RETURN
108 static void irreco_button_browser_widget_init (IrrecoButtonBrowserWidget *self)
110 GtkWidget *frame_for_themes;
111 GtkWidget *frame_for_images;
112 IRRECO_ENTER
114 self->current_theme = g_string_new("");
115 self->current_image = NULL;
117 /* Create themes */
119 /* Create Frame for Themes */
120 frame_for_themes = gtk_frame_new("");
121 gtk_frame_set_label_widget(GTK_FRAME(frame_for_themes),
122 irreco_gtk_label_bold("Themes", 0, 0, 0, 0, 0, 0));
124 /* Create list of themes */
125 self->themes = IRRECO_LISTBOX_TEXT(
126 irreco_listbox_text_new_with_autosize(200, 200,
127 200, 200));
128 gtk_container_add(GTK_CONTAINER(frame_for_themes),
129 GTK_WIDGET(self->themes));
131 /* Create Images */
133 /* Create frame for Images */
134 frame_for_images = gtk_frame_new("");
135 gtk_frame_set_label_widget(GTK_FRAME(frame_for_images),
136 irreco_gtk_label_bold("Images", 0, 0, 0, 0, 0, 0));
138 /* Create list of images */
139 self->images = IRRECO_LISTBOX_IMAGE(
140 irreco_listbox_image_new_with_autosize(400, 400,
141 200, 200));
142 irreco_listbox_set_select_new_rows(IRRECO_LISTBOX(self->images), FALSE);
143 gtk_container_add(GTK_CONTAINER(frame_for_images),
144 GTK_WIDGET(self->images));
146 /* Signal handlers. */
147 g_signal_connect(G_OBJECT(self), "destroy",
148 G_CALLBACK(irreco_button_browser_widget_destroy_event), NULL);
150 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(self->themes)->tree_selection),
151 "changed",
152 G_CALLBACK(irreco_button_browser_widget_theme_selection_changed),
153 self);
155 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(self->images)->tree_selection),
156 "changed",
157 G_CALLBACK(irreco_button_browser_widget_image_selection_changed),
158 self);
160 /* Create hbox */
161 self->hbox = g_object_new(GTK_TYPE_HBOX, NULL);
162 gtk_box_set_spacing(GTK_BOX(self->hbox), 8);
164 gtk_box_pack_start(GTK_BOX(self->hbox), GTK_WIDGET(frame_for_themes),
165 TRUE, TRUE, 0);
167 gtk_box_pack_start(GTK_BOX(self->hbox), GTK_WIDGET(frame_for_images),
168 TRUE, TRUE, 0);
170 gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(self->hbox),
171 FALSE, TRUE, 0);
173 IRRECO_RETURN
176 IrrecoButtonBrowserWidget *irreco_button_browser_widget_new(IrrecoData *irreco_data)
178 IrrecoButtonBrowserWidget *self;
179 IrrecoStringTable *themes = irreco_data->theme_manager->themes;
180 IRRECO_ENTER
182 self = IRRECO_BUTTON_BROWSER_WIDGET(
183 g_object_new (IRRECO_TYPE_BUTTON_BROWSER_WIDGET, NULL));
185 self->irreco_data = irreco_data;
187 if (irreco_string_table_lenght(themes) > 0) {
189 const gchar *theme_name;
190 irreco_button_browser_widget_populate_themes(self);
191 irreco_listbox_set_selection(IRRECO_LISTBOX(self->themes), 0);
193 irreco_string_table_index(themes, 0, &theme_name, NULL);
195 g_string_printf(self->current_theme, "%s", theme_name);
196 /*g_print("\nteemaaa: %s\n", theme_name);*/
198 irreco_button_browser_widget_loader_start(self,
199 G_SOURCEFUNC(irreco_button_browser_widget_loader_images), NULL);
200 /*g_free(theme_name);*/
203 IRRECO_RETURN_PTR(GTK_WIDGET(self));
206 /** @} */
208 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
209 /* Private Functions */
210 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
212 * @name Private Functions
213 * @{
217 * Show hildon progressbar banner.
219 * This function will create a new banner if one has not been created yet,
220 * if banner already exists, it's properties will be changed.
222 * @param text Text to show.
223 * @param fraction Value of progress.
225 static void irreco_button_browser_widget_set_banner(IrrecoButtonBrowserWidget *self,
226 const gchar *text,
227 gdouble fraction)
229 IRRECO_ENTER
230 if (self->banner == NULL) {
231 self->banner = hildon_banner_show_progress(
232 GTK_WIDGET(self), NULL, "");
235 hildon_banner_set_text(HILDON_BANNER(self->banner), text);
236 hildon_banner_set_fraction(HILDON_BANNER(self->banner), fraction);
237 IRRECO_RETURN
241 * Destroy banner, if it exists.
243 static void irreco_button_browser_widget_hide_banner(IrrecoButtonBrowserWidget *self)
245 IRRECO_ENTER
246 if (self->banner) {
247 gtk_widget_destroy(self->banner);
248 self->banner = NULL;
250 IRRECO_RETURN
254 * Start a loader state machine if one is not running already.
256 static void irreco_button_browser_widget_loader_start(IrrecoButtonBrowserWidget *self,
257 GSourceFunc function,
258 GtkTreeIter *parent_iter)
260 IRRECO_ENTER
262 if (self->loader_func_id == 0) {
263 #if 0
264 if (parent_iter) {
265 self->loader_parent_iter = gtk_tree_iter_copy(
266 parent_iter);
268 #endif
270 if (function) {
271 self->loader_func_id = g_idle_add(function, self);
272 } else {
273 IRRECO_ERROR("Loader function pointer not given.\n");
277 IRRECO_RETURN
281 * Stop and cleanup loader if a loader is running.
283 static void irreco_button_browser_widget_loader_stop(IrrecoButtonBrowserWidget *self)
285 IRRECO_ENTER
286 if (self->loader_func_id != 0) {
287 g_source_remove(self->loader_func_id);
288 self->loader_func_id = 0;
289 self->loader_state = 0;
290 #if 0
291 if (self->loader_parent_iter) {
292 gtk_tree_iter_free(self->loader_parent_iter);
294 self->loader_parent_iter = NULL;
295 #endif
297 IRRECO_RETURN
301 * Theme loader.
303 * This loader will request a list of themes from the IrrecoThemeManager and
304 * update the TreeView accordingly.
307 static gboolean irreco_button_browser_widget_populate_themes(
308 IrrecoButtonBrowserWidget *self)
310 IrrecoStringTable *themes = NULL;
311 IrrecoThemeManager *theme_manager = self->irreco_data->theme_manager;
312 IRRECO_ENTER
314 themes = irreco_theme_manager_get_themes(theme_manager);
316 if (themes != NULL) {
317 IRRECO_STRING_TABLE_FOREACH_KEY(themes, key)
318 irreco_listbox_text_append(self->themes, key, NULL);
319 IRRECO_STRING_TABLE_FOREACH_END
320 } else {
321 irreco_error_dlg(GTK_WINDOW(self),
322 "There's no themes installed");
325 IRRECO_RETURN_BOOL(TRUE);
329 * Background-image loader.
331 * This loader will request a list of background-images from the
332 * IrrecoThemeManager and update the TreeView accordingly.
334 static gboolean irreco_button_browser_widget_loader_images(
335 IrrecoButtonBrowserWidget *self)
337 IRRECO_ENTER
339 switch (self->loader_state) {
340 case LOADER_STATE_INIT:
341 irreco_button_browser_widget_set_banner(self, _("Loading ..."), 0);
342 self->loader_state = LOADER_STATE_LOOP;
343 self->loader_index = 0;
344 irreco_listbox_clear(IRRECO_LISTBOX(self->images));
345 IRRECO_RETURN_BOOL(TRUE);
347 case LOADER_STATE_LOOP: {
348 gint theme_button_count;
349 gfloat banner;
350 const gchar *image_name;
351 IrrecoThemeManager *manager = self->irreco_data->theme_manager;
352 IrrecoTheme *theme;
354 irreco_string_table_get(manager->themes,
355 self->current_theme->str,
356 (gpointer *) &theme);
358 theme_button_count = irreco_string_table_lenght(theme->buttons);
359 /*theme_button_count = irreco_string_table_lenght(self->irreco_data->button_style_array);*/
361 if (theme_button_count > 0) {
362 IrrecoThemeButton *button_image;
363 irreco_string_table_index(theme->buttons,
364 self->loader_index,
365 &image_name,
366 (gpointer *) &button_image);
368 irreco_listbox_image_append(self->images,
369 button_image->name->str,
370 button_image,
371 button_image->image_up->str);
372 } else {
373 /*irreco_listbox_image_append(self->images,
374 "Empty imagelist",
375 NULL, "");*/
376 self->current_image = NULL;
377 theme_button_count = 1;
380 self->loader_index++;
381 banner = (gfloat)self->loader_index / (gfloat)theme_button_count;
382 irreco_button_browser_widget_set_banner(self, _("Loading ..."),
383 banner);
385 if(self->loader_index >= theme_button_count) {
386 self->loader_state = LOADER_STATE_END;
389 IRRECO_RETURN_BOOL(TRUE);
392 case LOADER_STATE_END:
393 irreco_button_browser_widget_hide_banner(self);
394 irreco_button_browser_widget_loader_stop(self);
397 IRRECO_RETURN_BOOL(FALSE);
400 /** @} */
402 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
403 /* Public Functions */
404 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
407 * @name Public Functions
408 * @{
411 /* Add functions here. */
413 /** @} */
415 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
416 /* Events and Callbacks */
417 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
420 * @name Events and Callbacks
421 * @{
424 static void irreco_button_browser_widget_destroy_event(IrrecoButtonBrowserWidget *self,
425 gpointer user_data)
427 IRRECO_ENTER
428 irreco_button_browser_widget_loader_stop(self);
429 IRRECO_RETURN
432 static void irreco_button_browser_widget_theme_selection_changed(
433 GtkTreeSelection *selection,
434 IrrecoButtonBrowserWidget *self)
436 gint sel_index = -1;
437 gchar *sel_label = NULL;
438 gpointer sel_user_data = NULL;
439 IRRECO_ENTER
441 if (self->loader_func_id != 0) {
442 irreco_button_browser_widget_loader_stop(self);
445 irreco_listbox_get_selection(IRRECO_LISTBOX(self->themes),
446 &sel_index, &sel_label, &sel_user_data);
448 g_string_printf(self->current_theme, "%s", sel_label);
450 irreco_button_browser_widget_loader_start(self,
451 G_SOURCEFUNC(irreco_button_browser_widget_loader_images), NULL);
453 g_free(sel_label);
454 IRRECO_RETURN
457 static void irreco_button_browser_widget_image_selection_changed(
458 GtkTreeSelection *selection,
459 IrrecoButtonBrowserWidget *self)
461 gint sel_index = -1;
462 gchar *sel_label = NULL;
463 IrrecoThemeButton *button = NULL;
464 IRRECO_ENTER
466 if (irreco_listbox_get_selection(IRRECO_LISTBOX(self->images),
467 &sel_index, &sel_label, (gpointer *)&button)) {
468 self->current_image = button;
469 } else {
470 self->current_image = NULL;
473 g_free(sel_label);
474 IRRECO_RETURN
477 /** @} */
479 /** @} */