2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.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_window.h"
23 * @addtogroup IrrecoWindow
26 * Base class for other Irreco windows.
33 * Source file of @ref IrrecoWindow.
37 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
39 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
40 static void irreco_window_fix_scrollbar_increment(GtkAdjustment
* adjustment
);
41 static gboolean
irreco_window_delete_event(GtkWidget
*widget
,
44 static gboolean
irreco_window_state_event(GtkWidget
*widget
,
45 GdkEventWindowState
*event
,
50 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
51 /* Construction & Destruction */
52 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
55 * @name Construction & Destruction
59 G_DEFINE_TYPE(IrrecoWindow
, irreco_window
, HILDON_TYPE_WINDOW
)
61 static void irreco_window_finalize(GObject
*object
)
63 G_OBJECT_CLASS (irreco_window_parent_class
)->finalize (object
);
66 static void irreco_window_class_init(IrrecoWindowClass
*klass
)
68 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
69 object_class
->finalize
= irreco_window_finalize
;
72 static void irreco_window_init(IrrecoWindow
*self
)
79 * There is a little problem with the HildonWindow and the skin borders
80 * around it, for some reason the hildon window includes the borders of
81 * the windows _inside_ the window. This means that mouse events dont
82 * properly align to the left top corner of the window, and that the
83 * size of the window also contains the size of the borders. By creaging
84 * an eventbox, which has it's own GdkWindow, we can get the real usable
87 self
->event_box
= gtk_event_box_new();
88 gtk_event_box_set_visible_window(GTK_EVENT_BOX(self
->event_box
),
90 gtk_container_add(GTK_CONTAINER(self
), GTK_WIDGET(self
->event_box
));
92 /* Create scrollable GtkLayout. */
93 self
->scrolled_window
= gtk_scrolled_window_new(NULL
, NULL
);
94 gtk_container_add(GTK_CONTAINER(self
->event_box
),
95 self
->scrolled_window
);
96 self
->layout
= gtk_layout_new(NULL
, NULL
);
97 gtk_container_add(GTK_CONTAINER(self
->scrolled_window
),
100 /* Setup size & scrollbars. */
101 gtk_layout_set_size(GTK_LAYOUT(self
->layout
),
103 IRRECO_LAYOUT_HEIGHT
);
104 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(
105 self
->scrolled_window
),
106 GTK_POLICY_AUTOMATIC
,
107 GTK_POLICY_AUTOMATIC
);
108 irreco_window_fix_scrollbar_increment(
109 gtk_scrolled_window_get_hadjustment(
110 GTK_SCROLLED_WINDOW(self
->scrolled_window
)));
111 irreco_window_fix_scrollbar_increment(
112 gtk_scrolled_window_get_vadjustment(
113 GTK_SCROLLED_WINDOW(self
->scrolled_window
)));
116 g_signal_connect(G_OBJECT(self
), "delete-event",
117 G_CALLBACK(irreco_window_delete_event
), NULL
);
118 g_signal_connect(G_OBJECT(self
), "window-state-event",
119 G_CALLBACK(irreco_window_state_event
), self
);
120 gtk_widget_show_all(GTK_WIDGET(self
));
124 GtkWidget
* irreco_window_new()
129 self
= g_object_new(IRRECO_TYPE_WINDOW
, NULL
);
130 hildon_program_add_window(HILDON_PROGRAM(hildon_program_get_instance()),
131 HILDON_WINDOW(self
));
132 IRRECO_RETURN_PTR(self
);
139 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
140 /* Private Functions */
141 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
144 * @name Private Functions
149 * Set scrollbar so that a click will move
151 static void irreco_window_fix_scrollbar_increment(GtkAdjustment
* adjustment
)
156 hidden_area
= adjustment
->upper
- adjustment
->page_size
;
157 adjustment
->page_increment
= hidden_area
;
158 adjustment
->step_increment
= hidden_area
;
167 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
169 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
172 * @name Public Functions
177 * A pixbuf loading frapper around irreco_window_set_background_buf().
179 gboolean
irreco_window_set_background_image(IrrecoWindow
*self
,
180 const GdkColor
* color
,
181 const gchar
* image1
,
182 const gchar
* image2
)
184 GError
*error
= NULL
;
185 GdkPixbuf
*pixbuf1
= NULL
;
186 GdkPixbuf
*pixbuf2
= NULL
;
189 g_assert(self
!= NULL
);
191 if (image1
!= NULL
) {
192 pixbuf1
= gdk_pixbuf_new_from_file_at_scale(
193 image1
, IRRECO_SCREEN_WIDTH
, IRRECO_SCREEN_HEIGHT
,
195 if (irreco_gerror_check_print(&error
)) {
196 IRRECO_RETURN_BOOL(FALSE
);
200 if (image2
!= NULL
) {
201 pixbuf2
= gdk_pixbuf_new_from_file_at_scale(
202 image1
, IRRECO_SCREEN_WIDTH
, IRRECO_SCREEN_HEIGHT
,
204 if (irreco_gerror_check_print(&error
)) {
205 g_object_unref(G_OBJECT(pixbuf1
));
206 IRRECO_RETURN_BOOL(FALSE
);
210 irreco_window_set_background_buf(self
, color
, pixbuf1
, pixbuf2
);
211 if (pixbuf1
!= NULL
) g_object_unref(G_OBJECT(pixbuf1
));
212 if (pixbuf2
!= NULL
) g_object_unref(G_OBJECT(pixbuf2
));
213 IRRECO_RETURN_BOOL(TRUE
);
217 * Set background image of scrolled window.
219 * This functions will:
220 * @li Fill the background with the background color.
221 * @li Draw the first image on top of the background color.
222 * @li Draw the second image on top of the first image.
224 * @param pixbuf1 First image pixbuf, or NULL.
225 * @param pixbuf2 Second image pixbuf, or NULL.
227 void irreco_window_set_background_buf(IrrecoWindow
*self
,
228 const GdkColor
* color
,
232 gint width
= IRRECO_SCREEN_WIDTH
;
233 gint height
= IRRECO_SCREEN_HEIGHT
;
234 GdkPixmap
*pixmap
= NULL
;
238 /* Create and fill pixmap with background color. */
239 pixmap
= gdk_pixmap_new(GDK_DRAWABLE(GTK_LAYOUT(
240 self
->layout
)->bin_window
),
243 /* Fill background with solid color. */
244 bg_gc
= gdk_gc_new(GDK_DRAWABLE(GTK_LAYOUT(
245 self
->layout
)->bin_window
));
246 gdk_gc_set_rgb_fg_color(bg_gc
, color
);
247 gdk_gc_set_rgb_bg_color(bg_gc
, color
);
248 gdk_draw_rectangle(GDK_DRAWABLE(pixmap
),
249 bg_gc
, TRUE
, 0, 0, width
, height
);
250 g_object_unref(G_OBJECT(bg_gc
));
252 /* Draw images to pixmap. */
253 if (pixbuf1
!= NULL
) {
254 width
= gdk_pixbuf_get_width(pixbuf1
);
255 height
= gdk_pixbuf_get_height(pixbuf1
);
256 gdk_draw_pixbuf(GDK_DRAWABLE(pixmap
), NULL
, pixbuf1
, 0, 0, 0, 0,
257 width
, height
, GDK_RGB_DITHER_NORMAL
, 0, 0);
259 if (pixbuf2
!= NULL
) {
260 width
= gdk_pixbuf_get_width(pixbuf2
);
261 height
= gdk_pixbuf_get_height(pixbuf2
);
262 gdk_draw_pixbuf(GDK_DRAWABLE(pixmap
), NULL
, pixbuf2
,
263 0, 0, 0, 0, width
, height
,
264 GDK_RGB_DITHER_NORMAL
, 0, 0);
267 /* Set background image, and queque redraw, so the image is shown.*/
268 gdk_window_set_back_pixmap(GTK_LAYOUT(self
->layout
)->bin_window
,
270 gtk_widget_queue_draw_area(GTK_WIDGET(self
->layout
), 0, 0,
271 GTK_WIDGET(self
->layout
)->allocation
.width
,
272 GTK_WIDGET(self
->layout
)->allocation
.height
);
273 g_object_unref(G_OBJECT(pixmap
));
278 * How much of the left-top corner is hidden due to scrolling.
280 void irreco_window_get_scroll_offset(IrrecoWindow
*self
,
281 gdouble
*x
, gdouble
*y
)
284 *x
= gtk_scrolled_window_get_hadjustment(
285 GTK_SCROLLED_WINDOW(self
->scrolled_window
))->value
;
286 *y
= gtk_scrolled_window_get_vadjustment(
287 GTK_SCROLLED_WINDOW(self
->scrolled_window
))->value
;
292 * Adjust scrollbars so that the given point is visible.
294 void irreco_window_scroll_visible(IrrecoWindow
*self
, gdouble x
, gdouble y
)
296 GtkAdjustment
*x_adjustment
, *y_adjustment
;
299 x_adjustment
= gtk_scrolled_window_get_hadjustment(
300 GTK_SCROLLED_WINDOW(self
->scrolled_window
));
301 y_adjustment
= gtk_scrolled_window_get_vadjustment(
302 GTK_SCROLLED_WINDOW(self
->scrolled_window
));
305 if (x_adjustment
->value
+ x_adjustment
->page_size
< x
) {
306 gtk_adjustment_set_value(x_adjustment
,
307 x
- x_adjustment
->page_size
);
309 if (y_adjustment
->value
+ y_adjustment
->page_size
< y
) {
310 gtk_adjustment_set_value(y_adjustment
,
311 y
- y_adjustment
->page_size
);
313 if (x_adjustment
->value
> x
) {
314 gtk_adjustment_set_value(x_adjustment
, x
);
316 if (y_adjustment
->value
> y
) {
317 gtk_adjustment_set_value(y_adjustment
, y
);
323 gboolean
irreco_window_is_fullscreen(IrrecoWindow
*self
)
328 window
= GTK_WIDGET(self
)->window
;
329 IRRECO_RETURN_BOOL(gdk_window_get_state(window
)
330 & GDK_WINDOW_STATE_FULLSCREEN
);
333 void irreco_window_toggle_fullscreen(IrrecoWindow
*self
)
337 if (irreco_window_is_fullscreen(self
)) {
338 gtk_window_unfullscreen(GTK_WINDOW(self
));
340 gtk_window_fullscreen(GTK_WINDOW(self
));
346 void irreco_window_scrollbar_hide(IrrecoWindow
*self
)
349 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(
350 self
->scrolled_window
),
356 void irreco_window_scrollbar_show(IrrecoWindow
*self
)
359 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(
360 self
->scrolled_window
),
361 GTK_POLICY_AUTOMATIC
,
362 GTK_POLICY_AUTOMATIC
);
370 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
372 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
379 static gboolean
irreco_window_delete_event(GtkWidget
*widget
,
383 gboolean rvalue
= TRUE
;
387 msg
= g_string_new(NULL
);
388 g_string_printf(msg
, _("Exit %s?"), IRRECO_APP_NAME_CONBINED
);
390 if (irreco_yes_no_dlg(GTK_WINDOW(widget
), msg
->str
)) {
395 g_string_free(msg
, TRUE
);
396 IRRECO_RETURN_BOOL(rvalue
);
399 static gboolean
irreco_window_state_event(GtkWidget
*widget
,
400 GdkEventWindowState
*event
,
405 /* Hide scrollbars in fullscreen mode. */
406 if (event
->changed_mask
& GDK_WINDOW_STATE_FULLSCREEN
) {
407 if (event
->new_window_state
& GDK_WINDOW_STATE_FULLSCREEN
) {
408 irreco_window_scrollbar_hide(self
);
410 irreco_window_scrollbar_show(self
);
414 IRRECO_RETURN_BOOL(FALSE
);