From 7abf88d9ef929c926db351ed2e615a678879889a Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 1 Jul 2015 01:02:34 -0400 Subject: [PATCH] Finished reimplemented GTK+ uiTab. --- redo/unix/tab.c | 41 ++++++++++++++++++++++- unix/tab.c | 87 ------------------------------------------------- 2 files changed, 40 insertions(+), 88 deletions(-) delete mode 100644 unix/tab.c diff --git a/redo/unix/tab.c b/redo/unix/tab.c index ccb90d93..2a11df14 100644 --- a/redo/unix/tab.c +++ b/redo/unix/tab.c @@ -9,6 +9,8 @@ struct tab { GtkNotebook *notebook; GArray *pages; + + void (*baseCommitDestroy)(uiControl *); }; struct tabPage { @@ -19,6 +21,26 @@ struct tabPage { uiDefineControlType(uiTab, uiTypeTab, struct tab) +static void tabCommitDestroy(uiControl *c) +{ + struct tab *t = (struct tab *) c; + guint i; + struct tabPage *page; + + // the pages do not have a libui parent, so we can simply destroy them + // we need to remove them from the tab first; see below + for (i = 0; i < t->pages->len; i++) { + page = &g_array_index(t->pages, struct tabPage, i); + binSetChild(page->bin, NULL); + uiControlDestroy(page->c); + uiControlSetParent(page->bin, NULL); + uiControlDestroy(page->bin); + } + // then free ourselves + g_array_free(t->pages, TRUE); + (*(t->baseCommitDestroy))(uiControl(t)); +} + static uintptr_t tabHandle(uiControl *c) { struct tab *t = (struct tab *) c; @@ -53,8 +75,23 @@ static void tabInsertAt(uiTab *tt, const char *name, uintmax_t n, uiControl *chi static void tabDelete(uiTab *tt, uintmax_t n) { struct tab *t = (struct tab *) tt; + struct tabPage *page; - PUT_CODE_HERE; + page = &g_array_index(t->pages, struct tabPage, n); + + // make sure the page's control isn't destroyed + binSetChild(page->bin, NULL); + + // now destroy the page + // this will also remove the tab + // why? simple: both gtk_notebook_remove_tab() and gtk_widget_destroy() call gtk_container_remove() + // we need to remove them from the tab first, though, otherwise they won't really be destroyed properly + // (the GtkNotebook will still have the tab in it because its reference ISN'T destroyed, and we crash resizing a bin that no longer exists) + // TODO redo this comment + uiControlSetParent(page->bin, NULL); + uiControlDestroy(page->bin); + + g_array_remove_index(t->pages, n); } static uintmax_t tabNumPages(uiTab *tt) @@ -98,6 +135,8 @@ uiTab *uiNewTab(void) t->pages = g_array_new(FALSE, TRUE, sizeof (struct tabPage)); uiControl(t)->Handle = tabHandle; + t->baseCommitDestroy = uiControl(t)->CommitDestroy; + uiControl(t)->CommitDestroy = tabCommitDestroy; uiTab(t)->Append = tabAppend; uiTab(t)->InsertAt = tabInsertAt; diff --git a/unix/tab.c b/unix/tab.c deleted file mode 100644 index 68f3ff86..00000000 --- a/unix/tab.c +++ /dev/null @@ -1,87 +0,0 @@ -// 12 april 2015 -#include "uipriv_unix.h" - -struct tab { - uiTab t; - GtkWidget *widget; - GtkContainer *container; - GtkNotebook *notebook; - GArray *pages; -}; - -struct tabPage { - uiBin *bin; - // TODO remove the need for this - GtkWidget *binWidget; - int margined; -}; - -static void onDestroy(void *data) -{ - struct tab *t = (struct tab *) data; - guint i; - struct tabPage *page; - - // first hide ourselves to avoid flicker - gtk_widget_hide(t->widget); - // the pages do not have a libui parent, so we can simply destroy them - // we need to remove them from the tab first; see below - for (i = 0; i < t->pages->len; i++) { - page = &g_array_index(t->pages, struct tabPage, i); - uiBinRemoveOSParent(page->bin); - uiControlDestroy(uiControl(page->bin)); - } - // then free ourselves - g_array_free(t->pages, TRUE); - uiFree(t); -} - -static void tabShow(uiControl *c) -{ - struct tab *t = (struct tab *) t; - - // don't call gtk_widget_show_all() like the default handler does; that'll override user hiding of children - gtk_widget_show(t->widget); -} - - - -static void tabDeletePage(uiTab *tt, uintmax_t n) -{ - struct tab *t = (struct tab *) tt; - struct tabPage *page; - - page = &g_array_index(t->pages, struct tabPage, n); - - // make sure the page's control isn't destroyed - uiBinSetMainControl(page->bin, NULL); - - // now destroy the page - // this will also remove the tab - // why? simple: both gtk_notebook_remove_tab() and gtk_widget_destroy() call gtk_container_remove() - // we need to remove them from the tab first, though, otherwise they won't really be destroyed properly - // (the GtkNotebook will still have the tab in it because its reference ISN'T destroyed, and we crash resizing a bin that no longer exists - // TODO redo this comment - uiBinRemoveOSParent(page->bin); - uiControlDestroy(uiControl(page->bin)); - - g_array_remove_index(t->pages, n); -} - -uiTab *uiNewTab(void) -{ - struct tab *t; - - t = uiNew(struct tab); - - uiControl(t)->Show = tabShow; - - uiTab(t)->AppendPage = tabAppendPage; - uiTab(t)->InsertPageBefore = tabInsertPageBefore; - uiTab(t)->DeletePage = tabDeletePage; - uiTab(t)->NumPages = tabNumPages; - uiTab(t)->Margined = tabMargined; - uiTab(t)->SetMargined = tabSetMargined; - - return uiTab(t); -}