Taked Joni's widget and made it my own, also included it to style_browser.
[irreco.git] / irreco / trunk / src / core / irreco_background_dlg.c
blob833c80f590b927e8008f4435fe1df77a9e422443
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi)
4 * 2008 Joni Kokko (t5kojo01@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_background_dlg.h"
22 #include <hildon/hildon-color-button.h>
23 #include <hildon/hildon-file-chooser-dialog.h>
26 /**
27 * @typedef IrrecoBackgroundDlg
29 * Allow user to setup layout background.
32 #define IRRECO_BACKGROUND_PREVIEW_WIDHT (IRRECO_SCREEN_WIDTH / 6)
33 #define IRRECO_BACKGROUND_PREVIEW_HEIGHT (IRRECO_SCREEN_HEIGHT / 6)
37 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
38 /* Prototypes */
39 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
41 void irreco_background_dlg_sync_radio(IrrecoBackgroundDlg * self);
42 gboolean irreco_background_dlg_draw_preview(IrrecoBackgroundDlg * self);
43 gboolean irreco_background_dlg_draw_preview_custom(IrrecoBackgroundDlg * self,
44 const gchar * image,
45 const GdkColor * bg_color);
46 void irreco_background_dlg_color_clicked(GtkColorButton *widget,
47 IrrecoBackgroundDlg * self);
48 void irreco_background_dlg_type_toggled(GtkToggleButton * togglebutton,
49 IrrecoBackgroundDlg * self);
50 void irreco_background_dlg_image_clicked(gpointer * ignore,
51 IrrecoBackgroundDlg * self);
52 void irreco_background_dlg_preview_clicked(gpointer * ignore1,
53 gpointer * ignore2,
54 IrrecoBackgroundDlg * self);
55 void irreco_background_dlg_theme_image_selection_changed(
56 GtkTreeSelection * selection,
57 IrrecoBackgroundDlg * self);
60 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
61 /* Public functions */
62 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
64 IrrecoBackgroundDlg *irreco_background_dlg_create(IrrecoData *irreco_data,
65 GtkWindow *parent_window)
67 IrrecoBackgroundDlg *self;
68 GtkWidget *vbox;
69 GtkWidget *hbox;
70 GtkWidget *vbox_left;
71 GtkWidget *vbox_right;
72 GtkTable *table_right;
74 GtkWidget *label_left;
75 GtkWidget *label_right;
76 GtkWidget *label_color;
77 GtkWidget *label_image;
79 GtkWidget *radio_default_a;
80 GtkWidget *radio_color_a;
81 GtkWidget *radio_image_a;
83 GtkWidget *button_image;
84 GtkWidget *preview_frame;
85 GtkWidget *preview_event_box;
86 IRRECO_ENTER
88 self = g_slice_new0(IrrecoBackgroundDlg);
89 self->filename = g_string_new(NULL);
90 self->dialog = gtk_dialog_new_with_buttons(
91 _("Background"), parent_window,
92 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT |
93 GTK_DIALOG_NO_SEPARATOR,
94 GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
95 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
96 NULL);
98 /* Create widgets. */
100 vbox = gtk_vbox_new(0, 0);
103 hbox = gtk_hbox_new(0, 12);
104 vbox_left = gtk_vbox_new(0, 0);
105 vbox_right = gtk_vbox_new(0, 0);
107 self->notebook = gtk_notebook_new();
109 gtk_notebook_append_page(GTK_NOTEBOOK(self->notebook),
110 vbox, gtk_label_new("Default"));
112 self->theme_bg_browser = irreco_bg_browser_widget_new(irreco_data);
113 gtk_notebook_append_page(GTK_NOTEBOOK(self->notebook),
114 GTK_WIDGET(self->theme_bg_browser),
115 gtk_label_new("Theme"));
116 /* Buttons page */
117 /*self->theme_button_browser = irreco_button_browser_widget_new(irreco_data);
118 gtk_notebook_append_page(GTK_NOTEBOOK(self->notebook),
119 self->theme_button_browser,
120 gtk_label_new("Button"));*/
122 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(self->dialog)->vbox),
123 self->notebook);
125 label_left = irreco_gtk_label_bold(_("Background"), 0, 0, 0, 6, 0, 0);
126 label_right = irreco_gtk_label_bold(_("Select"), 0, 0, 0, 6, 0, 0);
127 label_color = irreco_gtk_label(_("Color"), 0, 0.5, 0, 0, 12, 0);
128 label_image = irreco_gtk_label(_("Image"), 0, 0.5, 0, 0, 12, 0);
130 self->radio_default =
131 gtk_radio_button_new_with_label(
132 NULL, _("Default image"));
133 self->radio_color =
134 gtk_radio_button_new_with_label_from_widget(
135 GTK_RADIO_BUTTON(self->radio_default),
136 _("Color only"));
137 self->radio_image =
138 gtk_radio_button_new_with_label_from_widget(
139 GTK_RADIO_BUTTON(self->radio_color),
140 _("Color and Image"));
141 radio_default_a = irreco_gtk_pad(self->radio_default,
142 0, 0, 12, 0);
143 radio_color_a = irreco_gtk_pad(self->radio_color,
144 0, 0, 12, 0);
145 radio_image_a = irreco_gtk_pad(self->radio_image,
146 0, 0, 12, 0);
148 self->color_button = hildon_color_button_new();
149 button_image = gtk_button_new_with_label(_("Select"));
151 preview_frame = gtk_frame_new(NULL);
152 preview_event_box = gtk_event_box_new();
153 self->preview = gtk_drawing_area_new();
154 gtk_drawing_area_size(GTK_DRAWING_AREA(self->preview),
155 IRRECO_BACKGROUND_PREVIEW_WIDHT,
156 IRRECO_BACKGROUND_PREVIEW_HEIGHT);
158 /* Build dialog. */
159 table_right = GTK_TABLE(gtk_table_new(2, 2, FALSE));
160 gtk_table_set_row_spacings(table_right, 6);
161 gtk_table_set_col_spacings(table_right, 12);
162 gtk_table_attach_defaults(table_right, label_color, 0, 1, 0, 1);
163 gtk_table_attach_defaults(table_right, label_image, 0, 1, 1, 2);
164 gtk_table_attach_defaults(table_right, self->color_button,
165 1, 2, 0, 1);
166 gtk_table_attach_defaults(table_right, button_image, 1, 2, 1, 2);
168 gtk_box_pack_start_defaults(GTK_BOX(vbox),
169 irreco_gtk_pad(hbox, 12, 0, 12, 12));
170 gtk_box_pack_start_defaults(GTK_BOX(hbox), vbox_left);
171 gtk_box_pack_start_defaults(GTK_BOX(hbox), vbox_right);
172 gtk_box_pack_start(GTK_BOX(vbox_left), label_left, 0, 0, 0);
173 gtk_box_pack_start(GTK_BOX(vbox_left), radio_default_a, 0, 0, 0);
174 gtk_box_pack_start(GTK_BOX(vbox_left), radio_color_a, 0, 0, 0);
175 gtk_box_pack_start(GTK_BOX(vbox_left), radio_image_a, 0, 0, 0);
176 gtk_box_pack_start(GTK_BOX(vbox_right), label_right, 0, 0, 0);
177 gtk_box_pack_start(GTK_BOX(vbox_right), GTK_WIDGET(table_right),
178 0, 0, 0);
180 gtk_container_add(GTK_CONTAINER(preview_event_box), preview_frame);
181 gtk_container_add(GTK_CONTAINER(preview_frame),self->preview);
182 gtk_box_pack_start_defaults(GTK_BOX(vbox), irreco_gtk_align(
183 preview_event_box,
184 0.5, 0.5, 0, 0, 12, 0, 0, 0));
185 /* Radio button signals. */
186 g_signal_connect(G_OBJECT(self->radio_default), "toggled",
187 G_CALLBACK(irreco_background_dlg_type_toggled),
188 self);
189 g_object_set_data(G_OBJECT(self->radio_default),
190 "IrrecoButtonLayoutBgType",
191 (gpointer) IRRECO_BACKGROUND_DEFAULT);
192 g_signal_connect(G_OBJECT(self->radio_color), "toggled",
193 G_CALLBACK(irreco_background_dlg_type_toggled),
194 self);
195 g_object_set_data(G_OBJECT(self->radio_color),
196 "IrrecoButtonLayoutBgType",
197 (gpointer) IRRECO_BACKGROUND_COLOR);
198 g_signal_connect(G_OBJECT(self->radio_image), "toggled",
199 G_CALLBACK(irreco_background_dlg_type_toggled),
200 self);
201 g_object_set_data(G_OBJECT(self->radio_image),
202 "IrrecoButtonLayoutBgType",
203 (gpointer) IRRECO_BACKGROUND_IMAGE);
205 /* Button signals. */
206 g_signal_connect(G_OBJECT(button_image), "clicked",
207 G_CALLBACK(irreco_background_dlg_image_clicked),
208 self);
209 g_signal_connect(G_OBJECT(self->color_button), "clicked",
210 G_CALLBACK(irreco_background_dlg_color_clicked),
211 self);
212 g_signal_connect(G_OBJECT(preview_event_box), "button-release-event",
213 G_CALLBACK(irreco_background_dlg_preview_clicked),
214 self);
216 /* Signal handler for theme_bg_browser*/
217 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(
218 self->theme_bg_browser->images)->tree_selection),
219 "changed",
220 G_CALLBACK(irreco_background_dlg_theme_image_selection_changed),
221 self);
223 gtk_widget_show_all(self->dialog);
224 IRRECO_RETURN_PTR(self);
228 * Destroys and hides dialog.
230 void irreco_background_dlg_destroy(IrrecoBackgroundDlg * self)
232 IRRECO_ENTER
233 gtk_widget_destroy(self->dialog);
234 g_string_free(self->filename, TRUE);
235 g_slice_free(IrrecoBackgroundDlg, self);
236 IRRECO_RETURN
240 * Show dialog, and ask user for input.
242 gboolean irreco_background_dlg_run(IrrecoBackgroundDlg * self,
243 IrrecoButtonLayout * irreco_layout)
245 IRRECO_ENTER
247 /* Setup dialog. */
248 self->type = irreco_button_layout_get_bg_type(irreco_layout);
249 irreco_gstring_set(self->filename,
250 irreco_button_layout_get_bg_image(irreco_layout));
251 hildon_color_button_set_color(
252 HILDON_COLOR_BUTTON(self->color_button),
253 irreco_button_layout_get_bg_color(irreco_layout));
255 /* Prepare ui. */
256 irreco_background_dlg_sync_radio(self);
257 irreco_background_dlg_draw_preview(self);
259 if (gtk_dialog_run(GTK_DIALOG(self->dialog))
260 == GTK_RESPONSE_ACCEPT) {
261 GdkColor *color;
262 g_object_get(G_OBJECT(self->color_button),
263 "color", &color, NULL);
264 irreco_button_layout_set_bg_type(irreco_layout,
265 self->type);
266 irreco_button_layout_set_bg_color(irreco_layout, color);
267 irreco_button_layout_set_bg_image(
268 irreco_layout, self->filename->str);
270 IRRECO_PRINTF("%i\n",
271 irreco_button_layout_get_bg_type(irreco_layout));
273 IRRECO_RETURN_BOOL(TRUE);
275 IRRECO_RETURN_BOOL(FALSE);
280 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
281 /* Private functions */
282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
284 void irreco_background_dlg_sync_radio(IrrecoBackgroundDlg * self)
286 IRRECO_ENTER
287 switch (self->type) {
288 case IRRECO_BACKGROUND_DEFAULT:
289 gtk_widget_grab_focus(self->radio_default);
290 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
291 self->radio_default),
292 TRUE);
293 break;
295 case IRRECO_BACKGROUND_COLOR:
296 gtk_widget_grab_focus(self->radio_color);
297 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
298 self->radio_color),
299 TRUE);
300 break;
302 case IRRECO_BACKGROUND_IMAGE:
303 gtk_widget_grab_focus(self->radio_image);
304 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
305 self->radio_image),
306 TRUE);
307 break;
309 IRRECO_RETURN
313 * Draw preview with current image.
315 gboolean
316 irreco_background_dlg_draw_preview(IrrecoBackgroundDlg * self)
318 const gchar *image = NULL;
319 const GdkColor *color = NULL;
320 IRRECO_ENTER
322 switch (self->type) {
323 case IRRECO_BACKGROUND_DEFAULT:
324 image = irreco_button_layout_default_image;
325 color = &irreco_button_layout_default_color;
326 break;
328 case IRRECO_BACKGROUND_IMAGE:
329 image = self->filename->str;
330 if (irreco_str_isempty(image)) image = NULL;
332 case IRRECO_BACKGROUND_COLOR:
333 g_object_get(G_OBJECT(self->color_button),
334 "color", &color, NULL);
335 break;
338 IRRECO_RETURN_BOOL(irreco_background_dlg_draw_preview_custom(
339 self, image, color));
343 * Draw preview with custom image.
345 gboolean
346 irreco_background_dlg_draw_preview_custom(IrrecoBackgroundDlg * self,
347 const gchar * image,
348 const GdkColor * bg_color)
350 GError *error = NULL;
351 GdkPixbuf *pixbuf = NULL;
352 GdkPixmap *pixmap = NULL;
353 GdkGC *bg_gc = NULL;
354 IRRECO_ENTER
356 g_assert(self != NULL);
358 /* Attempt to load the image. */
359 if (image != NULL) {
360 pixbuf = gdk_pixbuf_new_from_file_at_scale(image,
361 IRRECO_BACKGROUND_PREVIEW_WIDHT,
362 IRRECO_BACKGROUND_PREVIEW_HEIGHT,
363 FALSE, &error);
364 if (irreco_gerror_check_print(&error)) {
365 IRRECO_RETURN_BOOL(FALSE);
369 pixmap = gdk_pixmap_new(GDK_DRAWABLE(
370 self->preview->window),
371 IRRECO_BACKGROUND_PREVIEW_WIDHT,
372 IRRECO_BACKGROUND_PREVIEW_HEIGHT,
373 -1);
375 /* Fill background with solid color. */
376 bg_gc = gdk_gc_new(GDK_DRAWABLE(self->preview->window));
377 gdk_gc_set_rgb_fg_color(bg_gc, bg_color);
378 gdk_gc_set_rgb_bg_color(bg_gc, bg_color);
379 gdk_draw_rectangle(GDK_DRAWABLE(pixmap), bg_gc, TRUE, 0, 0,
380 IRRECO_BACKGROUND_PREVIEW_WIDHT,
381 IRRECO_BACKGROUND_PREVIEW_HEIGHT);
382 g_object_unref(G_OBJECT(bg_gc));
384 /* Draw images to pixmap. */
385 if (pixbuf != NULL) {
386 gdk_draw_pixbuf(GDK_DRAWABLE(pixmap), NULL, pixbuf, 0, 0, 0, 0,
387 IRRECO_BACKGROUND_PREVIEW_WIDHT,
388 IRRECO_BACKGROUND_PREVIEW_HEIGHT,
389 GDK_RGB_DITHER_NORMAL, 0, 0);
392 /* Set background image, and queque redraw, so the image is shown.*/
393 gdk_window_set_back_pixmap(self->preview->window,
394 pixmap, FALSE);
395 gtk_widget_queue_draw_area(self->preview, 0, 0,
396 self->preview->allocation.width,
397 self->preview->allocation.height);
399 if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf));
400 if (pixmap != NULL) g_object_unref(G_OBJECT(pixmap));
401 IRRECO_RETURN_BOOL(TRUE);
404 void irreco_background_dlg_select_image(IrrecoBackgroundDlg * self)
406 GdkColor *color = NULL;
407 GtkWidget *file_dlg = NULL;
408 gchar *image_dir = NULL;
409 IRRECO_ENTER
411 /* Create image select dialog. */
412 file_dlg = hildon_file_chooser_dialog_new(GTK_WINDOW(
413 self->dialog),
414 GTK_FILE_CHOOSER_ACTION_OPEN);
415 gtk_window_set_title(GTK_WINDOW(file_dlg),_("Select background image"));
416 gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(file_dlg), TRUE);
417 image_dir = g_build_path("/", getenv("HOME"), "MyDocs/.images/", NULL);
418 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_dlg),
419 image_dir);
420 g_free(image_dir);
422 /* Loop until user cancels or we get a valid image. */
423 gtk_widget_show_all(GTK_WIDGET(file_dlg));
424 while (gtk_dialog_run(GTK_DIALOG(file_dlg)) == GTK_RESPONSE_OK) {
425 gchar *filename = gtk_file_chooser_get_filename(
426 GTK_FILE_CHOOSER(file_dlg));
427 IRRECO_PRINTF("Attempting to display background "
428 "image: \"%s\".\n", filename);
430 /* Attempt to display the image. */
431 g_object_get(G_OBJECT(self->color_button),
432 "color", &color, NULL);
433 if (irreco_background_dlg_draw_preview_custom(
434 self, filename, color)) {
435 IRRECO_PRINTF("Image OK.\n");
436 irreco_gstring_set_and_free(
437 self->filename, filename);
438 filename = NULL;
439 self->theme_bg_browser->current_image = NULL;
441 /* Set type as image. */
442 if (self->type != IRRECO_BACKGROUND_IMAGE) {
443 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
444 self->radio_image), TRUE);
446 break;
448 /* Cleanup */
449 } else {
450 gchar *basename = g_path_get_basename(filename);
451 irreco_error_dlg_printf(GTK_WINDOW(file_dlg),
452 _("Cannot open image \"%s\""),
453 basename);
454 IRRECO_PRINTF("Image invalid.\n");
455 g_free(basename);
456 g_free(filename);
460 gtk_widget_grab_focus(self->radio_image);
461 gtk_widget_destroy(file_dlg);
462 IRRECO_RETURN
467 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
468 /* Signal handlers. */
469 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
471 void irreco_background_dlg_color_clicked(GtkColorButton *widget,
472 IrrecoBackgroundDlg * self)
474 IRRECO_ENTER
476 /* Make sure the background type is color or image. */
477 if (self->type == IRRECO_BACKGROUND_DEFAULT) {
478 /* This should trigger a redraw ... */
479 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
480 self->radio_color),
481 TRUE);
482 } else {
483 irreco_background_dlg_draw_preview(self);
485 IRRECO_RETURN
488 void irreco_background_dlg_type_toggled(GtkToggleButton * togglebutton,
489 IrrecoBackgroundDlg * self)
491 IrrecoButtonLayoutBgType type;
492 IRRECO_ENTER
494 if (gtk_toggle_button_get_active(togglebutton) == TRUE) {
495 type = (IrrecoButtonLayoutBgType) g_object_get_data(
496 G_OBJECT(togglebutton), "IrrecoButtonLayoutBgType");
497 self->type = type;
498 IRRECO_PRINTF("Type: %i\n", self->type);
501 irreco_background_dlg_draw_preview(self);
502 IRRECO_RETURN
505 void irreco_background_dlg_image_clicked(gpointer * ignore,
506 IrrecoBackgroundDlg * self)
508 IRRECO_ENTER
509 irreco_background_dlg_select_image(self);
510 IRRECO_RETURN
513 void irreco_background_dlg_preview_clicked(gpointer * ignore1,
514 gpointer * ignore2,
515 IrrecoBackgroundDlg * self)
517 IRRECO_ENTER
518 irreco_background_dlg_select_image(self);
519 IRRECO_RETURN
522 void irreco_background_dlg_theme_image_selection_changed(
523 GtkTreeSelection * selection,
524 IrrecoBackgroundDlg * self)
526 IrrecoThemeBg *bg = self->theme_bg_browser->current_image;
527 IRRECO_ENTER
529 if (bg != NULL) {
530 g_string_printf (self->filename, "%s", bg->image_path->str);
532 /* Set type as image. */
533 if (self->type != IRRECO_BACKGROUND_IMAGE) {
534 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
535 self->radio_image), TRUE);
537 } else {
538 g_string_printf (self->filename, "%s", "");
541 irreco_background_dlg_draw_preview(self);
543 IRRECO_RETURN