]> git.sur5r.net Git - glabels/blob - src/view-text.c
Organized master branch to be top-level directory for glabels, instead of
[glabels] / src / view-text.c
1 /*
2  *  view-text.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-text.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_text.xbm"
33 #include "pixmaps/cursor_text_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 _glViewTextPrivate {
48 };
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 /* Boilerplate object stuff.                                                 */
86 /*****************************************************************************/
87 G_DEFINE_TYPE (glViewText, gl_view_text, GL_TYPE_VIEW_OBJECT);
88
89
90 static void
91 gl_view_text_class_init (glViewTextClass *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_text_parent_class = g_type_class_peek_parent (class);
99
100         object_class->finalize = gl_view_text_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
109 static void
110 gl_view_text_init (glViewText *view_text)
111 {
112         gl_debug (DEBUG_VIEW, "START");
113
114         view_text->priv = g_new0 (glViewTextPrivate, 1);
115
116         gl_debug (DEBUG_VIEW, "END");
117 }
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 /*****************************************************************************/
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 /*****************************************************************************/
165 /* Create a properties dialog for a text object.                             */
166 /*****************************************************************************/
167 static GtkWidget *
168 construct_properties_editor (glViewObject *view_object)
169 {
170         GtkWidget          *editor;
171         glViewText          *view_text = (glViewText *)view_object;
172         glLabelObject      *object;
173         GtkTextBuffer      *buffer;
174
175         gl_debug (DEBUG_VIEW, "START");
176
177         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_text));
178
179         /* Build editor. */
180         editor = gl_object_editor_new (GL_STOCK_TEXT, _("Text object properties"),
181                                        object->parent,
182                                        GL_OBJECT_EDITOR_SHADOW_PAGE,
183                                        GL_OBJECT_EDITOR_POSITION_PAGE,
184                                        GL_OBJECT_EDITOR_SIZE_PAGE,
185                                        GL_OBJECT_EDITOR_TEXT_PAGE,
186                                        GL_OBJECT_EDITOR_EDIT_PAGE,
187                                        0);
188
189         buffer = gl_label_text_get_buffer (GL_LABEL_TEXT(object));
190         gl_object_editor_set_text_buffer (GL_OBJECT_EDITOR(editor), buffer);
191         
192         /* Update */
193         update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
194         update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
195
196         /* Connect signals. */
197         g_signal_connect (G_OBJECT (editor), "changed",
198                           G_CALLBACK(update_object_from_editor_cb), object);
199         g_signal_connect (G_OBJECT (editor), "size_changed",
200                           G_CALLBACK(update_object_from_editor_size_cb), object);
201         g_signal_connect (G_OBJECT (object), "changed",
202                           G_CALLBACK (update_editor_from_object_cb), editor);
203         g_signal_connect (G_OBJECT (object), "moved",
204                           G_CALLBACK (update_editor_from_move_cb), editor);
205
206         gl_debug (DEBUG_VIEW, "END");
207
208         return editor;
209 }
210
211
212 /*---------------------------------------------------------------------------*/
213 /* PRIVATE.  editor "changed" callback.                                      */
214 /*---------------------------------------------------------------------------*/
215 static void
216 update_object_from_editor_cb (glObjectEditor *editor,
217                               glLabelObject  *object)
218 {
219         gdouble            x, y;
220         gchar             *font_family;
221         gdouble            font_size;
222         PangoWeight        font_weight;
223         gboolean           font_italic_flag;
224         glColorNode       *color_node;
225         PangoAlignment     align;
226         gdouble            text_line_spacing;
227         gboolean           auto_shrink;
228         gboolean           shadow_state;
229         gdouble            shadow_x, shadow_y;
230         glColorNode       *shadow_color_node;
231         gdouble            shadow_opacity;
232
233         gl_debug (DEBUG_VIEW, "START");
234
235         g_signal_handlers_block_by_func (G_OBJECT(object),
236                                          update_editor_from_object_cb,
237                                          editor);
238         g_signal_handlers_block_by_func (G_OBJECT(object),
239                                          update_editor_from_move_cb,
240                                          editor);
241
242         gl_object_editor_get_position (editor, &x, &y);
243         font_family = gl_object_editor_get_font_family (editor);
244         font_size = gl_object_editor_get_font_size (editor);
245         font_weight = gl_object_editor_get_font_weight (editor);
246         font_italic_flag = gl_object_editor_get_font_italic_flag (editor);
247         color_node = gl_object_editor_get_text_color (editor);
248         align = gl_object_editor_get_text_alignment (editor);
249         text_line_spacing = gl_object_editor_get_text_line_spacing (editor);
250         auto_shrink = gl_object_editor_get_text_auto_shrink (editor);
251
252         gl_label_object_set_position (object, x, y);
253         gl_label_object_set_font_family (object, font_family);
254         gl_label_object_set_font_size (object, font_size);
255         gl_label_object_set_font_weight (object, font_weight);
256         gl_label_object_set_font_italic_flag (object, font_italic_flag);
257         gl_label_object_set_text_color (object, color_node);
258         gl_label_object_set_text_alignment (object, align);
259         gl_label_object_set_text_line_spacing (object, text_line_spacing);
260         gl_label_text_set_auto_shrink (GL_LABEL_TEXT (object), auto_shrink);
261
262         gl_color_node_free (&color_node);
263         g_free (font_family);
264
265         shadow_state = gl_object_editor_get_shadow_state (editor);
266         gl_label_object_set_shadow_state (object, shadow_state);
267
268         gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
269         gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
270
271         shadow_color_node = gl_object_editor_get_shadow_color (editor);
272         gl_label_object_set_shadow_color (object, shadow_color_node);
273         gl_color_node_free (&shadow_color_node);
274
275         shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
276         gl_label_object_set_shadow_opacity (object, shadow_opacity);
277
278         g_signal_handlers_unblock_by_func (G_OBJECT(object),
279                                            update_editor_from_object_cb,
280                                            editor);
281         g_signal_handlers_unblock_by_func (G_OBJECT(object),
282                                            update_editor_from_move_cb,
283                                            editor);
284
285         gl_debug (DEBUG_VIEW, "END");
286 }
287
288
289 /*---------------------------------------------------------------------------*/
290 /* PRIVATE.  editor "changed" callback.                                      */
291 /*---------------------------------------------------------------------------*/
292 static void
293 update_object_from_editor_size_cb (glObjectEditor *editor,
294                                    glLabelObject  *object)
295 {
296         gdouble            w, h;
297
298         gl_debug (DEBUG_VIEW, "START");
299
300         g_signal_handlers_block_by_func (G_OBJECT(object),
301                                          update_editor_from_object_cb,
302                                          editor);
303         g_signal_handlers_block_by_func (G_OBJECT(object),
304                                          update_editor_from_move_cb,
305                                          editor);
306
307         gl_object_editor_get_size (editor, &w, &h);
308
309         gl_label_object_set_size (object, w, h);
310
311         g_signal_handlers_unblock_by_func (G_OBJECT(object),
312                                            update_editor_from_object_cb,
313                                            editor);
314         g_signal_handlers_unblock_by_func (G_OBJECT(object),
315                                            update_editor_from_move_cb,
316                                            editor);
317
318         gl_debug (DEBUG_VIEW, "END");
319 }
320
321
322 /*---------------------------------------------------------------------------*/
323 /* PRIVATE. label object "changed" callback.                                 */
324 /*---------------------------------------------------------------------------*/
325 static void
326 update_editor_from_object_cb (glLabelObject  *object,
327                               glObjectEditor *editor)
328 {
329         gdouble            w, h;
330         gchar             *font_family;
331         gdouble            font_size;
332         PangoWeight        font_weight;
333         gboolean           font_italic_flag;
334         glColorNode       *color_node;
335         PangoAlignment     align;
336         gdouble            text_line_spacing;
337         gboolean           auto_shrink;
338         gboolean           shadow_state;
339         gdouble            shadow_x, shadow_y;
340         glColorNode       *shadow_color_node;
341         gdouble            shadow_opacity;
342         glMerge           *merge;
343
344         gl_debug (DEBUG_VIEW, "START");
345
346         gl_label_object_get_size (object, &w, &h);
347         gl_object_editor_set_size (editor, w, h);
348         merge = gl_label_get_merge (GL_LABEL(object->parent));
349
350         font_family      = gl_label_object_get_font_family (object);
351         font_size        = gl_label_object_get_font_size (object);
352         font_weight      = gl_label_object_get_font_weight (object);
353         font_italic_flag = gl_label_object_get_font_italic_flag (object);
354         color_node       = gl_label_object_get_text_color (object);
355         align             = gl_label_object_get_text_alignment (object);
356         text_line_spacing = gl_label_object_get_text_line_spacing (object);
357         auto_shrink      = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
358
359         gl_object_editor_set_font_family (editor, font_family);
360         gl_object_editor_set_font_size (editor, font_size);
361         gl_object_editor_set_font_weight (editor, font_weight);
362         gl_object_editor_set_font_italic_flag (editor, font_italic_flag);
363         gl_object_editor_set_text_color (editor, (merge != NULL), color_node);
364         gl_object_editor_set_text_alignment (editor, align);
365         gl_object_editor_set_text_line_spacing (editor, text_line_spacing);
366         gl_object_editor_set_text_auto_shrink (editor, auto_shrink);
367
368         gl_color_node_free (&color_node);
369         g_free (font_family);
370
371         shadow_state = gl_label_object_get_shadow_state (object);
372         gl_object_editor_set_shadow_state (editor, shadow_state);
373
374         gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
375         gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
376
377         shadow_color_node = gl_label_object_get_shadow_color (object);
378         gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
379         gl_color_node_free (&shadow_color_node);
380
381         shadow_opacity = gl_label_object_get_shadow_opacity (object);
382         gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
383
384         gl_debug (DEBUG_VIEW, "END");
385 }
386
387
388 /*---------------------------------------------------------------------------*/
389 /* PRIVATE. label object "moved" callback.                                   */
390 /*---------------------------------------------------------------------------*/
391 static void
392 update_editor_from_move_cb (glLabelObject    *object,
393                             gdouble           dx,
394                             gdouble           dy,
395                             glObjectEditor   *editor)
396 {
397         gdouble            x, y;
398
399         gl_debug (DEBUG_VIEW, "START");
400
401         gl_label_object_get_position (object, &x, &y);
402         gl_object_editor_set_position (editor, x, y);
403
404         gl_debug (DEBUG_VIEW, "END");
405 }
406
407
408 /*****************************************************************************/
409 /* Is object at (x,y)?                                                       */
410 /*****************************************************************************/
411 static gboolean
412 object_at (glViewObject  *view_object,
413            cairo_t       *cr,
414            gdouble        x,
415            gdouble        y)
416 {
417         glLabelObject    *object;
418         gdouble           w, h;
419
420         object = gl_view_object_get_object (view_object);
421
422         gl_label_object_get_size (object, &w, &h);
423
424         cairo_rectangle (cr, 0.0, 0.0, w, h);
425
426         if (cairo_in_fill (cr, x, y))
427         {
428                 return TRUE;
429         }
430
431         return FALSE;
432 }
433
434
435 /*****************************************************************************/
436 /* Return apropos cursor for create object mode.                             */
437 /*****************************************************************************/
438 GdkCursor *
439 gl_view_text_get_create_cursor (void)
440 {
441         GdkCursor       *cursor = NULL;
442         GdkPixmap       *pixmap_data, *pixmap_mask;
443         GdkColor         fg = { 0, 0, 0, 0 };
444         GdkColor         bg = { 0, 65535, 65535, 65535 };
445
446         gl_debug (DEBUG_VIEW, "START");
447
448         pixmap_data = gdk_bitmap_create_from_data (NULL,
449                                                    (gchar *)cursor_text_bits,
450                                                    cursor_text_width,
451                                                    cursor_text_height);
452         pixmap_mask = gdk_bitmap_create_from_data (NULL,
453                                                    (gchar *)cursor_text_mask_bits,
454                                                    cursor_text_mask_width,
455                                                    cursor_text_mask_height);
456         cursor = gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
457                                              &bg, cursor_text_x_hot,
458                                              cursor_text_y_hot);
459
460         gl_debug (DEBUG_VIEW, "END");
461
462         return cursor;
463 }
464
465
466 /*****************************************************************************/
467 /* Object creation handler: button press event.                              */
468 /*****************************************************************************/
469 void
470 gl_view_text_create_button_press_event   (glView *view,
471                                           gdouble x,
472                                           gdouble y)
473 {
474         GObject             *object;
475         GList               *lines;
476         gchar               *family;
477         glColorNode         *color_node;
478
479         gl_view_unselect_all (view);
480
481         object = gl_label_text_new (view->label);
482         color_node = gl_color_node_new_default ();
483         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
484         family = gl_view_get_default_font_family (view);
485         gl_label_object_set_font_family (GL_LABEL_OBJECT(object), family);
486         gl_label_object_set_font_size (GL_LABEL_OBJECT(object),
487                                        gl_view_get_default_font_size (view));
488         gl_label_object_set_font_weight (GL_LABEL_OBJECT(object),
489                                          gl_view_get_default_font_weight (view));
490         gl_label_object_set_font_italic_flag (GL_LABEL_OBJECT(object),
491                                               gl_view_get_default_font_italic_flag (view));
492                                                                   
493         color_node->color = gl_color_set_opacity (gl_view_get_default_text_color (view), 0.5);
494         gl_label_object_set_text_color (GL_LABEL_OBJECT(object),
495                                                         color_node);
496         gl_label_object_set_text_alignment (GL_LABEL_OBJECT(object),
497                                             gl_view_get_default_text_alignment (view));
498         gl_label_object_set_text_line_spacing (GL_LABEL_OBJECT(object), gl_view_get_default_text_line_spacing (view));
499                                                        
500         g_free (family);
501         lines = gl_text_node_lines_new_from_text (_("Text"));
502         gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
503         gl_color_node_free (&color_node);
504
505         view->create_object = GL_LABEL_OBJECT (object);
506         view->create_x0 = x;
507         view->create_y0 = y;
508 }
509
510
511 /*****************************************************************************/
512 /* Object creation handler: motion event.                                    */
513 /*****************************************************************************/
514 void
515 gl_view_text_create_motion_event     (glView *view,
516                                       gdouble x,
517                                       gdouble y)
518 {
519         gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object), x, y);
520 }
521
522
523 /*****************************************************************************/
524 /* Object creation handler: button relesase event.                           */
525 /*****************************************************************************/
526 void
527 gl_view_text_create_button_release_event (glView *view,
528                                           gdouble x,
529                                           gdouble y)
530 {
531         glColorNode         *color_node;
532
533         color_node = gl_color_node_new_default ();
534         gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object), x, y);
535         color_node->color = gl_view_get_default_text_color(view);
536         gl_label_object_set_text_color (GL_LABEL_OBJECT(view->create_object), color_node);
537         gl_color_node_free (&color_node);
538 }
539
540
541
542 /*
543  * Local Variables:       -- emacs
544  * mode: C                -- emacs
545  * c-basic-offset: 8      -- emacs
546  * tab-width: 8           -- emacs
547  * indent-tabs-mode: nil  -- emacs
548  * End:                   -- emacs
549  */