2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi)
4 * 2008 Joni Kokko (t5kojo01@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_background_dlg.h"
22 #include <hildon/hildon-color-button.h>
23 #include <hildon/hildon-file-chooser-dialog.h>
25 #include "irreco_theme_upload_dlg.h"
26 #include "irreco_theme_creator_dlg.h"
30 * @addtogroup IrrecoBackgroundDlg
33 * Allow user to setup layout background.
40 * Source file of @ref IrrecoBackgroundDlg.
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
49 #define IRRECO_BACKGROUND_PREVIEW_WIDHT (IRRECO_SCREEN_WIDTH / 6)
50 #define IRRECO_BACKGROUND_PREVIEW_HEIGHT (IRRECO_SCREEN_HEIGHT / 6)
54 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
56 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
58 static gboolean
_draw_preview_custom(IrrecoBackgroundDlg
*self
,
60 const GdkColor
*bg_color
);
61 static void _signal_color_clicked(GtkColorButton
*widget
,
62 IrrecoBackgroundDlg
*self
);
63 static void _signal_type_toggled(GtkToggleButton
*togglebutton
,
64 IrrecoBackgroundDlg
*self
);
65 static void _signal_image_clicked(gpointer
*ignore
,
66 IrrecoBackgroundDlg
*self
);
67 static void _signal_preview_clicked(gpointer
*ignore1
,
69 IrrecoBackgroundDlg
*self
);
70 static void _signal_theme_image_selection_changed(GtkTreeSelection
*selection
,
71 IrrecoBackgroundDlg
*self
);
75 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
76 /* Construction & Destruction */
77 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
80 * @name Construction & Destruction
84 G_DEFINE_TYPE(IrrecoBackgroundDlg
, irreco_background_dlg
,
85 IRRECO_TYPE_INTERNAL_DLG
)
87 static void irreco_background_dlg_constructed(GObject
*object
)
89 IrrecoBackgroundDlg
*self
;
94 GtkWidget
*vbox_right
;
95 GtkTable
*table_right
;
97 GtkWidget
*label_left
;
98 GtkWidget
*label_right
;
99 GtkWidget
*label_color
;
100 GtkWidget
*label_image
;
102 GtkWidget
*radio_default_a
;
103 GtkWidget
*radio_color_a
;
104 GtkWidget
*radio_image_a
;
106 GtkWidget
*button_image
;
107 GtkWidget
*preview_frame
;
108 GtkWidget
*preview_event_box
;
111 G_OBJECT_CLASS(irreco_background_dlg_parent_class
)->constructed(object
);
112 self
= IRRECO_BACKGROUND_DLG(object
);
114 /* Construct dialog. */
115 gtk_window_set_title(GTK_WINDOW(self
), _("Background"));
116 gtk_window_set_modal(GTK_WINDOW(self
), TRUE
);
117 gtk_window_set_destroy_with_parent(GTK_WINDOW(self
), TRUE
);
118 gtk_dialog_set_has_separator(GTK_DIALOG(self
), FALSE
);
119 gtk_dialog_add_buttons(GTK_DIALOG(self
),
120 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
121 GTK_STOCK_OK
, GTK_RESPONSE_OK
,
124 /* Create widgets. */
125 vbox
= gtk_vbox_new(0, 0);
126 hbox
= gtk_hbox_new(0, 12);
127 vbox_left
= gtk_vbox_new(0, 0);
128 vbox_right
= gtk_vbox_new(0, 0);
129 self
->notebook
= gtk_notebook_new();
130 label_left
= irreco_gtk_label_bold(_("Background"), 0, 0, 0, 6, 0, 0);
131 label_right
= irreco_gtk_label_bold(_("Select"), 0, 0, 0, 6, 0, 0);
132 label_color
= irreco_gtk_label(_("Color"), 0, 0.5, 0, 0, 12, 0);
133 label_image
= irreco_gtk_label(_("Image"), 0, 0.5, 0, 0, 12, 0);
135 /* Create Background Browser tab. */
136 self
->theme_bg_browser
= irreco_bg_browser_widget_new(
137 irreco_internal_dlg_get_irreco_data(IRRECO_INTERNAL_DLG(self
)));
138 gtk_notebook_append_page(GTK_NOTEBOOK(self
->notebook
),
140 GTK_WIDGET(self
->theme_bg_browser
),
141 0, 0, 1, 1, 8, 8, 8, 8),
142 gtk_label_new("Theme"));
144 /* Create custom tab. */
145 gtk_notebook_append_page(GTK_NOTEBOOK(self
->notebook
),
146 vbox
, gtk_label_new("Custom"));
147 gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(self
)->vbox
),
150 self
->radio_default
=
151 gtk_radio_button_new_with_label(
152 NULL
, _("Default image"));
154 gtk_radio_button_new_with_label_from_widget(
155 GTK_RADIO_BUTTON(self
->radio_default
),
158 gtk_radio_button_new_with_label_from_widget(
159 GTK_RADIO_BUTTON(self
->radio_color
),
160 _("Color and Image"));
161 radio_default_a
= irreco_gtk_pad(self
->radio_default
,
163 radio_color_a
= irreco_gtk_pad(self
->radio_color
,
165 radio_image_a
= irreco_gtk_pad(self
->radio_image
,
168 self
->color_button
= hildon_color_button_new();
169 button_image
= gtk_button_new_with_label(_("Select"));
171 preview_frame
= gtk_frame_new(NULL
);
172 preview_event_box
= gtk_event_box_new();
173 self
->preview
= gtk_drawing_area_new();
174 gtk_drawing_area_size(GTK_DRAWING_AREA(self
->preview
),
175 IRRECO_BACKGROUND_PREVIEW_WIDHT
,
176 IRRECO_BACKGROUND_PREVIEW_HEIGHT
);
179 table_right
= GTK_TABLE(gtk_table_new(2, 2, FALSE
));
180 gtk_table_set_row_spacings(table_right
, 6);
181 gtk_table_set_col_spacings(table_right
, 12);
182 gtk_table_attach_defaults(table_right
, label_color
, 0, 1, 0, 1);
183 gtk_table_attach_defaults(table_right
, label_image
, 0, 1, 1, 2);
184 gtk_table_attach_defaults(table_right
, self
->color_button
,
186 gtk_table_attach_defaults(table_right
, button_image
, 1, 2, 1, 2);
188 gtk_box_pack_start_defaults(GTK_BOX(vbox
),
189 irreco_gtk_pad(hbox
, 12, 0, 12, 12));
190 gtk_box_pack_start_defaults(GTK_BOX(hbox
), vbox_left
);
191 gtk_box_pack_start_defaults(GTK_BOX(hbox
), vbox_right
);
192 gtk_box_pack_start(GTK_BOX(vbox_left
), label_left
, 0, 0, 0);
193 gtk_box_pack_start(GTK_BOX(vbox_left
), radio_default_a
, 0, 0, 0);
194 gtk_box_pack_start(GTK_BOX(vbox_left
), radio_color_a
, 0, 0, 0);
195 gtk_box_pack_start(GTK_BOX(vbox_left
), radio_image_a
, 0, 0, 0);
196 gtk_box_pack_start(GTK_BOX(vbox_right
), label_right
, 0, 0, 0);
197 gtk_box_pack_start(GTK_BOX(vbox_right
), GTK_WIDGET(table_right
),
200 gtk_container_add(GTK_CONTAINER(preview_event_box
), preview_frame
);
201 gtk_container_add(GTK_CONTAINER(preview_frame
),self
->preview
);
202 gtk_box_pack_start_defaults(GTK_BOX(vbox
), irreco_gtk_align(
204 0.5, 0.5, 0, 0, 12, 0, 0, 0));
206 /* Radio button signals. */
207 g_signal_connect(G_OBJECT(self
->radio_default
), "toggled",
208 G_CALLBACK(_signal_type_toggled
),
210 g_object_set_data(G_OBJECT(self
->radio_default
),
211 "IrrecoButtonLayoutBgType",
212 (gpointer
) IRRECO_BACKGROUND_DEFAULT
);
213 g_signal_connect(G_OBJECT(self
->radio_color
), "toggled",
214 G_CALLBACK(_signal_type_toggled
),
216 g_object_set_data(G_OBJECT(self
->radio_color
),
217 "IrrecoButtonLayoutBgType",
218 (gpointer
) IRRECO_BACKGROUND_COLOR
);
219 g_signal_connect(G_OBJECT(self
->radio_image
), "toggled",
220 G_CALLBACK(_signal_type_toggled
),
222 g_object_set_data(G_OBJECT(self
->radio_image
),
223 "IrrecoButtonLayoutBgType",
224 (gpointer
) IRRECO_BACKGROUND_IMAGE
);
226 /* Button signals. */
227 g_signal_connect(G_OBJECT(button_image
), "clicked",
228 G_CALLBACK(_signal_image_clicked
),
230 g_signal_connect(G_OBJECT(self
->color_button
), "clicked",
231 G_CALLBACK(_signal_color_clicked
),
233 g_signal_connect(G_OBJECT(preview_event_box
), "button-release-event",
234 G_CALLBACK(_signal_preview_clicked
),
237 /* Signal handler for theme_bg_browser*/
238 g_signal_connect(G_OBJECT(IRRECO_LISTBOX(
239 self
->theme_bg_browser
->images
)->tree_selection
),
241 G_CALLBACK(_signal_theme_image_selection_changed
),
244 gtk_widget_show_all(GTK_WIDGET(self
));
248 static void irreco_background_dlg_init(IrrecoBackgroundDlg
*self
)
251 self
->filename
= g_string_new(NULL
);
255 static void irreco_background_dlg_finalize(GObject
*object
)
257 IrrecoBackgroundDlg
*self
;
260 self
= IRRECO_BACKGROUND_DLG(object
);
261 g_string_free(self
->filename
, TRUE
);
262 self
->filename
= NULL
;
264 G_OBJECT_CLASS(irreco_background_dlg_parent_class
)->finalize(object
);
268 static void irreco_background_dlg_class_init(IrrecoBackgroundDlgClass
*klass
)
270 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
271 /* IrrecoDlgClass* parent_class = IRRECO_DLG_CLASS (klass); */
273 object_class
->finalize
= irreco_background_dlg_finalize
;
274 object_class
->constructed
= irreco_background_dlg_constructed
;
277 GtkWidget
*irreco_background_dlg_new(IrrecoData
*irreco_data
,
278 GtkWindow
*parent_window
)
280 IrrecoBackgroundDlg
*self
;
283 self
= g_object_new(IRRECO_TYPE_BACKGROUND_DLG
,
284 "irreco-data", irreco_data
,
286 irreco_dlg_set_parent(IRRECO_DLG(self
), parent_window
);
287 IRRECO_RETURN_PTR(self
);
292 * @todo Replace calls to irreco_background_dlg_create() with
293 * irreco_background_dlg_new().
295 IrrecoBackgroundDlg
*irreco_background_dlg_create(IrrecoData
*irreco_data
,
296 GtkWindow
*parent_window
)
299 IRRECO_RETURN_PTR(irreco_background_dlg_new(
300 irreco_data
, parent_window
));
305 * @todo Replace calls to irreco_background_dlg_destroy() with
306 * gtk_widget_destroy().
308 void irreco_background_dlg_destroy(IrrecoBackgroundDlg
* self
)
311 gtk_widget_destroy(GTK_WIDGET(self
));
319 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
320 /* Private Functions */
321 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
324 * @name Private Functions
328 static void _sync_radio(IrrecoBackgroundDlg
*self
)
331 switch (self
->type
) {
332 case IRRECO_BACKGROUND_DEFAULT
:
333 gtk_widget_grab_focus(self
->radio_default
);
334 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
335 self
->radio_default
),
339 case IRRECO_BACKGROUND_COLOR
:
340 gtk_widget_grab_focus(self
->radio_color
);
341 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
346 case IRRECO_BACKGROUND_IMAGE
:
347 gtk_widget_grab_focus(self
->radio_image
);
348 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
357 * Draw preview with current image.
359 static gboolean
_draw_preview(IrrecoBackgroundDlg
*self
)
361 const gchar
*image
= NULL
;
362 const GdkColor
*color
= NULL
;
365 switch (self
->type
) {
366 case IRRECO_BACKGROUND_DEFAULT
:
367 image
= irreco_button_layout_default_image
;
368 color
= &irreco_button_layout_default_color
;
371 case IRRECO_BACKGROUND_IMAGE
:
372 image
= self
->filename
->str
;
373 if (irreco_str_isempty(image
)) image
= NULL
;
375 case IRRECO_BACKGROUND_COLOR
:
376 g_object_get(G_OBJECT(self
->color_button
),
377 "color", &color
, NULL
);
381 IRRECO_RETURN_BOOL(_draw_preview_custom(
382 self
, image
, color
));
386 * Draw preview with custom image.
388 static gboolean
_draw_preview_custom(IrrecoBackgroundDlg
*self
,
390 const GdkColor
*bg_color
)
392 GError
*error
= NULL
;
393 GdkPixbuf
*pixbuf
= NULL
;
394 GdkPixmap
*pixmap
= NULL
;
398 g_assert(self
!= NULL
);
400 /* Attempt to load the image. */
402 pixbuf
= gdk_pixbuf_new_from_file_at_scale(image
,
403 IRRECO_BACKGROUND_PREVIEW_WIDHT
,
404 IRRECO_BACKGROUND_PREVIEW_HEIGHT
,
406 if (irreco_gerror_check_print(&error
)) {
407 IRRECO_RETURN_BOOL(FALSE
);
411 gtk_widget_realize(GTK_WIDGET(self
->preview
));
412 pixmap
= gdk_pixmap_new(GDK_DRAWABLE(
413 self
->preview
->window
),
414 IRRECO_BACKGROUND_PREVIEW_WIDHT
,
415 IRRECO_BACKGROUND_PREVIEW_HEIGHT
,
418 /* Fill background with solid color. */
419 bg_gc
= gdk_gc_new(GDK_DRAWABLE(self
->preview
->window
));
420 gdk_gc_set_rgb_fg_color(bg_gc
, bg_color
);
421 gdk_gc_set_rgb_bg_color(bg_gc
, bg_color
);
422 gdk_draw_rectangle(GDK_DRAWABLE(pixmap
), bg_gc
, TRUE
, 0, 0,
423 IRRECO_BACKGROUND_PREVIEW_WIDHT
,
424 IRRECO_BACKGROUND_PREVIEW_HEIGHT
);
425 g_object_unref(G_OBJECT(bg_gc
));
427 /* Draw images to pixmap. */
428 if (pixbuf
!= NULL
) {
429 gdk_draw_pixbuf(GDK_DRAWABLE(pixmap
), NULL
, pixbuf
, 0, 0, 0, 0,
430 IRRECO_BACKGROUND_PREVIEW_WIDHT
,
431 IRRECO_BACKGROUND_PREVIEW_HEIGHT
,
432 GDK_RGB_DITHER_NORMAL
, 0, 0);
435 /* Set background image, and queque redraw, so the image is shown.*/
436 gdk_window_set_back_pixmap(self
->preview
->window
,
438 gtk_widget_queue_draw_area(self
->preview
, 0, 0,
439 self
->preview
->allocation
.width
,
440 self
->preview
->allocation
.height
);
442 if (pixbuf
!= NULL
) g_object_unref(G_OBJECT(pixbuf
));
443 if (pixmap
!= NULL
) g_object_unref(G_OBJECT(pixmap
));
444 IRRECO_RETURN_BOOL(TRUE
);
447 static void _select_image(IrrecoBackgroundDlg
*self
)
449 GdkColor
*color
= NULL
;
450 GtkWidget
*file_dlg
= NULL
;
451 gchar
*image_dir
= NULL
;
454 /* Create image select dialog. */
455 file_dlg
= hildon_file_chooser_dialog_new(GTK_WINDOW(self
),
456 GTK_FILE_CHOOSER_ACTION_OPEN
);
457 gtk_window_set_title(GTK_WINDOW(file_dlg
),_("Select background image"));
458 gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(file_dlg
), TRUE
);
459 image_dir
= g_build_path("/", getenv("HOME"), "MyDocs/.images/", NULL
);
460 gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_dlg
),
464 /* Loop until user cancels or we get a valid image. */
465 gtk_widget_show_all(GTK_WIDGET(file_dlg
));
466 while (gtk_dialog_run(GTK_DIALOG(file_dlg
)) == GTK_RESPONSE_OK
) {
467 gchar
*filename
= gtk_file_chooser_get_filename(
468 GTK_FILE_CHOOSER(file_dlg
));
469 IRRECO_PRINTF("Attempting to display background "
470 "image: \"%s\".\n", filename
);
472 /* Attempt to display the image. */
473 g_object_get(G_OBJECT(self
->color_button
),
474 "color", &color
, NULL
);
475 if (_draw_preview_custom(
476 self
, filename
, color
)) {
477 IRRECO_PRINTF("Image OK.\n");
478 irreco_gstring_set_and_free(
479 self
->filename
, filename
);
481 self
->theme_bg_browser
->current_image
= NULL
;
483 /* Set type as image. */
484 if (self
->type
!= IRRECO_BACKGROUND_IMAGE
) {
485 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
486 self
->radio_image
), TRUE
);
492 gchar
*basename
= g_path_get_basename(filename
);
493 irreco_error_dlg_printf(GTK_WINDOW(file_dlg
),
494 _("Cannot open image \"%s\""),
496 IRRECO_PRINTF("Image invalid.\n");
502 gtk_widget_grab_focus(self
->radio_image
);
503 gtk_widget_destroy(file_dlg
);
511 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
512 /* Public Functions */
513 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
516 * @name Public Functions
521 * Show dialog, and ask user for input.
523 gboolean
irreco_background_dlg_run(IrrecoBackgroundDlg
*self
,
524 IrrecoButtonLayout
*irreco_layout
)
529 self
->type
= irreco_button_layout_get_bg_type(irreco_layout
);
530 irreco_gstring_set(self
->filename
,
531 irreco_button_layout_get_bg_image(irreco_layout
));
532 hildon_color_button_set_color(
533 HILDON_COLOR_BUTTON(self
->color_button
),
534 irreco_button_layout_get_bg_color(irreco_layout
));
540 if (gtk_dialog_run(GTK_DIALOG(self
)) == GTK_RESPONSE_OK
) {
542 g_object_get(G_OBJECT(self
->color_button
),
543 "color", &color
, NULL
);
544 irreco_button_layout_set_bg_type(irreco_layout
,
546 irreco_button_layout_set_bg_color(irreco_layout
, color
);
547 irreco_button_layout_set_bg_image(
548 irreco_layout
, self
->filename
->str
);
550 IRRECO_PRINTF("%i\n",
551 irreco_button_layout_get_bg_type(irreco_layout
));
553 IRRECO_RETURN_BOOL(TRUE
);
555 IRRECO_RETURN_BOOL(FALSE
);
562 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
563 /* Events and Callbacks */
564 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
567 * @name Events and Callbacks
571 static void _signal_color_clicked(GtkColorButton
*widget
,
572 IrrecoBackgroundDlg
*self
)
576 /* Make sure the background type is color or image. */
577 if (self
->type
== IRRECO_BACKGROUND_DEFAULT
) {
578 /* This should trigger a redraw ... */
579 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
588 static void _signal_type_toggled(GtkToggleButton
*togglebutton
,
589 IrrecoBackgroundDlg
*self
)
591 IrrecoButtonLayoutBgType type
;
594 if (gtk_toggle_button_get_active(togglebutton
) == TRUE
) {
595 type
= (IrrecoButtonLayoutBgType
) g_object_get_data(
596 G_OBJECT(togglebutton
), "IrrecoButtonLayoutBgType");
598 IRRECO_PRINTF("Type: %i\n", self
->type
);
605 static void _signal_image_clicked(gpointer
*ignore
,
606 IrrecoBackgroundDlg
*self
)
613 static void _signal_preview_clicked(gpointer
*ignore1
,
615 IrrecoBackgroundDlg
*self
)
622 static void _signal_theme_image_selection_changed(GtkTreeSelection
*selection
,
623 IrrecoBackgroundDlg
*self
)
625 IrrecoThemeBg
*bg
= self
->theme_bg_browser
->current_image
;
629 g_string_printf (self
->filename
, "%s", bg
->image_path
->str
);
631 /* Set type as image. */
632 if (self
->type
!= IRRECO_BACKGROUND_IMAGE
) {
633 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
634 self
->radio_image
), TRUE
);
637 g_string_printf (self
->filename
, "%s", "");