From 44baea907f896bee5c086228c6cd4885378beb6d Mon Sep 17 00:00:00 2001 From: lecoanet Date: Mon, 8 Apr 2002 13:49:24 +0000 Subject: Restructuration de Item.c. Group a r�cup�r� tout le code manipulant son �tat interne, principalement la display list, la liste des d�pendants. Il exporte des fonctions permettant l'acc�s � certaines donn�es en lecture. --- generic/Group.c | 329 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 313 insertions(+), 16 deletions(-) diff --git a/generic/Group.c b/generic/Group.c index 73df941..db9aecc 100644 --- a/generic/Group.c +++ b/generic/Group.c @@ -30,6 +30,7 @@ #include "Types.h" #include "WidgetInfo.h" #include "Item.h" +#include "Group.h" #include "Geo.h" #include "tkZinc.h" @@ -41,6 +42,30 @@ static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " /* + * Group item special record. + */ +typedef struct _GroupItemStruct { + ItemStruct header; + + /* Public data */ + Item clip; + unsigned char alpha; + + /* Private data */ + Item head; /* Doubly linked list of all items. */ + Item tail; + ZnList dependents; /* List of dependent items. */ +#ifdef OM + /* Overlap manager variables. + * These variables are valid *only* if the overlap + * manager is active. */ + ZnBool call_om; /* Tell if there is a need to call the */ + /* overlap manager. */ +#endif +} GroupItemStruct, *GroupItem; + + +/* ********************************************************************************** * * Specific Group item record @@ -186,7 +211,7 @@ Clone(Item item) /*printf("item %d correspond to ", current_item->connected_item->id);*/ current_item->connected_item = (Item) Tcl_GetHashValue(entry); /*printf("%d\n", current_item->connected_item->id);*/ - ITEM.InsertDependentItem(current_item); + ZnInsertDependentItem(current_item); } } Tcl_DeleteHashTable(&mapping); @@ -387,7 +412,7 @@ Configure(Item item, GroupItem group = (GroupItem) item; WidgetInfo *wi = item->wi; - if (ITEM_P.ConfigureAttributes((char *) item, -1, argc, argv, flags) == ZN_ERROR) { + if (ZnConfigureAttributes(wi, item, group_attrs, argc, argv, flags) == ZN_ERROR) { return ZN_ERROR; } @@ -424,7 +449,7 @@ Query(Item item, int argc, Tcl_Obj *CONST argv[]) { - if (ITEM_P.QueryAttribute((char *) item, -1, argv[0]) == ZN_ERROR) { + if (ZnQueryAttribute(item->wi, item, group_attrs, argv[0]) == ZN_ERROR) { return ZN_ERROR; } @@ -455,7 +480,7 @@ PushClip(GroupItem group, ((((Item) group) != wi->top_group) || !wi->reshape)) { simple = group->clip->class->GetClipVertices(group->clip, &tristrip); /*printf("Group: PushClip group %d\n", ((Item) group)->id);*/ - ITEM_P.PushClip(wi, &tristrip, simple, set_gc); + ZnPushClip(wi, &tristrip, simple, set_gc); } } @@ -477,7 +502,7 @@ PopClip(GroupItem group, if ((group->clip != ZN_NO_ITEM) && ((((Item) group) != wi->top_group) || !wi->reshape)) { /*printf("Group: PopClip group %d\n", ((Item) group)->id);*/ - ITEM_P.PopClip(wi, set_gc); + ZnPopClip(wi, set_gc); } } @@ -500,9 +525,9 @@ PushTransform(Item item) return; } - ITEM_P.PushTransform(item->wi, item->transfo, - ISSET(item->flags, COMPOSE_SCALE_BIT), - ISSET(item->flags, COMPOSE_ROTATION_BIT)); + ZnPushTransform(item->wi, item->transfo, + ISSET(item->flags, COMPOSE_SCALE_BIT), + ISSET(item->flags, COMPOSE_ROTATION_BIT)); /*printf("Pushing transfo for item: %d\n;", item->id); ZnPrintTransfo(wi->current_transfo);*/ } @@ -525,7 +550,7 @@ PopTransform(Item item) return; } - ITEM_P.PopTransform(item->wi); + ZnPopTransform(item->wi); /*printf("Popping transfo for item: %d\n", item->id); ZnPrintTransfo(wi->current_transfo);*/ } @@ -553,7 +578,7 @@ CallRegularCC(Item item) * Do some generic pre-work in behalf of the (regular) children. */ if (ISSET(item->flags, VISIBLE_BIT)) { - ITEM_P.Damage(wi, &item->item_bounding_box); + ZnDamage(wi, &item->item_bounding_box); } PushTransform(item); @@ -574,7 +599,7 @@ CallRegularCC(Item item) it partially uncovered the clip area. Have to watch any possible breakage. - if (ITEM_P.CurrentClip(wi, NULL, &clip_box, NULL)) { + if (ZnCurrentClip(wi, NULL, &clip_box, NULL)) { ZnBBox inter; IntersectBBox(&item->item_bounding_box, clip_box, &inter); @@ -597,7 +622,7 @@ CallRegularCC(Item item) */ if (ISSET(item->flags, VISIBLE_BIT) || (item == ((GroupItem) item->parent)->clip)) { - ITEM_P.Damage(wi, &item->item_bounding_box); + ZnDamage(wi, &item->item_bounding_box); } PopTransform(item); item->inv_flags = 0; @@ -790,7 +815,7 @@ ToArea(Item item, } } if (!atomic && (result >= enclosed)) { - DoItem(item->wi->interp, current_item, ZN_NO_PART, tag_uid); + ZnDoItem(item->wi->interp, current_item, ZN_NO_PART, tag_uid); } if (current_item->class != ZnGroup) { @@ -834,7 +859,7 @@ Draw(Item item) PushTransform(item); PushClip(group, True); if (group->clip != ZN_NO_ITEM) { - ITEM_P.CurrentClip(wi, NULL, &clip_box, NULL); + ZnCurrentClip(wi, NULL, &clip_box, NULL); old_damaged_area = wi->damaged_area; IntersectBBox(&wi->damaged_area, clip_box, &bbox); wi->damaged_area = bbox; @@ -908,7 +933,7 @@ Render(Item item) PushClip(group, True); #ifdef GLX_DAMAGE if (group->clip != ZN_NO_ITEM) { - ITEM_P.CurrentClip(wi, NULL, &clip_box, NULL); + ZnCurrentClip(wi, NULL, &clip_box, NULL); old_damaged_area = wi->damaged_area; IntersectBBox(&wi->damaged_area, clip_box, &bbox); wi->damaged_area = bbox; @@ -1024,7 +1049,7 @@ Pick(Item item, bbox.corner.x = p->x + (aperture?aperture:1); bbox.corner.y = p->y + (aperture?aperture:1); - if (ITEM_P.CurrentClip(wi, NULL, &clip_box, NULL)) { + if (ZnCurrentClip(wi, NULL, &clip_box, NULL)) { IntersectBBox(&bbox, clip_box, &inter); if (IsEmptyBBox(&inter)) { goto out; @@ -1045,6 +1070,11 @@ Pick(Item item, } do { + /* + * Sensitive item must be reported even if they are invisible. + * It is legal to fire bindings on invisible sensitive items. + * This is _not_ a bug do _not_ modify the test below. + */ if (ISCLEAR(current_item->flags, SENSITIVE_BIT) && ISCLEAR(current_item->flags, VISIBLE_BIT)) { goto cont; @@ -1157,6 +1187,273 @@ PostScript(Item item, } + +Item +ZnGroupHead(Item group) +{ + if (group->class != ZnGroup) { + return ZN_NO_ITEM; + } + return ((GroupItem) group)->head; +} + +Item +ZnGroupTail(Item group) +{ + if (group->class != ZnGroup) { + return ZN_NO_ITEM; + } + return ((GroupItem) group)->tail; +} + +ZnBool +ZnGroupCallOm(Item group) +{ + if (group->class != ZnGroup) { + return False; + } + return ((GroupItem) group)->call_om; +} + +void +ZnGroupSetCallOm(Item group, + ZnBool set) +{ + if (group->class != ZnGroup) { + return; + } + ((GroupItem) group)->call_om = set; +} + + +void +ZnGroupRemoveClip(Item group, + Item clip) +{ + GroupItem grp = (GroupItem) group; + + if (grp->clip == clip) { + grp->clip = ZN_NO_ITEM; + ITEM.Invalidate(group, ZN_COORDS_FLAG); + } +} + + +/* + ********************************************************************************** + * + * ZnInsertDependentItem -- + * + ********************************************************************************** + */ +void +ZnInsertDependentItem(Item item) +{ + GroupItem group = (GroupItem) item->parent; + + if (!group) { + return; + } + if (!group->dependents) { + group->dependents = ZnListNew(2, sizeof(Item)); + } + ZnListAdd(group->dependents, &item, ZnListTail); +} + + +/* + ********************************************************************************** + * + * ZnExtractDependentItem -- + * + ********************************************************************************** + */ +void +ZnExtractDependentItem(Item item) +{ + GroupItem group = (GroupItem) item->parent; + int index, num_items; + Item *deps; + + if (!group || !group->dependents) { + return; + } + num_items = ZnListSize(group->dependents); + deps = (Item *) ZnListArray(group->dependents); + for (index = 0; index < num_items; index++) { + if (deps[index]->id == item->id) { + ZnListDelete(group->dependents, index); + if (ZnListSize(group->dependents) == 0) { + ZnListFree(group->dependents); + group->dependents = NULL; + break; + } + } + } +} + + +/* + ********************************************************************************** + * + * ZnDisconnectDependentItems -- + * + * + ********************************************************************************** + */ +void +ZnDisconnectDependentItems(Item item) +{ + Item current_item; + GroupItem group = (GroupItem) item->parent; + Item *deps; + int num_deps, i; + + if (!group || !group->dependents) { + return; + } + deps = (Item *) ZnListArray(group->dependents); + num_deps = ZnListSize(group->dependents); + + for (i = num_deps-1; i >= 0; i--) { + current_item = deps[i]; + if (current_item->connected_item == item) { + current_item->connected_item = ZN_NO_ITEM; + ZnListDelete(group->dependents, i); + ITEM.Invalidate(current_item, ZN_COORDS_FLAG); + } + } + if (ZnListSize(group->dependents) == 0) { + ZnListFree(group->dependents); + group->dependents = NULL; + } +} + + +/* + ********************************************************************************** + * + * ZnGroupExtractItem -- + * + ********************************************************************************** + */ +void +ZnGroupExtractItem(Item item) +{ + GroupItem group; + + if (!item->parent) { + return; + } + group = (GroupItem) item->parent; + + if (item->previous != ZN_NO_ITEM) { + item->previous->next = item->next; + } + else { + group->head = item->next; + } + + if (item->next != ZN_NO_ITEM) { + item->next->previous = item->previous; + } + else { + group->tail = item->previous; + } + + item->previous = ZN_NO_ITEM; + item->next = ZN_NO_ITEM; + item->parent = NULL; +} + + +/* + ********************************************************************************** + * + * ZnGroupInsertItem -- + * + ********************************************************************************** + */ +void +ZnGroupInsertItem(Item group, + Item item, + Item mark_item, + ZnBool before) +{ + GroupItem grp = (GroupItem) group; + + /* + * Empty list, add the first item. + */ + if (grp->head == ZN_NO_ITEM) { + grp->head = grp->tail = item; + item->previous = item->next = ZN_NO_ITEM; + return; + } + + if (mark_item != ZN_NO_ITEM) { + /* + * Better leave here, mark_item will not + * have the links set right. + */ + if (mark_item == item) { + return; + } + /* + * Force the priority to be the same as the reference + * item; + */ + item->priority = mark_item->priority; + } + else { + mark_item = grp->head; + while ((mark_item != ZN_NO_ITEM) && + (mark_item->priority > item->priority)) { + mark_item = mark_item->next; + } + before = True; + } + + if (before && (mark_item != ZN_NO_ITEM)) { + /* + * Insert before mark. + */ + item->next = mark_item; + item->previous = mark_item->previous; + if (mark_item->previous == ZN_NO_ITEM) { + grp->head = item; + } + else { + mark_item->previous->next = item; + } + mark_item->previous = item; + } + else { + /* + * Insert after mark either because 'before' is False + * and mark_item valid or because the right place is at + * the end of the list and mark_item is ZN_NO_ITEM. + */ + if (mark_item == ZN_NO_ITEM) { + grp->tail->next = item; + item->previous = grp->tail; + grp->tail = item; + } + else { + item->previous = mark_item; + item->next = mark_item->next; + if (item->next == ZN_NO_ITEM) { + grp->tail = item; + } + else { + item->next->previous = item; + } + mark_item->next = item; + } + } +} + + /* ********************************************************************************** * -- cgit v1.1