diff --git a/common/utils/T/tracer/gui/container.c b/common/utils/T/tracer/gui/container.c index 3dfcef2e2cf307f15c353001ac7378ed6c8d09f5..3ec408ecd7a35aef01039b9e5d638d505f7eee33 100644 --- a/common/utils/T/tracer/gui/container.c +++ b/common/utils/T/tracer/gui/container.c @@ -18,6 +18,7 @@ static void add_child(gui *g, widget *_this, widget *child, int position) { LOGD("ADD_CHILD container\n"); struct container_widget *this = _this; + this->hints_are_valid = 0; widget_add_child_internal(g, this, child, position); @@ -35,6 +36,24 @@ static void add_child(gui *g, widget *_this, widget *child, int position) this->nchildren++; } +static void del_child(gui *g, widget *_this, widget *child) +{ + LOGD("DEL_CHILD container\n"); + struct container_widget *this = _this; + int position = widget_get_child_position(g, _this, child); + + this->hints_are_valid = 0; + widget_del_child_internal(g, this, child); + + memmove(this->growable + position, this->growable + position+1, + (this->nchildren - position - 1) * sizeof(int)); + + this->growable = realloc(this->growable, (this->nchildren-1)*sizeof(int)); + if (this->growable == NULL) abort(); + + this->nchildren--; +} + static void compute_vertical_hints(struct gui *g, struct container_widget *this) { @@ -271,6 +290,7 @@ widget *new_container(gui *_gui, int vertical) w->common.paint = paint; w->common.add_child = add_child; + w->common.del_child = del_child; w->common.repack = repack; if (vertical) { diff --git a/common/utils/T/tracer/gui/gui.h b/common/utils/T/tracer/gui/gui.h index aa89a53c75e89dbc8d25e9c367e4c6a722bf33a6..2561fe6d16cf018d8c43d58fd3e213a3164da2d5 100644 --- a/common/utils/T/tracer/gui/gui.h +++ b/common/utils/T/tracer/gui/gui.h @@ -16,6 +16,7 @@ gui *gui_init(void); /* position = -1 to put at the end */ void widget_add_child(gui *gui, widget *parent, widget *child, int position); +void widget_del_child(gui *gui, widget *parent, widget *child); void widget_dirty(gui *gui, widget *this); widget *new_toplevel_window(gui *gui, int width, int height, char *title); diff --git a/common/utils/T/tracer/gui/gui_defs.h b/common/utils/T/tracer/gui/gui_defs.h index afc590c7be1bb7f6310d3dec5bb678bbb62e77df..bca856d5ea16ec0f51569525c6f0b712c4128d84 100644 --- a/common/utils/T/tracer/gui/gui_defs.h +++ b/common/utils/T/tracer/gui/gui_defs.h @@ -46,6 +46,7 @@ struct widget { struct widget *parent; void (*repack)(gui *g, widget *this); void (*add_child)(gui *g, widget *this, widget *child, int position); + void (*del_child)(gui *g, widget *this, widget *child); void (*allocate)(gui *g, widget *this, int x, int y, int width, int height); void (*hints)(gui *g, widget *this, int *width, int *height); void (*paint)(gui *g, widget *this); @@ -197,6 +198,8 @@ struct gui { widget *new_widget(struct gui *g, enum widget_type type, int size); void widget_add_child_internal( gui *_gui, widget *parent, widget *child, int position); +void widget_del_child_internal(gui *_gui, widget *parent, widget *child); +int widget_get_child_position(gui *_gui, widget *parent, widget *child); const char *widget_name(enum widget_type type); diff --git a/common/utils/T/tracer/gui/widget.c b/common/utils/T/tracer/gui/widget.c index 8411a4602fa54ee61f4f6e7390635301a83a6ce3..76e303fbe9fac89f5f510e5b79428395f9c90209 100644 --- a/common/utils/T/tracer/gui/widget.c +++ b/common/utils/T/tracer/gui/widget.c @@ -12,6 +12,7 @@ static void default_allocate( gui *gui, widget *_this, int x, int y, int width, int height); static void default_add_child( gui *_gui, widget *_this, widget *child, int position); +static void default_del_child(gui *_gui, widget *_this, widget *child); static void default_hints(gui *g, widget *this, int *width, int *height); static void default_button(gui *gui, widget *_this, int x, int y, int button, int up); @@ -47,6 +48,7 @@ widget *new_widget(struct gui *g, enum widget_type type, int size) ret->clear = default_clear; ret->repack = default_repack; ret->add_child = default_add_child; + ret->del_child = default_del_child; ret->allocate = default_allocate; ret->hints = default_hints; ret->button = default_button; @@ -121,6 +123,65 @@ repack: send_event(_gui, REPACK, p->id); } +void widget_del_child_internal(gui *_gui, widget *parent, widget *child) +{ + struct widget *p = parent; + struct widget *c = child; + struct widget_list *prev, *cur; + int i; + + c->parent = NULL; + + prev = NULL; + cur = p->children; + + while (cur != NULL && cur->item != c) { + prev = cur; + cur = cur->next; + } + + if (cur == NULL) ERR("child not found\n"); + + if (prev == NULL) { + /* child is at head */ + p->children = cur->next; + if (p->children != NULL) p->children->last = cur->last; + goto done; + } + + if (cur->next == NULL) { + /* child is last (and prev is != NULL) */ + prev->next = NULL; + p->children->last = prev; + goto done; + } + + /* child is between two existing items */ + prev->next = cur->next; + +done: + free(cur); + send_event(_gui, REPACK, p->id); +} + +int widget_get_child_position(gui *_gui, widget *parent, widget *child) +{ + struct widget *p = parent; + struct widget *c = child; + struct widget_list *cur; + int i = 0; + + cur = p->children; + + while (cur != NULL && cur->item != c) { + cur = cur->next; + i++; + } + + if (cur == NULL) return -1; + return i; +} + /*************************************************************************/ /* default functions */ /*************************************************************************/ @@ -140,12 +201,18 @@ static void default_repack(gui *gui, widget *_this) } static void default_add_child( - gui *_gui, widget *_this, widget *child, int position) + gui *_gui, widget *_this, widget *child, int position) { struct widget *this = _this; WARN("cannot add child to widget %s\n", widget_name(this->type)); } +static void default_del_child( gui *_gui, widget *_this, widget *child) +{ + struct widget *this = _this; + WARN("cannot del child from widget %s\n", widget_name(this->type)); +} + static void default_allocate( gui *gui, widget *_this, int x, int y, int width, int height) { @@ -180,6 +247,14 @@ void widget_add_child(gui *_gui, widget *parent, widget *child, int position) gunlock(_gui); } +void widget_del_child(gui *_gui, widget *parent, widget *child) +{ + struct widget *this = parent; + glock(_gui); + this->del_child(_gui, parent, child); + gunlock(_gui); +} + void widget_dirty(gui *_gui, widget *_this) { struct gui *g = _gui;