From: NeilBrown Date: Sun, 13 Dec 2015 04:13:19 +0000 (+1100) Subject: Add global 'z' level. X-Git-Tag: lca2016~41 X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=4c0d80a3cc4fdbbcf584edde206fd1e3ba3ef1ad;p=edlib.git Add global 'z' level. 'abs_z' can be compared between pane to determine global z order. Signed-off-by: NeilBrown --- diff --git a/core-pane.c b/core-pane.c index a1bf339b..2d541c26 100644 --- a/core-pane.c +++ b/core-pane.c @@ -99,6 +99,10 @@ struct pane *pane_register(struct pane *parent, int z, return p; } +/* 'abs_z' is a global z-depth number. + * 'abs_z' of root is 0, and abs_z of every other pane is 1 more than abs_zhi + * of siblings with lower 'z', or same as parent if no such siblings. + */ static void __pane_refresh(struct cmd_info ci) { struct pane *c; @@ -106,9 +110,12 @@ static void __pane_refresh(struct cmd_info ci) struct pane *p = ci.home; int ret = 0; int nextz; + int abs_z = p->abs_z; - if (p->damaged & DAMAGED_CLOSED) + if (p->damaged & DAMAGED_CLOSED) { + p->abs_zhi = abs_z; return; + } if (p->focus == NULL) p->focus = list_first_entry_or_null( @@ -119,9 +126,7 @@ static void __pane_refresh(struct cmd_info ci) damage |= p->damaged; if (!damage) return; - if (damage == DAMAGED_CHILD) - damage = 0; - else { + if (damage & (DAMAGED_NEED_CALL)) { struct cmd_info ci2 = ci; ci2.extra = damage; if (ci2.extra & DAMAGED_SIZE) @@ -133,21 +138,31 @@ static void __pane_refresh(struct cmd_info ci) ret = p->handle->func(&ci2); if (ret == 0) pane_check_size(p); - } + } else + damage = 0; p->damaged = 0; ci.extra = damage; nextz = 0; while (nextz >= 0) { int z = nextz; + int abs_zhi = abs_z; nextz = -1; list_for_each_entry(c, &p->children, siblings) { if (c->z > z && (nextz == -1 || c->z < nextz)) nextz = c->z; if (c->z == z) { + if (c->abs_z != abs_z) { + c->abs_z = abs_z; + c->damaged |= DAMAGED_Z; + } ci.home = c; __pane_refresh(ci); + if (c->abs_zhi > abs_zhi) + abs_zhi = c->abs_zhi; } } + p->abs_zhi = abs_zhi; + abs_z = abs_zhi + 1; } if (ret == 2) { /* "Refresh" requested a post-order call */ @@ -162,9 +177,10 @@ void pane_refresh(struct pane *p) { struct cmd_info ci = {0}; pane_damaged(p, DAMAGED_CURSOR); - /* Always refresh a while display */ + /* Always refresh a whole display */ while (p->parent) p = p->parent; + p->abs_z = 0; ci.focus = ci.home = p; ci.key = "Refresh"; __pane_refresh(ci); diff --git a/core.h b/core.h index c7cf6210..08aeb8ca 100644 --- a/core.h +++ b/core.h @@ -48,6 +48,7 @@ struct pane { int h,w; struct pane *focus; int cx, cy; /* cursor position */ + int abs_z, abs_zhi; /* 'hi' is the max of all children */ int damaged; @@ -320,7 +321,10 @@ enum { DAMAGED_CLOSED = 1024, DAMAGED_EVENTS = 2048, /* event loop changed, resubmit requests */ + DAMAGED_Z = 4096, /* global-z has changed */ }; +#define DAMAGED_NEED_CALL (DAMAGED_SIZE | DAMAGED_CONTENT | DAMAGED_CURSOR \ + | DAMAGED_EVENTS) struct pane *pane_register(struct pane *parent, int z, struct command *handle, void *data, diff --git a/lang-python.c b/lang-python.c index 39e7f228..7935cfcb 100644 --- a/lang-python.c +++ b/lang-python.c @@ -444,6 +444,7 @@ static PyObject *pane_getnum(Pane *p, char *which) case 'X': n = p->pane->cx; break; case 'Y': n = p->pane->cy; break; case 'z': n = p->pane->z; break; + case 'Z': n = p->pane->abs_z; break; } return PyInt_FromLong(n); } @@ -461,6 +462,10 @@ static int pane_setnum(Pane *p, PyObject *v, char *which) PyErr_SetString(PyExc_TypeError, "z cannot be set"); return -1; } + if (*which == 'Z') { + PyErr_SetString(PyExc_TypeError, "abs_z cannot be set"); + return -1; + } val = PyInt_AsLong(v); if (val == -1 && PyErr_Occurred()) return -1; @@ -540,6 +545,9 @@ static PyGetSetDef pane_getseters[] = { {"cy", (getter)pane_getnum, (setter)pane_setnum, "Cursor Y offset in pane", "Y" }, + {"abs_z", + (getter)pane_getnum, (setter)pane_setnum, + "global Z offset", "Z" }, {"parent", (getter)pane_getpane, (setter)pane_nosetpane, "Parent pane", "p"},