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 {
52 /*========================================================*/
53 /* Private globals. */
54 /*========================================================*/
57 /*========================================================*/
58 /* Private function prototypes. */
59 /*========================================================*/
61 static void gl_view_image_finalize (GObject *object);
63 static GtkWidget *construct_properties_editor (glViewObject *view_object);
65 static void update_object_from_editor_cb (glObjectEditor *editor,
66 glLabelObject *object);
68 static void update_editor_from_object_cb (glLabelObject *object,
69 glObjectEditor *editor);
71 static void update_editor_from_move_cb (glLabelObject *object,
74 glObjectEditor *editor);
76 static gboolean object_at (glViewObject *view_object,
83 /*****************************************************************************/
84 /* Boilerplate object stuff. */
85 /*****************************************************************************/
86 G_DEFINE_TYPE (glViewImage, gl_view_image, GL_TYPE_VIEW_OBJECT);
90 gl_view_image_class_init (glViewImageClass *class)
92 GObjectClass *object_class = G_OBJECT_CLASS (class);
93 glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
95 gl_debug (DEBUG_VIEW, "START");
97 gl_view_image_parent_class = g_type_class_peek_parent (class);
99 object_class->finalize = gl_view_image_finalize;
101 view_object_class->construct_editor = construct_properties_editor;
102 view_object_class->object_at = object_at;
104 gl_debug (DEBUG_VIEW, "END");
108 gl_view_image_init (glViewImage *view_image)
110 gl_debug (DEBUG_VIEW, "START");
112 view_image->priv = g_new0 (glViewImagePrivate, 1);
114 gl_debug (DEBUG_VIEW, "END");
118 gl_view_image_finalize (GObject *object)
120 glViewImage *view_image = GL_VIEW_IMAGE (object);
122 gl_debug (DEBUG_VIEW, "START");
124 g_return_if_fail (object && GL_IS_VIEW_IMAGE (object));
126 g_free (view_image->priv);
128 G_OBJECT_CLASS (gl_view_image_parent_class)->finalize (object);
130 gl_debug (DEBUG_VIEW, "END");
133 /*****************************************************************************/
134 /* NEW image object view. */
135 /*****************************************************************************/
137 gl_view_image_new (glLabelImage *object,
140 glViewImage *view_image;
142 gl_debug (DEBUG_VIEW, "START");
144 g_return_val_if_fail (object && GL_IS_LABEL_IMAGE (object), NULL);
145 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
147 view_image = g_object_new (gl_view_image_get_type(), NULL);
149 gl_view_object_set_object (GL_VIEW_OBJECT(view_image),
150 GL_LABEL_OBJECT(object),
151 GL_VIEW_OBJECT_HANDLES_BOX);
152 gl_view_object_set_view (GL_VIEW_OBJECT(view_image), view);
154 gl_debug (DEBUG_VIEW, "END");
156 return GL_VIEW_OBJECT (view_image);
159 /*****************************************************************************/
160 /* Create a properties dialog for a image object. */
161 /*****************************************************************************/
163 construct_properties_editor (glViewObject *view_object)
166 glViewImage *view_image = (glViewImage *)view_object;
167 glLabelObject *object;
169 gl_debug (DEBUG_VIEW, "START");
171 object = gl_view_object_get_object (GL_VIEW_OBJECT(view_image));
174 editor = gl_object_editor_new (GL_STOCK_IMAGE, _("Image object properties"),
176 GL_OBJECT_EDITOR_POSITION_PAGE,
177 GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE,
178 GL_OBJECT_EDITOR_IMAGE_PAGE,
182 update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
183 update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
185 /* Connect signals. */
186 g_signal_connect (G_OBJECT (editor), "changed",
187 G_CALLBACK(update_object_from_editor_cb), object);
188 g_signal_connect (G_OBJECT (object), "changed",
189 G_CALLBACK (update_editor_from_object_cb), editor);
190 g_signal_connect (G_OBJECT (object), "moved",
191 G_CALLBACK (update_editor_from_move_cb), editor);
193 gl_debug (DEBUG_VIEW, "END");
198 /*---------------------------------------------------------------------------*/
199 /* PRIVATE. editor "changed" callback. */
200 /*---------------------------------------------------------------------------*/
202 update_object_from_editor_cb (glObjectEditor *editor,
203 glLabelObject *object)
206 glTextNode *filename;
207 const GdkPixbuf *pixbuf;
208 gdouble image_w, image_h;
209 gdouble new_w, new_h;
211 gl_debug (DEBUG_VIEW, "START");
213 g_signal_handlers_block_by_func (G_OBJECT(object),
214 update_editor_from_object_cb,
216 g_signal_handlers_block_by_func (G_OBJECT(object),
217 update_editor_from_move_cb,
221 gl_object_editor_get_position (editor, &x, &y);
222 gl_label_object_set_position (object, x, y);
224 gl_object_editor_get_size (editor, &w, &h);
225 gl_label_object_set_size (object, w, h);
227 filename = gl_object_editor_get_image (editor);
228 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
229 gl_text_node_free (&filename);
231 /* Setting filename may have modified the size. */
232 gl_label_object_get_size (object, &new_w, &new_h);
233 if ( (new_w != w) || (new_h != h) )
235 gl_object_editor_set_size (editor, new_w, new_h);
238 /* It may also have a new base size. */
239 pixbuf = gl_label_image_get_pixbuf (GL_LABEL_IMAGE(object), NULL);
240 image_w = gdk_pixbuf_get_width (pixbuf);
241 image_h = gdk_pixbuf_get_height (pixbuf);
242 gl_object_editor_set_base_size (editor, image_w, image_h);
244 g_signal_handlers_unblock_by_func (G_OBJECT(object),
245 update_editor_from_object_cb,
247 g_signal_handlers_unblock_by_func (G_OBJECT(object),
248 update_editor_from_move_cb,
251 gl_debug (DEBUG_VIEW, "END");
254 /*---------------------------------------------------------------------------*/
255 /* PRIVATE. label object "changed" callback. */
256 /*---------------------------------------------------------------------------*/
258 update_editor_from_object_cb (glLabelObject *object,
259 glObjectEditor *editor)
262 const GdkPixbuf *pixbuf;
263 gdouble image_w, image_h;
264 glTextNode *filename;
267 gl_debug (DEBUG_VIEW, "START");
269 gl_label_object_get_size (object, &w, &h);
270 gl_object_editor_set_size (editor, w, h);
272 pixbuf = gl_label_image_get_pixbuf (GL_LABEL_IMAGE(object), NULL);
273 image_w = gdk_pixbuf_get_width (pixbuf);
274 image_h = gdk_pixbuf_get_height (pixbuf);
275 gl_object_editor_set_base_size (editor, image_w, image_h);
277 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
278 merge = gl_label_get_merge (GL_LABEL(object->parent));
279 if ( filename != NULL ) {
280 gl_object_editor_set_image (editor, (merge != NULL), filename);
283 gl_debug (DEBUG_VIEW, "END");
286 /*---------------------------------------------------------------------------*/
287 /* PRIVATE. label object "moved" callback. */
288 /*---------------------------------------------------------------------------*/
290 update_editor_from_move_cb (glLabelObject *object,
293 glObjectEditor *editor)
297 gl_debug (DEBUG_VIEW, "START");
299 gl_label_object_get_position (object, &x, &y);
300 gl_object_editor_set_position (editor, x, y);
302 gl_debug (DEBUG_VIEW, "END");
305 /*****************************************************************************/
306 /* Is object at (x,y)? */
307 /*****************************************************************************/
309 object_at (glViewObject *view_object,
314 glLabelObject *object;
317 object = gl_view_object_get_object (view_object);
319 gl_label_object_get_size (object, &w, &h);
321 cairo_rectangle (cr, 0.0, 0.0, w, h);
323 if (cairo_in_fill (cr, x, y))
332 /*****************************************************************************/
333 /* Return apropos cursor for create object mode. */
334 /*****************************************************************************/
336 gl_view_image_get_create_cursor (void)
338 GdkCursor *cursor = NULL;
339 GdkPixmap *pixmap_data, *pixmap_mask;
340 GdkColor fg = { 0, 0, 0, 0 };
341 GdkColor bg = { 0, 65535, 65535, 65535 };
343 gl_debug (DEBUG_VIEW, "START");
345 pixmap_data = gdk_bitmap_create_from_data (NULL,
346 (gchar *)cursor_image_bits,
348 cursor_image_height);
349 pixmap_mask = gdk_bitmap_create_from_data (NULL,
350 (gchar *)cursor_image_mask_bits,
351 cursor_image_mask_width,
352 cursor_image_mask_height);
353 cursor = gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
354 &bg, cursor_image_x_hot,
357 gl_debug (DEBUG_VIEW, "END");
362 /*****************************************************************************/
363 /* Object creation handler: button press event. */
364 /*****************************************************************************/
366 gl_view_image_create_button_press_event (glView *view,
372 gl_view_unselect_all (view);
374 object = gl_label_image_new (view->label);
375 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
376 gl_label_object_set_size (GL_LABEL_OBJECT(object), 0.0, 0.0);
378 view->create_object = GL_LABEL_OBJECT (object);
383 /*****************************************************************************/
384 /* Object creation handler: motion event. */
385 /*****************************************************************************/
387 gl_view_image_create_motion_event (glView *view,
393 gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
394 MIN (x, view->create_x0), MIN (y, view->create_y0));
395 w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
396 h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
397 gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
400 /*****************************************************************************/
401 /* Object creation handler: button relesase event. */
402 /*****************************************************************************/
404 gl_view_image_create_button_release_event (glView *view,
410 if ((view->create_x0 == x) && (view->create_y0 == y)) {
411 x = view->create_x0 + 36.0;
412 y = view->create_y0 + 36.0;
414 gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
415 MIN (x, view->create_x0), MIN (y, view->create_y0));
416 w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
417 h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
418 gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);