diff options
author | Christopher James Lahey <clahey@helixcode.com> | 2000-03-08 09:41:47 +0800 |
---|---|---|
committer | Chris Lahey <clahey@src.gnome.org> | 2000-03-08 09:41:47 +0800 |
commit | 6f357b4c2d22d66d81be5ec3f0276ac3393805a1 (patch) | |
tree | f8c66838af485a217260dfb3c2e36dc48504af4a /widgets/text/e-text.c | |
parent | 0bfae7d16b83458d64b0957fd5e88bc54a131b2a (diff) | |
download | gsoc2013-evolution-6f357b4c2d22d66d81be5ec3f0276ac3393805a1.tar.gz gsoc2013-evolution-6f357b4c2d22d66d81be5ec3f0276ac3393805a1.tar.zst gsoc2013-evolution-6f357b4c2d22d66d81be5ec3f0276ac3393805a1.zip |
Added a "break_characters" argument. It lets you define a set of
2000-03-07 Christopher James Lahey <clahey@helixcode.com>
* widgets/e-text/e-text.c, widgets/e-text/e-text.h: Added a
"break_characters" argument. It lets you define a set of
characters which should cause optional linebreaks to occur. Made
setting the "clip_height" argument to -1 mean no height clipping.
Moved calling the "resize" signal into an idle handler to avoid
reentering the canvas update loop. Made EText recalc bounds if
the affine has changed. Fixed up tooltip_count (this counts the
number of ENTER and LEAVE events.)
* widgets/e-text/e-text-test.c: Got rid of a few warnings.
* widgets/e-minicard/e-minicard-label.h: Reindent a few lines.
* widgets/e-minicard/e-minicard.c,
widgets/e-minicard/e-minicard-label.c: Switch from using "x" and
"y" to set the children's position to using
e_canvas_item_move_absolute.
svn path=/trunk/; revision=2079
Diffstat (limited to 'widgets/text/e-text.c')
-rw-r--r-- | widgets/text/e-text.c | 189 |
1 files changed, 147 insertions, 42 deletions
diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c index daa607007e..d9448fe783 100644 --- a/widgets/text/e-text.c +++ b/widgets/text/e-text.c @@ -74,6 +74,7 @@ enum { ARG_USE_ELLIPSIS, ARG_ELLIPSIS, ARG_LINE_WRAP, + ARG_BREAK_CHARACTERS, ARG_MAX_LINES }; @@ -245,6 +246,8 @@ e_text_class_init (ETextClass *klass) GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_ELLIPSIS); gtk_object_add_arg_type ("EText::line_wrap", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_LINE_WRAP); + gtk_object_add_arg_type ("EText::break_characters", + GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_BREAK_CHARACTERS); gtk_object_add_arg_type ("EText::max_lines", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_MAX_LINES); @@ -278,8 +281,8 @@ e_text_init (EText *text) text->y = 0.0; text->anchor = GTK_ANCHOR_CENTER; text->justification = GTK_JUSTIFY_LEFT; - text->clip_width = 0.0; - text->clip_height = 0.0; + text->clip_width = 1.0; + text->clip_height = -1.0; text->xofs = 0.0; text->yofs = 0.0; @@ -320,6 +323,7 @@ e_text_init (EText *text) text->default_cursor_shown = TRUE; text->line_wrap = FALSE; + text->break_characters = NULL; text->max_lines = -1; } @@ -420,14 +424,20 @@ get_bounds_item_relative (EText *text, double *px1, double *py1, double *px2, do case GTK_ANCHOR_CENTER: case GTK_ANCHOR_E: y -= text->height / 2; - clip_y -= text->clip_height / 2; + if ( text->clip_height >= 0 ) + clip_y -= text->clip_height / 2; + else + clip_y -= text->height / 2; break; case GTK_ANCHOR_SW: case GTK_ANCHOR_S: case GTK_ANCHOR_SE: y -= text->height; - clip_y -= text->clip_height; + if ( text->clip_height >= 0 ) + clip_y -= text->clip_height; + else + clip_y -= text->height; break; } @@ -438,7 +448,10 @@ get_bounds_item_relative (EText *text, double *px1, double *py1, double *px2, do *px1 = clip_x; *py1 = clip_y; *px2 = clip_x + text->clip_width; - *py2 = clip_y + text->clip_height; + if ( text->clip_height >= 0 ) + *py2 = clip_y + text->clip_height; + else + *py2 = clip_y + text->height; } else { *px1 = x; *py1 = y; @@ -447,6 +460,22 @@ get_bounds_item_relative (EText *text, double *px1, double *py1, double *px2, do } } + +static gboolean +idle_resize(gpointer data) +{ + EText *text = E_TEXT(data); + gtk_signal_emit_by_name (GTK_OBJECT (text), "resize"); + return FALSE; +} + +static void +queue_resize_signal(EText *text) +{ + if (text->idle == 0) + text->idle = g_idle_add(idle_resize, text); +} + static void get_bounds (EText *text, double *px1, double *py1, double *px2, double *py2) { @@ -456,6 +485,18 @@ get_bounds (EText *text, double *px1, double *py1, double *px2, double *py2) item = GNOME_CANVAS_ITEM (text); + /* Calculate text dimensions */ + + old_height = text->height; + + if (text->text && text->font) + text->height = (text->font->ascent + text->font->descent) * text->num_lines; + else + text->height = 0; + + if (old_height != text->height) + queue_resize_signal(text); + /* Get canvas pixel coordinates for text position */ wx = text->x; @@ -467,19 +508,10 @@ get_bounds (EText *text, double *px1, double *py1, double *px2, double *py2) gnome_canvas_w2c (item->canvas, wx, wy, &text->clip_cx, &text->clip_cy); text->clip_cwidth = text->clip_width * item->canvas->pixels_per_unit; - text->clip_cheight = text->clip_height * item->canvas->pixels_per_unit; - - /* Calculate text dimensions */ - - old_height = text->height; - - if (text->text && text->font) - text->height = (text->font->ascent + text->font->descent) * text->num_lines; + if ( text->clip_height >= 0 ) + text->clip_cheight = text->clip_height * item->canvas->pixels_per_unit; else - text->height = 0; - - if (old_height != text->height) - gtk_signal_emit_by_name (GTK_OBJECT (text), "resize"); + text->clip_cheight = text->height * item->canvas->pixels_per_unit; /* Anchor text */ @@ -603,6 +635,7 @@ calc_line_widths (EText *text) } } +#define IS_BREAKCHAR(text,c) ((text)->break_characters && strchr ((text)->break_characters, (c))) /* Splits the text of the text item into lines */ static void split_into_lines (EText *text) @@ -647,6 +680,21 @@ split_into_lines (EText *text) laststart = p + 1; lastend = p; } + } else if (text->line_wrap && (IS_BREAKCHAR(text, *p))) { + if ( laststart != lastend + && p != linestart + 1 + && gdk_text_width(text->font, + linestart, + p + 1 - linestart) + > text->clip_width ) { + text->num_lines ++; + linestart = laststart; + laststart = p + 1; + lastend = p + 1; + } else { + laststart = p + 1; + lastend = p + 1; + } } if (*p == '\n') { text->num_lines ++; @@ -703,6 +751,25 @@ split_into_lines (EText *text) len ++; } handled = TRUE; + } else if (text->line_wrap && (IS_BREAKCHAR(text, *p))) { + if ( laststart != lastend + && p != lines->text + 1 + && gdk_text_width(text->font, + lines->text, + p + 1 - lines->text) + > text->clip_width ) { + lines->length = lastend - lines->text; + lines++; + line_num++; + len = p + 1 - laststart; + lines->text = laststart; + laststart = p + 1; + lastend = p + 1; + } else { + laststart = p + 1; + lastend = p + 1; + len ++; + } } if ( line_num >= text->num_lines ) break; @@ -974,6 +1041,16 @@ e_text_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) text->line_wrap = GTK_VALUE_BOOL (*arg); text->needs_split_into_lines = 1; break; + + case ARG_BREAK_CHARACTERS: + if ( text->break_characters ) { + g_free(text->break_characters); + text->break_characters = NULL; + } + if ( GTK_VALUE_STRING (*arg) ) + text->break_characters = g_strdup( GTK_VALUE_STRING (*arg) ); + text->needs_split_into_lines = 1; + break; case ARG_MAX_LINES: text->max_lines = GTK_VALUE_INT (*arg); @@ -1090,6 +1167,10 @@ e_text_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) case ARG_LINE_WRAP: GTK_VALUE_BOOL (*arg) = text->line_wrap; break; + + case ARG_BREAK_CHARACTERS: + GTK_VALUE_STRING (*arg) = g_strdup (text->break_characters); + break; case ARG_MAX_LINES: GTK_VALUE_INT (*arg) = text->max_lines; @@ -1124,13 +1205,25 @@ e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int fla calc_line_widths(text); text->needs_calc_line_widths = 0; text->needs_recalc_bounds = 1; + text->needs_redraw = 1; } - if ( text->needs_recalc_bounds ) { - gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); + if ( text->needs_recalc_bounds + || (flags & GNOME_CANVAS_UPDATE_AFFINE)) { if (!item->canvas->aa) { set_text_gc_foreground (text); set_stipple (text, text->stipple, TRUE); get_bounds (text, &x1, &y1, &x2, &y2); + if ( item->x1 != x1 || + item->x2 != x2 || + item->y1 != y1 || + item->y2 != y2 ) { + gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); + item->x1 = x1; + item->y1 = y1; + item->x2 = x2; + item->y2 = y2; + text->needs_redraw = 1; + } } else { /* aa rendering */ for (i = 0; i < 6; i++) @@ -1138,12 +1231,7 @@ e_text_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int fla get_bounds_item_relative (text, &i_bbox.x0, &i_bbox.y0, &i_bbox.x1, &i_bbox.y1); art_drect_affine_transform (&c_bbox, &i_bbox, affine); } - item->x1 = x1; - item->y1 = y1; - item->x2 = x2; - item->y2 = y2; text->needs_recalc_bounds = 0; - text->needs_redraw = 1; } if ( text->needs_redraw ) { gnome_canvas_request_redraw (item->canvas, item->x1, item->y1, item->x2, item->y2); @@ -1589,12 +1677,16 @@ e_text_point (GnomeCanvasItem *item, double x, double y, if (y1 < text->clip_cy) y1 = text->clip_cy; + + if ( text->clip_width >= 0 ) { + if (x2 > (text->clip_cx + text->clip_width)) + x2 = text->clip_cx + text->clip_width; + } - if (x2 > (text->clip_cx + text->clip_width)) - x2 = text->clip_cx + text->clip_width; - - if (y2 > (text->clip_cy + text->clip_height)) - y2 = text->clip_cy + text->clip_height; + if ( text->clip_height >= 0 ) { + if (y2 > (text->clip_cy + text->clip_height)) + y2 = text->clip_cy + text->clip_height; + } if ((x1 >= x2) || (y1 >= y2)) continue; @@ -1645,7 +1737,9 @@ e_text_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double if (text->clip) { width = text->clip_width; - height = text->clip_height; + if ( text->clip_height >= 0 ) + height = text->clip_height; + else height = text->height; } else { width = text->max_width / item->canvas->pixels_per_unit; height = text->height / item->canvas->pixels_per_unit; @@ -1829,13 +1923,21 @@ _do_tooltip (gpointer data) GtkWidget *label, *vbox; gint x, y, pointer_x, pointer_y, scr_w, scr_h, tip_w, tip_h; int i; + gboolean cut_off; if (text->editing) return FALSE; lines = text->lines; - - if (lines->length <= lines->ellipsis_length) + + cut_off = FALSE; + for ( lines = text->lines, i = 0; i < text->num_lines; lines++, i++ ) { + if (lines->length > lines->ellipsis_length) { + cut_off = TRUE; + break; + } + } + if ( ! cut_off ) return FALSE; scr_w = gdk_screen_width (); @@ -1844,6 +1946,7 @@ _do_tooltip (gpointer data) text->tooltip_window = gtk_window_new (GTK_WINDOW_POPUP); vbox = gtk_vbox_new (TRUE, 0); + lines = text->lines; for (i = 0; i < text->num_lines; i++) { gchar *linetext; @@ -1944,13 +2047,13 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) break; case GDK_BUTTON_PRESS: /* Fall Through */ case GDK_BUTTON_RELEASE: - text->tooltip_count --; - if ( text->tooltip_count == 0 && text->clip) { + if (text->tooltip_timeout) { gtk_timeout_remove (text->tooltip_timeout); - if (text->tooltip_window) { - gtk_widget_destroy (text->tooltip_window); - text->tooltip_window = NULL; - } + text->tooltip_timeout = 0; + } + if (text->tooltip_window) { + gtk_widget_destroy (text->tooltip_window); + text->tooltip_window = NULL; } if ((!text->editing) && text->editable @@ -2005,10 +2108,9 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) } break; case GDK_ENTER_NOTIFY: - if ( text->tooltip_count == 0 && text->clip) { + if ( text->tooltip_count == 0 && text->clip) text->tooltip_timeout = gtk_timeout_add (1000, _do_tooltip, text); - text->tooltip_count ++; - } + text->tooltip_count ++; text->pointer_in = TRUE; if (text->editing) { if ( text->default_cursor_shown ) { @@ -2020,7 +2122,10 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) case GDK_LEAVE_NOTIFY: text->tooltip_count --; if ( text->tooltip_count == 0 && text->clip) { - gtk_timeout_remove (text->tooltip_timeout); + if ( text->tooltip_timeout ) { + gtk_timeout_remove (text->tooltip_timeout); + text->tooltip_timeout = 0; + } if (text->tooltip_window) { gtk_widget_destroy (text->tooltip_window); text->tooltip_window = NULL; |