Clean code and added a few amendments (if()).
[irreco.git] / irreco / src / core / irreco_window.c
bloba15194af1bca1b96d6ba64974bf620300dddc098
1 /*
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"
22 /**
23 * @addtogroup IrrecoWindow
24 * @ingroup Irreco
26 * Base class for other Irreco windows.
28 * @{
31 /**
32 * @file
33 * Source file of @ref IrrecoWindow.
37 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
38 /* Prototypes */
39 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
40 static void irreco_window_fix_scrollbar_increment(GtkAdjustment* adjustment);
41 static gboolean irreco_window_delete_event(GtkWidget *widget,
42 GdkEvent *event,
43 gpointer *data);
44 static gboolean irreco_window_state_event(GtkWidget *widget,
45 GdkEventWindowState *event,
46 IrrecoWindow *self);
50 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
51 /* Construction & Destruction */
52 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
54 /**
55 * @name Construction & Destruction
56 * @{
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)
74 IRRECO_ENTER
77 * Create eventbox
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
85 * area.
87 self->event_box = gtk_event_box_new();
88 gtk_event_box_set_visible_window(GTK_EVENT_BOX(self->event_box),
89 TRUE);
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),
98 self->layout);
100 /* Setup size & scrollbars. */
101 gtk_layout_set_size(GTK_LAYOUT(self->layout),
102 IRRECO_LAYOUT_WIDTH,
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)));
115 /* Signals. */
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));
121 IRRECO_RETURN
124 GtkWidget* irreco_window_new()
126 IrrecoWindow* self;
127 IRRECO_ENTER
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);
135 /** @} */
139 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
140 /* Private Functions */
141 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
144 * @name Private Functions
145 * @{
149 * Set scrollbar so that a click will move
151 static void irreco_window_fix_scrollbar_increment(GtkAdjustment* adjustment)
153 gint hidden_area;
154 IRRECO_ENTER
156 hidden_area = adjustment->upper - adjustment->page_size;
157 adjustment->page_increment = hidden_area;
158 adjustment->step_increment = hidden_area;
160 IRRECO_RETURN
163 /** @} */
167 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
168 /* Functions */
169 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
172 * @name Public Functions
173 * @{
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;
187 IRRECO_ENTER
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,
194 FALSE, &error);
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,
203 FALSE, &error);
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,
229 GdkPixbuf * pixbuf1,
230 GdkPixbuf * pixbuf2)
232 gint width = IRRECO_SCREEN_WIDTH;
233 gint height = IRRECO_SCREEN_HEIGHT;
234 GdkPixmap *pixmap = NULL;
235 GdkGC *bg_gc = NULL;
236 IRRECO_ENTER
238 /* Create and fill pixmap with background color. */
239 pixmap = gdk_pixmap_new(GDK_DRAWABLE(GTK_LAYOUT(
240 self->layout)->bin_window),
241 width, height, -1);
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,
269 pixmap, FALSE);
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));
274 IRRECO_RETURN
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)
283 IRRECO_ENTER
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;
288 IRRECO_RETURN
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;
297 IRRECO_ENTER
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);
320 IRRECO_RETURN
323 gboolean irreco_window_is_fullscreen(IrrecoWindow *self)
325 GdkWindow *window;
326 IRRECO_ENTER
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)
335 IRRECO_ENTER
337 if (irreco_window_is_fullscreen(self)) {
338 gtk_window_unfullscreen(GTK_WINDOW(self));
339 } else {
340 gtk_window_fullscreen(GTK_WINDOW(self));
343 IRRECO_RETURN
346 void irreco_window_scrollbar_hide(IrrecoWindow *self)
348 IRRECO_ENTER
349 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(
350 self->scrolled_window),
351 GTK_POLICY_NEVER,
352 GTK_POLICY_NEVER);
353 IRRECO_RETURN
356 void irreco_window_scrollbar_show(IrrecoWindow *self)
358 IRRECO_ENTER
359 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(
360 self->scrolled_window),
361 GTK_POLICY_AUTOMATIC,
362 GTK_POLICY_AUTOMATIC);
363 IRRECO_RETURN
366 /** @} */
370 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
371 /* Events */
372 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
375 * @name Events
376 * @{
379 static gboolean irreco_window_delete_event(GtkWidget *widget,
380 GdkEvent *event,
381 gpointer *data)
383 IRRECO_ENTER
384 if (irreco_yes_no_dlg(GTK_WINDOW(widget),
385 _("Exit Ir Remote Control?"))) {
386 gtk_main_quit();
387 IRRECO_RETURN_BOOL(FALSE);
389 IRRECO_RETURN_BOOL(TRUE);
392 static gboolean irreco_window_state_event(GtkWidget *widget,
393 GdkEventWindowState *event,
394 IrrecoWindow *self)
396 IRRECO_ENTER
398 /* Hide scrollbars in fullscreen mode. */
399 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
400 if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) {
401 irreco_window_scrollbar_hide(self);
402 } else {
403 irreco_window_scrollbar_show(self);
407 IRRECO_RETURN_BOOL(FALSE);
410 /** @} */
411 /** @} */