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