]> git.sur5r.net Git - glabels/blob - glabels2/src/view-box.c
2009-09-22 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / src / view-box.c
1 /*
2  *  view-box.c
3  *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include <config.h>
22
23 #include "view-box.h"
24
25 #include <glib/gi18n.h>
26 #include <glib.h>
27
28 #include "color.h"
29 #include "object-editor.h"
30 #include "stock.h"
31
32 #include "pixmaps/cursor_box.xbm"
33 #include "pixmaps/cursor_box_mask.xbm"
34
35 #include "debug.h"
36
37
38 /*========================================================*/
39 /* Private macros and constants.                          */
40 /*========================================================*/
41
42
43 /*========================================================*/
44 /* Private types.                                         */
45 /*========================================================*/
46
47 struct _glViewBoxPrivate {
48 };
49
50
51 /*========================================================*/
52 /* Private globals.                                       */
53 /*========================================================*/
54
55
56 /*========================================================*/
57 /* Private function prototypes.                           */
58 /*========================================================*/
59
60 static void       gl_view_box_finalize              (GObject          *object);
61
62 static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
63
64 static void       update_object_from_editor_cb      (glObjectEditor   *editor,
65                                                      glLabelObject    *object);
66
67 static void       update_editor_from_object_cb      (glLabelObject    *object,
68                                                      glObjectEditor   *editor);
69
70 static void       update_editor_from_move_cb        (glLabelObject    *object,
71                                                      gdouble           dx,
72                                                      gdouble           dy,
73                                                      glObjectEditor   *editor);
74
75 static gboolean   object_at                         (glViewObject     *view_object,
76                                                      cairo_t          *cr,
77                                                      gdouble           x,
78                                                      gdouble           y);
79
80
81 /*****************************************************************************/
82 /* Boilerplate object stuff.                                                 */
83 /*****************************************************************************/
84 G_DEFINE_TYPE (glViewBox, gl_view_box, GL_TYPE_VIEW_OBJECT);
85
86
87 static void
88 gl_view_box_class_init (glViewBoxClass *class)
89 {
90         GObjectClass      *object_class      = G_OBJECT_CLASS (class);
91         glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
92
93         gl_debug (DEBUG_VIEW, "START");
94
95         gl_view_box_parent_class = g_type_class_peek_parent (class);
96
97         object_class->finalize = gl_view_box_finalize;
98
99         view_object_class->construct_editor = construct_properties_editor;
100         view_object_class->object_at        = object_at;
101
102         gl_debug (DEBUG_VIEW, "END");
103 }
104
105
106 static void
107 gl_view_box_init (glViewBox *view_box)
108 {
109         gl_debug (DEBUG_VIEW, "START");
110
111         view_box->priv = g_new0 (glViewBoxPrivate, 1);
112
113         gl_debug (DEBUG_VIEW, "END");
114 }
115
116
117 static void
118 gl_view_box_finalize (GObject *object)
119 {
120         glViewBox *view_box = GL_VIEW_BOX (object);
121
122         gl_debug (DEBUG_VIEW, "START");
123
124         g_return_if_fail (object && GL_IS_VIEW_BOX (object));
125
126         g_free (view_box->priv);
127
128         G_OBJECT_CLASS (gl_view_box_parent_class)->finalize (object);
129
130         gl_debug (DEBUG_VIEW, "END");
131 }
132
133
134 /*****************************************************************************/
135 /* NEW box object view.                                                      */
136 /*****************************************************************************/
137 glViewObject *
138 gl_view_box_new (glLabelBox *object,
139                  glView     *view)
140 {
141         glViewBox         *view_box;
142
143         gl_debug (DEBUG_VIEW, "START");
144
145         g_return_val_if_fail (object && GL_IS_LABEL_BOX (object), NULL);
146         g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
147         
148         view_box = g_object_new (gl_view_box_get_type(), NULL);
149
150         gl_view_object_set_object (GL_VIEW_OBJECT(view_box),
151                                    GL_LABEL_OBJECT(object),
152                                    GL_VIEW_OBJECT_HANDLES_BOX);
153         gl_view_object_set_view (GL_VIEW_OBJECT(view_box), view);
154
155         gl_debug (DEBUG_VIEW, "END");
156
157         return GL_VIEW_OBJECT (view_box);
158 }
159
160
161 /*****************************************************************************/
162 /* Create a properties dialog for a box object.                              */
163 /*****************************************************************************/
164 static GtkWidget *
165 construct_properties_editor (glViewObject *view_object)
166 {
167         GtkWidget          *editor;
168         glViewBox          *view_box = (glViewBox *)view_object;
169         glLabelObject      *object;
170
171         gl_debug (DEBUG_VIEW, "START");
172
173         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_box));
174
175         /* Build editor. */
176         editor = gl_object_editor_new (GL_STOCK_BOX, _("Box object properties"),
177                                        object->parent,
178                                        GL_OBJECT_EDITOR_SHADOW_PAGE,
179                                        GL_OBJECT_EDITOR_POSITION_PAGE,
180                                        GL_OBJECT_EDITOR_SIZE_PAGE,
181                                        GL_OBJECT_EDITOR_FILL_PAGE,
182                                        GL_OBJECT_EDITOR_LINE_PAGE,
183                                        0);
184         
185         /* Update */
186         update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
187         update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
188
189         /* Connect signals. */
190         g_signal_connect (G_OBJECT (editor), "changed",
191                           G_CALLBACK(update_object_from_editor_cb), object);
192         g_signal_connect (G_OBJECT (object), "changed",
193                           G_CALLBACK (update_editor_from_object_cb), editor);
194         g_signal_connect (G_OBJECT (object), "moved",
195                           G_CALLBACK (update_editor_from_move_cb), editor);
196
197         gl_debug (DEBUG_VIEW, "END");
198
199         return editor;
200 }
201
202
203 /*---------------------------------------------------------------------------*/
204 /* PRIVATE.  editor "changed" callback.                                      */
205 /*---------------------------------------------------------------------------*/
206 static void
207 update_object_from_editor_cb (glObjectEditor *editor,
208                               glLabelObject  *object)
209 {
210         gdouble            x, y, w, h;
211         glColorNode       *line_color_node;
212         gdouble            line_width;
213         glColorNode       *fill_color_node;
214         gboolean           shadow_state;
215         gdouble            shadow_x, shadow_y;
216         glColorNode       *shadow_color_node;
217         gdouble            shadow_opacity;
218         
219
220         gl_debug (DEBUG_VIEW, "START");
221
222         g_signal_handlers_block_by_func (G_OBJECT(object),
223                                          update_editor_from_object_cb,
224                                          editor);
225         g_signal_handlers_block_by_func (G_OBJECT(object),
226                                          update_editor_from_move_cb,
227                                          editor);
228
229         gl_object_editor_get_position (editor, &x, &y);
230         gl_label_object_set_position (object, x, y);
231
232         gl_object_editor_get_size (editor, &w, &h);
233         gl_label_object_set_size (object, w, h);
234
235         fill_color_node = gl_object_editor_get_fill_color (editor);
236         gl_label_object_set_fill_color (object, fill_color_node);
237         gl_color_node_free (&fill_color_node);
238
239         line_color_node = gl_object_editor_get_line_color (editor);
240         gl_label_object_set_line_color (object, line_color_node);
241         gl_color_node_free (&line_color_node);
242
243         line_width = gl_object_editor_get_line_width (editor);
244         gl_label_object_set_line_width (object, line_width);
245
246         shadow_state = gl_object_editor_get_shadow_state (editor);
247         gl_label_object_set_shadow_state (object, shadow_state);
248
249         gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
250         gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
251
252         shadow_color_node = gl_object_editor_get_shadow_color (editor);
253         gl_label_object_set_shadow_color (object, shadow_color_node);
254         gl_color_node_free (&shadow_color_node);
255
256         shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
257         gl_label_object_set_shadow_opacity (object, shadow_opacity);
258
259         g_signal_handlers_unblock_by_func (G_OBJECT(object),
260                                            update_editor_from_object_cb,
261                                            editor);
262         g_signal_handlers_unblock_by_func (G_OBJECT(object),
263                                            update_editor_from_move_cb,
264                                            editor);
265
266         gl_debug (DEBUG_VIEW, "END");
267 }
268
269
270 /*---------------------------------------------------------------------------*/
271 /* PRIVATE. label object "changed" callback.                                 */
272 /*---------------------------------------------------------------------------*/
273 static void
274 update_editor_from_object_cb (glLabelObject  *object,
275                               glObjectEditor *editor)
276 {
277         gdouble            w, h;
278         glColorNode       *line_color_node;
279         gdouble            line_width;
280         glColorNode       *fill_color_node;
281         gboolean           shadow_state;
282         gdouble            shadow_x, shadow_y;
283         glColorNode       *shadow_color_node;
284         gdouble            shadow_opacity;
285         glMerge           *merge;
286
287         gl_debug (DEBUG_VIEW, "START");
288
289         gl_label_object_get_size (object, &w, &h);
290         gl_object_editor_set_size (editor, w, h);
291         merge = gl_label_get_merge (GL_LABEL(object->parent));
292         
293         fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
294         gl_object_editor_set_fill_color (editor, (merge != NULL), fill_color_node);
295         gl_color_node_free (&fill_color_node);
296
297         line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
298         gl_object_editor_set_line_color (editor, (merge != NULL), line_color_node);
299         gl_color_node_free (&line_color_node);
300
301         line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
302         gl_object_editor_set_line_width (editor, line_width);
303
304         shadow_state = gl_label_object_get_shadow_state (object);
305         gl_object_editor_set_shadow_state (editor, shadow_state);
306
307         gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
308         gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
309
310         shadow_color_node = gl_label_object_get_shadow_color (object);
311         gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
312         gl_color_node_free (&shadow_color_node);
313
314         shadow_opacity = gl_label_object_get_shadow_opacity (object);
315         gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
316
317         gl_debug (DEBUG_VIEW, "END");
318 }
319
320
321 /*---------------------------------------------------------------------------*/
322 /* PRIVATE. label object "moved" callback.                                   */
323 /*---------------------------------------------------------------------------*/
324 static void
325 update_editor_from_move_cb (glLabelObject    *object,
326                             gdouble           dx,
327                             gdouble           dy,
328                             glObjectEditor   *editor)
329 {
330         gdouble            x, y;
331
332         gl_debug (DEBUG_VIEW, "START");
333
334         gl_label_object_get_position (object, &x, &y);
335         gl_object_editor_set_position (editor, x, y);
336
337         gl_debug (DEBUG_VIEW, "END");
338 }
339
340
341 /*****************************************************************************/
342 /* Is object at (x,y)?                                                       */
343 /*****************************************************************************/
344 static gboolean
345 object_at (glViewObject  *view_object,
346            cairo_t       *cr,
347            gdouble        x,
348            gdouble        y)
349 {
350         glLabelObject    *object;
351         gdouble           w, h;
352         gdouble           line_width;
353
354         object = gl_view_object_get_object (view_object);
355
356         gl_label_object_get_size (object, &w, &h);
357
358         cairo_rectangle (cr, 0.0, 0.0, w, h);
359
360         if (cairo_in_fill (cr, x, y))
361         {
362                 return TRUE;
363         }
364
365         line_width = gl_label_object_get_line_width (object);
366         cairo_set_line_width (cr, line_width);
367         if (cairo_in_stroke (cr, x, y))
368         {
369                 return TRUE;
370         }
371
372         return FALSE;
373 }
374
375
376 /*****************************************************************************/
377 /* Return apropos cursor for create object mode.                             */
378 /*****************************************************************************/
379 GdkCursor *
380 gl_view_box_get_create_cursor (void)
381 {
382         GdkCursor       *cursor = NULL;
383         GdkPixmap       *pixmap_data, *pixmap_mask;
384         GdkColor         fg = { 0, 0, 0, 0 };
385         GdkColor         bg = { 0, 65535, 65535, 65535 };
386
387         gl_debug (DEBUG_VIEW, "START");
388
389         pixmap_data = gdk_bitmap_create_from_data (NULL,
390                                                    (gchar *)cursor_box_bits,
391                                                    cursor_box_width,
392                                                    cursor_box_height);
393         pixmap_mask = gdk_bitmap_create_from_data (NULL,
394                                                    (gchar *)cursor_box_mask_bits,
395                                                    cursor_box_mask_width,
396                                                    cursor_box_mask_height);
397         cursor = gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
398                                              &bg, cursor_box_x_hot,
399                                              cursor_box_y_hot);
400
401         gl_debug (DEBUG_VIEW, "END");
402
403         return cursor;
404 }
405
406
407 /*****************************************************************************/
408 /* Object creation handler: button press event.                              */
409 /*****************************************************************************/
410 void
411 gl_view_box_create_button_press_event   (glView *view,
412                                          gdouble x,
413                                          gdouble y)
414 {
415         GObject             *object;
416         glColorNode         *fill_color_node;
417         glColorNode         *line_color_node;
418
419         gl_view_unselect_all (view);
420
421         fill_color_node = gl_color_node_new_default ();
422         line_color_node = gl_color_node_new_default ();
423                 
424         object = gl_label_box_new (view->label);
425         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
426         gl_label_object_set_size (GL_LABEL_OBJECT(object), 0.0, 0.0);
427         line_color_node->color = gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5);
428         fill_color_node->color = gl_color_set_opacity (gl_view_get_default_fill_color(view), 0.5);
429         gl_label_object_set_line_width (GL_LABEL_OBJECT(object),
430                                         gl_view_get_default_line_width(view));
431         gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
432                                         line_color_node);
433         gl_label_object_set_fill_color (GL_LABEL_OBJECT(object),
434                                         fill_color_node);
435
436         gl_color_node_free (&fill_color_node);
437         gl_color_node_free (&line_color_node);
438                         
439         view->create_object = GL_LABEL_OBJECT (object);
440         view->create_x0 = x;
441         view->create_y0 = y;
442 }
443
444
445 /*****************************************************************************/
446 /* Object creation handler: motion event.                                    */
447 /*****************************************************************************/
448 void
449 gl_view_box_create_motion_event         (glView *view,
450                                          gdouble x,
451                                          gdouble y)
452 {
453         gdouble w, h;
454
455         gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
456                                       MIN (x, view->create_x0), MIN (y, view->create_y0));
457         w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
458         h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
459         gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
460 }
461
462
463 /*****************************************************************************/
464 /* Object creation handler: button relesase event.                           */
465 /*****************************************************************************/
466 void
467 gl_view_box_create_button_release_event (glView *view,
468                                          gdouble x,
469                                          gdouble y)
470 {
471         glColorNode         *fill_color_node;
472         glColorNode         *line_color_node;
473         gdouble              w, h;
474
475         fill_color_node = gl_color_node_new_default ();
476         line_color_node = gl_color_node_new_default ();
477                 
478         if ((view->create_x0 == x) && (view->create_y0 == y)) {
479                 x = view->create_x0 + 36.0;
480                 y = view->create_y0 + 36.0;
481         }
482         gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
483                                       MIN (x, view->create_x0), MIN (y, view->create_y0));
484         w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
485         h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
486         gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
487         line_color_node->color = gl_view_get_default_line_color(view);
488         gl_label_object_set_line_color (GL_LABEL_OBJECT(view->create_object), line_color_node);
489         fill_color_node->color = gl_view_get_default_fill_color(view);
490         gl_label_object_set_fill_color (GL_LABEL_OBJECT(view->create_object), fill_color_node);
491         gl_color_node_free (&fill_color_node);
492         gl_color_node_free (&line_color_node);
493 }
494
495
496
497 /*
498  * Local Variables:       -- emacs
499  * mode: C                -- emacs
500  * c-basic-offset: 8      -- emacs
501  * tab-width: 8           -- emacs
502  * indent-tabs-mode: nil  -- emacs
503  * End:                   -- emacs
504  */