From 1778a7f3b1917fceb8bc6b5d48a5548d4e1ee7b9 Mon Sep 17 00:00:00 2001 From: Joel Bodenmann Date: Sun, 5 Jan 2014 20:42:19 +0100 Subject: [PATCH] gwinDestroy() and gwinRemoveChild() --- include/gwin/gwin.h | 22 +++++++++++++++++--- src/gwin/gwin.c | 50 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/include/gwin/gwin.h b/include/gwin/gwin.h index ded401d0..73f7ff82 100644 --- a/include/gwin/gwin.h +++ b/include/gwin/gwin.h @@ -389,14 +389,26 @@ extern "C" { /** * @brief Add a child widget to a parent one * - * @param[in] parent The parent widget (does not need to be parent yet) - * @param[in] child The child widget - * @param[in] last Should the child widget be added to the front or the back of the list? + * @param[in] parent The parent window (does not need to be parent yet) + * @param[in] child The child window + * @param[in] last Should the child window be added to the front or the back of the list? * * @api */ void gwinAddChild(GHandle parent, GHandle child, bool_t last); + /** + * @brief Remove a child from a parent + * + * @note Other children of the same parent stay + * @note Children of the child are lost, they have to be reassigned manually if necessary. + * + * @param[in] child The child window + * + * @api + */ + void gwinRemoveChild(GHandle child); + /** * @brief Get first child of a widget * @@ -882,6 +894,10 @@ extern "C" { #include "gwin/image.h" #endif + #if GWIN_NEED_LAYOUT || defined(__DOXYGEN__) + #include "gwin/layout.h" + #endif + #endif /* GFX_USE_GWIN */ #endif /* _GWIN_H */ diff --git a/src/gwin/gwin.c b/src/gwin/gwin.c index 88be0c88..923567ef 100644 --- a/src/gwin/gwin.c +++ b/src/gwin/gwin.c @@ -180,18 +180,20 @@ GHandle gwinGWindowCreate(GDisplay *g, GWindowObject *pgw, const GWindowInit *pI } void gwinDestroy(GHandle gh) { + if (!gh) { + // should log a runtime error here + return; + } + #if GWIN_NEED_HIERARCHY - // fix hierarchy structure - if (gh->parent->child == gh) { - // we are the first child - gh->parent->child = gh->sibling; - } else { - // find our predecessor - GHandle tmp = gh->parent->child; - while (tmp->sibling != gh) - tmp = tmp->sibling; - tmp->sibling = gh->sibling; - } + GHandle tmp; + + // recursively destroy our children first + for(tmp = gh->child; tmp; tmp = tmp->sibling) + gwinDestroy(tmp); + + // remove myself from the hierarchy + gwinRemoveChild(gh); #endif // Make the window invisible @@ -332,6 +334,32 @@ void gwinRedraw(GHandle gh) { gwinRedraw(parent); } + void gwinRemoveChild(GHandle gh) { + if(!gh || !gh->parent) { + // without a parent, removing is impossible + // should log a runtime error here + return; + } + + if (gh->parent->child == gh) { + // we are the first child, update parent + gh->parent->child = gh->sibling; + } else { + // otherwise find our predecessor + GHandle tmp = gh->parent->child; + while (tmp && tmp->sibling != gh) + tmp = tmp->sibling; + + if(!tmp) { + // our parent's children list is corrupted + // should log a runtime error here + return; + } + + tmp->sibling = gh->sibling; + } + } + GHandle gwinGetFirstChild(GHandle gh) { return gh->child; }