Modified xmlrpc to send irreco version in correct format.
[irreco.git] / irreco / src / core / irreco_window.c
blob8d6d8d506a6747e1d0c4ee316febaa42e24c59f1
1 /*
2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi)
4 *
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.
9 *
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 * @typedef IrrecoWindow
25 * Base class for other Irreco windows.
30 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
31 /* Prototypes */
32 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
33 static void irreco_window_fix_scrollbar_increment(GtkAdjustment* adjustment);
34 static gboolean irreco_window_delete_event(GtkWidget *widget,
35 GdkEvent *event,
36 gpointer *data);
37 static gboolean irreco_window_state_event(GtkWidget *widget,
38 GdkEventWindowState *event,
39 IrrecoWindow *self);
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)
62 IRRECO_ENTER
64 /*
65 * Create eventbox
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
73 * area.
75 self->event_box = gtk_event_box_new();
76 gtk_event_box_set_visible_window(GTK_EVENT_BOX(self->event_box),
77 TRUE);
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),
86 self->layout);
88 /* Setup size & scrollbars. */
89 gtk_layout_set_size(GTK_LAYOUT(self->layout),
90 IRRECO_LAYOUT_WIDTH,
91 IRRECO_LAYOUT_HEIGHT);
92 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(
93 self->scrolled_window),
94 GTK_POLICY_AUTOMATIC,
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)));
103 /* Signals. */
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));
109 IRRECO_RETURN
112 GtkWidget* irreco_window_new()
114 IrrecoWindow* self;
115 IRRECO_ENTER
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)
134 gint hidden_area;
135 IRRECO_ENTER
137 hidden_area = adjustment->upper - adjustment->page_size;
138 adjustment->page_increment = hidden_area;
139 adjustment->step_increment = hidden_area;
141 IRRECO_RETURN
146 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
147 /* Functions */
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;
161 IRRECO_ENTER
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,
168 FALSE, &error);
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,
177 FALSE, &error);
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,
203 GdkPixbuf * pixbuf1,
204 GdkPixbuf * pixbuf2)
206 gint width = IRRECO_SCREEN_WIDTH;
207 gint height = IRRECO_SCREEN_HEIGHT;
208 GdkPixmap *pixmap = NULL;
209 GdkGC *bg_gc = NULL;
210 IRRECO_ENTER
212 /* Create and fill pixmap with background color. */
213 pixmap = gdk_pixmap_new(GDK_DRAWABLE(GTK_LAYOUT(
214 self->layout)->bin_window),
215 width, height, -1);
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,
243 pixmap, FALSE);
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));
248 IRRECO_RETURN
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)
257 IRRECO_ENTER
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;
262 IRRECO_RETURN
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;
271 IRRECO_ENTER
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);
294 IRRECO_RETURN
297 gboolean irreco_window_is_fullscreen(IrrecoWindow *self)
299 GdkWindow *window;
300 IRRECO_ENTER
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)
309 IRRECO_ENTER
311 if (irreco_window_is_fullscreen(self)) {
312 gtk_window_unfullscreen(GTK_WINDOW(self));
313 } else {
314 gtk_window_fullscreen(GTK_WINDOW(self));
317 IRRECO_RETURN
320 void irreco_window_scrollbar_hide(IrrecoWindow *self)
322 IRRECO_ENTER
323 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(
324 self->scrolled_window),
325 GTK_POLICY_NEVER,
326 GTK_POLICY_NEVER);
327 IRRECO_RETURN
330 void irreco_window_scrollbar_show(IrrecoWindow *self)
332 IRRECO_ENTER
333 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(
334 self->scrolled_window),
335 GTK_POLICY_AUTOMATIC,
336 GTK_POLICY_AUTOMATIC);
337 IRRECO_RETURN
342 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
343 /* Events */
344 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
346 static gboolean irreco_window_delete_event(GtkWidget *widget,
347 GdkEvent *event,
348 gpointer *data)
350 IRRECO_ENTER
351 if (irreco_yes_no_dlg(GTK_WINDOW(widget),
352 _("Exit Ir Remote Control?"))) {
353 gtk_main_quit();
354 IRRECO_RETURN_BOOL(FALSE);
356 IRRECO_RETURN_BOOL(TRUE);
359 static gboolean irreco_window_state_event(GtkWidget *widget,
360 GdkEventWindowState *event,
361 IrrecoWindow *self)
363 IRRECO_ENTER
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);
369 } else {
370 irreco_window_scrollbar_show(self);
374 IRRECO_RETURN_BOOL(FALSE);