Finished uiControl migration. Now to fix up the rest of the code...
This commit is contained in:
parent
56db594d4d
commit
d3663ae44b
109
redo/unix/tab.c
109
redo/unix/tab.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue