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>
24 * @addtogroup IrrecoBgBrowserWidget
27 * This widget helps selection of background.
29 * This widget allows background selection from themes
35 * Source file of @ref IrrecoBgBrowserWidget.
40 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
42 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
44 GtkWidget
*irreco_bg_browser_create_label(IrrecoBgBrowserWidget
*self
,
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
,
55 GtkTreeIter
*parent_iter
);
57 static void irreco_bg_browser_widget_destroy_event(IrrecoBgBrowserWidget
*self
,
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 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
75 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
88 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
89 /* Construction & Destruction */
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
93 * @name Construction & Destruction
97 G_DEFINE_TYPE(IrrecoBgBrowserWidget
, irreco_bg_browser_widget
,
98 IRRECO_TYPE_INTERNAL_WIDGET
)
100 static void irreco_bg_browser_widget_finalize(GObject
*object
)
104 if (G_OBJECT_CLASS(irreco_bg_browser_widget_parent_class
)->finalize
)
105 G_OBJECT_CLASS(irreco_bg_browser_widget_parent_class
)->finalize (object
);
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
;
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
;
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));
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
),
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
),
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
),
176 G_CALLBACK(irreco_bg_browser_widget_theme_selection_changed
),
179 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(self
->images
)->tree_selection
),
181 G_CALLBACK(irreco_bg_browser_widget_image_selection_changed
),
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
),
191 gtk_box_pack_start(GTK_BOX(self
->hbox
), GTK_WIDGET(frame_for_images
),
194 gtk_box_pack_start(GTK_BOX(self
), GTK_WIDGET(self
->hbox
),
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
);
214 static void irreco_bg_browser_widget_class_init(IrrecoBgBrowserWidgetClass
*klass
)
216 GObjectClass
*object_class
;
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
;
226 static void irreco_bg_browser_widget_init(IrrecoBgBrowserWidget
*self
)
230 IrrecoBgBrowserWidget
*irreco_bg_browser_widget_new(IrrecoData
*irreco_data
)
232 IrrecoBgBrowserWidget
*self
;
235 self
= g_object_new(IRRECO_TYPE_BG_BROWSER_WIDGET
,
236 "irreco-data", irreco_data
,
238 IRRECO_RETURN_PTR(GTK_WIDGET(self
));
245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
246 /* Private Functions */
247 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
250 * @name Private Functions
255 * Create a center aligned label with text wrapping and marginals.
257 GtkWidget
*irreco_bg_browser_create_label(IrrecoBgBrowserWidget
*self
,
260 GtkWidget
*label
= NULL
;
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
,
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
);
298 * Destroy banner, if it exists.
300 static void irreco_bg_browser_widget_hide_banner(IrrecoBgBrowserWidget
*self
)
304 gtk_widget_destroy(self
->banner
);
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
)
319 if (self
->loader_func_id
== 0) {
321 self
->loader_func_id
= g_idle_add(function
, self
);
323 IRRECO_ERROR("Loader function pointer not given.\n");
331 * Stop and cleanup loader if a loader is running.
333 static void irreco_bg_browser_widget_loader_stop(IrrecoBgBrowserWidget
*self
)
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;
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
;
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
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
;
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
: {
404 const gchar
*image_name
;
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
,
420 (gpointer
*) &background_image
);
422 irreco_listbox_image_append_with_size(self
->images
,
423 background_image
->image_name
->str
,
425 background_image
->image_path
->str
,
426 IRRECO_SCREEN_WIDTH
/ 6,
427 IRRECO_SCREEN_HEIGHT
/ 6);
429 gtk_widget_show(GTK_WIDGET(self
->error_text
));
430 gtk_widget_hide(GTK_WIDGET(self
->images
));
431 self
->current_image
= NULL
;
435 self
->loader_index
++;
436 banner
= (gfloat
)self
->loader_index
/ (gfloat
)theme_bg_count
;
437 irreco_bg_browser_widget_set_banner(self
, _("Loading ..."),
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
;
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
),
476 IRRECO_RETURN_BOOL(rvalue
);
483 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
484 /* Public Functions */
485 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
488 * @name Public Functions
492 /* Add functions here. */
498 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
499 /* Events and Callbacks */
500 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
503 * @name Events and Callbacks
507 static void irreco_bg_browser_widget_destroy_event(IrrecoBgBrowserWidget
*self
,
511 irreco_bg_browser_widget_loader_stop(self
);
515 static void irreco_bg_browser_widget_theme_selection_changed(
516 GtkTreeSelection
*selection
,
517 IrrecoBgBrowserWidget
*self
)
520 gchar
*sel_label
= NULL
;
521 gpointer sel_user_data
= NULL
;
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
);
540 static void irreco_bg_browser_widget_image_selection_changed(
541 GtkTreeSelection
*selection
,
542 IrrecoBgBrowserWidget
*self
)
545 gchar
*sel_label
= NULL
;
546 IrrecoThemeBg
*bg
= NULL
;
549 if (irreco_listbox_get_selection(IRRECO_LISTBOX(self
->images
),
550 &sel_index
, &sel_label
, (gpointer
*)&bg
)) {
551 self
->current_image
= bg
;
553 self
->current_image
= NULL
;