Clean code and added a few amendments (if()).
[irreco.git] / irreco / src / core / irreco_bg_browser_widget.c
blob496f15a632795a5fa1b9feddec466e1be17c2981
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2008 Joni Kokko (t5kojo01@students.oamk.fi)
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.
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 /**
24 * @addtogroup IrrecoBgBrowserWidget
25 * @ingroup Irreco
27 * This widget helps selection of background.
29 * This widget allows background selection from themes
30 * @{
33 /**
34 * @file
35 * Source file of @ref IrrecoBgBrowserWidget.
40 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
41 /* Prototypes */
42 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
44 GtkWidget *irreco_bg_browser_create_label(IrrecoBgBrowserWidget *self,
45 const gchar *text);
47 static gboolean irreco_bg_browser_widget_populate_themes(
48 IrrecoBgBrowserWidget *self);
50 static gboolean irreco_bg_browser_widget_loader_images(
51 IrrecoBgBrowserWidget *self);
53 static void irreco_bg_browser_widget_loader_start(IrrecoBgBrowserWidget *self,
54 GSourceFunc function,
55 GtkTreeIter *parent_iter);
57 static void irreco_bg_browser_widget_destroy_event(IrrecoBgBrowserWidget *self,
58 gpointer user_data);
60 static void irreco_bg_browser_widget_theme_selection_changed(
61 GtkTreeSelection * selection,
62 IrrecoBgBrowserWidget *self);
64 static void irreco_bg_browser_widget_image_selection_changed(
65 GtkTreeSelection * selection,
66 IrrecoBgBrowserWidget *self);
68 static gboolean irreco_bg_browser_widget_do_themes_exist(
69 IrrecoBgBrowserWidget *self);
73 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
74 /* Datatypes */
75 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
77 /** Loader states. */
78 enum
80 LOADER_STATE_INIT,
81 LOADER_STATE_LOOP,
82 LOADER_STATE_END,
83 LOADER_STATE_CLEANUP
88 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
89 /* Construction & Destruction */
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
92 /**
93 * @name Construction & Destruction
94 * @{
97 G_DEFINE_TYPE(IrrecoBgBrowserWidget, irreco_bg_browser_widget,
98 IRRECO_TYPE_INTERNAL_WIDGET)
100 static void irreco_bg_browser_widget_finalize(GObject *object)
102 IRRECO_ENTER
104 if (G_OBJECT_CLASS(irreco_bg_browser_widget_parent_class)->finalize)
105 G_OBJECT_CLASS(irreco_bg_browser_widget_parent_class)->finalize (object);
107 IRRECO_RETURN
110 static void irreco_bg_browser_widget_constructed(GObject *object)
112 IrrecoBgBrowserWidget *self = NULL;
113 GtkWidget *frame_for_themes = NULL;
114 GtkWidget *frame_for_images = NULL;
115 const gchar *theme_name = NULL;
116 IrrecoData *irreco_data = NULL;
117 GtkWidget *hbox = NULL;
118 IrrecoStringTable *themes = NULL;
119 IRRECO_ENTER
121 /* Constructed method boilerplate. */
122 G_OBJECT_CLASS(irreco_bg_browser_widget_parent_class)->constructed(object);
123 self = IRRECO_BG_BROWSER_WIDGET(object);
125 /* Init variables. */
126 hbox = gtk_hbox_new(0, 8);
127 irreco_data = irreco_internal_widget_get_irreco_data(
128 IRRECO_INTERNAL_WIDGET(self));
129 themes = irreco_data->theme_manager->themes;
130 self->current_theme = g_string_new("");
131 self->current_image = NULL;
133 /* Create themes */
135 /* Create Frame for Themes */
136 frame_for_themes = gtk_frame_new("");
137 gtk_frame_set_label_widget(GTK_FRAME(frame_for_themes),
138 irreco_gtk_label_bold("Themes", 0, 0, 0, 0, 0, 0));
140 /* Create list of themes */
141 self->themes = IRRECO_LISTBOX_TEXT(
142 irreco_listbox_text_new_with_autosize(100, 200, 180, 180));
143 gtk_container_add(GTK_CONTAINER(frame_for_themes),
144 irreco_gtk_align(GTK_WIDGET(self->themes),
145 0, 0, 1, 1, 1, 1, 1, 1));
147 /* Create Images */
149 /* Create frame for Images */
150 frame_for_images = gtk_frame_new("");
151 gtk_frame_set_label_widget(GTK_FRAME(frame_for_images),
152 irreco_gtk_label_bold("Images", 0, 0, 0, 0, 0, 0));
154 /* Create list of images */
155 self->images = IRRECO_LISTBOX_IMAGE(
156 irreco_listbox_image_new_with_autosize(100, 400, 180, 180));
157 irreco_listbox_set_select_new_rows(IRRECO_LISTBOX(self->images), FALSE);
158 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(self->images),
159 TRUE, TRUE, 0);
161 /* Create error text */
162 self->error_text = irreco_bg_browser_create_label(self,
163 "This theme does not contain any background images.");
164 gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(self->error_text),
165 TRUE, TRUE, 0);
166 gtk_container_add(GTK_CONTAINER(frame_for_images),
167 irreco_gtk_align(GTK_WIDGET(hbox),
168 0, 0, 1, 1, 1, 1, 1, 1));
170 /* Signal handlers. */
171 g_signal_connect(G_OBJECT(self), "destroy",
172 G_CALLBACK(irreco_bg_browser_widget_destroy_event), NULL);
174 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(self->themes)->tree_selection),
175 "changed",
176 G_CALLBACK(irreco_bg_browser_widget_theme_selection_changed),
177 self);
179 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(self->images)->tree_selection),
180 "changed",
181 G_CALLBACK(irreco_bg_browser_widget_image_selection_changed),
182 self);
184 /* Create hbox */
185 self->hbox = g_object_new(GTK_TYPE_HBOX, NULL);
186 gtk_box_set_spacing(GTK_BOX(self->hbox), 8);
188 gtk_box_pack_start(GTK_BOX(self->hbox), GTK_WIDGET(frame_for_themes),
189 TRUE, TRUE, 0);
191 gtk_box_pack_start(GTK_BOX(self->hbox), GTK_WIDGET(frame_for_images),
192 TRUE, TRUE, 0);
194 gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(self->hbox),
195 FALSE, TRUE, 0);
197 /* Fill widget. */
198 if (irreco_bg_browser_widget_do_themes_exist(self)) {
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);
211 IRRECO_RETURN
214 static void irreco_bg_browser_widget_class_init(IrrecoBgBrowserWidgetClass *klass)
216 GObjectClass *object_class;
217 IRRECO_ENTER
219 object_class = G_OBJECT_CLASS (klass);
220 object_class->finalize = irreco_bg_browser_widget_finalize;
221 object_class->constructed = irreco_bg_browser_widget_constructed;
223 IRRECO_RETURN
226 static void irreco_bg_browser_widget_init(IrrecoBgBrowserWidget *self)
230 IrrecoBgBrowserWidget *irreco_bg_browser_widget_new(IrrecoData *irreco_data)
232 IrrecoBgBrowserWidget *self;
233 IRRECO_ENTER
235 self = g_object_new(IRRECO_TYPE_BG_BROWSER_WIDGET,
236 "irreco-data", irreco_data,
237 NULL);
238 IRRECO_RETURN_PTR(GTK_WIDGET(self));
241 /** @} */
245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
246 /* Private Functions */
247 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
250 * @name Private Functions
251 * @{
255 * Create a center aligned label with text wrapping and marginals.
257 GtkWidget *irreco_bg_browser_create_label(IrrecoBgBrowserWidget *self,
258 const gchar *text)
260 GtkWidget *label = NULL;
261 IRRECO_ENTER
263 label = gtk_label_new(text);
264 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
265 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
266 gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR);
268 gtk_widget_set_size_request(GTK_WIDGET(label), 300, -1);
269 label = irreco_gtk_align(label, 0.5, 0.5, 1, 1, 8, 8, 8, 8);
270 IRRECO_RETURN_PTR(label);
274 * Show hildon progressbar banner.
276 * This function will create a new banner if one has not been created yet,
277 * if banner already exists, it's properties will be changed.
279 * @param text Text to show.
280 * @param fraction Value of progress.
282 static void irreco_bg_browser_widget_set_banner(IrrecoBgBrowserWidget *self,
283 const gchar *text,
284 gdouble fraction)
286 IRRECO_ENTER
287 if (self->banner == NULL) {
288 self->banner = hildon_banner_show_progress(
289 GTK_WIDGET(self), NULL, "");
292 hildon_banner_set_text(HILDON_BANNER(self->banner), text);
293 hildon_banner_set_fraction(HILDON_BANNER(self->banner), fraction);
294 IRRECO_RETURN
298 * Destroy banner, if it exists.
300 static void irreco_bg_browser_widget_hide_banner(IrrecoBgBrowserWidget *self)
302 IRRECO_ENTER
303 if (self->banner) {
304 gtk_widget_destroy(self->banner);
305 self->banner = NULL;
307 IRRECO_RETURN
311 * Start a loader state machine if one is not running already.
313 static void irreco_bg_browser_widget_loader_start(IrrecoBgBrowserWidget *self,
314 GSourceFunc function,
315 GtkTreeIter *parent_iter)
317 IRRECO_ENTER
319 if (self->loader_func_id == 0) {
320 if (function) {
321 self->loader_func_id = g_idle_add(function, self);
322 } else {
323 IRRECO_ERROR("Loader function pointer not given.\n");
327 IRRECO_RETURN
331 * Stop and cleanup loader if a loader is running.
333 static void irreco_bg_browser_widget_loader_stop(IrrecoBgBrowserWidget *self)
335 IRRECO_ENTER
336 if (self->loader_func_id != 0) {
337 g_source_remove(self->loader_func_id);
338 self->loader_func_id = 0;
339 self->loader_state = 0;
341 IRRECO_RETURN
345 * Theme loader.
347 * This loader will request a list of themes from the IrrecoThemeManager and
348 * update the TreeView accordingly.
351 static gboolean irreco_bg_browser_widget_populate_themes(
352 IrrecoBgBrowserWidget *self)
354 IrrecoStringTable *themes = NULL;
355 IrrecoData *irreco_data = NULL;
356 IrrecoThemeManager *theme_manager = NULL;
357 IRRECO_ENTER
359 irreco_data = irreco_internal_widget_get_irreco_data(
360 IRRECO_INTERNAL_WIDGET(self));
361 theme_manager = irreco_data->theme_manager;
362 themes = irreco_theme_manager_get_themes(theme_manager);
364 if (themes != NULL) {
365 IRRECO_STRING_TABLE_FOREACH_KEY(themes, key)
366 irreco_listbox_text_append(self->themes, key, NULL);
367 IRRECO_STRING_TABLE_FOREACH_END
368 } else {
369 irreco_error_dlg(GTK_WINDOW(self),
370 "There's no themes installed");
373 IRRECO_RETURN_BOOL(TRUE);
377 * Background-image loader.
379 * This loader will request a list of background-images from the
380 * IrrecoThemeManager and update the TreeView accordingly.
382 static gboolean irreco_bg_browser_widget_loader_images(
383 IrrecoBgBrowserWidget *self)
385 IrrecoData *irreco_data = NULL;
386 IrrecoThemeManager *manager = NULL;
387 IRRECO_ENTER
389 irreco_data = irreco_internal_widget_get_irreco_data(
390 IRRECO_INTERNAL_WIDGET(self));
391 manager = irreco_data->theme_manager;
393 switch (self->loader_state) {
394 case LOADER_STATE_INIT:
395 irreco_bg_browser_widget_set_banner(self, _("Loading ..."), 0);
396 self->loader_state = LOADER_STATE_LOOP;
397 self->loader_index = 0;
398 irreco_listbox_clear(IRRECO_LISTBOX(self->images));
399 IRRECO_RETURN_BOOL(TRUE);
401 case LOADER_STATE_LOOP: {
402 gint theme_bg_count;
403 gfloat banner;
404 const gchar *image_name;
405 IrrecoTheme *theme;
407 irreco_string_table_get(manager->themes,
408 self->current_theme->str,
409 (gpointer *) &theme);
411 theme_bg_count = irreco_string_table_lenght(theme->backgrounds);
413 if (theme_bg_count > 0) {
414 IrrecoThemeBg *background_image;
415 gtk_widget_show(GTK_WIDGET(self->images));
416 gtk_widget_hide(GTK_WIDGET(self->error_text));
417 irreco_string_table_index(theme->backgrounds,
418 self->loader_index,
419 &image_name,
420 (gpointer *) &background_image);
422 irreco_listbox_image_append_with_size(self->images,
423 background_image->image_name->str,
424 background_image,
425 background_image->image_path->str,
426 IRRECO_SCREEN_WIDTH / 6,
427 IRRECO_SCREEN_HEIGHT / 6);
428 } else {
429 gtk_widget_show(GTK_WIDGET(self->error_text));
430 gtk_widget_hide(GTK_WIDGET(self->images));
431 self->current_image = NULL;
432 theme_bg_count = 1;
435 self->loader_index++;
436 banner = (gfloat)self->loader_index / (gfloat)theme_bg_count;
437 irreco_bg_browser_widget_set_banner(self, _("Loading ..."),
438 banner);
440 if(self->loader_index >= theme_bg_count) {
441 self->loader_state = LOADER_STATE_END;
444 IRRECO_RETURN_BOOL(TRUE);
447 case LOADER_STATE_END:
448 irreco_bg_browser_widget_hide_banner(self);
449 irreco_bg_browser_widget_loader_stop(self);
452 IRRECO_RETURN_BOOL(FALSE);
455 static gboolean irreco_bg_browser_widget_do_themes_exist(
456 IrrecoBgBrowserWidget *self)
458 IrrecoData *irreco_data = NULL;
459 gboolean rvalue = TRUE;
460 IRRECO_ENTER
462 irreco_data = irreco_internal_widget_get_irreco_data(
463 IRRECO_INTERNAL_WIDGET(self));
465 if (irreco_string_table_lenght(
466 irreco_data->theme_manager->themes) == 0) {
467 GtkWidget *error = irreco_bg_browser_create_label(self,
468 "No themes have been installed.");
470 gtk_container_remove(GTK_CONTAINER(self),
471 GTK_WIDGET(self->hbox));
472 gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(error),
473 FALSE, TRUE, 0);
474 rvalue = FALSE;
476 IRRECO_RETURN_BOOL(rvalue);
479 /** @} */
483 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
484 /* Public Functions */
485 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
488 * @name Public Functions
489 * @{
492 /* Add functions here. */
494 /** @} */
498 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
499 /* Events and Callbacks */
500 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
503 * @name Events and Callbacks
504 * @{
507 static void irreco_bg_browser_widget_destroy_event(IrrecoBgBrowserWidget *self,
508 gpointer user_data)
510 IRRECO_ENTER
511 irreco_bg_browser_widget_loader_stop(self);
512 IRRECO_RETURN
515 static void irreco_bg_browser_widget_theme_selection_changed(
516 GtkTreeSelection *selection,
517 IrrecoBgBrowserWidget *self)
519 gint sel_index = -1;
520 gchar *sel_label = NULL;
521 gpointer sel_user_data = NULL;
522 IRRECO_ENTER
524 if (self->loader_func_id != 0) {
525 irreco_bg_browser_widget_loader_stop(self);
528 irreco_listbox_get_selection(IRRECO_LISTBOX(self->themes),
529 &sel_index, &sel_label, &sel_user_data);
531 g_string_printf(self->current_theme, "%s", sel_label);
533 irreco_bg_browser_widget_loader_start(self,
534 G_SOURCEFUNC(irreco_bg_browser_widget_loader_images), NULL);
536 g_free(sel_label);
537 IRRECO_RETURN
540 static void irreco_bg_browser_widget_image_selection_changed(
541 GtkTreeSelection *selection,
542 IrrecoBgBrowserWidget *self)
544 gint sel_index = -1;
545 gchar *sel_label = NULL;
546 IrrecoThemeBg *bg = NULL;
547 IRRECO_ENTER
549 if (irreco_listbox_get_selection(IRRECO_LISTBOX(self->images),
550 &sel_index, &sel_label, (gpointer *)&bg)) {
551 self->current_image = bg;
552 } else {
553 self->current_image = NULL;
556 g_free(sel_label);
557 IRRECO_RETURN
560 /** @} */
562 /** @} */