Did the GTK+ conversion to uiParent. Now to build.

This commit is contained in:
Pietro Gagliardi 2015-04-13 12:05:14 -04:00
parent 5a0a0d1584
commit 159337df73
6 changed files with 216 additions and 183 deletions

View File

@ -1,132 +0,0 @@
// 13 august 2014
#include "uipriv_unix.h"
G_DEFINE_TYPE(uiContainer, uiContainer, GTK_TYPE_CONTAINER)
static void uiContainer_init(uiContainer *c)
{
if (options.debugLogAllocations)
fprintf(stderr, "%p alloc uiContainer\n", c);
c->children = g_ptr_array_new();
gtk_widget_set_has_window(GTK_WIDGET(c), FALSE);
}
// instead of having GtkContainer itself unref all our controls, we'll run our own uiControlDestroy() functions for child, which will do that and more
// we still chain up because we need to, but by that point there will be no children for GtkContainer to free
static void uiContainer_dispose(GObject *obj)
{
uiContainer *c = uiContainer(obj);
if (c->children != NULL) {
g_ptr_array_unref(c->children);
c->children = NULL;
}
if (c->child != NULL) {
uiControlDestroy(c->child);
c->child = NULL;
}
G_OBJECT_CLASS(uiContainer_parent_class)->dispose(obj);
}
static void uiContainer_finalize(GObject *obj)
{
G_OBJECT_CLASS(uiContainer_parent_class)->finalize(obj);
if (options.debugLogAllocations)
fprintf(stderr, "%p free\n", obj);
}
static void uiContainer_add(GtkContainer *container, GtkWidget *widget)
{
uiContainer *c = uiContainer(container);
gtk_widget_set_parent(widget, GTK_WIDGET(c));
if (c->children != NULL)
g_ptr_array_add(c->children, widget);
}
static void uiContainer_remove(GtkContainer *container, GtkWidget *widget)
{
uiContainer *c = uiContainer(container);
gtk_widget_unparent(widget);
if (c->children != NULL)
g_ptr_array_remove(c->children, widget);
}
#define gtkXMargin 12
#define gtkYMargin 12
#define gtkXPadding 12
#define gtkYPadding 6
static void uiContainer_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
{
uiContainer *c = uiContainer(widget);
uiSizing d;
intmax_t x, y, width, height;
gtk_widget_set_allocation(GTK_WIDGET(c), allocation);
if (c->child == NULL)
return;
x = allocation->x;
y = allocation->y;
width = allocation->width;
height = allocation->height;
if (c->margined) {
x += gtkXMargin;
y += gtkYMargin;
width -= 2 * gtkXMargin;
height -= 2 * gtkYMargin;
}
d.xPadding = gtkXPadding;
d.yPadding = gtkYPadding;
uiControlResize(c->child, x, y, width, height, &d);
}
struct forall {
GtkCallback callback;
gpointer data;
};
static void doforall(gpointer obj, gpointer data)
{
struct forall *s = (struct forall *) data;
(*(s->callback))(GTK_WIDGET(obj), s->data);
}
static void uiContainer_forall(GtkContainer *container, gboolean includeInternals, GtkCallback callback, gpointer data)
{
uiContainer *c = uiContainer(container);
struct forall s;
s.callback = callback;
s.data = data;
if (c->children != NULL)
g_ptr_array_foreach(c->children, doforall, &s);
}
static void uiContainer_class_init(uiContainerClass *class)
{
G_OBJECT_CLASS(class)->dispose = uiContainer_dispose;
G_OBJECT_CLASS(class)->finalize = uiContainer_finalize;
GTK_WIDGET_CLASS(class)->size_allocate = uiContainer_size_allocate;
GTK_CONTAINER_CLASS(class)->add = uiContainer_add;
GTK_CONTAINER_CLASS(class)->remove = uiContainer_remove;
GTK_CONTAINER_CLASS(class)->forall = uiContainer_forall;
}
GtkWidget *newContainer(void)
{
GtkWidget *w;
w = GTK_WIDGET(g_object_new(uiContainerType, NULL));
// call gtk_widget_show_all() here to make the container visible
gtk_widget_show_all(w);
return w;
}
void updateParent(uintptr_t parent)
{
if (parent != 0)
gtk_widget_queue_resize(GTK_WIDGET(parent));
}

View File

@ -7,7 +7,7 @@ struct singleWidget {
GtkWidget *widget;
GtkWidget *scrolledWindow;
GtkWidget *immediate; // the widget that is added to the parent container; either widget or scrolledWindow
uintptr_t parent;
uiParent *parent;
gboolean userHid;
gboolean containerHid;
gboolean userDisabled;
@ -28,13 +28,13 @@ static uintptr_t singleHandle(uiControl *c)
return (uintptr_t) (s->widget);
}
static void singleSetParent(uiControl *c, uintptr_t parent)
static void singleSetParent(uiControl *c, uiParent *parent)
{
singleWidget *s = (singleWidget *) (c->internal);
s->parent = parent;
gtk_container_add(GTK_CONTAINER(s->parent), s->immediate);
updateParent(s->parent);
uiParentUpdate(s->parent);
}
static void singleRemoveParent(uiControl *c)
@ -45,7 +45,7 @@ static void singleRemoveParent(uiControl *c)
oldparent = s->parent;
s->parent = NULL;
gtk_container_remove(GTK_CONTAINER(oldparent), s->immediate);
updateParent(oldparent);
uiParentUpdate(oldparent);
}
static void singlePreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
@ -89,7 +89,8 @@ static void singleShow(uiControl *c)
s->userHid = FALSE;
if (!s->containerHid) {
gtk_widget_show_all(s->immediate);
updateParent(s->parent);
if (s->parent != NULL)
uiParentUpdate(s->parent);
}
}
@ -99,7 +100,8 @@ static void singleHide(uiControl *c)
s->userHid = TRUE;
gtk_widget_hide(s->immediate);
updateParent(s->parent);
if (s->parent != NULL)
uiParentUpdate(s->parent);
}
static void singleContainerShow(uiControl *c)
@ -109,7 +111,8 @@ static void singleContainerShow(uiControl *c)
s->containerHid = FALSE;
if (!s->userHid) {
gtk_widget_show_all(s->immediate);
updateParent(s->parent);
if (s->parent != NULL)
uiParentUpdate(s->parent);
}
}
@ -119,7 +122,8 @@ static void singleContainerHide(uiControl *c)
s->containerHid = TRUE;
gtk_widget_hide(s->immediate);
updateParent(s->parent);
if (s->parent != NULL)
uiParentUpdate(s->parent);
}
static void singleEnable(uiControl *c)

183
parent_unix.c Normal file
View File

@ -0,0 +1,183 @@
// 13 august 2014
#include "uipriv_unix.h"
#define uipParentType (uipParent_get_type())
#define uipParent(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), uipParentType, uipParent))
#define uipIsParent(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), uipParentType))
#define uipParentClass(class) (G_TYPE_CHECK_CLASS_CAST((class), uipParentType, uipParentClass))
#define uipIsParentClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), uipParent))
#define uipGetParentClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), uipParentType, uipParentClass))
typedef struct uipParent uipParent;
typedef struct uipParentClass uipParentClass;
struct uipParent {
GtkContainer parent_instance;
// this is what triggers the resizing of all the children
uiControl *child;
// these are the actual children widgets of the container as far as GTK+ is concerned
GPtrArray *children; // for forall()
intmax_t marginLeft;
intmax_t marginTop;
intmax_t marginRight;
intmax_t marginBottom;
};
struct uipParentClass {
GtkContainerClass parent_class;
};
G_DEFINE_TYPE(uipParent, uipParent, GTK_TYPE_CONTAINER)
static void uipParent_init(uipParent *p)
{
if (options.debugLogAllocations)
fprintf(stderr, "%p alloc uipParent\n", p);
p->children = g_ptr_array_new();
gtk_widget_set_has_window(GTK_WIDGET(c), FALSE);
}
// instead of having GtkContainer itself unref all our controls, we'll run our own uiControlDestroy() functions for child, which will do that and more
// we still chain up because we need to, but by that point there will be no children for GtkContainer to free
static void uipParent_dispose(GObject *obj)
{
uipParent *p = uipParent(obj);
if (p->children != NULL) {
g_ptr_array_unref(c->children);
p->children = NULL;
}
if (p->child != NULL) {
uiControlDestroy(c->child);
p->child = NULL;
}
G_OBJECT_CLASS(uipParent_parent_class)->dispose(obj);
}
static void uipParent_finalize(GObject *obj)
{
G_OBJECT_CLASS(uipParent_parent_class)->finalize(obj);
if (options.debugLogAllocations)
fprintf(stderr, "%p free\n", obj);
}
static void uipParent_add(GtkContainer *container, GtkWidget *widget)
{
uipParent *p = uipParent(container);
gtk_widget_set_parent(widget, GTK_WIDGET(c));
if (p->children != NULL)
g_ptr_array_add(p->children, widget);
}
static void uipParent_remove(GtkContainer *container, GtkWidget *widget)
{
uipParent *p = uipParent(container);
gtk_widget_unparent(widget);
if (p->children != NULL)
g_ptr_array_remove(p->children, widget);
}
#define gtkXPadding 12
#define gtkYPadding 6
static void uipParent_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
{
uipParent *p = uipParent(widget);
uiSizing d;
intmax_t x, y, width, height;
gtk_widget_set_allocation(GTK_WIDGET(c), allocation);
if (c->child == NULL)
return;
x = allocation->x + p->marginLeft;
y = allocation->y + p->marginTop;
width = allocation->width - (p->marginLeft + p->marginRight);
height = allocation->height - (p->marginTop + p->marginBottom);
d.xPadding = gtkXPadding;
d.yPadding = gtkYPadding;
uiControlResize(c->child, x, y, width, height, &d);
}
struct forall {
GtkCallback callback;
gpointer data;
};
static void doforall(gpointer obj, gpointer data)
{
struct forall *s = (struct forall *) data;
(*(s->callback))(GTK_WIDGET(obj), s->data);
}
static void uipParent_forall(GtkContainer *container, gboolean includeInternals, GtkCallback callback, gpointer data)
{
uipParent *p = uipParent(container);
struct forall s;
s.callback = callback;
s.data = data;
if (p->children != NULL)
g_ptr_array_foreach(c->children, doforall, &s);
}
static void uipParent_class_init(uipParentClass *class)
{
G_OBJECT_CLASS(class)->dispose = uipParent_dispose;
G_OBJECT_CLASS(class)->finalize = uipParent_finalize;
GTK_WIDGET_CLASS(class)->size_allocate = uipParent_size_allocate;
GTK_CONTAINER_CLASS(class)->add = uipParent_add;
GTK_CONTAINER_CLASS(class)->remove = uipParent_remove;
GTK_CONTAINER_CLASS(class)->forall = uipParent_forall;
}
static uintptr_t parentHandle(uiParent *p)
{
uipParent *pp = uipParent(p->Internal);
return (uintptr_t) pp;
}
static void parentSetChild(uiParent *p, uiControl *child)
{
uipParent *pp = uipParent(p->Internal);
pp->child = child;
if (pp->child != NULL)
uiControlSetParent(child, p);
}
static void parentSetMargins(uiParent *p, intmax_t left, intmax_t top, intmax_t right, intmax_t bottom)
{
uipParent *pp = uipParent(p->Internal);
pp->marginLeft = left;
pp->marginTop = top;
pp->marginRight = right;
pp->marginBottom = bottom;
}
static void parentUpdate(uiParent *p)
{
uipParent *pp = uipParent(p->Internal);
gtk_queue_resize(GTK_WIDGET(pp));
}
uiParent *uiNewParent(uintptr_t osParent)
{
uiParent *p;
p = uiNew(uiParent);
p->Internal = g_object_new(uipParentType, NULL);
p->Handle = parentHandle;
p->SetChild = parentSetChild;
p->SetMargins = parentSetMargins;
p->Update = parentUpdate;
gtk_container_add(GTK_CONTAINER(osParent), GTK_WIDGET(p->Internal));
// and make it visible by default
gtk_widget_show_all(GTK_WIDGET(p->internal));
return p;
}

View File

@ -2,15 +2,11 @@
#include "uipriv_unix.h"
struct tab {
struct tabPage *pages;
uiParent **pages;
uintmax_t len;
uintmax_t cap;
};
struct tabPage {
GtkWidget *container;
};
static void onDestroy(GtkWidget *widget, gpointer data)
{
struct tab *t = (struct tab *) data;
@ -44,21 +40,19 @@ void uiTabAddPage(uiControl *c, const char *name, uiControl *child)
{
struct tab *t = (struct tab *) (c->data);
GtkWidget *notebook;
GtkWidget *container;
uiParent *content;
if (t->len >= t->cap) {
t->cap += tabCapGrow;
t->pages = (struct tabPage *) uiRealloc(t->pages, t->cap * sizeof (struct tabPage), "struct tabPage[]");
t->pages = (uiParent **) uiRealloc(t->pages, t->cap * sizeof (uiParent *), "uiParent *[]");
}
container = newContainer();
uiContainer(container)->child = child;
uiControlSetParent(uiContainer(container)->child, (uintptr_t) (container));
notebook = GTK_WIDGET(uiControlHandle(c));
gtk_container_add(GTK_CONTAINER(notebook), container);
content = uiNewParent((uintptr_t) notebook);
uiParentSetChild(content, child);
uiParentUpdate(content);
gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(notebook), container, name);
gtk_widget_show_all(container);
t->pages[t->len].container = container;
t->pages[t->len] = content;
t->len++;
}

View File

@ -7,25 +7,5 @@
#include "uipriv.h"
#include "ui_unix.h"
// container_unix.c
#define uiContainerType (uiContainer_get_type())
#define uiContainer(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), uiContainerType, uiContainer))
#define uiIsContainer(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), uiContainerType))
#define uiContainerClass(class) (G_TYPE_CHECK_CLASS_CAST((class), uiContainerType, uiContainerClass))
#define uiIsContainerClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), uiContainer))
#define uiGetContainerClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), uiContainerType, uiContainerClass))
typedef struct uiContainer uiContainer;
typedef struct uiContainerClass uiContainerClass;
struct uiContainer {
GtkContainer parent_instance;
// this is what triggers the resizing of all the children
uiControl *child;
// these are the actual children widgets of the container as far as GTK+ is concerned
GPtrArray *children; // for forall()
gboolean margined;
};
struct uiContainerClass {
GtkContainerClass parent_class;
};
extern GType uiContainer_get_type(void);
extern GtkWidget *newContainer(void);
#define gtkXMargin 12
#define gtkYMargin 12

View File

@ -3,9 +3,10 @@
struct uiWindow {
GtkWidget *widget;
GtkWidget *container;
uiParent *content;
int (*onClosing)(uiWindow *, void *);
void *onClosingData;
int margined;
};
static gboolean onClosing(GtkWidget *win, GdkEvent *e, gpointer data)
@ -40,8 +41,7 @@ uiWindow *uiNewWindow(char *title, int width, int height)
gtk_window_resize(GTK_WINDOW(w->widget), width, height);
g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w);
g_signal_connect(w->widget, "destroy", G_CALLBACK(onDestroy), w);
w->container = newContainer();
gtk_container_add(GTK_CONTAINER(w->widget), w->container);
w->content = uiNewParent((uintptr_t) (w->widget));
w->onClosing = defaultOnClosing;
return w;
}
@ -85,17 +85,21 @@ void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data)
void uiWindowSetChild(uiWindow *w, uiControl *c)
{
uiContainer(w->container)->child = c;
uiControlSetParent(uiContainer(w->container)->child, (uintptr_t) (w->container));
uiParentSetChild(w->content, c);
uiParentUpdate(w->content);
}
int uiWindowMargined(uiWindow *w)
{
return uiContainer(w->container)->margined;
return w->margined;
}
void uiWindowSetMargined(uiWindow *w, int margined)
{
uiContainer(w->container)->margined = margined;
updateParent((uintptr_t) (w->container));
w->margined = margined;
if (w->margined)
uiParentSetMargins(w->content, gtkXMargin, gtkYMargin, gtkXMargin, gtkYMargin);
else
uiParentSetMargins(w->content, 0, 0, 0, 0);
uiParentUpdate(w->content);
}