aboutsummaryrefslogtreecommitdiff
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/Field.c202
1 files 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);
}