]> git.sur5r.net Git - glabels/blob - src/view-image.c
Imported Upstream version 2.2.8
[glabels] / src / view-image.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
3 /*
4  *  (GLABELS) Label and Business Card Creation program for GNOME
5  *
6  *  view_image.c:  GLabels label image object view
7  *
8  *  Copyright (C) 2001-2007  Jim Evins <evins@snaught.com>.
9  *
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.
14  *
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.
19  *
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
23  */
24 #include <config.h>
25
26 #include "view-image.h"
27
28 #include <glib/gi18n.h>
29 #include <glib/gmem.h>
30
31 #include "color.h"
32 #include "object-editor.h"
33 #include "stock.h"
34
35 #include "pixmaps/cursor_image.xbm"
36 #include "pixmaps/cursor_image_mask.xbm"
37
38 #include "debug.h"
39
40 /*========================================================*/
41 /* Private macros and constants.                          */
42 /*========================================================*/
43
44
45 /*========================================================*/
46 /* Private types.                                         */
47 /*========================================================*/
48
49 struct _glViewImagePrivate {
50         int place_holder; /* Place holder for future private data. */
51 };
52
53 /*========================================================*/
54 /* Private globals.                                       */
55 /*========================================================*/
56
57
58 /*========================================================*/
59 /* Private function prototypes.                           */
60 /*========================================================*/
61
62 static void       gl_view_image_finalize            (GObject          *object);
63
64 static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
65
66 static void       update_object_from_editor_cb      (glObjectEditor   *editor,
67                                                      glLabelObject    *object);
68
69 static void       update_editor_from_object_cb      (glLabelObject    *object,
70                                                      glObjectEditor   *editor);
71
72 static void       update_editor_from_move_cb        (glLabelObject    *object,
73                                                      gdouble           dx,
74                                                      gdouble           dy,
75                                                      glObjectEditor   *editor);
76
77 static gboolean   object_at                         (glViewObject     *view_object,
78                                                      cairo_t          *cr,
79                                                      gdouble           x,
80                                                      gdouble           y);
81
82
83 \f
84 /*****************************************************************************/
85 /* Boilerplate object stuff.                                                 */
86 /*****************************************************************************/
87 G_DEFINE_TYPE (glViewImage, gl_view_image, GL_TYPE_VIEW_OBJECT);
88
89
90 static void
91 gl_view_image_class_init (glViewImageClass *class)
92 {
93         GObjectClass      *object_class      = G_OBJECT_CLASS (class);
94         glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
95
96         gl_debug (DEBUG_VIEW, "START");
97
98         gl_view_image_parent_class = g_type_class_peek_parent (class);
99
100         object_class->finalize = gl_view_image_finalize;
101
102         view_object_class->construct_editor = construct_properties_editor;
103         view_object_class->object_at        = object_at;
104
105         gl_debug (DEBUG_VIEW, "END");
106 }
107
108 static void
109 gl_view_image_init (glViewImage *view_image)
110 {
111         gl_debug (DEBUG_VIEW, "START");
112
113         view_image->priv = g_new0 (glViewImagePrivate, 1);
114
115         gl_debug (DEBUG_VIEW, "END");
116 }
117
118 static void
119 gl_view_image_finalize (GObject *object)
120 {
121         glViewImage *view_image = GL_VIEW_IMAGE (object);
122
123         gl_debug (DEBUG_VIEW, "START");
124
125         g_return_if_fail (object && GL_IS_VIEW_IMAGE (object));
126
127         g_free (view_image->priv);
128
129         G_OBJECT_CLASS (gl_view_image_parent_class)->finalize (object);
130
131         gl_debug (DEBUG_VIEW, "END");
132 }
133
134 /*****************************************************************************/
135 /* NEW image object view.                                                    */
136 /*****************************************************************************/
137 glViewObject *
138 gl_view_image_new (glLabelImage *object,
139                    glView       *view)
140 {
141         glViewImage         *view_image;
142
143         gl_debug (DEBUG_VIEW, "START");
144
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);
147         
148         view_image = g_object_new (gl_view_image_get_type(), NULL);
149
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);
154
155         gl_debug (DEBUG_VIEW, "END");
156
157         return GL_VIEW_OBJECT (view_image);
158 }
159
160 /*****************************************************************************/
161 /* Create a properties dialog for a image object.                            */
162 /*****************************************************************************/
163 static GtkWidget *
164 construct_properties_editor (glViewObject *view_object)
165 {
166         GtkWidget          *editor;
167         glViewImage        *view_image = (glViewImage *)view_object;
168         glLabelObject      *object;
169
170         gl_debug (DEBUG_VIEW, "START");
171
172         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_image));
173
174         /* Build editor. */
175         editor = gl_object_editor_new (GL_STOCK_IMAGE, _("Image object properties"),
176                                        object->parent,
177                                        GL_OBJECT_EDITOR_POSITION_PAGE,
178                                        GL_OBJECT_EDITOR_SIZE_IMAGE_PAGE,
179                                        GL_OBJECT_EDITOR_IMAGE_PAGE,
180                                        0);
181         
182         /* Update */
183         update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
184         update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
185
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);
193
194         gl_debug (DEBUG_VIEW, "END");
195
196         return editor;
197 }
198
199 /*---------------------------------------------------------------------------*/
200 /* PRIVATE.  editor "changed" callback.                                      */
201 /*---------------------------------------------------------------------------*/
202 static void
203 update_object_from_editor_cb (glObjectEditor *editor,
204                               glLabelObject  *object)
205 {
206         gdouble            x, y, w, h;
207         glTextNode        *filename;
208         const GdkPixbuf   *pixbuf;
209         gdouble            image_w, image_h;
210         gdouble            new_w, new_h;
211
212         gl_debug (DEBUG_VIEW, "START");
213
214         g_signal_handlers_block_by_func (G_OBJECT(object),
215                                          update_editor_from_object_cb,
216                                          editor);
217         g_signal_handlers_block_by_func (G_OBJECT(object),
218                                          update_editor_from_move_cb,
219                                          editor);
220
221
222         gl_object_editor_get_position (editor, &x, &y);
223         gl_label_object_set_position (object, x, y);
224
225         gl_object_editor_get_size (editor, &w, &h);
226         gl_label_object_set_size (object, w, h);
227
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);
231
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) )
235         {
236                 gl_object_editor_set_size (editor, new_w, new_h);
237         }
238
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);
244
245         g_signal_handlers_unblock_by_func (G_OBJECT(object),
246                                            update_editor_from_object_cb,
247                                            editor);
248         g_signal_handlers_unblock_by_func (G_OBJECT(object),
249                                            update_editor_from_move_cb,
250                                            editor);
251
252         gl_debug (DEBUG_VIEW, "END");
253 }
254
255 /*---------------------------------------------------------------------------*/
256 /* PRIVATE. label object "changed" callback.                                 */
257 /*---------------------------------------------------------------------------*/
258 static void
259 update_editor_from_object_cb (glLabelObject  *object,
260                               glObjectEditor *editor)
261 {
262         gdouble            w, h;
263         const GdkPixbuf   *pixbuf;
264         gdouble            image_w, image_h;
265         glTextNode        *filename;
266         glMerge           *merge;
267
268         gl_debug (DEBUG_VIEW, "START");
269
270         gl_label_object_get_size (object, &w, &h);
271         gl_object_editor_set_size (editor, w, h);
272
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);
277
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);
282         }
283
284         gl_debug (DEBUG_VIEW, "END");
285 }
286
287 /*---------------------------------------------------------------------------*/
288 /* PRIVATE. label object "moved" callback.                                   */
289 /*---------------------------------------------------------------------------*/
290 static void
291 update_editor_from_move_cb (glLabelObject    *object,
292                             gdouble           dx,
293                             gdouble           dy,
294                             glObjectEditor   *editor)
295 {
296         gdouble            x, y;
297
298         gl_debug (DEBUG_VIEW, "START");
299
300         gl_label_object_get_position (object, &x, &y);
301         gl_object_editor_set_position (editor, x, y);
302
303         gl_debug (DEBUG_VIEW, "END");
304 }
305
306 /*****************************************************************************/
307 /* Is object at (x,y)?                                                       */
308 /*****************************************************************************/
309 static gboolean
310 object_at (glViewObject  *view_object,
311            cairo_t       *cr,
312            gdouble        x,
313            gdouble        y)
314 {
315         glLabelObject    *object;
316         gdouble           w, h;
317
318         object = gl_view_object_get_object (view_object);
319
320         gl_label_object_get_size (object, &w, &h);
321
322         cairo_rectangle (cr, 0.0, 0.0, w, h);
323
324         if (cairo_in_fill (cr, x, y))
325         {
326                 return TRUE;
327         }
328
329         return FALSE;
330 }
331
332
333 /*****************************************************************************/
334 /* Return apropos cursor for create object mode.                             */
335 /*****************************************************************************/
336 GdkCursor *
337 gl_view_image_get_create_cursor (void)
338 {
339         GdkCursor       *cursor = NULL;
340         GdkPixmap       *pixmap_data, *pixmap_mask;
341         GdkColor         fg = { 0, 0, 0, 0 };
342         GdkColor         bg = { 0, 65535, 65535, 65535 };
343
344         gl_debug (DEBUG_VIEW, "START");
345
346         pixmap_data = gdk_bitmap_create_from_data (NULL,
347                                                    (gchar *)cursor_image_bits,
348                                                    cursor_image_width,
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,
356                                              cursor_image_y_hot);
357
358         gl_debug (DEBUG_VIEW, "END");
359
360         return cursor;
361 }
362
363 /*****************************************************************************/
364 /* Object creation handler: button press event.                              */
365 /*****************************************************************************/
366 void
367 gl_view_image_create_button_press_event   (glView *view,
368                                            gdouble x,
369                                            gdouble y)
370 {
371         GObject             *object;
372
373         gl_view_unselect_all (view);
374
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);
378
379         view->create_object = GL_LABEL_OBJECT (object);
380         view->create_x0 = x;
381         view->create_y0 = y;
382 }
383
384 /*****************************************************************************/
385 /* Object creation handler: motion event.                                    */
386 /*****************************************************************************/
387 void
388 gl_view_image_create_motion_event     (glView *view,
389                                        gdouble x,
390                                        gdouble y)
391 {
392         gdouble w, h;
393
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);
399 }
400
401 /*****************************************************************************/
402 /* Object creation handler: button relesase event.                           */
403 /*****************************************************************************/
404 void
405 gl_view_image_create_button_release_event (glView *view,
406                                            gdouble x,
407                                            gdouble y)
408 {
409         gdouble              w, h;
410
411         if ((view->create_x0 == x) && (view->create_y0 == y)) {
412                 x = view->create_x0 + 36.0;
413                 y = view->create_y0 + 36.0;
414         }
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);
420 }
421