1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * view_image.c: GLabels label image object view
8 * Copyright (C) 2001-2007 Jim Evins <evins@snaught.com>.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include "view-image.h"
28 #include <glib/gi18n.h>
29 #include <glib/gmem.h>
32 #include "object-editor.h"
35 #include "pixmaps/cursor_image.xbm"
36 #include "pixmaps/cursor_image_mask.xbm"
40 /*========================================================*/
41 /* Private macros and constants. */
42 /*========================================================*/
45 /*========================================================*/
47 /*========================================================*/
49 struct _glViewImagePrivate {
50 int place_holder; /* Place holder for future private data. */
53 /*========================================================*/
54 /* Private globals. */
55 /*========================================================*/
58 /*========================================================*/
59 /* Private function prototypes. */
60 /*========================================================*/
62 static void gl_view_image_finalize (GObject *object);
64 static GtkWidget *construct_properties_editor (glViewObject *view_object);
66 static void update_object_from_editor_cb (glObjectEditor *editor,
67 glLabelObject *object);
69 static void update_editor_from_object_cb (glLabelObject *object,
70 glObjectEditor *editor);
72 static void update_editor_from_move_cb (glLabelObject *object,
75 glObjectEditor *editor);
77 static gboolean object_at (glViewObject *view_object,
84 /*****************************************************************************/
85 /* Boilerplate object stuff. */
86 /*****************************************************************************/
87 G_DEFINE_TYPE (glViewImage, gl_view_image, GL_TYPE_VIEW_OBJECT);
91 gl_view_image_class_init (glViewImageClass *class)
93 GObjectClass *object_class = G_OBJECT_CLASS (class);
94 glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
96 gl_debug (DEBUG_VIEW, "START");
98 gl_view_image_parent_class = g_type_class_peek_parent (class);
100 object_class->finalize = gl_view_image_finalize;
102 view_object_class->construct_editor = construct_properties_editor;
103 view_object_class->object_at = object_at;
105 gl_debug (DEBUG_VIEW, "END");
109 gl_view_image_init (glViewImage *view_image)
111 gl_debug (DEBUG_VIEW, "START");
113 view_image->priv = g_new0 (glViewImagePrivate, 1);
115 gl_debug (DEBUG_VIEW, "END");
119 gl_view_image_finalize (GObject *object)
121 glViewImage *view_image = GL_VIEW_IMAGE (object);
123 gl_debug (DEBUG_VIEW, "START");
125 g_return_if_fail (object && GL_IS_VIEW_IMAGE (object));
127 g_free (view_image->priv);
129 G_OBJECT_CLASS (gl_view_image_parent_class)->finalize (object);
131 gl_debug (DEBUG_VIEW, "END");
134 /*****************************************************************************/
135 /* NEW image object view. */
136 /*****************************************************************************/
138 gl_view_image_new (glLabelImage *object,
141 glViewImage *view_image;
143 gl_debug (DEBUG_VIEW, "START");
145 g_return_val_if_fail (object && GL_IS_LABEL_IMAGE (object), NULL);
146 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
148 view_image = g_object_new (gl_view_image_get_type(), NULL);
150 gl_view_object_set_object (GL_VIEW_OBJECT(view_image),
151 GL_LABEL_OBJECT(object),
152 GL_VIEW_OBJECT_HANDLES_BOX);
153 gl_view_object_set_view (GL_VIEW_OBJECT(view_image), view);
155 gl_debug (DEBUG_VIEW, "END");
157 return GL_VIEW_OBJECT (view_image);
160 /*****************************************************************************/
161 /* Create a properties dialog for a image object. */
162 /*****************************************************************************/
164 construct_properties_editor (glViewObject *view_object)
167 glViewImage *view_image = (glViewImage *)view_object;
168 glLabelObject *object;
170 gl_debug (DEBUG_VIEW, "START");
172 object = gl_view_object_get_object (GL_VIEW_OBJECT(view_image));
175 editor = gl_object_editor_new (GL_STOCK_IMAGE, _("Image object properties"),
177 GL_OBJECT_EDITOR_POSITION_PAGE,
178 GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE,
179 GL_OBJECT_EDITOR_IMAGE_PAGE,
183 update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
184 update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
186 /* Connect signals. */
187 g_signal_connect (G_OBJECT (editor), "changed",
188 G_CALLBACK(update_object_from_editor_cb), object);
189 g_signal_connect (G_OBJECT (object), "changed",
190 G_CALLBACK (update_editor_from_object_cb), editor);
191 g_signal_connect (G_OBJECT (object), "moved",
192 G_CALLBACK (update_editor_from_move_cb), editor);
194 gl_debug (DEBUG_VIEW, "END");
199 /*---------------------------------------------------------------------------*/
200 /* PRIVATE. editor "changed" callback. */
201 /*---------------------------------------------------------------------------*/
203 update_object_from_editor_cb (glObjectEditor *editor,
204 glLabelObject *object)
207 glTextNode *filename;
208 const GdkPixbuf *pixbuf;
209 gdouble image_w, image_h;
210 gdouble new_w, new_h;
212 gl_debug (DEBUG_VIEW, "START");
214 g_signal_handlers_block_by_func (G_OBJECT(object),
215 update_editor_from_object_cb,
217 g_signal_handlers_block_by_func (G_OBJECT(object),
218 update_editor_from_move_cb,
222 gl_object_editor_get_position (editor, &x, &y);
223 gl_label_object_set_position (object, x, y);
225 gl_object_editor_get_size (editor, &w, &h);
226 gl_label_object_set_size (object, w, h);
228 filename = gl_object_editor_get_image (editor);
229 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
230 gl_text_node_free (&filename);
232 /* Setting filename may have modified the size. */
233 gl_label_object_get_size (object, &new_w, &new_h);
234 if ( (new_w != w) || (new_h != h) )
236 gl_object_editor_set_size (editor, new_w, new_h);
239 /* It may also have a new base size. */
240 pixbuf = gl_label_image_get_pixbuf (GL_LABEL_IMAGE(object), NULL);
241 image_w = gdk_pixbuf_get_width (pixbuf);
242 image_h = gdk_pixbuf_get_height (pixbuf);
243 gl_object_editor_set_base_size (editor, image_w, image_h);
245 g_signal_handlers_unblock_by_func (G_OBJECT(object),
246 update_editor_from_object_cb,
248 g_signal_handlers_unblock_by_func (G_OBJECT(object),
249 update_editor_from_move_cb,
252 gl_debug (DEBUG_VIEW, "END");
255 /*---------------------------------------------------------------------------*/
256 /* PRIVATE. label object "changed" callback. */
257 /*---------------------------------------------------------------------------*/
259 update_editor_from_object_cb (glLabelObject *object,
260 glObjectEditor *editor)
263 const GdkPixbuf *pixbuf;
264 gdouble image_w, image_h;
265 glTextNode *filename;
268 gl_debug (DEBUG_VIEW, "START");
270 gl_label_object_get_size (object, &w, &h);
271 gl_object_editor_set_size (editor, w, h);
273 pixbuf = gl_label_image_get_pixbuf (GL_LABEL_IMAGE(object), NULL);
274 image_w = gdk_pixbuf_get_width (pixbuf);
275 image_h = gdk_pixbuf_get_height (pixbuf);
276 gl_object_editor_set_base_size (editor, image_w, image_h);
278 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
279 merge = gl_label_get_merge (GL_LABEL(object->parent));
280 if ( filename != NULL ) {
281 gl_object_editor_set_image (editor, (merge != NULL), filename);
284 gl_debug (DEBUG_VIEW, "END");
287 /*---------------------------------------------------------------------------*/
288 /* PRIVATE. label object "moved" callback. */
289 /*---------------------------------------------------------------------------*/
291 update_editor_from_move_cb (glLabelObject *object,
294 glObjectEditor *editor)
298 gl_debug (DEBUG_VIEW, "START");
300 gl_label_object_get_position (object, &x, &y);
301 gl_object_editor_set_position (editor, x, y);
303 gl_debug (DEBUG_VIEW, "END");
306 /*****************************************************************************/
307 /* Is object at (x,y)? */
308 /*****************************************************************************/
310 object_at (glViewObject *view_object,
315 glLabelObject *object;
318 object = gl_view_object_get_object (view_object);
320 gl_label_object_get_size (object, &w, &h);
322 cairo_rectangle (cr, 0.0, 0.0, w, h);
324 if (cairo_in_fill (cr, x, y))
333 /*****************************************************************************/
334 /* Return apropos cursor for create object mode. */
335 /*****************************************************************************/
337 gl_view_image_get_create_cursor (void)
339 GdkCursor *cursor = NULL;
340 GdkPixmap *pixmap_data, *pixmap_mask;
341 GdkColor fg = { 0, 0, 0, 0 };
342 GdkColor bg = { 0, 65535, 65535, 65535 };
344 gl_debug (DEBUG_VIEW, "START");
346 pixmap_data = gdk_bitmap_create_from_data (NULL,
347 (gchar *)cursor_image_bits,
349 cursor_image_height);
350 pixmap_mask = gdk_bitmap_create_from_data (NULL,
351 (gchar *)cursor_image_mask_bits,
352 cursor_image_mask_width,
353 cursor_image_mask_height);
354 cursor = gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
355 &bg, cursor_image_x_hot,
358 gl_debug (DEBUG_VIEW, "END");
363 /*****************************************************************************/
364 /* Object creation handler: button press event. */
365 /*****************************************************************************/
367 gl_view_image_create_button_press_event (glView *view,
373 gl_view_unselect_all (view);
375 object = gl_label_image_new (view->label);
376 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
377 gl_label_object_set_size (GL_LABEL_OBJECT(object), 0.0, 0.0);
379 view->create_object = GL_LABEL_OBJECT (object);
384 /*****************************************************************************/
385 /* Object creation handler: motion event. */
386 /*****************************************************************************/
388 gl_view_image_create_motion_event (glView *view,
394 gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
395 MIN (x, view->create_x0), MIN (y, view->create_y0));
396 w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
397 h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
398 gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
401 /*****************************************************************************/
402 /* Object creation handler: button relesase event. */
403 /*****************************************************************************/
405 gl_view_image_create_button_release_event (glView *view,
411 if ((view->create_x0 == x) && (view->create_y0 == y)) {
412 x = view->create_x0 + 36.0;
413 y = view->create_y0 + 36.0;
415 gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
416 MIN (x, view->create_x0), MIN (y, view->create_y0));
417 w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
418 h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
419 gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);