]> git.sur5r.net Git - glabels/blob - src/view-text.c
Imported Upstream version 2.2.8
[glabels] / src / view-text.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_text.c:  GLabels label text 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-text.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_text.xbm"
36 #include "pixmaps/cursor_text_mask.xbm"
37
38 #include "debug.h"
39
40 /*========================================================*/
41 /* Private macros and constants.                          */
42 /*========================================================*/
43
44 /*========================================================*/
45 /* Private types.                                         */
46 /*========================================================*/
47
48 struct _glViewTextPrivate {
49         int place_holder; /* Place holder for future private data. */
50 };
51
52 /*========================================================*/
53 /* Private globals.                                       */
54 /*========================================================*/
55
56
57 /*========================================================*/
58 /* Private function prototypes.                           */
59 /*========================================================*/
60
61 static void       gl_view_text_finalize             (GObject          *object);
62
63 static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
64
65 static void       update_object_from_editor_cb      (glObjectEditor   *editor,
66                                                      glLabelObject    *object);
67
68 static void       update_object_from_editor_size_cb (glObjectEditor   *editor,
69                                                      glLabelObject    *object);
70
71 static void       update_editor_from_object_cb      (glLabelObject    *object,
72                                                      glObjectEditor   *editor);
73
74 static void       update_editor_from_move_cb        (glLabelObject    *object,
75                                                      gdouble           dx,
76                                                      gdouble           dy,
77                                                      glObjectEditor   *editor);
78
79 static gboolean   object_at                         (glViewObject     *view_object,
80                                                      cairo_t          *cr,
81                                                      gdouble           x,
82                                                      gdouble           y);
83
84
85
86 \f
87 /*****************************************************************************/
88 /* Boilerplate object stuff.                                                 */
89 /*****************************************************************************/
90 G_DEFINE_TYPE (glViewText, gl_view_text, GL_TYPE_VIEW_OBJECT);
91
92
93 static void
94 gl_view_text_class_init (glViewTextClass *class)
95 {
96         GObjectClass      *object_class      = G_OBJECT_CLASS (class);
97         glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
98
99         gl_debug (DEBUG_VIEW, "START");
100
101         gl_view_text_parent_class = g_type_class_peek_parent (class);
102
103         object_class->finalize = gl_view_text_finalize;
104
105         view_object_class->construct_editor = construct_properties_editor;
106         view_object_class->object_at        = object_at;
107
108         gl_debug (DEBUG_VIEW, "END");
109 }
110
111 static void
112 gl_view_text_init (glViewText *view_text)
113 {
114         gl_debug (DEBUG_VIEW, "START");
115
116         view_text->priv = g_new0 (glViewTextPrivate, 1);
117
118         gl_debug (DEBUG_VIEW, "END");
119 }
120
121 static void
122 gl_view_text_finalize (GObject *object)
123 {
124         glViewText *view_text = GL_VIEW_TEXT (object);
125
126         gl_debug (DEBUG_VIEW, "START");
127
128         g_return_if_fail (object && GL_IS_VIEW_TEXT (object));
129
130         g_free (view_text->priv);
131
132         G_OBJECT_CLASS (gl_view_text_parent_class)->finalize (object);
133
134         gl_debug (DEBUG_VIEW, "END");
135 }
136
137 /*****************************************************************************/
138 /* NEW text object view.                                                     */
139 /*****************************************************************************/
140 glViewObject *
141 gl_view_text_new (glLabelText *object,
142                   glView      *view)
143 {
144         glViewText         *view_text;
145
146         gl_debug (DEBUG_VIEW, "START");
147
148         g_return_val_if_fail (object && GL_IS_LABEL_TEXT (object), NULL);
149         g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
150         
151         view_text = g_object_new (gl_view_text_get_type(), NULL);
152
153         gl_view_object_set_object (GL_VIEW_OBJECT(view_text),
154                                    GL_LABEL_OBJECT(object),
155                                    GL_VIEW_OBJECT_HANDLES_BOX);
156         gl_view_object_set_view (GL_VIEW_OBJECT(view_text), view);
157
158         gl_debug (DEBUG_VIEW, "END");
159
160         return GL_VIEW_OBJECT (view_text);
161 }
162
163 /*****************************************************************************/
164 /* Create a properties dialog for a text object.                             */
165 /*****************************************************************************/
166 static GtkWidget *
167 construct_properties_editor (glViewObject *view_object)
168 {
169         GtkWidget          *editor;
170         glViewText          *view_text = (glViewText *)view_object;
171         glLabelObject      *object;
172         GtkTextBuffer      *buffer;
173
174         gl_debug (DEBUG_VIEW, "START");
175
176         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_text));
177
178         /* Build editor. */
179         editor = gl_object_editor_new (GL_STOCK_TEXT, _("Text object properties"),
180                                        object->parent,
181                                        GL_OBJECT_EDITOR_SHADOW_PAGE,
182                                        GL_OBJECT_EDITOR_POSITION_PAGE,
183                                        GL_OBJECT_EDITOR_SIZE_PAGE,
184                                        GL_OBJECT_EDITOR_TEXT_PAGE,
185                                        GL_OBJECT_EDITOR_EDIT_PAGE,
186                                        0);
187
188         buffer = gl_label_text_get_buffer (GL_LABEL_TEXT(object));
189         gl_object_editor_set_text_buffer (GL_OBJECT_EDITOR(editor), buffer);
190         
191         /* Update */
192         update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
193         update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
194
195         /* Connect signals. */
196         g_signal_connect (G_OBJECT (editor), "changed",
197                           G_CALLBACK(update_object_from_editor_cb), object);
198         g_signal_connect (G_OBJECT (editor), "size_changed",
199                           G_CALLBACK(update_object_from_editor_size_cb), object);
200         g_signal_connect (G_OBJECT (object), "changed",
201                           G_CALLBACK (update_editor_from_object_cb), editor);
202         g_signal_connect (G_OBJECT (object), "moved",
203                           G_CALLBACK (update_editor_from_move_cb), editor);
204
205         gl_debug (DEBUG_VIEW, "END");
206
207         return editor;
208 }
209
210 /*---------------------------------------------------------------------------*/
211 /* PRIVATE.  editor "changed" callback.                                      */
212 /*---------------------------------------------------------------------------*/
213 static void
214 update_object_from_editor_cb (glObjectEditor *editor,
215                               glLabelObject  *object)
216 {
217         gdouble            x, y;
218         gchar             *font_family;
219         gdouble            font_size;
220         PangoWeight        font_weight;
221         gboolean           font_italic_flag;
222         glColorNode       *color_node;
223         PangoAlignment     align;
224         gdouble            text_line_spacing;
225         gboolean           auto_shrink;
226         gboolean           shadow_state;
227         gdouble            shadow_x, shadow_y;
228         glColorNode       *shadow_color_node;
229         gdouble            shadow_opacity;
230
231         gl_debug (DEBUG_VIEW, "START");
232
233         g_signal_handlers_block_by_func (G_OBJECT(object),
234                                          update_editor_from_object_cb,
235                                          editor);
236         g_signal_handlers_block_by_func (G_OBJECT(object),
237                                          update_editor_from_move_cb,
238                                          editor);
239
240         gl_object_editor_get_position (editor, &x, &y);
241         font_family = gl_object_editor_get_font_family (editor);
242         font_size = gl_object_editor_get_font_size (editor);
243         font_weight = gl_object_editor_get_font_weight (editor);
244         font_italic_flag = gl_object_editor_get_font_italic_flag (editor);
245         color_node = gl_object_editor_get_text_color (editor);
246         align = gl_object_editor_get_text_alignment (editor);
247         text_line_spacing = gl_object_editor_get_text_line_spacing (editor);
248         auto_shrink = gl_object_editor_get_text_auto_shrink (editor);
249
250         gl_label_object_set_position (object, x, y);
251         gl_label_object_set_font_family (object, font_family);
252         gl_label_object_set_font_size (object, font_size);
253         gl_label_object_set_font_weight (object, font_weight);
254         gl_label_object_set_font_italic_flag (object, font_italic_flag);
255         gl_label_object_set_text_color (object, color_node);
256         gl_label_object_set_text_alignment (object, align);
257         gl_label_object_set_text_line_spacing (object, text_line_spacing);
258         gl_label_text_set_auto_shrink (GL_LABEL_TEXT (object), auto_shrink);
259
260         gl_color_node_free (&color_node);
261         g_free (font_family);
262
263         shadow_state = gl_object_editor_get_shadow_state (editor);
264         gl_label_object_set_shadow_state (object, shadow_state);
265
266         gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
267         gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
268
269         shadow_color_node = gl_object_editor_get_shadow_color (editor);
270         gl_label_object_set_shadow_color (object, shadow_color_node);
271         gl_color_node_free (&shadow_color_node);
272
273         shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
274         gl_label_object_set_shadow_opacity (object, shadow_opacity);
275
276         g_signal_handlers_unblock_by_func (G_OBJECT(object),
277                                            update_editor_from_object_cb,
278                                            editor);
279         g_signal_handlers_unblock_by_func (G_OBJECT(object),
280                                            update_editor_from_move_cb,
281                                            editor);
282
283         gl_debug (DEBUG_VIEW, "END");
284 }
285
286 /*---------------------------------------------------------------------------*/
287 /* PRIVATE.  editor "changed" callback.                                      */
288 /*---------------------------------------------------------------------------*/
289 static void
290 update_object_from_editor_size_cb (glObjectEditor *editor,
291                                    glLabelObject  *object)
292 {
293         gdouble            w, h;
294
295         gl_debug (DEBUG_VIEW, "START");
296
297         g_signal_handlers_block_by_func (G_OBJECT(object),
298                                          update_editor_from_object_cb,
299                                          editor);
300         g_signal_handlers_block_by_func (G_OBJECT(object),
301                                          update_editor_from_move_cb,
302                                          editor);
303
304         gl_object_editor_get_size (editor, &w, &h);
305
306         gl_label_object_set_size (object, w, h);
307
308         g_signal_handlers_unblock_by_func (G_OBJECT(object),
309                                            update_editor_from_object_cb,
310                                            editor);
311         g_signal_handlers_unblock_by_func (G_OBJECT(object),
312                                            update_editor_from_move_cb,
313                                            editor);
314
315         gl_debug (DEBUG_VIEW, "END");
316 }
317
318 /*---------------------------------------------------------------------------*/
319 /* PRIVATE. label object "changed" callback.                                 */
320 /*---------------------------------------------------------------------------*/
321 static void
322 update_editor_from_object_cb (glLabelObject  *object,
323                               glObjectEditor *editor)
324 {
325         gdouble            w, h;
326         gchar             *font_family;
327         gdouble            font_size;
328         PangoWeight        font_weight;
329         gboolean           font_italic_flag;
330         glColorNode       *color_node;
331         PangoAlignment     align;
332         gdouble            text_line_spacing;
333         gboolean           auto_shrink;
334         gboolean           shadow_state;
335         gdouble            shadow_x, shadow_y;
336         glColorNode       *shadow_color_node;
337         gdouble            shadow_opacity;
338         glMerge           *merge;
339
340         gl_debug (DEBUG_VIEW, "START");
341
342         gl_label_object_get_size (object, &w, &h);
343         gl_object_editor_set_size (editor, w, h);
344         merge = gl_label_get_merge (GL_LABEL(object->parent));
345
346         font_family      = gl_label_object_get_font_family (object);
347         font_size        = gl_label_object_get_font_size (object);
348         font_weight      = gl_label_object_get_font_weight (object);
349         font_italic_flag = gl_label_object_get_font_italic_flag (object);
350         color_node       = gl_label_object_get_text_color (object);
351         align             = gl_label_object_get_text_alignment (object);
352         text_line_spacing = gl_label_object_get_text_line_spacing (object);
353         auto_shrink      = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
354
355         gl_object_editor_set_font_family (editor, font_family);
356         gl_object_editor_set_font_size (editor, font_size);
357         gl_object_editor_set_font_weight (editor, font_weight);
358         gl_object_editor_set_font_italic_flag (editor, font_italic_flag);
359         gl_object_editor_set_text_color (editor, (merge != NULL), color_node);
360         gl_object_editor_set_text_alignment (editor, align);
361         gl_object_editor_set_text_line_spacing (editor, text_line_spacing);
362         gl_object_editor_set_text_auto_shrink (editor, auto_shrink);
363
364         gl_color_node_free (&color_node);
365         g_free (font_family);
366
367         shadow_state = gl_label_object_get_shadow_state (object);
368         gl_object_editor_set_shadow_state (editor, shadow_state);
369
370         gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
371         gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
372
373         shadow_color_node = gl_label_object_get_shadow_color (object);
374         gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
375         gl_color_node_free (&shadow_color_node);
376
377         shadow_opacity = gl_label_object_get_shadow_opacity (object);
378         gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
379
380         gl_debug (DEBUG_VIEW, "END");
381 }
382
383 /*---------------------------------------------------------------------------*/
384 /* PRIVATE. label object "moved" callback.                                   */
385 /*---------------------------------------------------------------------------*/
386 static void
387 update_editor_from_move_cb (glLabelObject    *object,
388                             gdouble           dx,
389                             gdouble           dy,
390                             glObjectEditor   *editor)
391 {
392         gdouble            x, y;
393
394         gl_debug (DEBUG_VIEW, "START");
395
396         gl_label_object_get_position (object, &x, &y);
397         gl_object_editor_set_position (editor, x, y);
398
399         gl_debug (DEBUG_VIEW, "END");
400 }
401
402
403 /*****************************************************************************/
404 /* Is object at (x,y)?                                                       */
405 /*****************************************************************************/
406 static gboolean
407 object_at (glViewObject  *view_object,
408            cairo_t       *cr,
409            gdouble        x,
410            gdouble        y)
411 {
412         glLabelObject    *object;
413         gdouble           w, h;
414
415         object = gl_view_object_get_object (view_object);
416
417         gl_label_object_get_size (object, &w, &h);
418
419         cairo_rectangle (cr, 0.0, 0.0, w, h);
420
421         if (cairo_in_fill (cr, x, y))
422         {
423                 return TRUE;
424         }
425
426         return FALSE;
427 }
428
429
430 /*****************************************************************************/
431 /* Return apropos cursor for create object mode.                             */
432 /*****************************************************************************/
433 GdkCursor *
434 gl_view_text_get_create_cursor (void)
435 {
436         GdkCursor       *cursor = NULL;
437         GdkPixmap       *pixmap_data, *pixmap_mask;
438         GdkColor         fg = { 0, 0, 0, 0 };
439         GdkColor         bg = { 0, 65535, 65535, 65535 };
440
441         gl_debug (DEBUG_VIEW, "START");
442
443         pixmap_data = gdk_bitmap_create_from_data (NULL,
444                                                    (gchar *)cursor_text_bits,
445                                                    cursor_text_width,
446                                                    cursor_text_height);
447         pixmap_mask = gdk_bitmap_create_from_data (NULL,
448                                                    (gchar *)cursor_text_mask_bits,
449                                                    cursor_text_mask_width,
450                                                    cursor_text_mask_height);
451         cursor = gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
452                                              &bg, cursor_text_x_hot,
453                                              cursor_text_y_hot);
454
455         gl_debug (DEBUG_VIEW, "END");
456
457         return cursor;
458 }
459
460 /*****************************************************************************/
461 /* Object creation handler: button press event.                              */
462 /*****************************************************************************/
463 void
464 gl_view_text_create_button_press_event   (glView *view,
465                                           gdouble x,
466                                           gdouble y)
467 {
468         GObject             *object;
469         GList               *lines;
470         gchar               *family;
471         glColorNode         *color_node;
472
473         gl_view_unselect_all (view);
474
475         object = gl_label_text_new (view->label);
476         color_node = gl_color_node_new_default ();
477         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
478         family = gl_view_get_default_font_family (view);
479         gl_label_object_set_font_family (GL_LABEL_OBJECT(object), family);
480         gl_label_object_set_font_size (GL_LABEL_OBJECT(object),
481                                        gl_view_get_default_font_size (view));
482         gl_label_object_set_font_weight (GL_LABEL_OBJECT(object),
483                                          gl_view_get_default_font_weight (view));
484         gl_label_object_set_font_italic_flag (GL_LABEL_OBJECT(object),
485                                               gl_view_get_default_font_italic_flag (view));
486                                                                   
487         color_node->color = gl_color_set_opacity (gl_view_get_default_text_color (view), 0.5);
488         gl_label_object_set_text_color (GL_LABEL_OBJECT(object),
489                                                         color_node);
490         gl_label_object_set_text_alignment (GL_LABEL_OBJECT(object),
491                                             gl_view_get_default_text_alignment (view));
492         gl_label_object_set_text_line_spacing (GL_LABEL_OBJECT(object), gl_view_get_default_text_line_spacing (view));
493                                                        
494         g_free (family);
495         lines = gl_text_node_lines_new_from_text (_("Text"));
496         gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
497         gl_color_node_free (&color_node);
498
499         view->create_object = GL_LABEL_OBJECT (object);
500         view->create_x0 = x;
501         view->create_y0 = y;
502 }
503
504 /*****************************************************************************/
505 /* Object creation handler: motion event.                                    */
506 /*****************************************************************************/
507 void
508 gl_view_text_create_motion_event     (glView *view,
509                                       gdouble x,
510                                       gdouble y)
511 {
512         gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object), x, y);
513 }
514
515 /*****************************************************************************/
516 /* Object creation handler: button relesase event.                           */
517 /*****************************************************************************/
518 void
519 gl_view_text_create_button_release_event (glView *view,
520                                           gdouble x,
521                                           gdouble y)
522 {
523         glColorNode         *color_node;
524
525         color_node = gl_color_node_new_default ();
526         gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object), x, y);
527         color_node->color = gl_view_get_default_text_color(view);
528         gl_label_object_set_text_color (GL_LABEL_OBJECT(view->create_object), color_node);
529         gl_color_node_free (&color_node);
530 }
531