Finished uiControl migration. Now to fix up the rest of the code...

This commit is contained in:
Pietro Gagliardi 2015-08-28 09:56:41 -04:00
parent 56db594d4d
commit d3663ae44b
2 changed files with 86 additions and 142 deletions

View File

@ -1,29 +1,32 @@
// 11 june 2015 // 11 june 2015
#include "uipriv_unix.h" #include "uipriv_unix.h"
struct tab { struct uiTab {
uiTab t; uiUnixControl c;
GtkWidget *widget; GtkWidget *widget;
GtkContainer *container; GtkContainer *container;
GtkNotebook *notebook; GtkNotebook *notebook;
GArray *pages; GArray *pages;
void (*baseCommitDestroy)(uiControl *);
}; };
struct tabPage { struct tabPage {
uiControl *bin; GtkWidget *box;
GtkWidget *binWidget;
uiControl *c; uiControl *c;
int margined;
}; };
uiDefineControlType(uiTab, uiTypeTab, struct tab) static void onDestroy(uiTab *);
static void tabCommitDestroy(uiControl *c) uiUnixDefineControlWithOnDestroy(
uiTab, // type name
uiTabType, // type function
onDestroy(this); // on destroy
)
static void onDestroy(uiTab *t)
{ {
struct tab *t = (struct tab *) c;
guint i; guint i;
struct tabPage *page; struct tabPage *page;
@ -31,121 +34,91 @@ static void tabCommitDestroy(uiControl *c)
// we need to remove them from the tab first; see below // we need to remove them from the tab first; see below
for (i = 0; i < t->pages->len; i++) { for (i = 0; i < t->pages->len; i++) {
page = &g_array_index(t->pages, struct tabPage, i); page = &g_array_index(t->pages, struct tabPage, i);
binSetChild(page->bin, NULL); uiControlSetParent(page->c, NULL);
uiControlDestroy(page->c); uiControlDestroy(page->c);
uiControlSetParent(page->bin, NULL); gtk_widget_destroy(page->box);
uiControlDestroy(page->bin);
} }
// then free ourselves
g_array_free(t->pages, TRUE); g_array_free(t->pages, TRUE);
(*(t->baseCommitDestroy))(uiControl(t));
} }
static uintptr_t tabHandle(uiControl *c) // TODO tabContainerUpdateState()
{
struct tab *t = (struct tab *) c;
return (uintptr_t) (t->widget); void uiTabAppend(uiTab *t, const char *name, uiControl *child)
{
uiTabInsertAt(t, name, t->pages->len, child);
} }
// TODO tabContainerUpdateState()? void uiTabInsertAt(uiTab *t, const char *name, uintmax_t n, uiControl *child)
static void tabAppend(uiTab *tt, const char *name, uiControl *child)
{ {
struct tab *t = (struct tab *) tt;
uiTabInsertAt(tt, name, t->pages->len, child);
}
static void tabInsertAt(uiTab *tt, const char *name, uintmax_t n, uiControl *child)
{
struct tab *t = (struct tab *) tt;
struct tabPage page; struct tabPage page;
page.c = child; page.c = child;
page.bin = newBin(); page.box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
page.binWidget = GTK_WIDGET(uiControlHandle(page.bin)); gtk_container_add(GTK_CONTAINER(page.box),
binSetChild(page.bin, page.c); GTK_WIDGET(uiControlHandle(page.c)));
uiControlSetParent(page.bin, uiControl(t)); gtk_container_add(t->container, page.box);
gtk_notebook_set_tab_label_text(t->notebook, page.binWidget, name); gtk_notebook_set_tab_label_text(t->notebook, page.box, name);
gtk_notebook_reorder_child(t->notebook, page.binWidget, n); gtk_notebook_reorder_child(t->notebook, page.box, n);
g_array_insert_val(t->pages, n, page); g_array_insert_val(t->pages, n, page);
} }
static void tabDelete(uiTab *tt, uintmax_t n) void uiTabDelete(uiTab *t, uintmax_t n)
{ {
struct tab *t = (struct tab *) tt;
struct tabPage *page; struct tabPage *page;
page = &g_array_index(t->pages, struct tabPage, n); page = &g_array_index(t->pages, struct tabPage, n);
// make sure the page's control isn't destroyed // make sure the page's control isn't destroyed
binSetChild(page->bin, NULL); uiControlSetParent(page->c, NULL);
gtk_container_remove(GTK_CONTAINER(page->box),
GTK+WIDGET(uiControlHandle(page->c)));
// now destroy the page
// this will also remove the tab // this will also remove the tab
// why? simple: both gtk_notebook_remove_tab() and gtk_widget_destroy() call gtk_container_remove() gtk_widget_destroy(page->box);
// 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); g_array_remove_index(t->pages, n);
} }
static uintmax_t tabNumPages(uiTab *tt) uintmax_t uiTabNumPages(uiTab *t)
{ {
struct tab *t = (struct tab *) tt;
return t->pages->len; return t->pages->len;
} }
static int tabMargined(uiTab *tt, uintmax_t n) int uiTabMargined(uiTab *t, uintmax_t n)
{ {
struct tab *t = (struct tab *) tt;
struct tabPage *page; struct tabPage *page;
page = &g_array_index(t->pages, struct tabPage, n); page = &g_array_index(t->pages, struct tabPage, n);
return binMargined(page->bin); return page->margined;
} }
static void tabSetMargined(uiTab *tt, uintmax_t n, int margined) void uiTabSetMargined(uiTab *t, uintmax_t n, int margined)
{ {
struct tab *t = (struct tab *) tt;
struct tabPage *page; struct tabPage *page;
page = &g_array_index(t->pages, struct tabPage, n); page = &g_array_index(t->pages, struct tabPage, n);
binSetMargined(page->bin, margined); page->margined = margined;
setMargined(GTK_CONTAINER(page->box), page->margined);
} }
uiTab *uiNewTab(void) uiTab *uiNewTab(void)
{ {
struct tab *t; uiTab *t;
t = (struct tab *) uiNewControl(uiTypeTab()); t = (uiTab *) uiNewControl(uiTypeTab());
t->widget = gtk_notebook_new(); t->widget = gtk_notebook_new();
t->container = GTK_CONTAINER(t->widget); t->container = GTK_CONTAINER(t->widget);
t->notebook = GTK_NOTEBOOK(t->widget); t->notebook = GTK_NOTEBOOK(t->widget);
uiUnixMakeSingleWidgetControl(uiControl(t), t->widget);
gtk_notebook_set_scrollable(t->notebook, TRUE); gtk_notebook_set_scrollable(t->notebook, TRUE);
t->pages = g_array_new(FALSE, TRUE, sizeof (struct tabPage)); t->pages = g_array_new(FALSE, TRUE, sizeof (struct tabPage));
uiControl(t)->Handle = tabHandle; uiUnixFinishNewControl(t, uiTab);
t->baseCommitDestroy = uiControl(t)->CommitDestroy; //TODO uiControl(t)->ContainerUpdateState = tabContainerUpdateState;
uiControl(t)->CommitDestroy = tabCommitDestroy;
uiTab(t)->Append = tabAppend; return t;
uiTab(t)->InsertAt = tabInsertAt;
uiTab(t)->Delete = tabDelete;
uiTab(t)->NumPages = tabNumPages;
uiTab(t)->Margined = tabMargined;
uiTab(t)->SetMargined = tabSetMargined;
return uiTab(t);
} }

View File

@ -1,10 +1,8 @@
// 11 june 2015 // 11 june 2015
#include "uipriv_unix.h" #include "uipriv_unix.h"
// TODO ban uiControl methods that don't apply struct uiWindow {
uiUnixControl c;
struct window {
uiWindow w;
GtkWidget *widget; GtkWidget *widget;
GtkContainer *container; GtkContainer *container;
@ -16,22 +14,26 @@ struct window {
GtkWidget *menubar; GtkWidget *menubar;
uiControl *bin;
uiControl *child; uiControl *child;
int (*onClosing)(uiWindow *, void *); int (*onClosing)(uiWindow *, void *);
void *onClosingData; void *onClosingData;
void (*baseCommitDestroy)(uiControl *c);
}; };
uiDefineControlType(uiWindow, uiTypeWindow, struct window) static void onDestroy(uiWindow *);
uiUnixDefineControlWithOnDestroy(
uiWindow, // type name
uiWindowType, // type function
onDestroy(this); // on destroy
)
static gboolean onClosing(GtkWidget *win, GdkEvent *e, gpointer data) static gboolean onClosing(GtkWidget *win, GdkEvent *e, gpointer data)
{ {
struct window *w = (struct window *) data; uiWindow *w = uiWindow(data);
// manually destroy the window ourselves; don't let the delete-event handler do it // manually destroy the window ourselves; don't let the delete-event handler do it
if ((*(w->onClosing))(uiWindow(w), w->onClosingData)) if ((*(w->onClosing))(w, w->onClosingData))
uiControlDestroy(uiControl(w)); uiControlDestroy(uiControl(w));
// don't continue to the default delete-event handler; we destroyed the window by now // don't continue to the default delete-event handler; we destroyed the window by now
return TRUE; return TRUE;
@ -42,10 +44,8 @@ static int defaultOnClosing(uiWindow *w, void *data)
return 0; return 0;
} }
static void windowCommitDestroy(uiControl *c) static void onDestroy(uiWindow *w)
{ {
struct window *w = (struct window *) c;
// first hide ourselves // first hide ourselves
gtk_widget_hide(w->widget); gtk_widget_hide(w->widget);
// now destroy the child // now destroy the child
@ -56,21 +56,12 @@ static void windowCommitDestroy(uiControl *c)
// now destroy the menus, if any // now destroy the menus, if any
if (w->menubar != NULL) if (w->menubar != NULL)
freeMenubar(w->menubar); freeMenubar(w->menubar);
// now destroy ourselves gtk_widget_destroy(w->vboxWidget);
// this will also free the vbox
(*(w->baseCommitDestroy))(uiControl(w));
}
static uintptr_t windowHandle(uiControl *c)
{
struct window *w = (struct window *) c;
return (uintptr_t) (w->widget);
} }
static void windowCommitShow(uiControl *c) static void windowCommitShow(uiControl *c)
{ {
struct window *w = (struct window *) c; uiWindow *w = uiWindow(c);
// don't use gtk_widget_show_all() as that will show all children, regardless of user settings // don't use gtk_widget_show_all() as that will show all children, regardless of user settings
// don't use gtk_widget_show(); that doesn't bring to front or give keyboard focus // don't use gtk_widget_show(); that doesn't bring to front or give keyboard focus
@ -80,78 +71,65 @@ static void windowCommitShow(uiControl *c)
static void windowContainerUpdateState(uiControl *c) static void windowContainerUpdateState(uiControl *c)
{ {
struct window *w = (struct window *) c; uiWindow *w = uiWindow(c);
if (w->child != NULL) if (w->child != NULL)
uiControlUpdateState(w->child); uiControlUpdateState(w->child);
} }
static char *windowTitle(uiWindow *ww) char *uiWindowTitle(uiWindow *w)
{ {
struct window *w = (struct window *) ww;
return uiUnixStrdupText(gtk_window_get_title(w->window)); return uiUnixStrdupText(gtk_window_get_title(w->window));
} }
static void windowSetTitle(uiWindow *ww, const char *title) void uiWindowSetTitle(uiWindow *w, const char *title)
{ {
struct window *w = (struct window *) ww;
gtk_window_set_title(w->window, title); gtk_window_set_title(w->window, title);
// don't queue resize; the caption isn't part of what affects layout and sizing of the client area (it'll be ellipsized if too long) // don't queue resize; the caption isn't part of what affects layout and sizing of the client area (it'll be ellipsized if too long)
} }
static void windowOnClosing(uiWindow *ww, int (*f)(uiWindow *, void *), void *data) void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data)
{ {
struct window *w = (struct window *) ww;
w->onClosing = f; w->onClosing = f;
w->onClosingData = data; w->onClosingData = data;
} }
static void windowSetChild(uiWindow *ww, uiControl *child) void uiWindowSetChild(uiWindow *w, uiControl *child)
{ {
struct window *w = (struct window *) ww; if (w->child != NULL) {
gtk_container_remove(GTK_CONTAINER(w->childbox),
if (w->child != NULL) GTK_WIDGET(uiControlHandle(w->child)));
binSetChild(w->bin, NULL); uiControlSetParent(w->child, NULL);
}
w->child = child; w->child = child;
if (w->child != NULL) if (w->child != NULL) {
binSetChild(w->bin, w->child); uiControlSetParent(w->child, uiControl(w));
gtk_container_add(GTK_CONTAINER(w->childbox),
GTK_WIDGET(uiControlHandle(w->child)));
}
} }
static int windowMargined(uiWindow *ww) int uiWindowMargined(uiWindow *w)
{ {
struct window *w = (struct window *) ww; return w->margined;
return binMargined(w->bin);
} }
static void windowSetMargined(uiWindow *ww, int margined) void uiWindowSetMargined(uiWindow *w, int margined)
{ {
struct window *w = (struct window *) ww; w->margined = margined;
setMargined(GTK_CONTAINER(w->childbox), w->margined);
binSetMargined(w->bin, margined);
uiControlQueueResize(uiControl(w));
}
static void windowResizeChild(uiWindow *ww)
{
complain("uiWindowResizeChild() meaningless on GTK+");
} }
uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar) uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)
{ {
struct window *w; uiWindow *w;
w = (struct window *) uiNewControl(uiTypeWindow()); w = (uiWindow *) uiNewControl(uiTypeWindow());
w->widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); w->widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
w->container = GTK_CONTAINER(w->widget); w->container = GTK_CONTAINER(w->widget);
w->window = GTK_WINDOW(w->widget); w->window = GTK_WINDOW(w->widget);
uiUnixMakeSingleWidgetControl(uiControl(w), w->widget);
gtk_window_set_title(w->window, title); gtk_window_set_title(w->window, title);
gtk_window_resize(w->window, width, height); gtk_window_resize(w->window, width, height);
@ -167,30 +145,23 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)
gtk_container_add(w->vboxContainer, w->menubar); gtk_container_add(w->vboxContainer, w->menubar);
} }
w->bin = newBin(); w->childbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_container_add(w->vboxContainer, GTK_WIDGET(uiControlHandle(w->bin))); gtk_widget_set_hexpand(w->childbox, TRUE);
gtk_widget_set_halign(w->childbox, GTK_ALIGN_FILL);
gtk_widget_set_vexpand(w->childbox, TRUE);
gtk_widget_set_valign(w->childbox, GTK_ALIGN_FILL);
gtk_container_add(w->vboxContainer, w->childbox);
// show everything in the vbox, but not the GtkWindow itself // show everything in the vbox, but not the GtkWindow itself
gtk_widget_show_all(w->vboxWidget); gtk_widget_show_all(w->vboxWidget);
// and connect our OnClosing() event // and connect our OnClosing() event
g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w); g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w);
uiWindowOnClosing(w, defaultOnClosing, NULL);
w->onClosing = defaultOnClosing; uiUnixFinishNewControl(w, uiWindow);
uiControl(w)->Handle = windowHandle;
w->baseCommitDestroy = uiControl(w)->CommitDestroy;
uiControl(w)->CommitDestroy = windowCommitDestroy;
uiControl(w)->CommitShow = windowCommitShow; uiControl(w)->CommitShow = windowCommitShow;
uiControl(w)->ContainerUpdateState = windowContainerUpdateState; uiControl(w)->ContainerUpdateState = windowContainerUpdateState;
uiWindow(w)->Title = windowTitle; return w;
uiWindow(w)->SetTitle = windowSetTitle;
uiWindow(w)->OnClosing = windowOnClosing;
uiWindow(w)->SetChild = windowSetChild;
uiWindow(w)->Margined = windowMargined;
uiWindow(w)->SetMargined = windowSetMargined;
uiWindow(w)->ResizeChild = windowResizeChild;
return uiWindow(w);
} }