1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * view_text.c: GLabels label text object view
8 * Copyright (C) 2001-2007 Jim Evins <evins@snaught.com>.
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.
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.
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
26 #include "view-text.h"
28 #include <glib/gi18n.h>
29 #include <glib/gmem.h>
32 #include "object-editor.h"
35 #include "pixmaps/cursor_text.xbm"
36 #include "pixmaps/cursor_text_mask.xbm"
40 /*========================================================*/
41 /* Private macros and constants. */
42 /*========================================================*/
44 /*========================================================*/
46 /*========================================================*/
48 struct _glViewTextPrivate {
51 /*========================================================*/
52 /* Private globals. */
53 /*========================================================*/
56 /*========================================================*/
57 /* Private function prototypes. */
58 /*========================================================*/
60 static void gl_view_text_finalize (GObject *object);
62 static GtkWidget *construct_properties_editor (glViewObject *view_object);
64 static void update_object_from_editor_cb (glObjectEditor *editor,
65 glLabelObject *object);
67 static void update_object_from_editor_size_cb (glObjectEditor *editor,
68 glLabelObject *object);
70 static void update_editor_from_object_cb (glLabelObject *object,
71 glObjectEditor *editor);
73 static void update_editor_from_move_cb (glLabelObject *object,
76 glObjectEditor *editor);
78 static void update_editor_from_label_cb (glLabel *label,
79 glObjectEditor *editor);
81 static gboolean object_at (glViewObject *view_object,
89 /*****************************************************************************/
90 /* Boilerplate object stuff. */
91 /*****************************************************************************/
92 G_DEFINE_TYPE (glViewText, gl_view_text, GL_TYPE_VIEW_OBJECT);
96 gl_view_text_class_init (glViewTextClass *class)
98 GObjectClass *object_class = G_OBJECT_CLASS (class);
99 glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
101 gl_debug (DEBUG_VIEW, "START");
103 gl_view_text_parent_class = g_type_class_peek_parent (class);
105 object_class->finalize = gl_view_text_finalize;
107 view_object_class->construct_editor = construct_properties_editor;
108 view_object_class->object_at = object_at;
110 gl_debug (DEBUG_VIEW, "END");
114 gl_view_text_init (glViewText *view_text)
116 gl_debug (DEBUG_VIEW, "START");
118 view_text->priv = g_new0 (glViewTextPrivate, 1);
120 gl_debug (DEBUG_VIEW, "END");
124 gl_view_text_finalize (GObject *object)
126 glViewText *view_text = GL_VIEW_TEXT (object);
128 gl_debug (DEBUG_VIEW, "START");
130 g_return_if_fail (object && GL_IS_VIEW_TEXT (object));
132 g_free (view_text->priv);
134 G_OBJECT_CLASS (gl_view_text_parent_class)->finalize (object);
136 gl_debug (DEBUG_VIEW, "END");
139 /*****************************************************************************/
140 /* NEW text object view. */
141 /*****************************************************************************/
143 gl_view_text_new (glLabelText *object,
146 glViewText *view_text;
148 gl_debug (DEBUG_VIEW, "START");
150 g_return_val_if_fail (object && GL_IS_LABEL_TEXT (object), NULL);
151 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
153 view_text = g_object_new (gl_view_text_get_type(), NULL);
155 gl_view_object_set_object (GL_VIEW_OBJECT(view_text),
156 GL_LABEL_OBJECT(object),
157 GL_VIEW_OBJECT_HANDLES_BOX);
158 gl_view_object_set_view (GL_VIEW_OBJECT(view_text), view);
160 gl_debug (DEBUG_VIEW, "END");
162 return GL_VIEW_OBJECT (view_text);
165 /*****************************************************************************/
166 /* Create a properties dialog for a text object. */
167 /*****************************************************************************/
169 construct_properties_editor (glViewObject *view_object)
172 glViewText *view_text = (glViewText *)view_object;
173 glLabelObject *object;
174 GtkTextBuffer *buffer;
176 gl_debug (DEBUG_VIEW, "START");
178 object = gl_view_object_get_object (GL_VIEW_OBJECT(view_text));
181 editor = gl_object_editor_new (GL_STOCK_TEXT, _("Text object properties"),
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,
189 buffer = gl_label_text_get_buffer (GL_LABEL_TEXT(object));
190 gl_object_editor_set_text_buffer (GL_OBJECT_EDITOR(editor), buffer);
193 update_editor_from_label_cb (object->parent, GL_OBJECT_EDITOR(editor));
194 update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
195 update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
197 /* Connect signals. */
198 g_signal_connect (G_OBJECT (editor), "changed",
199 G_CALLBACK(update_object_from_editor_cb), object);
200 g_signal_connect (G_OBJECT (editor), "size_changed",
201 G_CALLBACK(update_object_from_editor_size_cb), object);
202 g_signal_connect (G_OBJECT (object), "changed",
203 G_CALLBACK (update_editor_from_object_cb), editor);
204 g_signal_connect (G_OBJECT (object), "moved",
205 G_CALLBACK (update_editor_from_move_cb), editor);
206 g_signal_connect (G_OBJECT (object->parent), "size_changed",
207 G_CALLBACK (update_editor_from_label_cb), editor);
208 g_signal_connect (G_OBJECT (object->parent), "merge_changed",
209 G_CALLBACK (update_editor_from_label_cb), editor);
211 gl_debug (DEBUG_VIEW, "END");
216 /*---------------------------------------------------------------------------*/
217 /* PRIVATE. editor "changed" callback. */
218 /*---------------------------------------------------------------------------*/
220 update_object_from_editor_cb (glObjectEditor *editor,
221 glLabelObject *object)
226 PangoWeight font_weight;
227 gboolean font_italic_flag;
228 glColorNode *color_node;
229 PangoAlignment align;
230 gdouble text_line_spacing;
231 gboolean auto_shrink;
232 gboolean shadow_state;
233 gdouble shadow_x, shadow_y;
234 glColorNode *shadow_color_node;
235 gdouble shadow_opacity;
237 gl_debug (DEBUG_VIEW, "START");
239 g_signal_handlers_block_by_func (G_OBJECT(object),
240 update_editor_from_object_cb,
242 g_signal_handlers_block_by_func (G_OBJECT(object),
243 update_editor_from_move_cb,
246 gl_object_editor_get_position (editor, &x, &y);
247 font_family = gl_object_editor_get_font_family (editor);
248 font_size = gl_object_editor_get_font_size (editor);
249 font_weight = gl_object_editor_get_font_weight (editor);
250 font_italic_flag = gl_object_editor_get_font_italic_flag (editor);
251 color_node = gl_object_editor_get_text_color (editor);
252 align = gl_object_editor_get_text_alignment (editor);
253 text_line_spacing = gl_object_editor_get_text_line_spacing (editor);
254 auto_shrink = gl_object_editor_get_text_auto_shrink (editor);
256 gl_label_object_set_position (object, x, y);
257 gl_label_object_set_font_family (object, font_family);
258 gl_label_object_set_font_size (object, font_size);
259 gl_label_object_set_font_weight (object, font_weight);
260 gl_label_object_set_font_italic_flag (object, font_italic_flag);
261 gl_label_object_set_text_color (object, color_node);
262 gl_label_object_set_text_alignment (object, align);
263 gl_label_object_set_text_line_spacing (object, text_line_spacing);
264 gl_label_text_set_auto_shrink (GL_LABEL_TEXT (object), auto_shrink);
266 gl_color_node_free (&color_node);
267 g_free (font_family);
269 shadow_state = gl_object_editor_get_shadow_state (editor);
270 gl_label_object_set_shadow_state (object, shadow_state);
272 gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
273 gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
275 shadow_color_node = gl_object_editor_get_shadow_color (editor);
276 gl_label_object_set_shadow_color (object, shadow_color_node);
277 gl_color_node_free (&shadow_color_node);
279 shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
280 gl_label_object_set_shadow_opacity (object, shadow_opacity);
282 g_signal_handlers_unblock_by_func (G_OBJECT(object),
283 update_editor_from_object_cb,
285 g_signal_handlers_unblock_by_func (G_OBJECT(object),
286 update_editor_from_move_cb,
289 gl_debug (DEBUG_VIEW, "END");
292 /*---------------------------------------------------------------------------*/
293 /* PRIVATE. editor "changed" callback. */
294 /*---------------------------------------------------------------------------*/
296 update_object_from_editor_size_cb (glObjectEditor *editor,
297 glLabelObject *object)
301 gl_debug (DEBUG_VIEW, "START");
303 g_signal_handlers_block_by_func (G_OBJECT(object),
304 update_editor_from_object_cb,
306 g_signal_handlers_block_by_func (G_OBJECT(object),
307 update_editor_from_move_cb,
310 gl_object_editor_get_size (editor, &w, &h);
312 gl_label_object_set_size (object, w, h);
314 g_signal_handlers_unblock_by_func (G_OBJECT(object),
315 update_editor_from_object_cb,
317 g_signal_handlers_unblock_by_func (G_OBJECT(object),
318 update_editor_from_move_cb,
321 gl_debug (DEBUG_VIEW, "END");
324 /*---------------------------------------------------------------------------*/
325 /* PRIVATE. label object "changed" callback. */
326 /*---------------------------------------------------------------------------*/
328 update_editor_from_object_cb (glLabelObject *object,
329 glObjectEditor *editor)
334 PangoWeight font_weight;
335 gboolean font_italic_flag;
336 glColorNode *color_node;
337 PangoAlignment align;
338 gdouble text_line_spacing;
339 gboolean auto_shrink;
340 gboolean shadow_state;
341 gdouble shadow_x, shadow_y;
342 glColorNode *shadow_color_node;
343 gdouble shadow_opacity;
346 gl_debug (DEBUG_VIEW, "START");
348 gl_label_object_get_size (object, &w, &h);
349 gl_object_editor_set_size (editor, w, h);
350 merge = gl_label_get_merge (GL_LABEL(object->parent));
352 font_family = gl_label_object_get_font_family (object);
353 font_size = gl_label_object_get_font_size (object);
354 font_weight = gl_label_object_get_font_weight (object);
355 font_italic_flag = gl_label_object_get_font_italic_flag (object);
356 color_node = gl_label_object_get_text_color (object);
357 align = gl_label_object_get_text_alignment (object);
358 text_line_spacing = gl_label_object_get_text_line_spacing (object);
359 auto_shrink = gl_label_text_get_auto_shrink (GL_LABEL_TEXT (object));
361 gl_object_editor_set_font_family (editor, font_family);
362 gl_object_editor_set_font_size (editor, font_size);
363 gl_object_editor_set_font_weight (editor, font_weight);
364 gl_object_editor_set_font_italic_flag (editor, font_italic_flag);
365 gl_object_editor_set_text_color (editor, (merge != NULL), color_node);
366 gl_object_editor_set_text_alignment (editor, align);
367 gl_object_editor_set_text_line_spacing (editor, text_line_spacing);
368 gl_object_editor_set_text_auto_shrink (editor, auto_shrink);
370 gl_color_node_free (&color_node);
371 g_free (font_family);
373 shadow_state = gl_label_object_get_shadow_state (object);
374 gl_object_editor_set_shadow_state (editor, shadow_state);
376 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
377 gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
379 shadow_color_node = gl_label_object_get_shadow_color (object);
380 gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
381 gl_color_node_free (&shadow_color_node);
383 shadow_opacity = gl_label_object_get_shadow_opacity (object);
384 gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
386 gl_debug (DEBUG_VIEW, "END");
389 /*---------------------------------------------------------------------------*/
390 /* PRIVATE. label object "moved" callback. */
391 /*---------------------------------------------------------------------------*/
393 update_editor_from_move_cb (glLabelObject *object,
396 glObjectEditor *editor)
400 gl_debug (DEBUG_VIEW, "START");
402 gl_label_object_get_position (object, &x, &y);
403 gl_object_editor_set_position (editor, x, y);
405 gl_debug (DEBUG_VIEW, "END");
408 /*---------------------------------------------------------------------------*/
409 /* PRIVATE. label "changed" callback. */
410 /*---------------------------------------------------------------------------*/
412 update_editor_from_label_cb (glLabel *label,
413 glObjectEditor *editor)
415 gdouble label_width, label_height;
418 gl_debug (DEBUG_VIEW, "START");
420 gl_label_get_size (label, &label_width, &label_height);
421 gl_object_editor_set_max_position (GL_OBJECT_EDITOR (editor),
422 label_width, label_height);
423 gl_object_editor_set_max_size (GL_OBJECT_EDITOR (editor),
424 label_width, label_height);
425 gl_object_editor_set_max_shadow_offset (GL_OBJECT_EDITOR (editor),
426 label_width, label_height);
428 merge = gl_label_get_merge (label);
429 gl_object_editor_set_key_names (editor, merge);
431 gl_debug (DEBUG_VIEW, "END");
434 /*****************************************************************************/
435 /* Is object at (x,y)? */
436 /*****************************************************************************/
438 object_at (glViewObject *view_object,
443 glLabelObject *object;
446 object = gl_view_object_get_object (view_object);
448 gl_label_object_get_size (object, &w, &h);
450 cairo_rectangle (cr, 0.0, 0.0, w, h);
452 if (cairo_in_fill (cr, x, y))
461 /*****************************************************************************/
462 /* Return apropos cursor for create object mode. */
463 /*****************************************************************************/
465 gl_view_text_get_create_cursor (void)
467 GdkCursor *cursor = NULL;
468 GdkPixmap *pixmap_data, *pixmap_mask;
469 GdkColor fg = { 0, 0, 0, 0 };
470 GdkColor bg = { 0, 65535, 65535, 65535 };
472 gl_debug (DEBUG_VIEW, "START");
474 pixmap_data = gdk_bitmap_create_from_data (NULL,
475 (gchar *)cursor_text_bits,
478 pixmap_mask = gdk_bitmap_create_from_data (NULL,
479 (gchar *)cursor_text_mask_bits,
480 cursor_text_mask_width,
481 cursor_text_mask_height);
482 cursor = gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
483 &bg, cursor_text_x_hot,
486 gl_debug (DEBUG_VIEW, "END");
491 /*****************************************************************************/
492 /* Object creation handler: button press event. */
493 /*****************************************************************************/
495 gl_view_text_create_button_press_event (glView *view,
500 glViewObject *view_text;
503 glColorNode *color_node;
505 gl_view_unselect_all (view);
507 object = gl_label_text_new (view->label);
508 color_node = gl_color_node_new_default ();
509 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
510 family = gl_view_get_default_font_family (view);
511 gl_label_object_set_font_family (GL_LABEL_OBJECT(object), family);
512 gl_label_object_set_font_size (GL_LABEL_OBJECT(object),
513 gl_view_get_default_font_size (view));
514 gl_label_object_set_font_weight (GL_LABEL_OBJECT(object),
515 gl_view_get_default_font_weight (view));
516 gl_label_object_set_font_italic_flag (GL_LABEL_OBJECT(object),
517 gl_view_get_default_font_italic_flag (view));
519 color_node->color = gl_color_set_opacity (gl_view_get_default_text_color (view), 0.5);
520 gl_label_object_set_text_color (GL_LABEL_OBJECT(object),
522 gl_label_object_set_text_alignment (GL_LABEL_OBJECT(object),
523 gl_view_get_default_text_alignment (view));
524 gl_label_object_set_text_line_spacing (GL_LABEL_OBJECT(object), gl_view_get_default_text_line_spacing (view));
527 lines = gl_text_node_lines_new_from_text (_("Text"));
528 gl_label_text_set_lines (GL_LABEL_TEXT(object), lines);
529 view_text = gl_view_text_new (GL_LABEL_TEXT(object), view);
530 gl_color_node_free (&color_node);
532 view->create_object = GL_LABEL_OBJECT (object);
537 /*****************************************************************************/
538 /* Object creation handler: motion event. */
539 /*****************************************************************************/
541 gl_view_text_create_motion_event (glView *view,
545 gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object), x, y);
548 /*****************************************************************************/
549 /* Object creation handler: button relesase event. */
550 /*****************************************************************************/
552 gl_view_text_create_button_release_event (glView *view,
556 glColorNode *color_node;
558 color_node = gl_color_node_new_default ();
559 gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object), x, y);
560 color_node->color = gl_view_get_default_text_color(view);
561 gl_label_object_set_text_color (GL_LABEL_OBJECT(view->create_object), color_node);
562 gl_color_node_free (&color_node);