From 819bf7115667448382e6680c705db84239794ab5 Mon Sep 17 00:00:00 2001 From: lecoanet Date: Thu, 11 Apr 2002 09:18:21 +0000 Subject: Simplification du protocole de DrawFields, RenderFields, FieldInsertChars, FieldDeleteChars suite au changement de variable dans FieldSet: au lieu de m�moriser wi on m�morise l'item correspondant au fieldset c'est plus logique et �a offre plus de possibilit�s. Correction d'un bug dans DeleteChars et InsertChars: il faut effacer le cache de layout des fields et prevenir l'appelant afin qu'il programme un recalcul de g�om�trie. Int�gration des nouveaux indices: bol, eol, bow, eow, up, down. Mise � jour des indices de s�lection et d'insertion lors d'une reconfiguration du texte (bug). --- generic/Field.c | 202 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 136 insertions(+), 66 deletions(-) diff --git a/generic/Field.c b/generic/Field.c index 232fda9..c1f49a0 100644 --- a/generic/Field.c +++ b/generic/Field.c @@ -81,7 +81,7 @@ typedef struct _FieldStruct { short orig_y; short corner_x; short corner_y; - FieldSet field_set; + FieldSet field_set; /* Only used by the image update callbacks */ int insert_index; #ifdef GLX TexFont *txf; @@ -809,10 +809,9 @@ FieldImageChange(ClientData client_data, ZnBBox bbox; if (field->image != ZnUnspecifiedImage) { - i = (((char *) field) - ((char *) field->field_set->fields)) / sizeof(FieldStruct); + i = (((char *)field) - ((char *)field->field_set->fields))/sizeof(FieldStruct); GetFieldBBox(field->field_set, i, &bbox); - ZnDamage(field->field_set->wi, &bbox); - ZnNeedRedisplay(field->field_set->wi); + ZnDamage(field->field_set->item->wi, &bbox); ClearFieldCache(field->field_set, i); } } @@ -839,11 +838,10 @@ FieldTileChange(ClientData client_data, ZnBBox bbox; if (field->tile != ZnUnspecifiedImage) { - i = (((char *) field) - ((char *) field->field_set->fields)) / sizeof(FieldStruct); + i = (((char *)field) - ((char *)field->field_set->fields))/sizeof(FieldStruct); InvalidateImage(field->tile_name); GetFieldBBox(field->field_set, i, &bbox); - ZnDamage(field->field_set->wi, &bbox); - ZnNeedRedisplay(field->field_set->wi); + ZnDamage(field->field_set->item->wi, &bbox); } } @@ -861,7 +859,7 @@ FieldTileChange(ClientData client_data, static void InitFields(FieldSet field_set) { - WidgetInfo *wi = field_set->wi; + WidgetInfo *wi = field_set->item->wi; Field field; unsigned int i, num_fields; @@ -923,7 +921,7 @@ InitFields(FieldSet field_set) static void CloneFields(FieldSet field_set) { - WidgetInfo *wi = field_set->wi; + WidgetInfo *wi = field_set->item->wi; Field field, fields_ret; unsigned int i, num_fields; char *text; @@ -998,9 +996,9 @@ ConfigureField(FieldSet fs, int i; Field field_ptr; ZnBBox bbox; - WidgetInfo *wi = fs->wi; + WidgetInfo *wi = fs->item->wi; XColor *color; - int alpha; + int alpha, old_num_chars, num_chars; #ifdef GLX ZnFont old_font; #endif @@ -1012,12 +1010,38 @@ ConfigureField(FieldSet fs, field_ptr = &fs->fields[field]; old_font = field_ptr->font; - + old_num_chars = strlen(field_ptr->text); + if (ZnConfigureAttributes(wi, field_ptr, field_attrs, argc, argv, flags) == ZN_ERROR) { return ZN_ERROR; } + num_chars = strlen(field_ptr->text); + if (old_num_chars != num_chars) { + TextInfo *ti = &wi->text_info; + /* + * The text has changed, update the selection and + * insertion pos to keep them valid. + */ + if ((fs->item == ti->sel_item) && (field == ti->sel_field)) { + if (ti->sel_last > num_chars) { + ti->sel_last = num_chars; + } + if (ti->sel_first >= ti->sel_last) { + ti->sel_item = ZN_NO_ITEM; + ti->sel_field = ZN_NO_PART; + } + if ((ti->anchor_item == fs->item) && (ti->anchor_field == field) && + (ti->sel_anchor > num_chars)) { + ti->sel_anchor = num_chars; + } + } + if (field_ptr->insert_index > num_chars) { + field_ptr->insert_index = num_chars; + } + } + #ifdef GLX if (old_font != field_ptr->font) { field_ptr->txf = NULL; @@ -1092,11 +1116,11 @@ QueryField(FieldSet fs, Tcl_Obj *CONST argv[]) { if (field >= fs->num_fields) { - Tcl_AppendResult(fs->wi->interp, "invalid field index \"", NULL); + Tcl_AppendResult(fs->item->wi->interp, "invalid field index \"", NULL); return ZN_ERROR; } - if (ZnQueryAttribute(fs->wi, &fs->fields[field], field_attrs, + if (ZnQueryAttribute(fs->item->wi, &fs->fields[field], field_attrs, argv[0]) == ZN_ERROR) { return ZN_ERROR; } @@ -1115,7 +1139,7 @@ QueryField(FieldSet fs, static void FreeFields(FieldSet field_set) { - WidgetInfo *wi = field_set->wi; + WidgetInfo *wi = field_set->item->wi; unsigned int i, num_fields; Field field; @@ -1232,28 +1256,56 @@ FieldPointToChar(FieldSet fs, } static int +WordMoveFromIndex(char *text, + int index, + int fwd) +{ + char *strp; + + if (fwd) { + strp = &text[index]; + while ((strp[1] == ' ') || (strp[1] == '\n')) { + strp++; + } + while ((strp[1] != ' ') && (strp[1] != '\n') && strp[1]) { + strp++; + } + return strp + 1 - text; + } + else { + strp = &text[index]; + while (((strp[-1] == ' ') || (strp[-1] == '\n')) && (strp != text)) { + strp--; + } + while ((strp[-1] != ' ') && (strp[-1] != '\n') && (strp != text)) { + strp--; + } + return strp - text; + } +} + +static int FieldIndex(FieldSet fs, int field, - Item item, Tcl_Obj *index_spec, int *index) { Field field_ptr; - TextInfo *ti; int num_chars; - WidgetInfo *wi = fs->wi; + WidgetInfo *wi = fs->item->wi; + TextInfo *ti = &wi->text_info; int c, length; int x, y; double tmp; char *end, *p; if (field == ZN_NO_PART) { - goto sel_err; + *index = 0; + return ZN_OK; } field_ptr = &fs->fields[field]; num_chars = strlen(field_ptr->text); - ti = &wi->text_info; p = Tcl_GetString(index_spec); c = p[0]; @@ -1262,24 +1314,47 @@ FieldIndex(FieldSet fs, if ((c == 'e') && (strncmp(p, "end", length) == 0)) { *index = num_chars; } + else if ((c == 'e') && (length > 1) && (strncmp(p, "eol", length) == 0)) { + *index = num_chars; + } + else if ((c == 'b') && (length > 1) && (strncmp(p, "bol", length) == 0)) { + *index = 0; + } + else if ((c == 'e') && (length > 1) && (strncmp(p, "eow", length) == 0)) { + *index = WordMoveFromIndex(field_ptr->text, field_ptr->insert_index, 1); + } + else if ((c == 'b') && (length > 1) && (strncmp(p, "bow", length) == 0)) { + *index = WordMoveFromIndex(field_ptr->text, field_ptr->insert_index, 0); + } + else if ((c == 'u') && (strncmp(p, "up", length) == 0)) { + *index = field_ptr->insert_index; + } + else if ((c == 'd') && (strncmp(p, "down", length) == 0)) { + *index = field_ptr->insert_index; + } else if ((c == 'i') && (strncmp(p, "insert", length) == 0)) { *index = field_ptr->insert_index; } else if ((c == 's') && (strncmp(p, "sel.first", length) == 0) && (length >= 5)) { - if ((ti->sel_item != item) || (ti->sel_field != field)) { + if ((ti->sel_item != fs->item) || (ti->sel_field != field)) { sel_err: Tcl_AppendResult(wi->interp, "selection isn't in field", (char *) NULL); return ZN_ERROR; } - *index = wi->text_info.sel_first; + *index = ti->sel_first; } else if ((c == 's') && (strncmp(p, "sel.last", length) == 0) && (length >= 5)) { - if ((ti->sel_item != item) || (ti->sel_field != field)) { + if ((ti->sel_item != fs->item) || (ti->sel_field != field)) { goto sel_err; } - *index = wi->text_info.sel_last; + /* + * We return a modified selection end so that it reflect + * the text index of the last character _not_ the insertion + * point between the last and the next. + */ + *index = ti->sel_last-1; } else if (c == '@') { p++; @@ -1314,25 +1389,24 @@ FieldIndex(FieldSet fs, return ZN_OK; } -static void +static ZnBool FieldInsertChars(FieldSet fs, int field, int *index, char *chars) { - ZnBBox bbox; Field field_ptr; int num_chars; int length; char *new; if (field == ZN_NO_PART) { - return; + return False; } length = strlen(chars); if (length == 0) { - return; + return False; } field_ptr = &fs->fields[field]; @@ -1356,31 +1430,30 @@ FieldInsertChars(FieldSet fs, } /* - * Need to update the field area later. + * Need to redo the fields layout (maybe). */ - GetFieldBBox(fs, field, &bbox); - ZnDamage(fs->wi, &bbox); + ClearFieldCache(fs, field); + return True; } -static void +static ZnBool FieldDeleteChars(FieldSet fs, int field, int *first, int *last) { - ZnBBox bbox; Field field_ptr; int count, num_chars; char *new; if (field == ZN_NO_PART) { - return; + return False; } field_ptr = &fs->fields[field]; num_chars = strlen(field_ptr->text); if (num_chars == 0) { - return; + return False; } if (*first < 0) { @@ -1390,7 +1463,7 @@ FieldDeleteChars(FieldSet fs, *last = num_chars-1; } if (*first > *last) { - return; + return False; } count = *last + 1 - *first; @@ -1411,10 +1484,10 @@ FieldDeleteChars(FieldSet fs, } /* - * Need to update the field area later. + * Need to redo the fields layout (maybe). */ - GetFieldBBox(fs, field, &bbox); - ZnDamage(fs->wi, &bbox); + ClearFieldCache(fs, field); + return True; } static void @@ -1458,7 +1531,7 @@ FieldSelection(FieldSet fs, return 0; } - ti = &fs->wi->text_info; + ti = &fs->item->wi->text_info; count = ti->sel_last - ti->sel_first - offset; if (count > max_chars) { count = max_chars; @@ -1477,7 +1550,7 @@ FieldSelection(FieldSet fs, return count; } - + /* ********************************************************************************** @@ -1523,13 +1596,13 @@ ComputeFieldImageLocation(Field field_ptr, */ static void FieldsEngine(FieldSet field_set, - Item item, void (*cb)()) { - WidgetInfo *wi = field_set->wi; + WidgetInfo *wi = field_set->item->wi; int i; /* This one *NEED* to be an int */ int num_fields, num_chars; Field field_ptr; + TextInfo *ti = &wi->text_info; ZnBBox lclip_bbox, fclip_bbox, bbox, *global_clip_box; ZnBBox tmp_bbox, text_bbox, pm_bbox; ZnPoint pts[2]; @@ -1586,18 +1659,17 @@ FieldsEngine(FieldSet field_set, num_chars = strlen(field_ptr->text); if (num_chars) { ComputeFieldTextLocation(field_ptr, &bbox, &text_pos, &text_bbox); - if ((wi->focus_item == item) && (wi->focus_field == i) && - wi->got_focus && wi->text_info.cursor_on) { + if ((field_set->item == wi->focus_item) && (wi->focus_field == i) && + wi->got_focus && ti->cursor_on) { cursor = Tk_TextWidth(field_ptr->font, field_ptr->text, field_ptr->insert_index); } - if ((wi->text_info.sel_item == item) && (wi->text_info.sel_field == i) && - (wi->text_info.sel_last >= 0) && - (wi->text_info.sel_first <= num_chars)) { - sel_start = Tk_TextWidth(field_ptr->font, field_ptr->text, - wi->text_info.sel_first); - sel_stop = Tk_TextWidth(field_ptr->font, field_ptr->text, - wi->text_info.sel_last); + if ((field_set->item == ti->sel_item) && (ti->sel_field == i) && + (ti->sel_last >= 0) && (ti->sel_first <= num_chars)) { + sel_start = Tk_TextWidth(field_ptr->font, + field_ptr->text, ti->sel_first); + sel_stop = Tk_TextWidth(field_ptr->font, + field_ptr->text, ti->sel_last); } IntersectBBox(&fclip_bbox, &text_bbox, &tmp_bbox); @@ -1668,6 +1740,7 @@ DrawField(WidgetInfo *wi, int sel_start, int sel_stop) { + TextInfo *ti = &wi->text_info; XGCValues values; XRectangle r; int j, xs, num_chars; @@ -1732,8 +1805,7 @@ DrawField(WidgetInfo *wi, num_chars = strlen(field_ptr->text); if (num_chars) { if (sel_start >= 0) { - values.foreground = ZnPixel(ZnGetGradientColor(wi->text_info.sel_color, 0, - NULL)); + values.foreground = ZnPixel(ZnGetGradientColor(ti->sel_color, 0, NULL)); XChangeGC(wi->dpy, wi->gc, GCForeground, &values); XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, text_bbox->orig.x+sel_start, text_bbox->orig.y, @@ -1748,9 +1820,8 @@ DrawField(WidgetInfo *wi, field_ptr->text, num_chars, text_pos->x, text_pos->y); if (cursor >= 0) { - values.line_width = wi->text_info.insert_width; - values.foreground = ZnPixel(ZnGetGradientColor(wi->text_info.insert_color, - 0, NULL)); + values.line_width = ti->insert_width; + values.foreground = ZnPixel(ZnGetGradientColor(ti->insert_color, 0, NULL)); XChangeGC(wi->dpy, wi->gc, GCForeground|GCLineWidth, &values); xs = text_bbox->orig.x + cursor; XDrawLine(wi->dpy, wi->draw_buffer, wi->gc, @@ -1811,10 +1882,9 @@ DrawField(WidgetInfo *wi, } static void -DrawFields(FieldSet field_set, - Item item) +DrawFields(FieldSet field_set) { - FieldsEngine(field_set, item, DrawField); + FieldsEngine(field_set, DrawField); } @@ -1855,6 +1925,7 @@ RenderField(WidgetInfo *wi, int j, alpha, num_chars; XColor *color; ZnReal xs; + TextInfo *ti = &wi->text_info; /* * Draw the background. @@ -1921,7 +1992,7 @@ RenderField(WidgetInfo *wi, if (field_ptr->txf) { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); if (sel_start >= 0) { - color = ZnGetGradientColor(wi->text_info.sel_color, 0, &alpha); + color = ZnGetGradientColor(ti->sel_color, 0, &alpha); alpha = ZnComposeAlpha(alpha, wi->alpha); glColor4us(color->red, color->green, color->blue, alpha); glBegin(GL_QUADS); @@ -1943,8 +2014,8 @@ RenderField(WidgetInfo *wi, glPopMatrix(); glDisable(GL_TEXTURE_2D); if (cursor >= 0) { - glLineWidth(wi->text_info.insert_width); - color = ZnGetGradientColor(wi->text_info.insert_color, 0, &alpha); + glLineWidth(ti->insert_width); + color = ZnGetGradientColor(ti->insert_color, 0, &alpha); alpha = ZnComposeAlpha(alpha, wi->alpha); glColor4us(color->red, color->green, color->blue, alpha); xs = text_bbox->orig.x + cursor; @@ -2016,10 +2087,9 @@ RenderField(WidgetInfo *wi, } static void -RenderFields(FieldSet field_set, - Item item) +RenderFields(FieldSet field_set) { - FieldsEngine(field_set, item, RenderField); + FieldsEngine(field_set, RenderField); } -- cgit v1.1