aboutsummaryrefslogtreecommitdiff
path: root/generic/tkZinc.c
diff options
context:
space:
mode:
authorlecoanet2002-04-08 14:08:22 +0000
committerlecoanet2002-04-08 14:08:22 +0000
commit10eca5c001349c8804bc4a1f359141896f8b2d71 (patch)
tree87eec5d0f537c8b3f4b89a70ae48331a01f26876 /generic/tkZinc.c
parentcab6a31eef6b1557eea728897bd4f555df7d384d (diff)
downloadtkzinc-10eca5c001349c8804bc4a1f359141896f8b2d71.zip
tkzinc-10eca5c001349c8804bc4a1f359141896f8b2d71.tar.gz
tkzinc-10eca5c001349c8804bc4a1f359141896f8b2d71.tar.bz2
tkzinc-10eca5c001349c8804bc4a1f359141896f8b2d71.tar.xz
Support du focus sur tous les items.
Support du focus sur les fields. Support de la s�lection/curseur sur les fields. Les textes des fields sont editables. Transfert des commandes sur les MapInfos dans MapInfo.c. R�cup�ration du code d'endommagement/r�paration depuis Item.c. Diverses modifs li�es � la restructuration de Item.c et � la suppression de ITEM_P. D�but de modif des routines de recherche sur les tags (transfert de param�tres entre ZnTagSearchScan et ZnTagSearchFirst).
Diffstat (limited to 'generic/tkZinc.c')
-rw-r--r--generic/tkZinc.c1864
1 files changed, 756 insertions, 1108 deletions
diff --git a/generic/tkZinc.c b/generic/tkZinc.c
index 43979d8..01c1554 100644
--- a/generic/tkZinc.c
+++ b/generic/tkZinc.c
@@ -42,6 +42,7 @@ static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ "
#include "Types.h"
#include "Geo.h"
#include "Item.h"
+#include "Group.h"
#include "WidgetInfo.h"
#include "tkZinc.h"
#include "MapInfo.h"
@@ -67,18 +68,7 @@ static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ "
#include <GL/glu.h>
#endif
-#if 0
-typedef struct TagSearch {
- WidgetInfo *wi;
- Tk_Uid tag;
- GroupItem group;
- Item current;
- Item previous; /* Needed to detect changes in the linked
- * list between calls. */
- ZnList item_stack;
- ZnBool over;
-} TagSearch;
-#endif
+
typedef struct _TagSearchExpr {
struct _TagSearchExpr *next; /* for linked lists of expressions - used in bindings */
Tk_Uid uid; /* the uid of the whole expression */
@@ -127,7 +117,6 @@ static unsigned char dither4x4[4][4] = {
};
static unsigned char bitmaps[NUM_ALPHA_STEPS][32][4];
-static ZnBool inited = False;
static Tk_Uid all_uid;
static Tk_Uid current_uid;
static Tk_Uid and_uid;
@@ -280,7 +269,7 @@ static void Event _ANSI_ARGS_((ClientData client_data, XEvent *eventPtr));
static void Bind _ANSI_ARGS_((ClientData client_data, XEvent *eventPtr));
static int FetchSelection _ANSI_ARGS_((ClientData clientData, int offset,
char *buffer, int maxBytes));
-static void SelectTo _ANSI_ARGS_((Item item, int index));
+static void SelectTo _ANSI_ARGS_((Item item, int field, int index));
static int WidgetObjCmd _ANSI_ARGS_((ClientData client_data,
Tcl_Interp *, int argc, Tcl_Obj *CONST args[]));
static int Configure _ANSI_ARGS_((Tcl_Interp *interp, WidgetInfo *wi,
@@ -289,6 +278,8 @@ static void Redisplay _ANSI_ARGS_((ClientData client_data));
static void Destroy _ANSI_ARGS_((char *mem_ptr));
static void InitZinc _ANSI_ARGS_((Tcl_Interp *interp));
static void Focus _ANSI_ARGS_((WidgetInfo *wi, ZnBool got_focus));
+static void Update _ANSI_ARGS_((WidgetInfo *wi));
+static void Repair _ANSI_ARGS_((WidgetInfo *wi));
Tcl_Obj *
@@ -473,9 +464,7 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
unsigned int num;
int major_op, first_err, first_evt;
- if (!inited) {
- InitZinc(interp);
- }
+ InitZinc(interp);
if (argc == 1) {
Tcl_AppendResult(interp, ZINCVERSION, NULL);
@@ -569,7 +558,7 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
wi->obj_id = 1;
wi->num_items = 0;
- wi->top_group = ITEM_P.CreateItem(wi, ZnGroup, 0, NULL);
+ wi->top_group = ZnCreateItem(wi, ZnGroup, 0, NULL);
#ifdef OM
wi->om_group_id = 0;
@@ -582,6 +571,9 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
wi->pick_aperture = 0;
wi->new_item = wi->current_item = ZN_NO_ITEM;
wi->new_part = wi->current_part = ZN_NO_PART;
+ wi->focus_item = ZN_NO_ITEM;
+ wi->focus_field = ZN_NO_PART;
+ wi->got_focus = False;
wi->monitoring = False;
wi->total_draw_chrono = NewChrono("Total draw time");
@@ -600,14 +592,14 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
*/
wi->text_info.sel_color = NULL;
wi->text_info.sel_item = ZN_NO_ITEM;
+ wi->text_info.sel_field = ZN_NO_PART;
wi->text_info.sel_first = -1;
wi->text_info.sel_last = -1;
wi->text_info.anchor_item = ZN_NO_ITEM;
+ wi->text_info.anchor_field = ZN_NO_PART;
wi->text_info.sel_anchor = 0;
wi->text_info.insert_color = NULL;
wi->text_info.insert_width = 0;
- wi->text_info.focus_item = ZN_NO_ITEM;
- wi->text_info.got_focus = False;
wi->text_info.cursor_on = False;
wi->insert_on_time = 0;
wi->insert_off_time = 0;
@@ -617,8 +609,8 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
wi->highlight_color = NULL;
wi->highlight_bg_color = NULL;
- ITEM_P.InitClipStack(wi);
- ITEM_P.InitTransformStack(wi);
+ ZnInitClipStack(wi);
+ ZnInitTransformStack(wi);
for (num = 0; num < NUM_ALPHA_STEPS; num++) {
char name[INTEGER_SPACE+12];
@@ -735,12 +727,12 @@ EncodeItemPart(Item item,
int part)
{
if (part >= 0) {
- FieldSet field_set;
+ FieldSet fs;
if (!item->class->has_fields) {
return item;
}
- field_set = item->class->GetFieldSet(item);
- return (ClientData) (((char *) field_set->fields)+(part%field_set->num_fields));
+ fs = item->class->GetFieldSet(item);
+ return (ClientData) (FIELD.GetFieldStruct(fs, part%FIELD.NumFields(fs)));
}
else if (part == ZN_NO_PART) {
return item;
@@ -1197,13 +1189,16 @@ static int
ZnTagSearchScan(WidgetInfo *wi,
Tcl_Obj *tag_obj, /* Object giving tag value, NULL
* is the same as 'all'. */
- TagSearch **search_var) /* Record describing tag search;
+ TagSearch **search_var, /* Record describing tag search;
* will be initialized here. */
+ Item group, /* Start group */
+ ZnBool recursive) /* Does the search walk down the
+ * tree ? */
{
char *tag;
int i;
TagSearch *search;
-
+
if (tag_obj) {
tag = Tcl_GetString(tag_obj);
}
@@ -1232,9 +1227,24 @@ ZnTagSearchScan(WidgetInfo *wi,
/* How long is the tagOrId ? */
search->tag_len = strlen(tag);
- /* Make sure there is enough buffer to hold rewritten tags */
- if ((unsigned int)search->tag_len >= search->rewrite_buf_alloc) {
- search->rewrite_buf_alloc = search->tag_len + 100;
+ /*
+ * Short-circuit impossible searches for null tags and
+ * mark the search as 'over' for ZnTagSearchFirst and
+ * ZnTagSearchNext. This test must not be migrated before
+ * allocating search structures or special care must be
+ * taken in ZnTagSearchDestroy to avoid deallocating unallocated
+ * memory.
+ */
+ if (search->tag_len == 0) {
+ search->over = True;
+ return ZN_OK;
+ }
+
+ /*
+ * Make sure there is enough buffer to hold rewritten tags (30%).
+ */
+ if ((unsigned int)search->tag_len*1.3 >= search->rewrite_buf_alloc) {
+ search->rewrite_buf_alloc = (unsigned int)search->tag_len*1.3;
search->rewrite_buf = ZnRealloc(search->rewrite_buf,
search->rewrite_buf_alloc);
}
@@ -1243,8 +1253,8 @@ ZnTagSearchScan(WidgetInfo *wi,
search->wi = wi;
search->over = False;
search->type = 0;
- search->group = (GroupItem) wi->top_group;
- search->recursive = True;
+ search->group = group;
+ search->recursive = recursive;
ZnListEmpty(search->item_stack);
/*
@@ -1269,11 +1279,6 @@ ZnTagSearchScan(WidgetInfo *wi,
*/
search->expr->uid = Tk_GetUid(tag);
- /* short circuit impossible searches for null tags */
- if (search->tag_len == 0) {
- return TCL_OK;
- }
-
/*
* Pre-scan tag for at least one unquoted "&&" "||" "^" "!"
* if not found then use string as simple tag
@@ -1357,23 +1362,17 @@ ZnTagSearchScan(WidgetInfo *wi,
*--------------------------------------------------------------
*/
static Item
-ZnTagSearchFirst(TagSearch *search, /* Record describing tag search */
- Item group, /* Start group */
- ZnBool recursive) /* Does the search walk down the
- * tree ? */
+ZnTagSearchFirst(TagSearch *search) /* Record describing tag search */
{
Item item, previous;
Tk_Uid uid, *tags;
int count;
/* short circuit impossible searches for null tags */
- if (search->tag_len == 0) {
+ if (search->over == True) {
return ZN_NO_ITEM;
}
- search->group = (GroupItem) group;
- search->recursive = recursive;
-
/*
* Find the first matching item in one of several ways. If the tag
* is a number then it selects the single item with the matching
@@ -1408,12 +1407,12 @@ ZnTagSearchFirst(TagSearch *search, /* Record describing tag search */
* All items match.
*/
search->previous = ZN_NO_ITEM;
- search->current = (Item) search->group->head;
+ search->current = ZnGroupHead(search->group);
return search->current;
}
uid = search->expr->uid;
- item = (Item) search->group->head;
+ item = ZnGroupHead(search->group);
previous = ZN_NO_ITEM;
do {
while (item != ZN_NO_ITEM) {
@@ -1446,15 +1445,16 @@ ZnTagSearchFirst(TagSearch *search, /* Record describing tag search */
}
}
if ((item->class == ZnGroup) && (search->recursive)) {
+ Item prev_group = (Item) search->group;
/*
* Explore the hierarchy depth first using the item stack
* to save the current node.
*/
/*printf("ZnTagSearchFirst diving for tag '%s', detph %d\n",
search->tag, ZnListSize(search->item_stack)/2);*/
- search->group = (GroupItem) item;
+ search->group = item;
previous = item;
- if (item == group) {
+ if (item == prev_group) {
item = ZN_NO_ITEM;
}
else {
@@ -1463,7 +1463,7 @@ ZnTagSearchFirst(TagSearch *search, /* Record describing tag search */
ZnListAdd(search->item_stack, &previous, ZnListTail);
ZnListAdd(search->item_stack, &item, ZnListTail);
previous = ZN_NO_ITEM;
- item = search->group->head;
+ item = ZnGroupHead(search->group);
}
else {
previous = item;
@@ -1482,7 +1482,7 @@ ZnTagSearchFirst(TagSearch *search, /* Record describing tag search */
ZnListDelete(search->item_stack, ZnListTail);
}
if (item != ZN_NO_ITEM) {
- search->group = (GroupItem) item->parent;
+ search->group = item->parent;
}
} while (item != ZN_NO_ITEM);
@@ -1529,7 +1529,7 @@ ZnTagSearchNext(TagSearch *search) /* Record describing search in progress. */
*/
previous = search->previous;
if (previous == ZN_NO_ITEM) {
- item = search->group->head;
+ item = ZnGroupHead(search->group);
}
else {
item = previous->next;
@@ -1548,7 +1548,7 @@ ZnTagSearchNext(TagSearch *search) /* Record describing search in progress. */
* Explore the hierarchy depth first using the item stack
* to save the current node.
*/
- search->group = (GroupItem) item;
+ search->group = item;
previous = item;
item = item->next;
/*printf("ZnTagSearchNext diving for all, pushing %d\n",
@@ -1556,7 +1556,7 @@ ZnTagSearchNext(TagSearch *search) /* Record describing search in progress. */
ZnListAdd(search->item_stack, &previous, ZnListTail);
ZnListAdd(search->item_stack, &item, ZnListTail);
previous = ZN_NO_ITEM;
- item = search->group->head;
+ item = ZnGroupHead(search->group);
}
else {
previous = item;
@@ -1574,7 +1574,7 @@ ZnTagSearchNext(TagSearch *search) /* Record describing search in progress. */
ZnListDelete(search->item_stack, ZnListTail);
}
if (item != ZN_NO_ITEM) {
- search->group = (GroupItem) item->parent;
+ search->group = item->parent;
/*printf("ZnTagSearchNext popping %d, previous %d, next %d\n",
item->id, (item->previous)?item->previous->id:0,
(item->next)?item->next->id:0);*/
@@ -1634,13 +1634,13 @@ ZnTagSearchNext(TagSearch *search) /* Record describing search in progress. */
*/
/*printf("ZnTagSearchNext diving for tag, depth %d\n",
ZnListSize(search->item_stack)/2);*/
- search->group = (GroupItem) item;
+ search->group = item;
previous = item;
item = item->next;
ZnListAdd(search->item_stack, &previous, ZnListTail);
ZnListAdd(search->item_stack, &item, ZnListTail);
previous = ZN_NO_ITEM;
- item = search->group->head;
+ item = ZnGroupHead(search->group);
}
else {
previous = item;
@@ -1656,7 +1656,7 @@ ZnTagSearchNext(TagSearch *search) /* Record describing search in progress. */
ZnListDelete(search->item_stack, ZnListTail);
}
if (item != ZN_NO_ITEM) {
- search->group = (GroupItem) item->parent;
+ search->group = item->parent;
}
} while (item != ZN_NO_ITEM);
@@ -1711,10 +1711,11 @@ ZnItemWithTagOrId(WidgetInfo *wi,
Item *item,
TagSearch **search_var)
{
- if (ZnTagSearchScan(wi, tag_or_id, search_var) != ZN_OK) {
+ if (ZnTagSearchScan(wi, tag_or_id, search_var,
+ group, recursive) != ZN_OK) {
return ZN_ERROR;
}
- *item = ZnTagSearchFirst(*search_var, group, recursive);
+ *item = ZnTagSearchFirst(*search_var);
return ZN_OK;
}
@@ -1722,7 +1723,7 @@ ZnItemWithTagOrId(WidgetInfo *wi,
/*
*----------------------------------------------------------------------
*
- * DoItem --
+ * ZnDoItem --
*
* Either add a tag to an item or add the item id/part to the
* interpreter result, depending on the value of tag. If tag
@@ -1732,10 +1733,10 @@ ZnItemWithTagOrId(WidgetInfo *wi,
*----------------------------------------------------------------------
*/
void
-DoItem(Tcl_Interp *interp,
- Item item,
- int part,
- Tk_Uid tag_uid)
+ZnDoItem(Tcl_Interp *interp,
+ Item item,
+ int part,
+ Tk_Uid tag_uid)
{
if (tag_uid == NULL) {
Tcl_Obj *l;
@@ -1882,7 +1883,7 @@ FindItems(WidgetInfo *wi,
&item, search_var);
if ((result == ZN_OK) &&
(item != ZN_NO_ITEM) && (item->previous != ZN_NO_ITEM)) {
- DoItem(wi->interp, item->previous, ZN_NO_PART, tag_uid);
+ ZnDoItem(wi->interp, item->previous, ZN_NO_PART, tag_uid);
}
}
break;
@@ -1914,12 +1915,12 @@ FindItems(WidgetInfo *wi,
* Go through the item list and collect all item ids. They
* are sorted from most visible to least visible.
*/
- if (ZnTagSearchScan(wi, NULL, search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, NULL, search_var, group, recursive) == ZN_ERROR) {
return ZN_ERROR;
}
- for (item = ZnTagSearchFirst(*search_var, group, recursive);
+ for (item = ZnTagSearchFirst(*search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(*search_var)) {
- DoItem(wi->interp, item, ZN_NO_PART, tag_uid);
+ ZnDoItem(wi->interp, item, ZN_NO_PART, tag_uid);
}
}
break;
@@ -1956,13 +1957,13 @@ FindItems(WidgetInfo *wi,
* Go through the item table and collect all items with
* the given priority.
*/
- if (ZnTagSearchScan(wi, NULL, search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, NULL, search_var, group, recursive) == ZN_ERROR) {
return ZN_ERROR;
}
- for (item = ZnTagSearchFirst(*search_var, group, recursive);
+ for (item = ZnTagSearchFirst(*search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(*search_var)) {
if (item->priority == pri) {
- DoItem(wi->interp, item, ZN_NO_PART, tag_uid);
+ ZnDoItem(wi->interp, item, ZN_NO_PART, tag_uid);
}
}
}
@@ -1994,15 +1995,16 @@ FindItems(WidgetInfo *wi,
}
}
item = ZN_NO_ITEM;
- if (ZnTagSearchScan(wi, args[first+1], search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[first+1], search_var,
+ group, recursive) == ZN_ERROR) {
return ZN_ERROR;
}
- for (next = ZnTagSearchFirst(*search_var, group, recursive);
+ for (next = ZnTagSearchFirst(*search_var);
next != ZN_NO_ITEM; next = ZnTagSearchNext(*search_var)) {
item = next;
}
if ((item != ZN_NO_ITEM) && (item->next != ZN_NO_ITEM)) {
- DoItem(wi->interp, item->next, ZN_NO_PART, tag_uid);
+ ZnDoItem(wi->interp, item->next, ZN_NO_PART, tag_uid);
}
}
break;
@@ -2052,7 +2054,7 @@ FindItems(WidgetInfo *wi,
&item, &part);
if (item != ZN_NO_ITEM) {
- DoItem(wi->interp, item, part, tag_uid);
+ ZnDoItem(wi->interp, item, part, tag_uid);
/*printf("first %d %d\n", item->id, part);*/
return TCL_OK;
}
@@ -2108,12 +2110,13 @@ FindItems(WidgetInfo *wi,
return ZN_ERROR;
}
}
- if (ZnTagSearchScan(wi, args[first+1], search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[first+1], search_var,
+ group, recursive) == ZN_ERROR) {
return ZN_ERROR;
}
- for (item = ZnTagSearchFirst(*search_var, group, recursive);
+ for (item = ZnTagSearchFirst(*search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(*search_var)) {
- DoItem(wi->interp, item, ZN_NO_PART, tag_uid);
+ ZnDoItem(wi->interp, item, ZN_NO_PART, tag_uid);
}
}
break;
@@ -2129,7 +2132,7 @@ FindItems(WidgetInfo *wi,
"itemType ?inGroup? ?recursive?");
return ZN_ERROR;
}
- cls = (ItemClass) ITEM_P.LookupItemClass(Tcl_GetString(args[first+1]));
+ cls = ZnLookupItemClass(Tcl_GetString(args[first+1]));
if (!cls) {
Tcl_AppendResult(wi->interp, "unknown item type \"",
Tcl_GetString(args[first+1]), "\"", NULL);
@@ -2154,13 +2157,13 @@ FindItems(WidgetInfo *wi,
* Go through the item table and collect all items with
* the given item type.
*/
- if (ZnTagSearchScan(wi, NULL, search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, NULL, search_var, group, recursive) == ZN_ERROR) {
return ZN_ERROR;
}
- for (item = ZnTagSearchFirst(*search_var, group, recursive);
+ for (item = ZnTagSearchFirst(*search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(*search_var)) {
if (item->class == cls) {
- DoItem(wi->interp, item, ZN_NO_PART, tag_uid);
+ ZnDoItem(wi->interp, item, ZN_NO_PART, tag_uid);
}
}
}
@@ -2178,7 +2181,7 @@ FindItems(WidgetInfo *wi,
*
*----------------------------------------------------------------------
*/
-int
+static int
ParseCoordList(WidgetInfo *wi,
Tcl_Obj *arg,
ZnPoint **pts,
@@ -2277,7 +2280,7 @@ Contour(WidgetInfo *wi,
* If something has changed in the geometry we need to
* update or the shape will be erroneous.
*/
- ITEM_P.Update(wi);
+ Update(wi);
if (!shape->class->GetContours &&
!shape->class->GetClipVertices) {
noshape:
@@ -2574,6 +2577,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
WidgetInfo *wi = (WidgetInfo *) client_data;
int result, cmd_index, index;
Item item, item2;
+ int field = ZN_NO_PART;
int num = 0, i, j;
char *end, *str;
ZnTransfo *t = NULL;
@@ -2638,9 +2642,9 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
if (argc == 2) { /* create subcommand alone, return the list of known
* object types. */
- ItemClass *classes = ZnListArray(ITEM_P.ItemClassList());
+ ItemClass *classes = ZnListArray(ZnItemClassList());
- num = ZnListSize(ITEM_P.ItemClassList());
+ num = ZnListSize(ZnItemClassList());
l = Tcl_GetObjResult(interp);
for (i = 0; i < num; i++) {
Tcl_ListObjAppendElement(interp, l, NewStringObj(classes[i]->name));
@@ -2656,7 +2660,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
if (str[0] == '-') {
goto add_err;
}
- cls = ITEM_P.LookupItemClass(str);
+ cls = ZnLookupItemClass(str);
if (!cls) {
Tcl_AppendResult(interp, "unknown item type \"", str, "\"", NULL);
goto error;
@@ -2672,12 +2676,12 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
argc -= 4;
args += 4;
- item = ITEM_P.CreateItem(wi, cls, &argc, &args);
+ item = ZnCreateItem(wi, cls, &argc, &args);
if (item == ZN_NO_ITEM) {
goto error;
}
ITEM.InsertItem(item, group, ZN_NO_ITEM, True);
- if (ITEM.ConfigureItem(item, -1, argc, args, True) == ZN_ERROR) {
+ if (ITEM.ConfigureItem(item, ZN_NO_PART, argc, args, True) == ZN_ERROR) {
goto error;
}
wi->hot_item = item;
@@ -2725,7 +2729,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
* If something has changed in the geometry we need to
* update or the anchor location will be erroneous.
*/
- ITEM_P.Update(wi);
+ Update(wi);
item->class->GetAnchor(item, anchor, &p);
l = Tcl_GetObjResult(wi->interp);
Tcl_ListObjAppendElement(wi->interp, l, NewDoubleObj(p.x));
@@ -2756,13 +2760,14 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
argc -= 2;
args += 2;
- ITEM_P.Update(wi);
+ Update(wi);
ResetBBox(&bbox);
for (i = 0; i < argc; i++) {
- if (ZnTagSearchScan(wi, args[i], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[i], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
AddBBoxToBBox(&bbox, &item->item_bounding_box);
}
@@ -2950,7 +2955,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
this_one = &t;
}
}
- ITEM.RemoveItem(item);
+ ITEM.ExtractItem(item);
ITEM.InsertItem(item, grp, ZN_NO_ITEM, True);
/*
* The item can be a group in which case we must
@@ -2974,17 +2979,18 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
Tcl_WrongNumArgs(interp, 1, args, "clone tagOrId ?option value ...?");
goto error;
}
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
argc -= 3;
args += 3;
l = Tcl_GetObjResult(interp);
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
item2 = ITEM.CloneItem(item);
ITEM.InsertItem(item2, item->parent, ZN_NO_ITEM, True);
- if (ITEM.ConfigureItem(item2, -1, argc, args, False) == ZN_ERROR) {
+ if (ITEM.ConfigureItem(item2, ZN_NO_PART, argc, args, False) == ZN_ERROR) {
goto error;
}
Tcl_ListObjAppendElement(interp, l, NewLongObj(item2->id));
@@ -3067,26 +3073,38 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
*/
case ZN_W_CURSOR:
{
- if (argc != 4) {
- Tcl_WrongNumArgs(interp, 1, args, "cursor tagOrId index");
+ if ((argc != 4) && (argc != 5)) {
+ Tcl_WrongNumArgs(interp, 1, args, "cursor tagOrId ?field? index");
goto error;
}
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ if (argc == 5) {
+ if (Tcl_GetIntFromObj(interp, args[3], &field) != ZN_OK) {
+ Tcl_AppendResult(interp, "invalid field index \"",
+ Tcl_GetString(args[3]),
+ "\", should be a positive integer", NULL);
+ goto error;
+ }
+ argc--;
+ args++;
+ }
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
if ((item->class->Cursor == NULL) ||
(item->class->Index == NULL)) {
continue;
}
- result = (*item->class->Index)(item, args[3], &index);
+ result = (*item->class->Index)(item, field, args[3], &index);
if (result != ZN_OK) {
goto error;
}
- (*item->class->Cursor)(item, index);
- if ((item == wi->text_info.focus_item) && wi->text_info.cursor_on) {
+ (*item->class->Cursor)(item, field, index);
+ if ((item == wi->focus_item) && (field == wi->focus_field) &&
+ wi->text_info.cursor_on) {
ITEM.Invalidate(item, ZN_COORDS_FLAG);
}
}
@@ -3098,26 +3116,38 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
case ZN_W_DCHARS:
{
int first, last;
-
- if ((argc != 4) && (argc != 5)) {
- Tcl_WrongNumArgs(interp, 1, args, "dchars tagOrId first ?last?");
+ TextInfo *ti = &wi->text_info;
+
+ if ((argc < 4) || (argc > 6)) {
+ Tcl_WrongNumArgs(interp, 1, args, "dchars tagOrId ?field? first ?last?");
goto error;
}
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ if (argc == 6) {
+ if (Tcl_GetIntFromObj(interp, args[3], &field) != ZN_OK) {
+ Tcl_AppendResult(interp, "invalid field index \"",
+ Tcl_GetString(args[3]),
+ "\", should be a positive integer", NULL);
+ goto error;
+ }
+ argc--;
+ args++;
+ }
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
if ((item->class->Index == NULL) ||
(item->class->DeleteChars == NULL)) {
continue;
}
- result = (*item->class->Index)(item, args[3], &first);
+ result = (*item->class->Index)(item, field, args[3], &first);
if (result != ZN_OK) {
goto error;
}
if (argc == 5) {
- result = (*item->class->Index)(item, args[4], &last);
+ result = (*item->class->Index)(item, field, args[4], &last);
if (result != ZN_OK) {
goto error;
}
@@ -3125,7 +3155,38 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
else {
last = first;
}
- (*item->class->DeleteChars)(item, first, last);
+ (*item->class->DeleteChars)(item, field, &first, &last);
+
+ /*
+ * Update indexes for the selection to reflect the
+ * change.
+ */
+ if ((ti->sel_item == item) && (ti->sel_field == field)) {
+ int count = last + 1 - first;
+ if (ti->sel_first > first) {
+ ti->sel_first -= count;
+ if (ti->sel_first < first) {
+ ti->sel_first = first;
+ }
+ }
+ if (ti->sel_last >= first) {
+ ti->sel_last -= count;
+ if (ti->sel_last < (first-1)) {
+ ti->sel_last = (first-1);
+ }
+ }
+ if (ti->sel_first > ti->sel_last) {
+ ti->sel_item = ZN_NO_ITEM;
+ ti->sel_field = ZN_NO_PART;
+ }
+ if ((ti->anchor_item == item) && (ti->anchor_field == field) &&
+ (ti->sel_anchor > first)) {
+ ti->sel_anchor -= count;
+ if (ti->sel_anchor < first) {
+ ti->sel_anchor = first;
+ }
+ }
+ }
}
}
break;
@@ -3146,10 +3207,11 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
else {
tag = Tk_GetUid(Tcl_GetString(args[2]));
}
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
ITEM.RemoveTag(item, (char *) tag);
}
@@ -3204,37 +3266,48 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
*/
case ZN_W_FOCUS:
{
- if ((argc != 2) && (argc != 3)) {
- Tcl_WrongNumArgs(interp, 1, args, "focus ?tagOrId?");
+ if (argc > 4) {
+ Tcl_WrongNumArgs(interp, 1, args, "focus ?tagOrId? ?field?");
goto error;
}
- item = wi->text_info.focus_item;
+ item = wi->focus_item;
+ field = wi->focus_field;
if (argc == 2) {
if (item != ZN_NO_ITEM) {
- l = NewLongObj(item->id);
- Tcl_SetObjResult(interp, l);
+ l = Tcl_GetObjResult(interp);
+ Tcl_ListObjAppendElement(interp, l, NewLongObj(item->id));
+ if (field != ZN_NO_PART) {
+ Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(field));
+ }
}
goto done;
}
- if ((item != ZN_NO_ITEM) && (wi->text_info.got_focus)) {
+ if ((item != ZN_NO_ITEM) && (item->class->Cursor != NULL) &&
+ (wi->got_focus)) {
ITEM.Invalidate(item, ZN_COORDS_FLAG);
}
if (Tcl_GetString(args[2])[0] == 0) {
- wi->text_info.focus_item = ZN_NO_ITEM;
+ wi->focus_item = ZN_NO_ITEM;
+ wi->focus_field = ZN_NO_PART;
goto done;
}
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnItemWithTagOrId(wi, args[2], wi->top_group, True,
+ &item, &search_var) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
- item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
- if (item->class->Cursor != NULL) {
- break;
+ field = ZN_NO_PART;
+ if (argc == 4) {
+ if (Tcl_GetIntFromObj(interp, args[3], &field) != ZN_OK) {
+ Tcl_AppendResult(interp, "invalid field index \"",
+ Tcl_GetString(args[3]),
+ "\", should be a positive integer", NULL);
+ goto error;
}
}
- wi->text_info.focus_item = item;
- if (wi->text_info.got_focus) {
- ITEM.Invalidate(wi->text_info.focus_item, ZN_COORDS_FLAG);
+ wi->focus_item = item;
+ wi->focus_field = field;
+ if (wi->got_focus && (item->class->Cursor != NULL)) {
+ ITEM.Invalidate(wi->focus_item, ZN_COORDS_FLAG);
}
}
break;
@@ -3403,17 +3476,28 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
*/
case ZN_W_INDEX:
{
- if (argc != 4) {
- Tcl_WrongNumArgs(interp, 1, args, "index tagOrId string");
+ if ((argc != 4) && (argc != 5)) {
+ Tcl_WrongNumArgs(interp, 1, args, "index tagOrId ?field? string");
goto error;
}
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ if (argc == 5) {
+ if (Tcl_GetIntFromObj(interp, args[3], &field) != ZN_OK) {
+ Tcl_AppendResult(interp, "invalid field index \"",
+ Tcl_GetString(args[3]),
+ "\", should be a positive integer", NULL);
+ goto error;
+ }
+ argc--;
+ args++;
+ }
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
if (item->class->Index != NULL) {
- result = (*item->class->Index)(item, args[3], &index);
+ result = (*item->class->Index)(item, field, args[3], &index);
if (result != ZN_OK) {
goto error;
}
@@ -3432,24 +3516,55 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
*/
case ZN_W_INSERT:
{
- if (argc != 5) {
- Tcl_WrongNumArgs(interp, 1, args, "insert tagOrId before string");
+ TextInfo *ti = &wi->text_info;
+ char *chars;
+
+ if ((argc != 5) && (argc != 6)) {
+ Tcl_WrongNumArgs(interp, 1, args, "insert tagOrId ?field? before string");
goto error;
}
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ if (argc == 6) {
+ if (Tcl_GetIntFromObj(interp, args[3], &field) != ZN_OK) {
+ Tcl_AppendResult(interp, "invalid field index \"",
+ Tcl_GetString(args[3]),
+ "\", should be a positive integer", NULL);
+ goto error;
+ }
+ argc--;
+ args++;
+ }
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
if ((item->class->Index == NULL) ||
(item->class->InsertChars == NULL)) {
continue;
}
- result = (*item->class->Index)(item, args[3], &index);
+ result = (*item->class->Index)(item, field, args[3], &index);
if (result != ZN_OK) {
goto error;
}
- (*item->class->InsertChars)(item, index, Tcl_GetString(args[4]));
+ chars = Tcl_GetString(args[4]);
+ (*item->class->InsertChars)(item, field, &index, chars);
+ /*
+ * Inserting characters invalidates selection indices.
+ */
+ if ((ti->sel_item == item) && (ti->sel_field== field)) {
+ int length = strlen(chars);
+ if (ti->sel_first >= index) {
+ ti->sel_first += length;
+ }
+ if (ti->sel_last >= index) {
+ ti->sel_last += length;
+ }
+ if ((ti->anchor_item == item) && (ti->anchor_field == field) &&
+ (ti->sel_anchor >= index)) {
+ ti->sel_anchor += length;
+ }
+ }
}
}
break;
@@ -3458,8 +3573,6 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
*/
case ZN_W_ITEMCGET:
{
- int field = -1;
-
if (argc < 4) {
itemcget_syntax:
Tcl_WrongNumArgs(interp, 1, args, "itemcget tagOrId ?field? option");
@@ -3472,7 +3585,8 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
}
if (argc == 5) {
if (Tcl_GetIntFromObj(interp, args[3], &field) != ZN_OK) {
- Tcl_AppendResult(interp, "invalid field index \"", Tcl_GetString(args[3]),
+ Tcl_AppendResult(interp, "invalid field index \"",
+ Tcl_GetString(args[3]),
"\", should be a positive integer", NULL);
goto error;
}
@@ -3492,13 +3606,13 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
*/
case ZN_W_ITEMCONFIGURE:
{
- int field = -1;
if (argc < 3) {
Tcl_WrongNumArgs(interp, 1, args,
"itemconfigure tagOrId ?field? option value ?option value? ...");
goto error;
}
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
if ((argc > 3) && (Tcl_GetString(args[3])[0] != '-')) {
@@ -3513,10 +3627,10 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
}
argc -= 3;
args += 3;
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
if (argc < 2) {
- result = ITEM.AttributesInfo(item, field, argc, args);
+ result = ZnAttributesInfo(wi, item, item->class->attr_desc, argc, args);
}
else {
result = ITEM.ConfigureItem(item, field, argc, args, False);
@@ -3542,10 +3656,11 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
goto error;
}
if (argc == 4) {
- if (ZnTagSearchScan(wi, args[3], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[3], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
mark = item;
}
@@ -3555,15 +3670,16 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
goto error;
}
}
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ item = ZnTagSearchFirst(search_var);
if (item == ZN_NO_ITEM) {
goto done;
}
if (mark == ZN_NO_ITEM) {
- mark = ((GroupItem) item->parent)->tail;
+ mark = ZnGroupTail(item->parent);
}
group = mark->parent;
for (; item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
@@ -3655,25 +3771,27 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
/*
* Find the topmost item with the tag.
*/
- if (ZnTagSearchScan(wi, args[3], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[3], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- mark = ZnTagSearchFirst(search_var, wi->top_group, True);
+ mark = ZnTagSearchFirst(search_var);
if (mark == ZN_NO_ITEM) {
Tcl_AppendResult(interp, "unknown tag or item \"",
Tcl_GetString(args[3]), "\"", NULL);
goto error;
}
}
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ item = ZnTagSearchFirst(search_var);
if (item == ZN_NO_ITEM) {
goto done;
}
if (mark == ZN_NO_ITEM) {
- mark = ((GroupItem) item->parent)->head;
+ mark = ZnGroupHead(item->parent);
}
group = mark->parent;
for (; item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
@@ -3691,7 +3809,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
*/
case ZN_W_REMOVE:
{
- FieldSet fs;
+ int num_fields;
if (argc < 3) {
Tcl_WrongNumArgs(interp, 1, args, "remove tagOrId ?tagOrId ...?");
@@ -3700,10 +3818,11 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
argc -= 2;
args += 2;
for (i = 0; i < argc; i++) {
- if (ZnTagSearchScan(wi, args[i], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[i], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
if (item == wi->top_group) {
continue;
@@ -3711,8 +3830,8 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
if (wi->binding_table != NULL) {
Tk_DeleteAllBindings(wi->binding_table, (ClientData) item);
if (item->class->has_fields) {
- fs = item->class->GetFieldSet(item);
- for (j = 0; j < fs->num_fields; j++) {
+ num_fields = FIELD.NumFields(item->class->GetFieldSet(item));
+ for (j = 0; j < num_fields; j++) {
Tk_DeleteAllBindings(wi->binding_table,
(ClientData) EncodeItemPart(item, j));
}
@@ -3753,7 +3872,8 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
t = (ZnTransfo *) Tcl_GetHashValue(entry);
}
else {
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
}
@@ -3771,7 +3891,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
}
}
else {
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
ITEM.RotateItem(item, angle, (argc == 6) ? &p : NULL);
}
@@ -3794,7 +3914,8 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
t = (ZnTransfo *) Tcl_GetHashValue(entry);
}
else {
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
}
@@ -3809,7 +3930,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
ZnScale(t, scale.x, scale.y);
}
else {
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
ITEM.ScaleItem(item, scale.x, scale.y);
}
@@ -3821,15 +3942,18 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
*/
case ZN_W_SELECT:
{
+ TextInfo *ti = &wi->text_info;
+
if (argc < 3) {
Tcl_WrongNumArgs(interp, 1, args, "select option ?tagOrId? ?arg?");
goto error;
}
if (argc >= 4) {
- if (ZnTagSearchScan(wi, args[3], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[3], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
if ((item->class->Index != NULL) &&
(item->class->Selection != NULL)) {
@@ -3842,66 +3966,82 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
goto error;
}
}
- if (argc == 5) {
- result = item->class->Index(item, args[4], &index);
- if (result != ZN_OK) {
- goto error;
- }
- }
if (Tcl_GetIndexFromObj(interp, args[2], sel_cmd_strings,
"selection option", 0, &cmd_index) != ZN_OK) {
goto error;
}
+ if ((argc == 5) || (argc == 6)) {
+ if (argc == 6) {
+ if (Tcl_GetIntFromObj(interp, args[4], &field) != ZN_OK) {
+ Tcl_AppendResult(interp, "invalid field index \"",
+ Tcl_GetString(args[4]),
+ "\", should be a positive integer", NULL);
+ goto error;
+ }
+ argc--;
+ args++;
+ }
+ result = item->class->Index(item, field, args[4], &index);
+ if (result != ZN_OK) {
+ goto error;
+ }
+ }
switch ((enum sel_cmds) cmd_index) {
case ZN_SEL_ADJUST:
if (argc != 5) {
- Tcl_WrongNumArgs(interp, 1, args, "select adjust tagOrId index");
+ Tcl_WrongNumArgs(interp, 1, args, "select adjust tagOrId ?field? index");
goto error;
}
- if (wi->text_info.sel_item == item) {
- if (index < (wi->text_info.sel_first + wi->text_info.sel_last)/2) {
- wi->text_info.sel_anchor = wi->text_info.sel_last+1;
+ if ((ti->sel_item == item) && (ti->sel_field == field)) {
+ if (index < (ti->sel_first + ti->sel_last)/2) {
+ ti->sel_anchor = ti->sel_last+1;
}
else {
- wi->text_info.sel_anchor = wi->text_info.sel_first;
+ ti->sel_anchor = ti->sel_first;
}
}
- SelectTo(item, index);
+ SelectTo(item, field, index);
break;
case ZN_SEL_CLEAR:
if (argc != 3) {
Tcl_WrongNumArgs(interp, 1, args, "select clear");
goto error;
}
- if (wi->text_info.sel_item != ZN_NO_ITEM) {
- ITEM.Invalidate(wi->text_info.sel_item, ZN_DRAW_FLAG);
- wi->text_info.sel_item = ZN_NO_ITEM;
+ if (ti->sel_item != ZN_NO_ITEM) {
+ ITEM.Invalidate(ti->sel_item, ZN_DRAW_FLAG);
+ ti->sel_item = ZN_NO_ITEM;
+ ti->sel_field = ZN_NO_PART;
}
break;
case ZN_SEL_FROM:
if (argc != 5) {
- Tcl_WrongNumArgs(interp, 1, args, "select from tagOrId index");
+ Tcl_WrongNumArgs(interp, 1, args, "select from tagOrId ?field? index");
goto error;
}
- wi->text_info.anchor_item = item;
- wi->text_info.sel_anchor = index;
+ ti->anchor_item = item;
+ ti->anchor_field = field;
+ ti->sel_anchor = index;
break;
case ZN_SEL_ITEM:
if (argc != 3) {
Tcl_WrongNumArgs(interp, 1, args, "select item");
goto error;
}
- if (wi->text_info.sel_item != ZN_NO_ITEM) {
- l = NewLongObj(wi->text_info.sel_item->id);
+ if (ti->sel_item != ZN_NO_ITEM) {
+ l = Tcl_GetObjResult(interp);
+ Tcl_ListObjAppendElement(interp, l, NewLongObj(ti->sel_item->id));
+ if (ti->sel_field != ZN_NO_PART) {
+ Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(ti->sel_field));
+ }
Tcl_SetObjResult(interp, l);
}
break;
case ZN_SEL_TO:
if (argc != 5) {
- Tcl_WrongNumArgs(interp, 1, args, "select to tagOrId index");
+ Tcl_WrongNumArgs(interp, 1, args, "select to tagOrId ?field? index");
goto error;
}
- SelectTo(item, index);
+ SelectTo(item, field, index);
break;
}
}
@@ -4046,7 +4186,8 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
t = (ZnTransfo *) Tcl_GetHashValue(entry);
}
else {
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
}
@@ -4061,7 +4202,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
ZnTranslate(t, trans.x, trans.y);
}
else {
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item =ZnTagSearchNext(search_var)) {
ITEM.TranslateItem(item, trans.x, trans.y);
}
@@ -4082,7 +4223,8 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
t = (ZnTransfo *) Tcl_GetHashValue(entry);
}
else {
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
}
@@ -4091,7 +4233,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
ZnTransfoSetIdentity(t);
}
else {
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
ITEM.ResetTransfo(item);
}
@@ -4114,10 +4256,11 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
goto error;
}
t = (ZnTransfo *) Tcl_GetHashValue(entry);
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
ITEM.SetTransfo(item, t);
}
@@ -4193,10 +4336,11 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
Tcl_WrongNumArgs(interp, 1, args, " vertexat tagOrId x y");
goto error;
}
- if (ZnTagSearchScan(wi, args[2], &search_var) == ZN_ERROR) {
+ if (ZnTagSearchScan(wi, args[2], &search_var,
+ wi->top_group, True) == ZN_ERROR) {
goto error;
}
- for (item = ZnTagSearchFirst(search_var, wi->top_group, True);
+ for (item = ZnTagSearchFirst(search_var);
item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) {
if (item->class->PickVertex != NULL) {
break;
@@ -4264,7 +4408,7 @@ TileChange(ClientData client_data,
bbox.orig.x = bbox.orig.y = 0;
bbox.corner.x = wi->width;
bbox.corner.y = wi->height;
- ITEM_P.Damage(wi, &bbox);
+ ZnDamage(wi, &bbox);
ZnNeedRedisplay(wi);
}
@@ -4339,7 +4483,7 @@ Configure(Tcl_Interp *interp,/* Used for error reporting. */
bbox.orig.x = bbox.orig.y = 0;
bbox.corner.x = wi->width;
bbox.corner.y = wi->height;
- ITEM_P.Damage(wi, &bbox);
+ ZnDamage(wi, &bbox);
ZnNeedRedisplay(wi);
}
if (CONFIG_PROBE(RELIEF_SPEC)) {
@@ -4352,7 +4496,7 @@ Configure(Tcl_Interp *interp,/* Used for error reporting. */
bbox.orig.x = bbox.orig.y = 0;
bbox.corner.x = wi->width;
bbox.corner.y = wi->height;
- ITEM_P.Damage(wi, &bbox);
+ ZnDamage(wi, &bbox);
}
if (CONFIG_PROBE(SPEED_VECTOR_LENGTH_SPEC) ||
CONFIG_PROBE(MANAGE_HISTORY_SPEC) ||
@@ -4381,7 +4525,7 @@ Configure(Tcl_Interp *interp,/* Used for error reporting. */
bbox.orig.x = bbox.orig.y = 0;
bbox.corner.x = wi->width;
bbox.corner.y = wi->height;
- ITEM_P.Damage(wi, &bbox);
+ ZnDamage(wi, &bbox);
ZnNeedRedisplay(wi);
}
@@ -4414,7 +4558,7 @@ Configure(Tcl_Interp *interp,/* Used for error reporting. */
/*
* Update the blinking cursor timing if on/off time has changed.
*/
- if (wi->text_info.got_focus &&
+ if (wi->got_focus &&
(CONFIG_PROBE(INSERT_ON_TIME_SPEC) ||
CONFIG_PROBE(INSERT_OFF_TIME_SPEC))) {
Focus(wi, True);
@@ -4446,7 +4590,7 @@ Blink(ClientData client_data)
{
WidgetInfo *wi = (WidgetInfo *) client_data;
- if (!wi->text_info.got_focus || (wi->insert_off_time == 0)) {
+ if (!wi->got_focus || (wi->insert_off_time == 0)) {
return;
}
if (wi->text_info.cursor_on) {
@@ -4459,8 +4603,9 @@ Blink(ClientData client_data)
wi->blink_handler = Tcl_CreateTimerHandler(wi->insert_on_time,
Blink, client_data);
}
- if (wi->text_info.focus_item != ZN_NO_ITEM) {
- ITEM.Invalidate(wi->text_info.focus_item, ZN_DRAW_FLAG);
+ if ((wi->focus_item != ZN_NO_ITEM) &&
+ (wi->focus_item->class->Cursor != NULL)) {
+ ITEM.Invalidate(wi->focus_item, ZN_DRAW_FLAG);
}
}
@@ -4470,7 +4615,7 @@ Focus(WidgetInfo *wi,
{
Tcl_DeleteTimerHandler(wi->blink_handler);
if (got_focus) {
- wi->text_info.got_focus = 1;
+ wi->got_focus = 1;
wi->text_info.cursor_on = 1;
if (wi->insert_off_time != 0) {
wi->blink_handler = Tcl_CreateTimerHandler(wi->insert_off_time,
@@ -4478,12 +4623,13 @@ Focus(WidgetInfo *wi,
}
}
else {
- wi->text_info.got_focus = 0;
+ wi->got_focus = 0;
wi->text_info.cursor_on = 0;
wi->blink_handler = (Tcl_TimerToken) NULL;
}
- if (wi->text_info.focus_item != ZN_NO_ITEM) {
- ITEM.Invalidate(wi->text_info.focus_item, ZN_COORDS_FLAG);
+ if ((wi->focus_item != ZN_NO_ITEM) &&
+ (wi->focus_item->class->Cursor != NULL)){
+ ITEM.Invalidate(wi->focus_item, ZN_COORDS_FLAG);
}
/*printf("focus %s\n", got_focus ? "in" : "out");*/
if (wi->highlight_width > 0) {
@@ -4496,7 +4642,7 @@ Focus(WidgetInfo *wi,
bbox.orig.x = bbox.orig.y = 0;
bbox.corner.x = Tk_Width(wi->win);
bbox.corner.y = Tk_Height(wi->win);
- ITEM_P.Damage(wi, &bbox);
+ ZnDamage(wi, &bbox);
ZnNeedRedisplay(wi);
}
#endif
@@ -4640,8 +4786,8 @@ Event(ClientData client_data, /* Information about widget. */
wi->opt_width = wi->width = int_width;
wi->opt_height = wi->height = int_height;
- ITEM_P.ResetTransformStack(wi);
- ITEM_P.Damage(wi, &bbox);
+ ZnResetTransformStack(wi);
+ ZnDamage(wi, &bbox);
ITEM.Invalidate(wi->top_group, ZN_TRANSFO_FLAG);
/*
@@ -4747,8 +4893,8 @@ DoEvent(WidgetInfo *wi,
item = wi->current_item;
part = wi->current_part;
if ((event->type == KeyPress) || (event->type == KeyRelease)) {
- item = wi->text_info.focus_item;
- part = ZN_NO_PART;
+ item = wi->focus_item;
+ part = wi->focus_field;
}
if ((item == ZN_NO_ITEM) || !item->class->IsSensitive(item, ZN_NO_PART)) {
@@ -5055,7 +5201,7 @@ PickCurrentItem(WidgetInfo *wi,
* Add the tag 'current' to the current item under the pointer.
*/
/*printf("Adding 'current' to %d\n", wi->current_item->id);*/
- DoItem((Tcl_Interp *) NULL, wi->current_item, ZN_NO_PART, current_uid);
+ ZnDoItem((Tcl_Interp *) NULL, wi->current_item, ZN_NO_PART, current_uid);
/*
* Then emit a fake Enter event on it.
*/
@@ -5179,7 +5325,7 @@ Bind(ClientData client_data, /* Information about widget. */
bbox.orig.x = bbox.orig.y = 0;
bbox.corner.x = Tk_Width(wi->win);
bbox.corner.y = Tk_Height(wi->win);
- ITEM_P.Damage(wi, &bbox);
+ ZnDamage(wi, &bbox);
ZnNeedRedisplay(wi);
}
#endif
@@ -5222,11 +5368,13 @@ static void
LostSelection(ClientData client_data)
{
WidgetInfo *wi = (WidgetInfo *) client_data;
+ TextInfo *ti = &wi->text_info;
- if (wi->text_info.sel_item != ZN_NO_ITEM) {
- ITEM.Invalidate(wi->text_info.sel_item, ZN_DRAW_FLAG);
+ if (ti->sel_item != ZN_NO_ITEM) {
+ ITEM.Invalidate(ti->sel_item, ZN_DRAW_FLAG);
}
- wi->text_info.sel_item = ZN_NO_ITEM;
+ ti->sel_item = ZN_NO_ITEM;
+ ti->sel_field = ZN_NO_PART;
}
@@ -5247,42 +5395,46 @@ LostSelection(ClientData client_data)
*----------------------------------------------------------------------
*/
static void
-SelectTo(Item item,
- int index)
+SelectTo(Item item,
+ int field,
+ int index)
{
WidgetInfo *wi = item->wi;
- int old_first, old_last;
+ TextInfo *ti = &wi->text_info;
+ int old_first, old_last, old_field;
Item old_sel_item;
- old_first = wi->text_info.sel_first;
- old_last = wi->text_info.sel_last;
- old_sel_item = wi->text_info.sel_item;
+ old_first = ti->sel_first;
+ old_last = ti->sel_last;
+ old_sel_item = ti->sel_item;
+ old_field = ti->sel_field;
/*
* Grab the selection if we don't own it already.
*/
- if (wi->text_info.sel_item == ZN_NO_ITEM) {
+ if (ti->sel_item == ZN_NO_ITEM) {
Tk_OwnSelection(wi->win, XA_PRIMARY, LostSelection, (ClientData) wi);
}
- else if (wi->text_info.sel_item != item) {
- ITEM.Invalidate(wi->text_info.sel_item, ZN_DRAW_FLAG);
+ else if ((ti->sel_item != item) || (ti->sel_field != field)) {
+ ITEM.Invalidate(ti->sel_item, ZN_DRAW_FLAG);
}
- wi->text_info.sel_item = item;
+ ti->sel_item = item;
- if (wi->text_info.anchor_item != item) {
- wi->text_info.anchor_item = item;
- wi->text_info.sel_anchor = index;
+ if ((ti->anchor_item != item) || (ti->anchor_field) != field) {
+ ti->anchor_item = item;
+ ti->anchor_field = field;
+ ti->sel_anchor = index;
}
- if (wi->text_info.sel_anchor <= index) {
- wi->text_info.sel_first = wi->text_info.sel_anchor;
- wi->text_info.sel_last = index;
+ if (ti->sel_anchor <= index) {
+ ti->sel_first = ti->sel_anchor;
+ ti->sel_last = index;
}
else {
- wi->text_info.sel_first = index;
- wi->text_info.sel_last = wi->text_info.sel_anchor;
+ ti->sel_first = index;
+ ti->sel_last = ti->sel_anchor;
}
- if ((wi->text_info.sel_first != old_first) ||
- (wi->text_info.sel_last != old_last) ||
+ if ((ti->sel_first != old_first) ||
+ (ti->sel_last != old_last) ||
(item != old_sel_item)) {
ITEM.Invalidate(item, ZN_DRAW_FLAG);
}
@@ -5320,15 +5472,16 @@ FetchSelection( ClientData client_data,
* NULL character. */
{
WidgetInfo *wi = (WidgetInfo *) client_data;
+ TextInfo *ti = &wi->text_info;
- if (wi->text_info.sel_item == NULL) {
+ if (ti->sel_item == ZN_NO_ITEM) {
return -1;
}
- if (wi->text_info.sel_item->class->Selection == NULL) {
+ if (ti->sel_item->class->Selection == NULL) {
return -1;
}
- return (*wi->text_info.sel_item->class->Selection)(wi->text_info.sel_item, offset,
- buffer, max_bytes);
+ return (*ti->sel_item->class->Selection)(ti->sel_item, ti->sel_field,
+ offset, buffer, max_bytes);
}
@@ -5471,8 +5624,8 @@ Destroy(char *mem_ptr) /* Info about the widget. */
/*
* Should be empty by now.
*/
- ITEM_P.FreeTransformStack(wi);
- ITEM_P.FreeClipStack(wi);
+ ZnFreeTransformStack(wi);
+ ZnFreeClipStack(wi);
ZnListFree(wi->work_pts);
#ifdef GLX
@@ -5489,966 +5642,461 @@ Destroy(char *mem_ptr) /* Info about the widget. */
/*
- *----------------------------------------------------------------------
- *
- * Redisplay --
- *
- * This procedure redraws the contents of a Zinc window.
- * It is invoked as a do-when-idle handler, so it only runs
- * when there's nothing else for the application to do.
- *
- * Results:
- * None.
+ **********************************************************************************
*
- * Side effects:
- * Information appears on the screen.
+ * ZnDamage --
*
- *----------------------------------------------------------------------
+ **********************************************************************************
*/
-
-static void
-Redisplay(ClientData client_data) /* Information about the widget. */
+void
+ZnDamage(WidgetInfo *wi,
+ ZnBBox *damage)
{
- WidgetInfo *wi = (WidgetInfo *) client_data;
-
- wi->update_pending = 0;
- if (!wi->realized || !Tk_IsMapped(wi->win)) {
+ if ((damage == NULL) || IsEmptyBBox(damage)) {
return;
}
-
- if (wi->monitoring) {
- XStartChrono(wi->total_draw_chrono, wi->dpy, ZnWindowId(wi->win));
- ResetChronos(wi->this_draw_chrono);
- XStartChrono(wi->this_draw_chrono, wi->dpy, ZnWindowId(wi->win));
- }
-
- do {
- /*
- * Update the items.
- * NOTE: See above.
- */
- ITEM_P.Update(wi);
-
- /*
- * Do enter/leave processing after the overlap manager
- * has finished with the items. Do it has many times
- * as needed, each round may trigger callbacks that
- * result in moved items and so forth. It can even
- * lead to the widget destruction, this is the reason
- * for Tcl_Preserve/Tcl_Release.
- */
- if (ISSET(wi->events_flags, INTERNAL_NEED_REPICK)) {
- Tk_Window tkwin;
-
- Tcl_Preserve((ClientData) wi);
- CLEAR(wi->events_flags, INTERNAL_NEED_REPICK);
- PickCurrentItem(wi, &wi->pick_event);
- tkwin = wi->win;
- Tcl_Release((ClientData) wi);
- if (tkwin == NULL) {
- return;
- }
- }
- }
- while (ISSET(wi->top_group->inv_flags, ZN_COORDS_FLAG) ||
- ISSET(wi->top_group->inv_flags, ZN_TRANSFO_FLAG) ||
- ISSET(wi->events_flags, INTERNAL_NEED_REPICK));
-
- /*
- * Repair the scene where it is no longer up to date,
- * then send the merged area back to the screen.
- */
- ITEM_P.Repair(wi);
- /*
- * Reset the exposed & damaged areas.
- */
- ResetBBox(&wi->exposed_area);
- ResetBBox(&wi->damaged_area);
+ /*printf("damaging area: %g %g %g %g\n", damage->orig.x,
+ damage->orig.y, damage->corner.x, damage->corner.y);*/
- if (wi->monitoring) {
- XStopChrono(wi->total_draw_chrono, wi->dpy, ZnWindowId(wi->win));
- XStopChrono(wi->this_draw_chrono, wi->dpy, ZnWindowId(wi->win));
+ if (IsEmptyBBox(&wi->damaged_area)) {
+ wi->damaged_area.orig.x = damage->orig.x;
+ wi->damaged_area.orig.y = damage->orig.y;
+ wi->damaged_area.corner.x = damage->corner.x;
+ wi->damaged_area.corner.y = damage->corner.y;
}
-}
-
-
-/*
- *--------------------------------------------------------------------------
- *
- * MapInfo stuff that should go eventually in its own file.
- *
- *--------------------------------------------------------------------------
- */
-
-static Tcl_HashTable mapInfoTable;
-static ZnBool map_info_inited = False;
-
-typedef struct {
- ClientData client_data;
- MapInfoChangeProc proc;
-} MapInfoClient;
-
-typedef struct {
- MapInfoId map_info;
- ZnBool deleted;
- ZnList clients;
-} MapInfoMaster;
-
-static void
-MapInfoInit()
-{
- Tcl_InitHashTable(&mapInfoTable, TCL_ONE_WORD_KEYS);
-
- map_info_inited = True;
+ else {
+ wi->damaged_area.orig.x = MIN(wi->damaged_area.orig.x, damage->orig.x);
+ wi->damaged_area.orig.y = MIN(wi->damaged_area.orig.y, damage->orig.y);
+ wi->damaged_area.corner.x = MAX(wi->damaged_area.corner.x, damage->corner.x);
+ wi->damaged_area.corner.y = MAX(wi->damaged_area.corner.y, damage->corner.y);
+ }
+ /*printf("damaged area: %g %g %g %g\n", wi->damaged_area.orig.x,
+ wi->damaged_area.orig.y, wi->damaged_area.corner.x,
+ wi->damaged_area.corner.y);*/
}
static void
-UpdateMapInfoClients(MapInfoMaster *master)
+ClampDamageArea(WidgetInfo *wi)
{
- int i, num;
- MapInfoClient *client;
+ int width, height;
- num = ZnListSize(master->clients);
- client = (MapInfoClient *) ZnListArray(master->clients);
- for (i = 0; i < num; i++, client++) {
- (*client->proc)(client->client_data, master->map_info);
+ if (wi->damaged_area.orig.x < wi->inset) {
+ wi->damaged_area.orig.x = wi->inset;
}
-}
-
-int
-ZnCreateMapInfo(Tcl_Interp *interp,
- char *name,
- MapInfoId *map_info)
-{
- Tk_Uid uid = Tk_GetUid(name);
- Tcl_HashEntry *entry;
- int new;
- MapInfoMaster *master;
-
- if (!map_info_inited) {
- MapInfoInit();
+ if (wi->damaged_area.orig.y < wi->inset) {
+ wi->damaged_area.orig.y = wi->inset;
}
-
- entry = Tcl_CreateHashEntry(&mapInfoTable, uid, &new);
- if (!new) {
- /*
- * Empty the map info if it is not.
- */
- master = (MapInfoMaster *) Tcl_GetHashValue(entry);
- if (master->deleted) {
- master->deleted = False;
- }
- else {
- MapInfoEmpty(master->map_info);
- UpdateMapInfoClients(master);
- }
+ if (wi->damaged_area.corner.x < wi->inset) {
+ wi->damaged_area.corner.x = wi->inset;
}
- else {
- master = (MapInfoMaster *) ZnMalloc(sizeof(MapInfoMaster));
- master->map_info = MapInfoCreate(name);
- master->deleted = False;
- master->clients = ZnListNew(1, sizeof(MapInfoClient));
- Tcl_SetHashValue(entry, master);
+ if (wi->damaged_area.corner.y < wi->inset) {
+ wi->damaged_area.corner.y = wi->inset;
}
- if (map_info) {
- *map_info = master->map_info;
+ width = wi->width - wi->inset;
+ height = wi->height - wi->inset;
+ if (wi->damaged_area.orig.x > width) {
+ wi->damaged_area.orig.x = width;
}
- return TCL_OK;
-}
-
-int
-ZnDuplicateMapInfo(Tcl_Interp *interp,
- char *name,
- MapInfoId map_info)
-{
- Tk_Uid uid = Tk_GetUid(name);
- Tcl_HashEntry *entry;
- int new;
- MapInfoMaster *master;
-
- if (!map_info_inited) {
- MapInfoInit();
+ if (wi->damaged_area.orig.y > height) {
+ wi->damaged_area.orig.y = height;
}
-
- entry = Tcl_CreateHashEntry(&mapInfoTable, uid, &new);
- if (!new) {
- Tcl_AppendResult(interp, "duplicate mapinfo \"", name, "\" already exists", NULL);
- return ZN_ERROR;
+ if (wi->damaged_area.corner.x > width) {
+ wi->damaged_area.corner.x = width;
}
- master = (MapInfoMaster *) ZnMalloc(sizeof(MapInfoMaster));
- master->map_info = MapInfoDuplicate(map_info);
- master->deleted = False;
- master->clients = ZnListNew(1, sizeof(MapInfoClient));
- Tcl_SetHashValue(entry, master);
-
- return TCL_OK;
-}
-
-MapInfoMaster *
-LookupMapInfoMaster(Tcl_Interp *interp,
- char *name)
-{
- Tk_Uid uid = Tk_GetUid(name);
- Tcl_HashEntry *entry;
- MapInfoMaster *master;
-
- if (!map_info_inited) {
- MapInfoInit();
- }
-
- entry = Tcl_FindHashEntry(&mapInfoTable, uid);
- if (entry == NULL) {
- mp_error:
- Tcl_AppendResult(interp, "mapinfo \"", name, "\" doesn't exist", NULL);
- return NULL;
- }
- master = (MapInfoMaster *) Tcl_GetHashValue(entry);
- if (master->deleted) {
- goto mp_error;
- }
- return master;
-}
-
-int
-ZnDeleteMapInfo(Tcl_Interp *interp,
- char *name)
-{
- MapInfoMaster *master;
- Tk_Uid uid = Tk_GetUid(name);
- Tcl_HashEntry *entry;
-
- if (!map_info_inited) {
- MapInfoInit();
- }
-
- entry = Tcl_FindHashEntry(&mapInfoTable, uid);
- if (entry == NULL) {
- return ZN_ERROR;
+ if (wi->damaged_area.corner.y > height) {
+ wi->damaged_area.corner.y = height;
}
-
- master = (MapInfoMaster *) Tcl_GetHashValue(entry);
- if (ZnListSize(master->clients) != 0) {
- master->deleted = True;
- MapInfoEmpty(master->map_info);
- UpdateMapInfoClients(master);
- }
- else {
- MapInfoDelete(master->map_info);
- ZnListFree(master->clients);
- Tcl_DeleteHashEntry(entry);
- ZnFree(master);
- }
-
- return TCL_OK;
}
-MapInfoId
-ZnGetMapInfo(Tcl_Interp *interp,
- char *name,
- MapInfoChangeProc proc,
- ClientData client_data)
-{
- MapInfoMaster *master;
- MapInfoClient client;
-
- master = LookupMapInfoMaster(interp, name);
- if (master == NULL) {
- return NULL;
- }
- client.proc = proc;
- client.client_data = client_data;
- ZnListAdd(master->clients, &client, ZnListTail);
-
- return master->map_info;
-}
-void
-ZnFreeMapInfo(MapInfoId map_info,
- MapInfoChangeProc proc,
- ClientData client_data)
+/*
+ **********************************************************************************
+ *
+ * Update --
+ *
+ **********************************************************************************
+ */
+static void
+Update(WidgetInfo *wi)
{
- Tk_Uid uid = Tk_GetUid(MapInfoName(map_info));
- Tcl_HashEntry *entry;
- MapInfoMaster *master;
- MapInfoClient *client;
- int num, i;
-
- if (!map_info_inited) {
- MapInfoInit();
- }
-
- entry = Tcl_FindHashEntry(&mapInfoTable, uid);
- if (entry == NULL) {
- return;
- }
- master = (MapInfoMaster *) Tcl_GetHashValue(entry);
- client = (MapInfoClient *) ZnListArray(master->clients);
- num = ZnListSize(master->clients);
- for (i = 0; i < num; i++, client++) {
- if ((client->client_data == client_data) &&
- (client->proc == proc)) {
- ZnListDelete(master->clients, i);
- return;
+ /*
+ * Give the overlap manager a chance to do its work.
+ */
+#ifdef OM
+ if ((wi->om_group != ZN_NO_ITEM) && ZnGroupCallOm(wi->om_group)) {
+ ZnPoint scale={1.0,1.0};
+ if (wi->om_group->transfo) {
+ ZnTransfoDecompose(wi->om_group->transfo, &scale,
+ NULL, NULL, NULL);
}
+ OmProcessOverlap((void *) wi, wi->width, wi->height, scale.x);
+ ZnGroupSetCallOm(wi->om_group, False);
}
-}
-
-void
-ZnUpdateMapInfoClients(MapInfoId map_info)
-{
- Tk_Uid uid = Tk_GetUid(MapInfoName(map_info));
- Tcl_HashEntry *entry;
- MapInfoMaster *master;
+#endif
- if (!map_info_inited) {
- MapInfoInit();
+ if (ISSET(wi->top_group->inv_flags, ZN_COORDS_FLAG) ||
+ ISSET(wi->top_group->inv_flags, ZN_TRANSFO_FLAG)) {
+ wi->top_group->class->ComputeCoordinates(wi->top_group, False);
}
-
- entry = Tcl_FindHashEntry(&mapInfoTable, uid);
- if (entry == NULL) {
- return;
- }
- master = (MapInfoMaster *) Tcl_GetHashValue(entry);
- UpdateMapInfoClients(master);
}
/*
- * These arrays must be kept in sync with the MapInfoLineStyle
- * and MapInfoTextStyle enums.
+ **********************************************************************************
+ *
+ * Repair --
+ *
+ **********************************************************************************
*/
-static char *line_style_strings[] = {
- "simple",
- "dashed",
- "dotted",
- "mixed",
- "marked",
-};
-
-static char *text_style_strings[] = {
- "normal",
- "underlined"
-};
-
-static char *
-MapInfoLineStyleToString(MapInfoLineStyle line_style)
-{
- return line_style_strings[line_style];
-}
-
-static int
-MapInfoLineStyleFromString(Tcl_Interp *interp,
- char *str,
- MapInfoLineStyle *line_style)
+static void
+Repair(WidgetInfo *wi)
{
- int i, num = sizeof(line_style_strings)/sizeof(char *);
+ XGCValues values;
+ ZnPoint pts[2];
+ ZnTriStrip tristrip;
+ XColor *color;
+ ZnReal int_width = Tk_Width(wi->win);
+ ZnReal int_height = Tk_Height(wi->win);
- for (i = 0; i < num; i++) {
- if (strcmp(str, line_style_strings[i]) == 0) {
- *line_style = i;
- return TCL_OK;
+ if (wi->render) {
+#ifdef GLX
+#ifdef GLX_DAMAGE
+ ClampDamageArea(wi);
+ /*
+ * Merge the exposed area.
+ */
+ AddBBoxToBBox(&wi->damaged_area, &wi->exposed_area);
+ if (IsEmptyBBox(&wi->damaged_area)) {
+ return;
}
- }
- Tcl_AppendResult(interp, " incorrect mapinfo line style \"",
- str,"\"", NULL);
- return ZN_ERROR;
-}
-
-static char *
-MapInfoTextStyleToString(MapInfoTextStyle text_style)
-{
- return text_style_strings[text_style];
-}
+#endif
-static int
-MapInfoTextStyleFromString(Tcl_Interp *interp,
- char *str,
- MapInfoTextStyle *text_style)
-{
- int i, num = sizeof(text_style_strings)/sizeof(char *);
+ glXMakeCurrent(wi->dpy, ZnWindowId(wi->win), wi->gl_context);
+ glEnable(GL_POINT_SMOOTH);
+ glEnable(GL_LINE_SMOOTH);
+#if 0
+ glEnable(GL_POLYGON_SMOOTH); /* expensive ? */
+#endif
- for (i = 0; i < num; i++) {
- if (strcmp(str, text_style_strings[i]) == 0) {
- *text_style = i;
- return TCL_OK;
- }
- }
- Tcl_AppendResult(interp, " incorrect mapinfo text style \"",
- str,"\"", NULL);
- return ZN_ERROR;
-}
+ glEnable(GL_BLEND);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-int
-MapInfoObjCmd(ClientData client_data,
- Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- Tcl_Obj *CONST args[])
-{
- int index, index2, result;
- MapInfoMaster *master;
- Tcl_Obj *l;
- static char *sub_cmd_strings[] = {
- "add", "count", "create", "delete", "duplicate",
- "get", "remove", "replace", "scale", "translate", NULL
- };
- static char *e_type_strings[] = {
- "arc", "line", "symbol", "text", NULL
- };
- enum sub_cmds {
- ZN_MI_ADD, ZN_MI_COUNT, ZN_MI_CREATE, ZN_MI_DELETE, ZN_MI_DUPLICATE,
- ZN_MI_GET, ZN_MI_REMOVE, ZN_MI_REPLACE, ZN_MI_SCALE, ZN_MI_TRANSLATE
- };
- enum e_types {
- ZN_E_ARC, ZN_E_LINE, ZN_E_SYMBOL, ZN_E_TEXT
- };
-
- if (!inited) {
- InitZinc(interp);
- }
-
- if (argc < 3) {
- Tcl_WrongNumArgs(interp, 1, args, "mapInfo/name subCmd ?args?");
- return ZN_ERROR;
- }
+ glClearStencil(0);
+ color = ZnGetGradientColor(wi->back_color, 0, NULL);
+ glClearColor(color->red/65536.0, color->green/65536.0,
+ color->blue/65536.0, 0.0);
- if (Tcl_GetIndexFromObj(interp, args[2], sub_cmd_strings,
- "subCmd", 0, &index) != ZN_OK) {
- return ZN_ERROR;
- }
- result = TCL_OK;
- /*printf("mapinfo command \"%s\", argc=%d\n",
- Tcl_GetString(args[2]), argc);*/
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- switch((enum sub_cmds) index) {
/*
- * create
+ * Init the composite group alpha.
*/
- case ZN_MI_CREATE:
- {
- if (argc != 3) {
- Tcl_WrongNumArgs(interp, 1, args, "name create");
- return ZN_ERROR;
- }
- if (ZnCreateMapInfo(interp, Tcl_GetString(args[1]), NULL) == ZN_ERROR) {
- return ZN_ERROR;
- }
- }
- break;
+ wi->alpha = 100;
+
+ glViewport(0, 0, (GLsizei) int_width, int_height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(0.0, int_width, int_height, 0.0);
+ glMatrixMode(GL_MODELVIEW);
+
+#ifdef GLX_DAMAGE
+ glEnable(GL_SCISSOR_TEST);
+
/*
- * delete
+ * Set the damaged area as the scissor area.
*/
- case ZN_MI_DELETE:
- {
- if (argc != 3) {
- Tcl_WrongNumArgs(interp, 1, args, "mapInfo delete");
- return ZN_ERROR;
- }
- if (ZnDeleteMapInfo(interp, Tcl_GetString(args[1])) == ZN_ERROR) {
- return ZN_ERROR;
- }
- }
- break;
+ wi->damaged_area.orig.x = REAL_TO_INT(wi->damaged_area.orig.x);
+ wi->damaged_area.orig.y = REAL_TO_INT(wi->damaged_area.orig.y);
+ wi->damaged_area.corner.x = REAL_TO_INT(wi->damaged_area.corner.x);
+ wi->damaged_area.corner.y = REAL_TO_INT(wi->damaged_area.corner.y);
+ glScissor(wi->damaged_area.orig.x,
+ int_height - wi->damaged_area.corner.y,
+ wi->damaged_area.corner.x - wi->damaged_area.orig.x,
+ wi->damaged_area.corner.y - wi->damaged_area.orig.y);
+#else
/*
- * duplicate
+ * We do not use the damaged area for GL rendering,
+ * set it to the whole area.
*/
- case ZN_MI_DUPLICATE:
- {
- if (argc != 4) {
- Tcl_WrongNumArgs(interp, 1, args, "mapInfo duplicate name");
- return ZN_ERROR;
- }
- master = LookupMapInfoMaster(interp, Tcl_GetString(args[1]));
- if (master == NULL) {
- return ZN_ERROR;
- }
- if (ZnDuplicateMapInfo(interp, Tcl_GetString(args[3]),
- master->map_info) == ZN_ERROR) {
- return ZN_ERROR;
- }
- }
- break;
+ wi->damaged_area.orig.x = wi->damaged_area.orig.y = wi->inset;
+ wi->damaged_area.corner.x = int_width-wi->inset;
+ wi->damaged_area.corner.y = int_height-wi->inset;
+#endif
+
/*
- * add/replace
+ * Clear the GL buffers.
*/
- case ZN_MI_ADD:
- case ZN_MI_REPLACE:
- {
- MapInfoLineStyle line_style;
- MapInfoTextStyle text_style;
- int i, insert;
- int coords[6];
- ZnBool add_cmd = (enum sub_cmds) index == ZN_MI_ADD;
- int num_param = add_cmd ? 4 : 5;
-
- if (argc < num_param) {
- Tcl_WrongNumArgs(interp, 3, args,
- add_cmd ? "elementType ?args?" : "elementType index ?args?");
- return ZN_ERROR;
- }
- master = LookupMapInfoMaster(interp, Tcl_GetString(args[1]));
- if (master == NULL) {
- return ZN_ERROR;
- }
- if (!add_cmd) {
- if (Tcl_GetIntFromObj(interp, args[4], &insert) == ZN_ERROR) {
- return ZN_ERROR;
- }
- if (insert < 0) {
- insert = 0;
- }
- }
- if (Tcl_GetIndexFromObj(interp, args[3], e_type_strings,
- "elementType", 0, &index2) != ZN_OK) {
- return ZN_ERROR;
- }
- switch ((enum e_types) index2) {
- case ZN_E_LINE:
- {
- if (argc != (num_param+6)) {
- Tcl_WrongNumArgs(interp, 4, args,
- add_cmd ? "style width x1 y1 x2 y2" : "index style width x1 y1 x2 y2");
- return ZN_ERROR;
- }
- if (MapInfoLineStyleFromString(interp, Tcl_GetString(args[num_param]),
- &line_style) == ZN_ERROR) {
- return ZN_ERROR;
- }
- for (i = 0; i < 5; i++) {
- if (Tcl_GetIntFromObj(interp, args[num_param+i+1], &coords[i]) == ZN_ERROR) {
- return ZN_ERROR;
- }
- }
- if (coords[0] < 0) {
- coords[0] = 0;
- }
- if (add_cmd) {
- MapInfoAddLine(master->map_info, ZnListTail, NULL, line_style,
- coords[0], coords[1], coords[2], coords[3], coords[4]);
- }
- else {
- MapInfoReplaceLine(master->map_info, insert, NULL, line_style,
- coords[0], coords[1], coords[2], coords[3], coords[4]);
- }
- }
- break;
- case ZN_E_SYMBOL:
- {
- if (argc != (num_param+3)) {
- Tcl_WrongNumArgs(interp, 4, args,
- add_cmd ? "x y intVal" : "index x y intVal");
- return ZN_ERROR;
- }
- for (i = 0; i < 3; i++) {
- if (Tcl_GetIntFromObj(interp, args[num_param+i], &coords[i]) == ZN_ERROR) {
- return ZN_ERROR;
- }
- }
- if (coords[2] < 0) {
- coords[2] = 0;
- }
- if (add_cmd) {
- MapInfoAddSymbol(master->map_info, ZnListTail, NULL, coords[0],
- coords[1], coords[2]);
- }
- else {
- MapInfoReplaceSymbol(master->map_info, insert, NULL, coords[0],
- coords[1], coords[2]);
- }
- }
- break;
- case ZN_E_TEXT:
- {
- if (argc != (num_param+5)) {
- Tcl_WrongNumArgs(interp, 4, args,
- add_cmd ? "textStyle lineStyle x y string" : "index textStyle lineStyle x y string");
- return ZN_ERROR;
- }
- if (MapInfoTextStyleFromString(interp, Tcl_GetString(args[num_param]),
- &text_style) == ZN_ERROR) {
- return ZN_ERROR;
- }
- if (MapInfoLineStyleFromString(interp, Tcl_GetString(args[num_param+1]),
- &line_style) == ZN_ERROR) {
- return ZN_ERROR;
- }
- for (i = 0; i < 2; i++) {
- if (Tcl_GetIntFromObj(interp, args[num_param+i+2], &coords[i]) == ZN_ERROR) {
- return ZN_ERROR;
- }
- }
- if (add_cmd) {
- MapInfoAddText(master->map_info, ZnListTail, NULL, text_style,
- line_style, coords[0], coords[1],
- Tcl_GetString(args[num_param+4]));
- }
- else {
- /*printf("replace text ts %d ls %d %d %d %s\n", text_style,
- line_style, coords[0], coords[1], Tcl_GetString(args[num_param+4]));*/
- MapInfoReplaceText(master->map_info, insert, NULL, text_style,
- line_style, coords[0], coords[1],
- Tcl_GetString(args[num_param+4]));
- }
- }
- break;
- case ZN_E_ARC:
- {
- if (argc != (num_param+7)) {
- Tcl_WrongNumArgs(interp, 4, args,
- add_cmd ? "style width cx cy radius start extent" : "index style width cx cy radius start extent");
- return ZN_ERROR;
- }
- if (MapInfoLineStyleFromString(interp, Tcl_GetString(args[num_param]),
- &line_style) == ZN_ERROR) {
- return ZN_ERROR;
- }
- for (i = 0; i < 6; i++) {
- if (Tcl_GetIntFromObj(interp, args[num_param+i+1], &coords[i]) == ZN_ERROR) {
- return ZN_ERROR;
- }
- }
- if (coords[0] < 0) {
- coords[0] = 0;
- }
- if (add_cmd) {
- MapInfoAddArc(master->map_info, ZnListTail, NULL, line_style,
- coords[0], coords[1], coords[2], coords[3], coords[4],
- coords[5]);
- }
- else {
- MapInfoReplaceArc(master->map_info, insert, NULL, line_style, coords[0],
- coords[1], coords[2], coords[3], coords[4], coords[5]);
- }
- }
- break;
- }
- UpdateMapInfoClients(master);
- }
- break;
+ glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
/*
- * count
+ * Setup the background tile if needed.
*/
- case ZN_MI_COUNT:
- {
- int count = 0;
- if (argc != 4) {
- Tcl_WrongNumArgs(interp, 1, args, "mapInfo count type");
- return ZN_ERROR;
- }
- master = LookupMapInfoMaster(interp, Tcl_GetString(args[1]));
- if (master == NULL) {
- return ZN_ERROR;
- }
- if (Tcl_GetIndexFromObj(interp, args[3], e_type_strings,
- "elementType", 0, &index2) != ZN_OK) {
- return ZN_ERROR;
- }
- switch ((enum e_types) index2) {
- case ZN_E_LINE:
- count = MapInfoNumLines(master->map_info);
- break;
- case ZN_E_SYMBOL:
- count = MapInfoNumSymbols(master->map_info);
- break;
- case ZN_E_TEXT:
- count = MapInfoNumTexts(master->map_info);
- break;
- case ZN_E_ARC:
- count = MapInfoNumArcs(master->map_info);
- break;
- }
- l = Tcl_NewIntObj(count);
- Tcl_SetObjResult(interp, l);
+ if (wi->tile != ZnUnspecifiedImage) {
+ ZnBBox bbox;
+
+ bbox.orig.x = bbox.orig.y = 0.0;
+ bbox.corner.x = int_width;
+ bbox.corner.y = int_height;
+
+ RenderTile(wi, GetImageTexture(wi->win, wi->tile_name, wi->tile),
+ NULL, NULL, NULL, (ZnPoint *) &bbox);
}
- break;
- /*
- * get
- */
- case ZN_MI_GET:
- {
- int insert;
- if (argc != 5) {
- Tcl_WrongNumArgs(interp, 1, args, "mapInfo get type index");
- return ZN_ERROR;
- }
- master = LookupMapInfoMaster(interp, Tcl_GetString(args[1]));
- if (master == NULL) {
- return ZN_ERROR;
- }
- if (Tcl_GetIntFromObj(interp, args[4], &insert) == ZN_ERROR) {
- return ZN_ERROR;
- }
- if (insert < 0) {
- insert = 0;
- }
- if (Tcl_GetIndexFromObj(interp, args[3], e_type_strings,
- "elementType", 0, &index2) != ZN_OK) {
- return ZN_ERROR;
- }
- switch ((enum e_types) index2) {
- case ZN_E_LINE:
- {
- MapInfoLineStyle line_style;
- int line_width;
- int x_from, y_from, x_to, y_to;
- MapInfoGetLine(master->map_info, insert, NULL, &line_style,
- &line_width, &x_from, &y_from, &x_to, &y_to);
- l = Tcl_GetObjResult(interp);
- Tcl_ListObjAppendElement(interp, l, NewStringObj(MapInfoLineStyleToString(line_style)));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(line_width));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(x_from));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(y_from));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(x_to));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(y_to));
- }
- break;
- case ZN_E_SYMBOL:
- {
- int x, y;
- char symbol;
- MapInfoGetSymbol(master->map_info, insert, NULL, &x, &y, &symbol);
- l = Tcl_GetObjResult(interp);
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(x));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(y));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(symbol));
- }
- break;
- case ZN_E_TEXT:
- {
- int x, y;
- char *text;
- MapInfoTextStyle text_style;
- MapInfoLineStyle line_style;
- MapInfoGetText(master->map_info, insert, NULL, &text_style, &line_style,
- &x, &y, &text);
- l = Tcl_GetObjResult(interp);
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(x));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(y));
- Tcl_ListObjAppendElement(interp, l, NewStringObj(MapInfoTextStyleToString(text_style)));
- Tcl_ListObjAppendElement(interp, l, NewStringObj(MapInfoLineStyleToString(line_style)));
- Tcl_ListObjAppendElement(interp, l, NewStringObj(text));
- }
- break;
- case ZN_E_ARC:
- {
- MapInfoLineStyle line_style;
- int line_width;
- int center_x, center_y, start, extent;
- unsigned int radius;
- MapInfoGetArc(master->map_info, insert, NULL, &line_style, &line_width,
- &center_x, &center_y, &radius, &start, &extent);
- l = Tcl_GetObjResult(interp);
- Tcl_ListObjAppendElement(interp, l, NewStringObj(MapInfoLineStyleToString(line_style)));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(line_width));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(center_x));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(center_y));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(radius));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(start));
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(extent));
- }
- break;
+
+ wi->top_group->class->Render(wi->top_group);
+
+ if ((wi->border_width > 0) || (wi->highlight_width > 0)) {
+ int alpha;
+
+#ifdef GLX_DAMAGE
+ glDisable(GL_SCISSOR_TEST);
+#endif
+ if (wi->highlight_width > 0) {
+ color = ZnGetGradientColor(wi->got_focus?wi->highlight_color:
+ wi->highlight_bg_color, 0, &alpha);
+ alpha = ZnComposeAlpha(alpha, 100);
+ glColor4us(color->red, color->green, color->blue, alpha);
+
+ glBegin(GL_QUAD_STRIP);
+ glVertex2f(0.0, 0.0);
+ glVertex2f(wi->highlight_width, wi->highlight_width);
+ glVertex2f(int_width, 0);
+ glVertex2f(int_width - wi->highlight_width, wi->highlight_width);
+ glVertex2f(int_width, int_height);
+ glVertex2f(int_width - wi->highlight_width, int_height - wi->highlight_width);
+ glVertex2f(0, int_height);
+ glVertex2f(wi->highlight_width, int_height - wi->highlight_width);
+ glVertex2f(0, 0);
+ glVertex2f(wi->highlight_width, wi->highlight_width);
+ glEnd();
+ }
+ if (wi->border_width > 0) {
+ ZnPoint p[5];
+
+ p[4].x = p[4].y = p[3].y = p[1].x = wi->highlight_width;
+ p[0] = p[4];
+ p[3].x = p[2].x = int_width - wi->highlight_width;
+ p[2].y = p[1].y = int_height - wi->highlight_width;
+ RenderPolygonRelief(wi, wi->relief, wi->relief_grad,
+ False, p, 5, wi->border_width);
}
+#ifdef GLX_DAMAGE
+ glEnable(GL_SCISSOR_TEST);
+#endif
}
- break;
+ /* Switch the GL buffers. */
+ glXSwapBuffers(wi->dpy, ZnWindowId(wi->win));
+ glFlush();
+
/*
- * remove
+ * Wait the end of GL update if we need to synchronize
+ * to monitor perfs.
*/
- case ZN_MI_REMOVE:
- {
- int insert;
- if (argc != 5) {
- Tcl_WrongNumArgs(interp, 1, args, "mapInfo remove type index");
- return ZN_ERROR;
- }
- master = LookupMapInfoMaster(interp, Tcl_GetString(args[1]));
- if (master == NULL) {
- return ZN_ERROR;
- }
- if (Tcl_GetIntFromObj(interp, args[4], &insert) == ZN_ERROR) {
- return ZN_ERROR;
- }
- if (insert < 0) {
- insert = 0;
- }
- if (Tcl_GetIndexFromObj(interp, args[3], e_type_strings,
- "elementType", 0, &index2) != ZN_OK) {
- return ZN_ERROR;
- }
- switch ((enum e_types) index2) {
- case ZN_E_LINE:
- MapInfoRemoveLine(master->map_info, insert);
- break;
- case ZN_E_SYMBOL:
- MapInfoRemoveSymbol(master->map_info, insert);
- break;
- case ZN_E_TEXT:
- MapInfoRemoveText(master->map_info, insert);
- break;
- case ZN_E_ARC:
- MapInfoRemoveArc(master->map_info, insert);
- break;
- }
- UpdateMapInfoClients(master);
+ if (wi->monitoring) {
+ glXWaitGL();
}
- break;
+#endif
+ }
+ else {
+ XRectangle r;
+ ZnBBox merge;
+
+ ClampDamageArea(wi);
/*
- * scale
+ * Merge the damaged area with the exposed area.
*/
- case ZN_MI_SCALE:
- {
- double factor;
+ ResetBBox(&merge);
+ CopyBBox(&wi->damaged_area, &merge);
+ AddBBoxToBBox(&merge, &wi->exposed_area);
+ if (!IsEmptyBBox(&merge)) {
- if (argc != 4) {
- Tcl_WrongNumArgs(interp, 1, args, "mapInfo scale factor");
- return ZN_ERROR;
- }
- master = LookupMapInfoMaster(interp, Tcl_GetString(args[1]));
- if (master == NULL) {
- return ZN_ERROR;
- }
- if (Tcl_GetDoubleFromObj(interp, args[3], &factor) == ZN_ERROR) {
- return ZN_ERROR;
+ /* Set the whole damaged area as clip rect. */
+ wi->damaged_area.orig.x = r.x = REAL_TO_INT(wi->damaged_area.orig.x);
+ wi->damaged_area.orig.y = r.y = REAL_TO_INT(wi->damaged_area.orig.y);
+ wi->damaged_area.corner.x = REAL_TO_INT(wi->damaged_area.corner.x);
+ wi->damaged_area.corner.y = REAL_TO_INT(wi->damaged_area.corner.y);
+ r.width = wi->damaged_area.corner.x - wi->damaged_area.orig.x;
+ r.height = wi->damaged_area.corner.y - wi->damaged_area.orig.y;
+ pts[0] = wi->damaged_area.orig;
+ pts[1] = wi->damaged_area.corner;
+ TRI_STRIP1(&tristrip, pts, 2);
+ ZnPushClip(wi, &tristrip, True, True);
+
+ /* Fill the background of the double buffer pixmap. */
+ if (wi->tile == ZnUnspecifiedImage) {
+ values.foreground = ZnPixel(ZnGetGradientColor(wi->back_color, 0, NULL));
+ values.fill_style = FillSolid;
+ XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCForeground, &values);
}
- MapInfoScale(master->map_info, factor);
- UpdateMapInfoClients(master);
+ else {
+ values.fill_style = FillTiled;
+ values.tile = GetImagePixmap(wi->win, wi->tile_name, wi->tile, NULL);
+ values.ts_x_origin = values.ts_y_origin = 0;
+ XChangeGC(wi->dpy, wi->gc,
+ GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin,
+ &values);
+ }
+ /*printf("Repair : filling rectangle: %d %d %d %d\n", r.x, r.y, r.width, r.height);*/
+ XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, r.width, r.height);
+
+ /* Draw the items */
+ /*printf("Drawing\n");*/
+ wi->top_group->class->Draw(wi->top_group);
+
+ ZnPopClip(wi, True);
+
+ /*
+ * Send the merged area back to screen.
+ */
+ merge.orig.x = MAX(merge.orig.x, wi->inset);
+ merge.orig.y = MAX(merge.orig.y, wi->inset);
+ merge.corner.x = MIN(merge.corner.x, int_width-wi->inset);
+ merge.corner.y = MIN(merge.corner.y, int_height-wi->inset);
+ BBox2XRect(&merge, &r);
+ XCopyArea(wi->dpy,
+ wi->draw_buffer, ZnWindowId(wi->win), wi->gc,
+ r.x, r.y, r.width, r.height, r.x, r.y);
}
- break;
+
/*
- * translate
+ * Redraw the borders.
*/
- case ZN_MI_TRANSLATE:
- {
- int x, y;
+ if (wi->border_width > 0) {
+ Pixmap save;
+ XRectangle r;
- if (argc != 5) {
- Tcl_WrongNumArgs(interp, 1, args, "mapInfo translate xAmount yAmount");
- return ZN_ERROR;
- }
- master = LookupMapInfoMaster(interp, Tcl_GetString(args[1]));
- if (master == NULL) {
- return ZN_ERROR;
- }
- if (Tcl_GetIntFromObj(interp, args[3], &x) == ZN_ERROR) {
- return ZN_ERROR;
- }
- if (Tcl_GetIntFromObj(interp, args[4], &y) == ZN_ERROR) {
- return ZN_ERROR;
- }
- MapInfoTranslate(master->map_info, x, y);
- UpdateMapInfoClients(master);
+ save = wi->draw_buffer;
+ wi->draw_buffer = ZnWindowId(wi->win);
+ r.x = r.y = wi->highlight_width;
+ r.width = int_width - 2*wi->highlight_width;
+ r.height = int_height - 2*wi->highlight_width;
+ DrawRectangleRelief(wi, wi->relief, wi->relief_grad,
+ &r, wi->border_width);
+ wi->draw_buffer = save;
+ }
+ if (wi->highlight_width > 0) {
+ XRectangle r[4];
+
+ XSetForeground(wi->dpy, wi->gc,
+ ZnPixel(ZnGetGradientColor(wi->got_focus?wi->highlight_color:
+ wi->highlight_bg_color, 0, NULL)));
+ XSetFillStyle(wi->dpy, wi->gc, FillSolid);
+ r[0].x = r[0].y = 0;
+ r[0].width = int_width;
+ r[0].height = wi->highlight_width;
+ r[1].x = int_width - wi->highlight_width;
+ r[1].y = 0;
+ r[1].width = wi->highlight_width;
+ r[1].height = int_height;
+ r[2].x = 0;
+ r[2].y = int_height - wi->highlight_width;
+ r[2].width = int_width;
+ r[2].height = wi->highlight_width;
+ r[3].x = r[3].y = 0;
+ r[3].width = wi->highlight_width;
+ r[3].height = int_height;
+ XFillRectangles(wi->dpy, ZnWindowId(wi->win), wi->gc, r, 4);
}
- break;
}
-
- return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
- * VideomapObjCmd --
+ * Redisplay --
+ *
+ * This procedure redraws the contents of a Zinc window.
+ * It is invoked as a do-when-idle handler, so it only runs
+ * when there's nothing else for the application to do.
+ *
+ * Results:
+ * None.
*
+ * Side effects:
+ * Information appears on the screen.
*
*----------------------------------------------------------------------
*/
-int
-VideomapObjCmd(ClientData client_data,
- Tcl_Interp *interp, /* Current interpreter. */
- int argc, /* Number of arguments. */
- Tcl_Obj *CONST args[])
+
+static void
+Redisplay(ClientData client_data) /* Information about the widget. */
{
- ZnList ids;
- int index;
- int *id_array, id_num, i;
- Tcl_Obj *l;
- static char *sub_cmd_strings[] = {
- "ids", "load", NULL
- };
- enum sub_cmds {
- ZN_V_IDS, ZN_V_LOAD
- };
-
- if (!inited) {
- InitZinc(interp);
- }
+ WidgetInfo *wi = (WidgetInfo *) client_data;
- if (argc < 2) {
- Tcl_WrongNumArgs(interp, 1, args, "?subCmd? filename $args?");
- return ZN_ERROR;
+ wi->update_pending = 0;
+ if (!wi->realized || !Tk_IsMapped(wi->win)) {
+ return;
}
- if (Tcl_GetIndexFromObj(interp, args[1], sub_cmd_strings,
- "subCmd", 0, &index) != ZN_OK) {
- return ZN_ERROR;
+ if (wi->monitoring) {
+ XStartChrono(wi->total_draw_chrono, wi->dpy, ZnWindowId(wi->win));
+ ResetChronos(wi->this_draw_chrono);
+ XStartChrono(wi->this_draw_chrono, wi->dpy, ZnWindowId(wi->win));
}
-
- switch((enum sub_cmds) index) {
+
+ do {
/*
- * ids
+ * Update the items.
+ * NOTE: See above.
*/
- case ZN_V_IDS:
- {
- if (argc != 3) {
- Tcl_WrongNumArgs(interp, 1, args,"ids filename");
- return ZN_ERROR;
- }
- ids = MapInfoVideomapIds(Tcl_GetString(args[2]));
- if (ids == NULL) {
- Tcl_AppendResult(interp, "unable to look at videomap file \"",
- Tcl_GetString(args[2]), "\"", NULL);
- return ZN_ERROR;
- }
- id_array = (int *) ZnListArray(ids);
- id_num = ZnListSize(ids);
- l = Tcl_GetObjResult(interp);
- for (i = 0; i < id_num; i++) {
- Tcl_ListObjAppendElement(interp, l, Tcl_NewIntObj(id_array[i]));
- }
- ZnListFree(ids);
- }
- break;
+ Update(wi);
+
/*
- * load
+ * Do enter/leave processing after the overlap manager
+ * has finished with the items. Do it has many times
+ * as needed, each round may trigger callbacks that
+ * result in moved items and so forth. It can even
+ * lead to the widget destruction, this is the reason
+ * for Tcl_Preserve/Tcl_Release.
*/
- case ZN_V_LOAD:
- {
- MapInfoId map_info;
- int insert;
-
- if (argc != 5) {
- Tcl_WrongNumArgs(interp, 1, args, "load filename index mapInfo");
- return ZN_ERROR;
- }
- if (Tcl_GetIntFromObj(interp, args[3], &insert) == ZN_ERROR) {
- return ZN_ERROR;
- }
- if (insert < 0) {
- insert = 0;
- }
- if (ZnCreateMapInfo(interp, Tcl_GetString(args[4]), &map_info) == ZN_ERROR) {
- return ZN_ERROR;
- }
- if (MapInfoGetVideomap(map_info, Tcl_GetString(args[2]), insert) == ZN_ERROR) {
- Tcl_AppendResult(interp, "unable to load videomap file \"",
- Tcl_GetString(args[2]), ":",
- Tcl_GetString(args[3]), "\"", NULL);
- return ZN_ERROR;
+ if (ISSET(wi->events_flags, INTERNAL_NEED_REPICK)) {
+ Tk_Window tkwin;
+
+ Tcl_Preserve((ClientData) wi);
+ CLEAR(wi->events_flags, INTERNAL_NEED_REPICK);
+ PickCurrentItem(wi, &wi->pick_event);
+ tkwin = wi->win;
+ Tcl_Release((ClientData) wi);
+ if (tkwin == NULL) {
+ return;
}
- ZnUpdateMapInfoClients(map_info);
}
- break;
}
+ while (ISSET(wi->top_group->inv_flags, ZN_COORDS_FLAG) ||
+ ISSET(wi->top_group->inv_flags, ZN_TRANSFO_FLAG) ||
+ ISSET(wi->events_flags, INTERNAL_NEED_REPICK));
- return TCL_OK;
+ /*
+ * Repair the scene where it is no longer up to date,
+ * then send the merged area back to the screen.
+ */
+ Repair(wi);
+
+ /*
+ * Reset the exposed & damaged areas.
+ */
+ ResetBBox(&wi->exposed_area);
+ ResetBBox(&wi->damaged_area);
+
+ if (wi->monitoring) {
+ XStopChrono(wi->total_draw_chrono, wi->dpy, ZnWindowId(wi->win));
+ XStopChrono(wi->this_draw_chrono, wi->dpy, ZnWindowId(wi->win));
+ }
}
static void
InitZinc(Tcl_Interp *interp) {
+ static ZnBool inited = False;
unsigned int i, x, y, bit;
char name[INTEGER_SPACE + 20];
+ if (inited) {
+ return;
+ }
+
/*
* Add the specific bitmaps.
*/
@@ -6498,7 +6146,7 @@ InitZinc(Tcl_Interp *interp) {
/*
* Initialize the item module.
*/
- ITEM_P.GlobalModuleInit();
+ ZnItemInit();
all_uid = Tk_GetUid("all");
current_uid = Tk_GetUid("current");