Added button image data transmission from
[irreco.git] / irreco / src / core / irreco_button_browser_widget.c
blob96c67e822d6722b909cc5a25f6a28049ffb2de82
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2008 Joni Kokko (t5kojo01@students.oamk.fi),
4 * Harri Vattulainen (t5vaha01@students.oamk.fi)
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
25 (IrrecoButtonBrowserWidget, irreco_button_browser_widget, GTK_TYPE_VBOX)
27 /**
28 * @addtogroup IrrecoButtonBrowserWidget
29 * @ingroup Irreco
31 * This widget helps selection of button.
33 * This widget allows button selection from themes
34 * @{
37 /**
38 * @file
39 * Source file of @ref IrrecoButtonBrowserWidget.
42 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
43 /* Prototypes */
44 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
46 static gboolean irreco_button_browser_widget_populate_themes(
47 IrrecoButtonBrowserWidget *self);
49 static gboolean irreco_button_browser_widget_loader_images(
50 IrrecoButtonBrowserWidget *self);
52 static void
53 irreco_button_browser_widget_loader_start(IrrecoButtonBrowserWidget *self,
54 GSourceFunc function,
55 GtkTreeIter *parent_iter);
57 static void
58 irreco_button_browser_widget_destroy_event(IrrecoButtonBrowserWidget *self,
59 gpointer user_data);
61 static void irreco_button_browser_widget_theme_selection_changed(
62 GtkTreeSelection * selection,
63 IrrecoButtonBrowserWidget *self);
65 static void irreco_button_browser_widget_image_selection_changed(
66 GtkTreeSelection * selection,
67 IrrecoButtonBrowserWidget *self);
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
70 /* Datatypes */
71 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
73 /** Loader states. */
74 enum
76 LOADER_STATE_INIT,
77 LOADER_STATE_LOOP,
78 LOADER_STATE_END,
79 LOADER_STATE_CLEANUP
82 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
83 /* Construction & Destruction */
84 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
86 /**
87 * @name Construction & Destruction
88 * @{
91 static void irreco_button_browser_widget_finalize (GObject *object)
93 IRRECO_ENTER
95 if (G_OBJECT_CLASS(irreco_button_browser_widget_parent_class)->finalize)
96 G_OBJECT_CLASS(irreco_button_browser_widget_parent_class)->finalize (object);
98 IRRECO_RETURN
101 static void irreco_button_browser_widget_class_init(IrrecoButtonBrowserWidgetClass *klass)
103 GObjectClass *object_class;
104 IRRECO_ENTER
106 object_class = G_OBJECT_CLASS (klass);
107 object_class->finalize = irreco_button_browser_widget_finalize;
109 IRRECO_RETURN
112 static void irreco_button_browser_widget_init (IrrecoButtonBrowserWidget *self)
114 GtkWidget *frame_for_themes;
115 GtkWidget *frame_for_images;
116 IRRECO_ENTER
118 self->current_theme = g_string_new("");
119 self->current_image = NULL;
121 /* Create themes */
123 /* Create Frame for Themes */
124 frame_for_themes = gtk_frame_new("");
125 gtk_frame_set_label_widget(GTK_FRAME(frame_for_themes),
126 irreco_gtk_label_bold("Themes", 0, 0, 0, 0, 0, 0));
128 /* Create list of themes */
129 self->themes = IRRECO_LISTBOX_TEXT(
130 irreco_listbox_text_new_with_autosize(200, 200,
131 200, 200));
132 gtk_container_add(GTK_CONTAINER(frame_for_themes),
133 GTK_WIDGET(self->themes));
135 /* Create Images */
137 /* Create frame for Images */
138 frame_for_images = gtk_frame_new("");
139 gtk_frame_set_label_widget(GTK_FRAME(frame_for_images),
140 irreco_gtk_label_bold("Images", 0, 0, 0, 0, 0, 0));
142 /* Create list of images */
143 self->images = IRRECO_LISTBOX_IMAGE(
144 irreco_listbox_image_new_with_autosize(400, 400,
145 200, 200));
146 irreco_listbox_set_select_new_rows(IRRECO_LISTBOX(self->images), FALSE);
147 gtk_container_add(GTK_CONTAINER(frame_for_images),
148 GTK_WIDGET(self->images));
150 /* Signal handlers. */
151 g_signal_connect(G_OBJECT(self), "destroy",
152 G_CALLBACK(irreco_button_browser_widget_destroy_event), NULL);
154 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(self->themes)->tree_selection),
155 "changed",
156 G_CALLBACK(irreco_button_browser_widget_theme_selection_changed),
157 self);
159 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(self->images)->tree_selection),
160 "changed",
161 G_CALLBACK(irreco_button_browser_widget_image_selection_changed),
162 self);
164 /* Create hbox */
165 self->hbox = g_object_new(GTK_TYPE_HBOX, NULL);
166 gtk_box_set_spacing(GTK_BOX(self->hbox), 8);
168 gtk_box_pack_start(GTK_BOX(self->hbox), GTK_WIDGET(frame_for_themes),
169 TRUE, TRUE, 0);
171 gtk_box_pack_start(GTK_BOX(self->hbox), GTK_WIDGET(frame_for_images),
172 TRUE, TRUE, 0);
174 gtk_box_pack_start(GTK_BOX(self), GTK_WIDGET(self->hbox),
175 FALSE, TRUE, 0);
177 IRRECO_RETURN
180 IrrecoButtonBrowserWidget
181 *irreco_button_browser_widget_new(IrrecoData *irreco_data)
183 IrrecoButtonBrowserWidget *self;
184 IrrecoStringTable *themes = irreco_data->theme_manager->themes;
185 IRRECO_ENTER
187 self = IRRECO_BUTTON_BROWSER_WIDGET(
188 g_object_new (IRRECO_TYPE_BUTTON_BROWSER_WIDGET, NULL));
190 self->irreco_data = irreco_data;
192 if (irreco_string_table_lenght(themes) > 0) {
194 const gchar *theme_name;
195 irreco_button_browser_widget_populate_themes(self);
196 irreco_listbox_set_selection(IRRECO_LISTBOX(self->themes), 0);
198 irreco_string_table_index(themes, 0, &theme_name, NULL);
200 g_string_printf(self->current_theme, "%s", theme_name);
202 irreco_button_browser_widget_loader_start(self,
203 G_SOURCEFUNC(irreco_button_browser_widget_loader_images), NULL);
206 IRRECO_RETURN_PTR(GTK_WIDGET(self));
209 /** @} */
211 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
212 /* Private Functions */
213 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
215 * @name Private Functions
216 * @{
220 * Show hildon progressbar banner.
222 * This function will create a new banner if one has not been created yet,
223 * if banner already exists, it's properties will be changed.
225 * @param text Text to show.
226 * @param fraction Value of progress.
228 static void
229 irreco_button_browser_widget_set_banner(IrrecoButtonBrowserWidget *self,
230 const gchar *text,
231 gdouble fraction)
233 IRRECO_ENTER
234 if (self->banner == NULL) {
235 self->banner = hildon_banner_show_progress(
236 GTK_WIDGET(self), NULL, "");
239 hildon_banner_set_text(HILDON_BANNER(self->banner), text);
240 hildon_banner_set_fraction(HILDON_BANNER(self->banner), fraction);
241 IRRECO_RETURN
245 * Destroy banner, if it exists.
247 static void
248 irreco_button_browser_widget_hide_banner(IrrecoButtonBrowserWidget *self)
250 IRRECO_ENTER
251 if (self->banner) {
252 gtk_widget_destroy(self->banner);
253 self->banner = NULL;
255 IRRECO_RETURN
259 * Start a loader state machine if one is not running already.
261 static void
262 irreco_button_browser_widget_loader_start(IrrecoButtonBrowserWidget *self,
263 GSourceFunc function,
264 GtkTreeIter *parent_iter)
266 IRRECO_ENTER
268 if (self->loader_func_id == 0) {
269 if (function) {
270 self->loader_func_id = g_idle_add(function, self);
271 } else {
272 IRRECO_ERROR("Loader function pointer not given.\n");
276 IRRECO_RETURN
280 * Stop and cleanup loader if a loader is running.
282 static void
283 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;
291 IRRECO_RETURN
295 * Theme loader.
297 * This loader will request a list of themes from the IrrecoThemeManager and
298 * update the TreeView accordingly.
301 static gboolean irreco_button_browser_widget_populate_themes(
302 IrrecoButtonBrowserWidget *self)
304 IrrecoStringTable *themes = NULL;
305 IrrecoThemeManager *theme_manager = self->irreco_data->theme_manager;
306 IRRECO_ENTER
308 themes = irreco_theme_manager_get_themes(theme_manager);
310 if (themes != NULL) {
311 IRRECO_STRING_TABLE_FOREACH_KEY(themes, key)
312 irreco_listbox_text_append(self->themes, key, NULL);
313 IRRECO_STRING_TABLE_FOREACH_END
314 } else {
315 irreco_error_dlg(GTK_WINDOW(self),
316 "There's no themes installed");
319 IRRECO_RETURN_BOOL(TRUE);
323 * Background-image loader.
325 * This loader will request a list of background-images from the
326 * IrrecoThemeManager and update the TreeView accordingly.
328 static gboolean irreco_button_browser_widget_loader_images(
329 IrrecoButtonBrowserWidget *self)
331 IRRECO_ENTER
333 switch (self->loader_state) {
334 case LOADER_STATE_INIT:
335 irreco_button_browser_widget_set_banner(self, _("Loading ..."), 0);
336 self->loader_state = LOADER_STATE_LOOP;
337 self->loader_index = 0;
338 irreco_listbox_clear(IRRECO_LISTBOX(self->images));
339 IRRECO_RETURN_BOOL(TRUE);
341 case LOADER_STATE_LOOP: {
342 gint theme_button_count;
343 gfloat banner;
344 const gchar *image_name;
345 IrrecoThemeManager *manager = self->irreco_data->theme_manager;
346 IrrecoTheme *theme;
348 irreco_string_table_get(manager->themes,
349 self->current_theme->str,
350 (gpointer *) &theme);
352 theme_button_count = irreco_string_table_lenght(theme->buttons);
354 if (theme_button_count > 0) {
355 IrrecoThemeButton *button_image;
356 irreco_string_table_index(theme->buttons,
357 self->loader_index,
358 &image_name,
359 (gpointer *) &button_image);
361 irreco_listbox_image_append(self->images,
362 button_image->name->str,
363 button_image,
364 button_image->image_up->str);
365 } else {
366 self->current_image = NULL;
367 theme_button_count = 1;
370 self->loader_index++;
371 banner = (gfloat)self->loader_index / (gfloat)theme_button_count;
372 irreco_button_browser_widget_set_banner(self, _("Loading ..."),
373 banner);
375 if(self->loader_index >= theme_button_count) {
376 self->loader_state = LOADER_STATE_END;
379 IRRECO_RETURN_BOOL(TRUE);
382 case LOADER_STATE_END:
383 irreco_button_browser_widget_hide_banner(self);
384 irreco_button_browser_widget_loader_stop(self);
387 IRRECO_RETURN_BOOL(FALSE);
390 /** @} */
392 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
393 /* Public Functions */
394 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
397 * @name Public Functions
398 * @{
401 /* Add functions here. */
403 /** @} */
405 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
406 /* Events and Callbacks */
407 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
410 * @name Events and Callbacks
411 * @{
414 static void
415 irreco_button_browser_widget_destroy_event(IrrecoButtonBrowserWidget *self,
416 gpointer user_data)
418 IRRECO_ENTER
419 irreco_button_browser_widget_loader_stop(self);
420 IRRECO_RETURN
423 static void irreco_button_browser_widget_theme_selection_changed(
424 GtkTreeSelection *selection,
425 IrrecoButtonBrowserWidget *self)
427 gint sel_index = -1;
428 gchar *sel_label = NULL;
429 gpointer sel_user_data = NULL;
430 IRRECO_ENTER
432 if (self->loader_func_id != 0) {
433 irreco_button_browser_widget_loader_stop(self);
436 irreco_listbox_get_selection(IRRECO_LISTBOX(self->themes),
437 &sel_index, &sel_label, &sel_user_data);
439 g_string_printf(self->current_theme, "%s", sel_label);
441 irreco_button_browser_widget_loader_start(self,
442 G_SOURCEFUNC(irreco_button_browser_widget_loader_images), NULL);
444 g_free(sel_label);
445 IRRECO_RETURN
448 static void irreco_button_browser_widget_image_selection_changed(
449 GtkTreeSelection *selection,
450 IrrecoButtonBrowserWidget *self)
452 gint sel_index = -1;
453 gchar *sel_label = NULL;
454 IrrecoThemeButton *button = NULL;
455 IRRECO_ENTER
457 if (irreco_listbox_get_selection(IRRECO_LISTBOX(self->images),
458 &sel_index, &sel_label, (gpointer *)&button)) {
459 self->current_image = button;
460 } else {
461 self->current_image = NULL;
464 g_free(sel_label);
465 IRRECO_RETURN
468 /** @} */
470 /** @} */