aboutsummaryrefslogtreecommitdiff
path: root/generic/Group.c
diff options
context:
space:
mode:
authorlecoanet2002-04-08 13:49:24 +0000
committerlecoanet2002-04-08 13:49:24 +0000
commit44baea907f896bee5c086228c6cd4885378beb6d (patch)
tree3b7da07275b3c06ab74cdbca7407f4d358014539 /generic/Group.c
parent737920a9203af23d93d9c8352737b93651392776 (diff)
downloadtkzinc-44baea907f896bee5c086228c6cd4885378beb6d.zip
tkzinc-44baea907f896bee5c086228c6cd4885378beb6d.tar.gz
tkzinc-44baea907f896bee5c086228c6cd4885378beb6d.tar.bz2
tkzinc-44baea907f896bee5c086228c6cd4885378beb6d.tar.xz
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.
Diffstat (limited to 'generic/Group.c')
-rw-r--r--generic/Group.c329
1 files 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;
+ }
+ }
+}
+
+
/*
**********************************************************************************
*