3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
23 #include "view-image.h"
25 #include <glib/gi18n.h>
29 #include "object-editor.h"
32 #include "pixmaps/cursor_image.xbm"
33 #include "pixmaps/cursor_image_mask.xbm"
38 /*========================================================*/
39 /* Private macros and constants. */
40 /*========================================================*/
43 /*========================================================*/
45 /*========================================================*/
47 struct _glViewImagePrivate {
51 /*========================================================*/
52 /* Private globals. */
53 /*========================================================*/
56 /*========================================================*/
57 /* Private function prototypes. */
58 /*========================================================*/
60 static void gl_view_image_finalize (GObject *object);
62 static GtkWidget *construct_properties_editor (glViewObject *view_object);
64 static void update_object_from_editor_cb (glObjectEditor *editor,
65 glLabelObject *object);
67 static void update_editor_from_object_cb (glLabelObject *object,
68 glObjectEditor *editor);
70 static void update_editor_from_move_cb (glLabelObject *object,
73 glObjectEditor *editor);
75 static gboolean object_at (glViewObject *view_object,
81 /*****************************************************************************/
82 /* Boilerplate object stuff. */
83 /*****************************************************************************/
84 G_DEFINE_TYPE (glViewImage, gl_view_image, GL_TYPE_VIEW_OBJECT);
88 gl_view_image_class_init (glViewImageClass *class)
90 GObjectClass *object_class = G_OBJECT_CLASS (class);
91 glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
93 gl_debug (DEBUG_VIEW, "START");
95 gl_view_image_parent_class = g_type_class_peek_parent (class);
97 object_class->finalize = gl_view_image_finalize;
99 view_object_class->construct_editor = construct_properties_editor;
100 view_object_class->object_at = object_at;
102 gl_debug (DEBUG_VIEW, "END");
107 gl_view_image_init (glViewImage *view_image)
109 gl_debug (DEBUG_VIEW, "START");
111 view_image->priv = g_new0 (glViewImagePrivate, 1);
113 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");
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);
161 /*****************************************************************************/
162 /* Create a properties dialog for a image object. */
163 /*****************************************************************************/
165 construct_properties_editor (glViewObject *view_object)
168 glViewImage *view_image = (glViewImage *)view_object;
169 glLabelObject *object;
171 gl_debug (DEBUG_VIEW, "START");
173 object = gl_view_object_get_object (GL_VIEW_OBJECT(view_image));
176 editor = gl_object_editor_new (GL_STOCK_IMAGE, _("Image object properties"),
178 GL_OBJECT_EDITOR_POSITION_PAGE,
179 GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE,
180 GL_OBJECT_EDITOR_IMAGE_PAGE,
184 update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
185 update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
187 /* Connect signals. */
188 g_signal_connect (G_OBJECT (editor), "changed",
189 G_CALLBACK(update_object_from_editor_cb), object);
190 g_signal_connect (G_OBJECT (object), "changed",
191 G_CALLBACK (update_editor_from_object_cb), editor);
192 g_signal_connect (G_OBJECT (object), "moved",
193 G_CALLBACK (update_editor_from_move_cb), editor);
195 gl_debug (DEBUG_VIEW, "END");
201 /*---------------------------------------------------------------------------*/
202 /* PRIVATE. editor "changed" callback. */
203 /*---------------------------------------------------------------------------*/
205 update_object_from_editor_cb (glObjectEditor *editor,
206 glLabelObject *object)
209 glTextNode *filename;
210 const GdkPixbuf *pixbuf;
211 gdouble image_w, image_h;
212 gdouble new_w, new_h;
214 gl_debug (DEBUG_VIEW, "START");
216 g_signal_handlers_block_by_func (G_OBJECT(object),
217 update_editor_from_object_cb,
219 g_signal_handlers_block_by_func (G_OBJECT(object),
220 update_editor_from_move_cb,
224 gl_object_editor_get_position (editor, &x, &y);
225 gl_label_object_set_position (object, x, y);
227 gl_object_editor_get_size (editor, &w, &h);
228 gl_label_object_set_size (object, w, h);
230 filename = gl_object_editor_get_image (editor);
231 gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
232 gl_text_node_free (&filename);
234 /* Setting filename may have modified the size. */
235 gl_label_object_get_size (object, &new_w, &new_h);
236 if ( (new_w != w) || (new_h != h) )
238 gl_object_editor_set_size (editor, new_w, new_h);
241 /* It may also have a new base size. */
242 pixbuf = gl_label_image_get_pixbuf (GL_LABEL_IMAGE(object), NULL);
243 image_w = gdk_pixbuf_get_width (pixbuf);
244 image_h = gdk_pixbuf_get_height (pixbuf);
245 gl_object_editor_set_base_size (editor, image_w, image_h);
247 g_signal_handlers_unblock_by_func (G_OBJECT(object),
248 update_editor_from_object_cb,
250 g_signal_handlers_unblock_by_func (G_OBJECT(object),
251 update_editor_from_move_cb,
254 gl_debug (DEBUG_VIEW, "END");
258 /*---------------------------------------------------------------------------*/
259 /* PRIVATE. label object "changed" callback. */
260 /*---------------------------------------------------------------------------*/
262 update_editor_from_object_cb (glLabelObject *object,
263 glObjectEditor *editor)
266 const GdkPixbuf *pixbuf;
267 gdouble image_w, image_h;
268 glTextNode *filename;
271 gl_debug (DEBUG_VIEW, "START");
273 gl_label_object_get_size (object, &w, &h);
274 gl_object_editor_set_size (editor, w, h);
276 pixbuf = gl_label_image_get_pixbuf (GL_LABEL_IMAGE(object), NULL);
277 image_w = gdk_pixbuf_get_width (pixbuf);
278 image_h = gdk_pixbuf_get_height (pixbuf);
279 gl_object_editor_set_base_size (editor, image_w, image_h);
281 filename = gl_label_image_get_filename (GL_LABEL_IMAGE(object));
282 merge = gl_label_get_merge (GL_LABEL(object->parent));
283 if ( filename != NULL ) {
284 gl_object_editor_set_image (editor, (merge != NULL), filename);
287 gl_debug (DEBUG_VIEW, "END");
291 /*---------------------------------------------------------------------------*/
292 /* PRIVATE. label object "moved" callback. */
293 /*---------------------------------------------------------------------------*/
295 update_editor_from_move_cb (glLabelObject *object,
298 glObjectEditor *editor)
302 gl_debug (DEBUG_VIEW, "START");
304 gl_label_object_get_position (object, &x, &y);
305 gl_object_editor_set_position (editor, x, y);
307 gl_debug (DEBUG_VIEW, "END");
311 /*****************************************************************************/
312 /* Is object at (x,y)? */
313 /*****************************************************************************/
315 object_at (glViewObject *view_object,
320 glLabelObject *object;
323 object = gl_view_object_get_object (view_object);
325 gl_label_object_get_size (object, &w, &h);
327 cairo_rectangle (cr, 0.0, 0.0, w, h);
329 if (cairo_in_fill (cr, x, y))
338 /*****************************************************************************/
339 /* Return apropos cursor for create object mode. */
340 /*****************************************************************************/
342 gl_view_image_get_create_cursor (void)
344 GdkCursor *cursor = NULL;
345 GdkPixmap *pixmap_data, *pixmap_mask;
346 GdkColor fg = { 0, 0, 0, 0 };
347 GdkColor bg = { 0, 65535, 65535, 65535 };
349 gl_debug (DEBUG_VIEW, "START");
351 pixmap_data = gdk_bitmap_create_from_data (NULL,
352 (gchar *)cursor_image_bits,
354 cursor_image_height);
355 pixmap_mask = gdk_bitmap_create_from_data (NULL,
356 (gchar *)cursor_image_mask_bits,
357 cursor_image_mask_width,
358 cursor_image_mask_height);
359 cursor = gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
360 &bg, cursor_image_x_hot,
363 gl_debug (DEBUG_VIEW, "END");
369 /*****************************************************************************/
370 /* Object creation handler: button press event. */
371 /*****************************************************************************/
373 gl_view_image_create_button_press_event (glView *view,
379 gl_view_unselect_all (view);
381 object = gl_label_image_new (view->label);
382 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
383 gl_label_object_set_size (GL_LABEL_OBJECT(object), 0.0, 0.0);
385 view->create_object = GL_LABEL_OBJECT (object);
391 /*****************************************************************************/
392 /* Object creation handler: motion event. */
393 /*****************************************************************************/
395 gl_view_image_create_motion_event (glView *view,
401 gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
402 MIN (x, view->create_x0), MIN (y, view->create_y0));
403 w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
404 h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
405 gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
409 /*****************************************************************************/
410 /* Object creation handler: button relesase event. */
411 /*****************************************************************************/
413 gl_view_image_create_button_release_event (glView *view,
419 if ((view->create_x0 == x) && (view->create_y0 == y)) {
420 x = view->create_x0 + 36.0;
421 y = view->create_y0 + 36.0;
423 gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
424 MIN (x, view->create_x0), MIN (y, view->create_y0));
425 w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
426 h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
427 gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
433 * Local Variables: -- emacs
435 * c-basic-offset: 8 -- emacs
436 * tab-width: 8 -- emacs
437 * indent-tabs-mode: nil -- emacs