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
|
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue