Some documenting thingies.
[irreco.git] / irreco / trunk / src / core / irreco_bg_browser_widget.c
blobb4f00740356ae76d9884d94fd65d095c8de04346
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2008 Joni Kokko (t5kojo01@students.oamk.fi)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "irreco_bg_browser_widget.h"
21 #include <hildon/hildon-banner.h>
23 G_DEFINE_TYPE (IrrecoBgBrowserWidget, irreco_bg_browser_widget, GTK_TYPE_VBOX)
25 /**
26 * @addtogroup IrrecoBgBrowserWidget
28 * This widget helps selection of background.
30 * This widget allows background selection from themes
31 * @{
34 /**
35 * @file
36 * Source file of @ref IrrecoBgBrowserWidget.
39 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
40 /* Prototypes */
41 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
43 static gboolean irreco_bg_browser_widget_populate_themes(
44 IrrecoBgBrowserWidget *self);
46 static gboolean irreco_bg_browser_widget_loader_images(
47 IrrecoBgBrowserWidget *self);
49 static void irreco_bg_browser_widget_loader_start(IrrecoBgBrowserWidget *self,
50 GSourceFunc function,
51 GtkTreeIter *parent_iter);
53 static void irreco_bg_browser_widget_destroy_event(IrrecoBgBrowserWidget *self,
54 gpointer user_data);
56 static void irreco_bg_browser_widget_theme_selection_changed(
57 GtkTreeSelection * selection,
58 IrrecoBgBrowserWidget *self);
60 static void irreco_bg_browser_widget_image_selection_changed(
61 GtkTreeSelection * selection,
62 IrrecoBgBrowserWidget *self);
64 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
65 /* Datatypes */
66 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
68 /** Loader states. */
69 enum
71 LOADER_STATE_INIT,
72 LOADER_STATE_LOOP,
73 LOADER_STATE_END,
74 LOADER_STATE_CLEANUP
77 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
78 /* Construction & Destruction */
79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
81 /**
82 * @name Construction & Destruction
83 * @{
86 static void irreco_bg_browser_widget_finalize (GObject *object)
88 IRRECO_ENTER
90 if (G_OBJECT_CLASS(irreco_bg_browser_widget_parent_class)->finalize)
91 G_OBJECT_CLASS(irreco_bg_browser_widget_parent_class)->finalize (object);
93 IRRECO_RETURN
96 static void irreco_bg_browser_widget_class_init(IrrecoBgBrowserWidgetClass *klass)
98 GObjectClass *object_class;
99 IRRECO_ENTER
101 object_class = G_OBJECT_CLASS (klass);
102 object_class->finalize = irreco_bg_browser_widget_finalize;
104 IRRECO_RETURN
107 static void irreco_bg_browser_widget_init (IrrecoBgBrowserWidget *self)
109 GtkWidget *frame_for_themes;
110 GtkWidget *frame_for_images;
111 GtkWidget *hbox = gtk_hbox_new(0, 8);
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_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(self->images),
144 TRUE, TRUE, 0);
146 /* Create error text */
147 self->error_text = gtk_label_new(
148 "This theme does\nnot contain any\nbackground images");
149 gtk_misc_set_alignment(GTK_MISC(self->error_text), 0, 0);
151 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(self->error_text),
152 TRUE, TRUE, 0);
154 gtk_container_add(GTK_CONTAINER(frame_for_images), GTK_WIDGET(hbox));
156 /* Signal handlers. */
157 g_signal_connect(G_OBJECT(self), "destroy",
158 G_CALLBACK(irreco_bg_browser_widget_destroy_event), NULL);
160 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(self->themes)->tree_selection),
161 "changed",
162 G_CALLBACK(irreco_bg_browser_widget_theme_selection_changed),
163 self);
165 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(self->images)->tree_selection),
166 "changed",
167 G_CALLBACK(irreco_bg_browser_widget_image_selection_changed),
168 self);
170 /* Create hbox */
171 self->hbox = g_object_new(GTK_TYPE_HBOX, NULL);
172 gtk_box_set_spacing(GTK_BOX(self->hbox), 8);
174 gtk_box_pack_start(GTK_BOX(self->hbox), GTK_WIDGET(frame_for_themes),
175 TRUE, TRUE, 0);
177 gtk_box_pack_start(GTK_BOX(self->hbox), GTK_WIDGET(frame_for_images),
178 TRUE, TRUE, 0);
180 gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(self->hbox),
181 FALSE, TRUE, 0);
183 IRRECO_RETURN
186 IrrecoBgBrowserWidget *irreco_bg_browser_widget_new(IrrecoData *irreco_data)
188 IrrecoBgBrowserWidget *self;
189 IrrecoStringTable *themes = irreco_data->theme_manager->themes;
190 IRRECO_ENTER
192 self = IRRECO_BG_BROWSER_WIDGET(
193 g_object_new (IRRECO_TYPE_BG_BROWSER_WIDGET, NULL));
195 self->irreco_data = irreco_data;
197 if (irreco_string_table_lenght(themes) > 0) {
199 const gchar *theme_name;
200 irreco_bg_browser_widget_populate_themes(self);
201 irreco_listbox_set_selection(IRRECO_LISTBOX(self->themes), 0);
203 irreco_string_table_index(themes, 0, &theme_name, NULL);
205 g_string_printf(self->current_theme, "%s", theme_name);
207 irreco_bg_browser_widget_loader_start(self,
208 G_SOURCEFUNC(irreco_bg_browser_widget_loader_images), NULL);
209 /*g_free(theme_name);*/
212 IRRECO_RETURN_PTR(GTK_WIDGET(self));
215 /** @} */
217 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
218 /* Private Functions */
219 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
221 * @name Private Functions
222 * @{
226 * Show hildon progressbar banner.
228 * This function will create a new banner if one has not been created yet,
229 * if banner already exists, it's properties will be changed.
231 * @param text Text to show.
232 * @param fraction Value of progress.
234 static void irreco_bg_browser_widget_set_banner(IrrecoBgBrowserWidget *self,
235 const gchar *text,
236 gdouble fraction)
238 IRRECO_ENTER
239 if (self->banner == NULL) {
240 self->banner = hildon_banner_show_progress(
241 GTK_WIDGET(self), NULL, "");
244 hildon_banner_set_text(HILDON_BANNER(self->banner), text);
245 hildon_banner_set_fraction(HILDON_BANNER(self->banner), fraction);
246 IRRECO_RETURN
250 * Destroy banner, if it exists.
252 static void irreco_bg_browser_widget_hide_banner(IrrecoBgBrowserWidget *self)
254 IRRECO_ENTER
255 if (self->banner) {
256 gtk_widget_destroy(self->banner);
257 self->banner = NULL;
259 IRRECO_RETURN
263 * Start a loader state machine if one is not running already.
265 static void irreco_bg_browser_widget_loader_start(IrrecoBgBrowserWidget *self,
266 GSourceFunc function,
267 GtkTreeIter *parent_iter)
269 IRRECO_ENTER
271 if (self->loader_func_id == 0) {
272 if (function) {
273 self->loader_func_id = g_idle_add(function, self);
274 } else {
275 IRRECO_ERROR("Loader function pointer not given.\n");
279 IRRECO_RETURN
283 * Stop and cleanup loader if a loader is running.
285 static void irreco_bg_browser_widget_loader_stop(IrrecoBgBrowserWidget *self)
287 IRRECO_ENTER
288 if (self->loader_func_id != 0) {
289 g_source_remove(self->loader_func_id);
290 self->loader_func_id = 0;
291 self->loader_state = 0;
293 IRRECO_RETURN
297 * Theme loader.
299 * This loader will request a list of themes from the IrrecoThemeManager and
300 * update the TreeView accordingly.
303 static gboolean irreco_bg_browser_widget_populate_themes(
304 IrrecoBgBrowserWidget *self)
306 IrrecoStringTable *themes = NULL;
307 IrrecoThemeManager *theme_manager = self->irreco_data->theme_manager;
308 IRRECO_ENTER
310 themes = irreco_theme_manager_get_themes(theme_manager);
312 if (themes != NULL) {
313 IRRECO_STRING_TABLE_FOREACH_KEY(themes, key)
314 irreco_listbox_text_append(self->themes, key, NULL);
315 IRRECO_STRING_TABLE_FOREACH_END
316 } else {
317 irreco_error_dlg(GTK_WINDOW(self),
318 "There's no themes installed");
321 IRRECO_RETURN_BOOL(TRUE);
325 * Background-image loader.
327 * This loader will request a list of background-images from the
328 * IrrecoThemeManager and update the TreeView accordingly.
330 static gboolean irreco_bg_browser_widget_loader_images(
331 IrrecoBgBrowserWidget *self)
333 IRRECO_ENTER
335 switch (self->loader_state) {
336 case LOADER_STATE_INIT:
337 irreco_bg_browser_widget_set_banner(self, _("Loading ..."), 0);
338 self->loader_state = LOADER_STATE_LOOP;
339 self->loader_index = 0;
340 irreco_listbox_clear(IRRECO_LISTBOX(self->images));
341 IRRECO_RETURN_BOOL(TRUE);
343 case LOADER_STATE_LOOP: {
344 gint theme_bg_count;
345 gfloat banner;
346 const gchar *image_name;
347 IrrecoThemeManager *manager = self->irreco_data->theme_manager;
348 IrrecoTheme *theme;
350 irreco_string_table_get(manager->themes,
351 self->current_theme->str,
352 (gpointer *) &theme);
354 theme_bg_count = irreco_string_table_lenght(theme->backgrounds);
356 if (theme_bg_count > 0) {
357 IrrecoThemeBg *background_image;
358 gtk_widget_show(GTK_WIDGET(self->images));
359 gtk_widget_hide(GTK_WIDGET(self->error_text));
360 irreco_string_table_index(theme->backgrounds,
361 self->loader_index,
362 &image_name,
363 (gpointer *) &background_image);
365 irreco_listbox_image_append_with_size(self->images,
366 background_image->image_name->str,
367 background_image,
368 background_image->image_path->str,
369 IRRECO_SCREEN_WIDTH / 6,
370 IRRECO_SCREEN_HEIGHT / 6);
371 } else {
372 gtk_widget_show(GTK_WIDGET(self->error_text));
373 gtk_widget_hide(GTK_WIDGET(self->images));
374 self->current_image = NULL;
375 theme_bg_count = 1;
378 self->loader_index++;
379 banner = (gfloat)self->loader_index / (gfloat)theme_bg_count;
380 irreco_bg_browser_widget_set_banner(self, _("Loading ..."),
381 banner);
383 if(self->loader_index >= theme_bg_count) {
384 self->loader_state = LOADER_STATE_END;
387 IRRECO_RETURN_BOOL(TRUE);
390 case LOADER_STATE_END:
391 irreco_bg_browser_widget_hide_banner(self);
392 irreco_bg_browser_widget_loader_stop(self);
395 IRRECO_RETURN_BOOL(FALSE);
398 /** @} */
400 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
401 /* Public Functions */
402 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
405 * @name Public Functions
406 * @{
409 /* Add functions here. */
411 /** @} */
413 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
414 /* Events and Callbacks */
415 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
418 * @name Events and Callbacks
419 * @{
422 static void irreco_bg_browser_widget_destroy_event(IrrecoBgBrowserWidget *self,
423 gpointer user_data)
425 IRRECO_ENTER
426 irreco_bg_browser_widget_loader_stop(self);
427 IRRECO_RETURN
430 static void irreco_bg_browser_widget_theme_selection_changed(
431 GtkTreeSelection *selection,
432 IrrecoBgBrowserWidget *self)
434 gint sel_index = -1;
435 gchar *sel_label = NULL;
436 gpointer sel_user_data = NULL;
437 IRRECO_ENTER
439 if (self->loader_func_id != 0) {
440 irreco_bg_browser_widget_loader_stop(self);
443 irreco_listbox_get_selection(IRRECO_LISTBOX(self->themes),
444 &sel_index, &sel_label, &sel_user_data);
446 g_string_printf(self->current_theme, "%s", sel_label);
448 irreco_bg_browser_widget_loader_start(self,
449 G_SOURCEFUNC(irreco_bg_browser_widget_loader_images), NULL);
451 g_free(sel_label);
452 IRRECO_RETURN
455 static void irreco_bg_browser_widget_image_selection_changed(
456 GtkTreeSelection *selection,
457 IrrecoBgBrowserWidget *self)
459 gint sel_index = -1;
460 gchar *sel_label = NULL;
461 IrrecoThemeBg *bg = NULL;
462 IRRECO_ENTER
464 if (irreco_listbox_get_selection(IRRECO_LISTBOX(self->images),
465 &sel_index, &sel_label, (gpointer *)&bg)) {
466 self->current_image = bg;
467 } else {
468 self->current_image = NULL;
471 g_free(sel_label);
472 IRRECO_RETURN
475 /** @} */
477 /** @} */