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 * @typedef IrrecoWindow
25 * Base class for other Irreco windows.
30 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
32 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
33 static void irreco_window_fix_scrollbar_increment(GtkAdjustment
* adjustment
);
34 static gboolean
irreco_window_delete_event(GtkWidget
*widget
,
37 static gboolean
irreco_window_state_event(GtkWidget
*widget
,
38 GdkEventWindowState
*event
,
43 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
44 /* Construction & Destruction */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
47 G_DEFINE_TYPE(IrrecoWindow
, irreco_window
, HILDON_TYPE_WINDOW
)
49 static void irreco_window_finalize(GObject
*object
)
51 G_OBJECT_CLASS (irreco_window_parent_class
)->finalize (object
);
54 static void irreco_window_class_init(IrrecoWindowClass
*klass
)
56 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
57 object_class
->finalize
= irreco_window_finalize
;
60 static void irreco_window_init(IrrecoWindow
*self
)
67 * There is a little problem with the HildonWindow and the skin borders
68 * around it, for some reason the hildon window includes the borders of
69 * the windows _inside_ the window. This means that mouse events dont
70 * properly align to the left top corner of the window, and that the
71 * size of the window also contains the size of the borders. By creaging
72 * an eventbox, which has it's own GdkWindow, we can get the real usable
75 self
->event_box
= gtk_event_box_new();
76 gtk_event_box_set_visible_window(GTK_EVENT_BOX(self
->event_box
),
78 gtk_container_add(GTK_CONTAINER(self
), GTK_WIDGET(self
->event_box
));
80 /* Create scrollable GtkLayout. */
81 self
->scrolled_window
= gtk_scrolled_window_new(NULL
, NULL
);
82 gtk_container_add(GTK_CONTAINER(self
->event_box
),
83 self
->scrolled_window
);
84 self
->layout
= gtk_layout_new(NULL
, NULL
);
85 gtk_container_add(GTK_CONTAINER(self
->scrolled_window
),
88 /* Setup size & scrollbars. */
89 gtk_layout_set_size(GTK_LAYOUT(self
->layout
),
91 IRRECO_LAYOUT_HEIGHT
);
92 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(
93 self
->scrolled_window
),
95 GTK_POLICY_AUTOMATIC
);
96 irreco_window_fix_scrollbar_increment(
97 gtk_scrolled_window_get_hadjustment(
98 GTK_SCROLLED_WINDOW(self
->scrolled_window
)));
99 irreco_window_fix_scrollbar_increment(
100 gtk_scrolled_window_get_vadjustment(
101 GTK_SCROLLED_WINDOW(self
->scrolled_window
)));
104 g_signal_connect(G_OBJECT(self
), "delete-event",
105 G_CALLBACK(irreco_window_delete_event
), NULL
);
106 g_signal_connect(G_OBJECT(self
), "window-state-event",
107 G_CALLBACK(irreco_window_state_event
), self
);
108 gtk_widget_show_all(GTK_WIDGET(self
));
112 GtkWidget
* irreco_window_new()
117 self
= g_object_new(IRRECO_TYPE_WINDOW
, NULL
);
118 hildon_program_add_window(HILDON_PROGRAM(hildon_program_get_instance()),
119 HILDON_WINDOW(self
));
120 IRRECO_RETURN_PTR(self
);
125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
126 /* Private Functions */
127 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
130 * Set scrollbar so that a click will move
132 static void irreco_window_fix_scrollbar_increment(GtkAdjustment
* adjustment
)
137 hidden_area
= adjustment
->upper
- adjustment
->page_size
;
138 adjustment
->page_increment
= hidden_area
;
139 adjustment
->step_increment
= hidden_area
;
146 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
148 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
151 * A pixbuf loading frapper around irreco_window_set_background_buf().
153 gboolean
irreco_window_set_background_image(IrrecoWindow
*self
,
154 const GdkColor
* color
,
155 const gchar
* image1
,
156 const gchar
* image2
)
158 GError
*error
= NULL
;
159 GdkPixbuf
*pixbuf1
= NULL
;
160 GdkPixbuf
*pixbuf2
= NULL
;
163 g_assert(self
!= NULL
);
165 if (image1
!= NULL
) {
166 pixbuf1
= gdk_pixbuf_new_from_file_at_scale(
167 image1
, IRRECO_SCREEN_WIDTH
, IRRECO_SCREEN_HEIGHT
,
169 if (irreco_gerror_check_print(&error
)) {
170 IRRECO_RETURN_BOOL(FALSE
);
174 if (image2
!= NULL
) {
175 pixbuf2
= gdk_pixbuf_new_from_file_at_scale(
176 image1
, IRRECO_SCREEN_WIDTH
, IRRECO_SCREEN_HEIGHT
,
178 if (irreco_gerror_check_print(&error
)) {
179 g_object_unref(G_OBJECT(pixbuf1
));
180 IRRECO_RETURN_BOOL(FALSE
);
184 irreco_window_set_background_buf(self
, color
, pixbuf1
, pixbuf2
);
185 if (pixbuf1
!= NULL
) g_object_unref(G_OBJECT(pixbuf1
));
186 if (pixbuf2
!= NULL
) g_object_unref(G_OBJECT(pixbuf2
));
187 IRRECO_RETURN_BOOL(TRUE
);
191 * Set background image of scrolled window.
193 * This functions will:
194 * @li Fill the background with the background color.
195 * @li Draw the first image on top of the background color.
196 * @li Draw the second image on top of the first image.
198 * @param pixbuf1 First image pixbuf, or NULL.
199 * @param pixbuf2 Second image pixbuf, or NULL.
201 void irreco_window_set_background_buf(IrrecoWindow
*self
,
202 const GdkColor
* color
,
206 gint width
= IRRECO_SCREEN_WIDTH
;
207 gint height
= IRRECO_SCREEN_HEIGHT
;
208 GdkPixmap
*pixmap
= NULL
;
212 /* Create and fill pixmap with background color. */
213 pixmap
= gdk_pixmap_new(GDK_DRAWABLE(GTK_LAYOUT(
214 self
->layout
)->bin_window
),
217 /* Fill background with solid color. */
218 bg_gc
= gdk_gc_new(GDK_DRAWABLE(GTK_LAYOUT(
219 self
->layout
)->bin_window
));
220 gdk_gc_set_rgb_fg_color(bg_gc
, color
);
221 gdk_gc_set_rgb_bg_color(bg_gc
, color
);
222 gdk_draw_rectangle(GDK_DRAWABLE(pixmap
),
223 bg_gc
, TRUE
, 0, 0, width
, height
);
224 g_object_unref(G_OBJECT(bg_gc
));
226 /* Draw images to pixmap. */
227 if (pixbuf1
!= NULL
) {
228 width
= gdk_pixbuf_get_width(pixbuf1
);
229 height
= gdk_pixbuf_get_height(pixbuf1
);
230 gdk_draw_pixbuf(GDK_DRAWABLE(pixmap
), NULL
, pixbuf1
, 0, 0, 0, 0,
231 width
, height
, GDK_RGB_DITHER_NORMAL
, 0, 0);
233 if (pixbuf2
!= NULL
) {
234 width
= gdk_pixbuf_get_width(pixbuf2
);
235 height
= gdk_pixbuf_get_height(pixbuf2
);
236 gdk_draw_pixbuf(GDK_DRAWABLE(pixmap
), NULL
, pixbuf2
,
237 0, 0, 0, 0, width
, height
,
238 GDK_RGB_DITHER_NORMAL
, 0, 0);
241 /* Set background image, and queque redraw, so the image is shown.*/
242 gdk_window_set_back_pixmap(GTK_LAYOUT(self
->layout
)->bin_window
,
244 gtk_widget_queue_draw_area(GTK_WIDGET(self
->layout
), 0, 0,
245 GTK_WIDGET(self
->layout
)->allocation
.width
,
246 GTK_WIDGET(self
->layout
)->allocation
.height
);
247 g_object_unref(G_OBJECT(pixmap
));
252 * How much of the left-top corner is hidden due to scrolling.
254 void irreco_window_get_scroll_offset(IrrecoWindow
*self
,
255 gdouble
*x
, gdouble
*y
)
258 *x
= gtk_scrolled_window_get_hadjustment(
259 GTK_SCROLLED_WINDOW(self
->scrolled_window
))->value
;
260 *y
= gtk_scrolled_window_get_vadjustment(
261 GTK_SCROLLED_WINDOW(self
->scrolled_window
))->value
;
266 * Adjust scrollbars so that the given point is visible.
268 void irreco_window_scroll_visible(IrrecoWindow
*self
, gdouble x
, gdouble y
)
270 GtkAdjustment
*x_adjustment
, *y_adjustment
;
273 x_adjustment
= gtk_scrolled_window_get_hadjustment(
274 GTK_SCROLLED_WINDOW(self
->scrolled_window
));
275 y_adjustment
= gtk_scrolled_window_get_vadjustment(
276 GTK_SCROLLED_WINDOW(self
->scrolled_window
));
279 if (x_adjustment
->value
+ x_adjustment
->page_size
< x
) {
280 gtk_adjustment_set_value(x_adjustment
,
281 x
- x_adjustment
->page_size
);
283 if (y_adjustment
->value
+ y_adjustment
->page_size
< y
) {
284 gtk_adjustment_set_value(y_adjustment
,
285 y
- y_adjustment
->page_size
);
287 if (x_adjustment
->value
> x
) {
288 gtk_adjustment_set_value(x_adjustment
, x
);
290 if (y_adjustment
->value
> y
) {
291 gtk_adjustment_set_value(y_adjustment
, y
);
297 gboolean
irreco_window_is_fullscreen(IrrecoWindow
*self
)
302 window
= GTK_WIDGET(self
)->window
;
303 IRRECO_RETURN_BOOL(gdk_window_get_state(window
)
304 & GDK_WINDOW_STATE_FULLSCREEN
);
307 void irreco_window_toggle_fullscreen(IrrecoWindow
*self
)
311 if (irreco_window_is_fullscreen(self
)) {
312 gtk_window_unfullscreen(GTK_WINDOW(self
));
314 gtk_window_fullscreen(GTK_WINDOW(self
));
320 void irreco_window_scrollbar_hide(IrrecoWindow
*self
)
323 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(
324 self
->scrolled_window
),
330 void irreco_window_scrollbar_show(IrrecoWindow
*self
)
333 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(
334 self
->scrolled_window
),
335 GTK_POLICY_AUTOMATIC
,
336 GTK_POLICY_AUTOMATIC
);
342 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
344 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
346 static gboolean
irreco_window_delete_event(GtkWidget
*widget
,
351 if (irreco_yes_no_dlg(GTK_WINDOW(widget
),
352 _("Exit Ir Remote Control?"))) {
354 IRRECO_RETURN_BOOL(FALSE
);
356 IRRECO_RETURN_BOOL(TRUE
);
359 static gboolean
irreco_window_state_event(GtkWidget
*widget
,
360 GdkEventWindowState
*event
,
365 /* Hide scrollbars in fullscreen mode. */
366 if (event
->changed_mask
& GDK_WINDOW_STATE_FULLSCREEN
) {
367 if (event
->new_window_state
& GDK_WINDOW_STATE_FULLSCREEN
) {
368 irreco_window_scrollbar_hide(self
);
370 irreco_window_scrollbar_show(self
);
374 IRRECO_RETURN_BOOL(FALSE
);