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
#include "uipriv_unix.h"
struct tab {
uiTab t;
struct uiTab {
uiUnixControl c;
GtkWidget *widget;
GtkContainer *container;
GtkNotebook *notebook;
GArray *pages;
void (*baseCommitDestroy)(uiControl *);
};
struct tabPage {
uiControl *bin;
GtkWidget *binWidget;
GtkWidget *box;
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;
struct tabPage *page;
@ -31,121 +34,91 @@ static void tabCommitDestroy(uiControl *c)
// 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);
uiControlSetParent(page->c, NULL);
uiControlDestroy(page->c);
uiControlSetParent(page->bin, NULL);
uiControlDestroy(page->bin);
gtk_widget_destroy(page->box);
}
// 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;
// TODO tabContainerUpdateState()
return (uintptr_t) (t->widget);
void uiTabAppend(uiTab *t, const char *name, uiControl *child)
{
uiTabInsertAt(t, name, t->pages->len, child);
}
// TODO tabContainerUpdateState()?
static void tabAppend(uiTab *tt, const char *name, uiControl *child)
void uiTabInsertAt(uiTab *t, const char *name, uintmax_t n, 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;
page.c = child;
page.bin = newBin();
page.binWidget = GTK_WIDGET(uiControlHandle(page.bin));
binSetChild(page.bin, page.c);
page.box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_container_add(GTK_CONTAINER(page.box),
GTK_WIDGET(uiControlHandle(page.c)));
uiControlSetParent(page.bin, uiControl(t));
gtk_notebook_set_tab_label_text(t->notebook, page.binWidget, name);
gtk_notebook_reorder_child(t->notebook, page.binWidget, n);
gtk_container_add(t->container, page.box);
gtk_notebook_set_tab_label_text(t->notebook, page.box, name);
gtk_notebook_reorder_child(t->notebook, page.box, n);
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;
page = &g_array_index(t->pages, struct tabPage, n);
// 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
// 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);
gtk_widget_destroy(page->box);
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;
}
static int tabMargined(uiTab *tt, uintmax_t n)
int uiTabMargined(uiTab *t, uintmax_t n)
{
struct tab *t = (struct tab *) tt;
struct tabPage *page;
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;
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)
{
struct tab *t;
uiTab *t;
t = (struct tab *) uiNewControl(uiTypeTab());
t = (uiTab *) uiNewControl(uiTypeTab());
t->widget = gtk_notebook_new();
t->container = GTK_CONTAINER(t->widget);
t->notebook = GTK_NOTEBOOK(t->widget);
uiUnixMakeSingleWidgetControl(uiControl(t), t->widget);
gtk_notebook_set_scrollable(t->notebook, TRUE);
t->pages = g_array_new(FALSE, TRUE, sizeof (struct tabPage));
uiControl(t)->Handle = tabHandle;
t->baseCommitDestroy = uiControl(t)->CommitDestroy;
uiControl(t)->CommitDestroy = tabCommitDestroy;
uiUnixFinishNewControl(t, uiTab);
//TODO uiControl(t)->ContainerUpdateState = tabContainerUpdateState;
uiTab(t)->Append = tabAppend;
uiTab(t)->InsertAt = tabInsertAt;
uiTab(t)->Delete = tabDelete;
uiTab(t)->NumPages = tabNumPages;
uiTab(t)->Margined = tabMargined;
uiTab(t)->SetMargined = tabSetMargined;
return uiTab(t);
return t;
}

View File

@ -1,10 +1,8 @@
// 11 june 2015
#include "uipriv_unix.h"
// TODO ban uiControl methods that don't apply
struct window {
uiWindow w;
struct uiWindow {
uiUnixControl c;
GtkWidget *widget;
GtkContainer *container;
@ -16,22 +14,26 @@ struct window {
GtkWidget *menubar;
uiControl *bin;
uiControl *child;
int (*onClosing)(uiWindow *, void *);
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)
{
struct window *w = (struct window *) data;
uiWindow *w = uiWindow(data);
// 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));
// don't continue to the default delete-event handler; we destroyed the window by now
return TRUE;
@ -42,10 +44,8 @@ static int defaultOnClosing(uiWindow *w, void *data)
return 0;
}
static void windowCommitDestroy(uiControl *c)
static void onDestroy(uiWindow *w)
{
struct window *w = (struct window *) c;
// first hide ourselves
gtk_widget_hide(w->widget);
// now destroy the child
@ -56,21 +56,12 @@ static void windowCommitDestroy(uiControl *c)
// now destroy the menus, if any
if (w->menubar != NULL)
freeMenubar(w->menubar);
// now destroy ourselves
// 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);
gtk_widget_destroy(w->vboxWidget);
}
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(); that doesn't bring to front or give keyboard focus
@ -80,78 +71,65 @@ static void windowCommitShow(uiControl *c)
static void windowContainerUpdateState(uiControl *c)
{
struct window *w = (struct window *) c;
uiWindow *w = uiWindow(c);
if (w->child != NULL)
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));
}
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);
// 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->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)
binSetChild(w->bin, NULL);
if (w->child != NULL) {
gtk_container_remove(GTK_CONTAINER(w->childbox),
GTK_WIDGET(uiControlHandle(w->child)));
uiControlSetParent(w->child, NULL);
}
w->child = child;
if (w->child != NULL)
binSetChild(w->bin, w->child);
if (w->child != NULL) {
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 binMargined(w->bin);
return w->margined;
}
static void windowSetMargined(uiWindow *ww, int margined)
void uiWindowSetMargined(uiWindow *w, int margined)
{
struct window *w = (struct window *) ww;
binSetMargined(w->bin, margined);
uiControlQueueResize(uiControl(w));
}
static void windowResizeChild(uiWindow *ww)
{
complain("uiWindowResizeChild() meaningless on GTK+");
w->margined = margined;
setMargined(GTK_CONTAINER(w->childbox), w->margined);
}
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->container = GTK_CONTAINER(w->widget);
w->window = GTK_WINDOW(w->widget);
uiUnixMakeSingleWidgetControl(uiControl(w), w->widget);
gtk_window_set_title(w->window, title);
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);
}
w->bin = newBin();
gtk_container_add(w->vboxContainer, GTK_WIDGET(uiControlHandle(w->bin)));
w->childbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
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
gtk_widget_show_all(w->vboxWidget);
// and connect our OnClosing() event
g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w);
uiWindowOnClosing(w, defaultOnClosing, NULL);
w->onClosing = defaultOnClosing;
uiControl(w)->Handle = windowHandle;
w->baseCommitDestroy = uiControl(w)->CommitDestroy;
uiControl(w)->CommitDestroy = windowCommitDestroy;
uiUnixFinishNewControl(w, uiWindow);
uiControl(w)->CommitShow = windowCommitShow;
uiControl(w)->ContainerUpdateState = windowContainerUpdateState;
uiWindow(w)->Title = windowTitle;
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);
return w;
}