Started cleaning up bin handling. uiBin is now a real type and all of the things you need to do to a bin are its methods.

This commit is contained in:
Pietro Gagliardi 2015-05-10 12:36:14 -04:00
parent 4a0e231247
commit a2cf4908a3
5 changed files with 171 additions and 107 deletions

View File

@ -23,6 +23,7 @@ baseHFILES = \
$(osHFILES)
baseCFILES = \
bin.c \
box.c \
ptrarray.c \
shouldquit.c \

134
bin.c Normal file
View File

@ -0,0 +1,134 @@
// 27 april 2015
#include "uipriv_windows.h"
struct bin {
uiBin b;
void (*baseDestroy)(uiControl *);
uiControl *mainControl;
intmax_t marginLeft;
intmax_t marginTop;
intmax_t marginRight;
intmax_t marginBottom;
};
static void binDestroy(uiControl *c)
{
struct bin *b = (struct bin *) c;
HWND hwnd;
// ensure clean removal by making sure the bin has no OS parent
if (uiBinHasOSParent(uiBin(b)))
complain("attempt to destroy bin %p while it has an OS parent", b);
// don't chain up to base here; we need to destroy children ourselves first
if (b->mainControl != NULL) {
uiControlSetParent(b->mainControl, NULL);
uiControlDestroy(b->mainControl);
}
// NOW we can chain up to base
(*(b->baseDestroy))(uiControl(b));
uiFree(b);
}
static void binPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
{
struct bin *b = (struct bin *) c;
intmax_t left, top, right, bottom;
intmax_t cwid, cht;
if (b->mainControl == NULL) {
*width = 0;
*height = 0;
return;
}
// first do margins
left = b->marginLeft;
top = b->marginTop;
right = b->marginRight;
bottom = b->marginBottom;
uiBinTranslateMargins(uiBin(b), &left, &top, &right, &bottom, d);
*width = left + right;
*height = top + bottom;
// then do the control
uiControlPreferredSize(b->mainControl, d, &cwid, &cht);
*width += cwid;
*height += cht;
}
static void binSysFunc(uiControl *c, uiControlSysFuncParams *p)
{
struct bin *b = (struct bin *) c;
if (b->mainControl != NULL)
uiControlSysFunc(b->mainControl, p);
}
static void binResizeChildren(uiContainer *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
{
struct bin *b = (struct bin *) c;
intmax_t left, top, right, bottom;
if (b->mainControl == NULL)
return;
left = b->marginLeft;
top = b->marginTop;
right = b->marginRight;
bottom = b->marginBottom;
uiBinTranslateMargins(uiBin(b), &left, &top, &right, &bottom, d);
x += left;
y += top;
width -= left + right;
height -= top + bottom;
uiControlResize(b->mainControl, x, y, width, height, d);
}
static void binSetMainControl(uiBin *bb, uiControl *mainControl)
{
struct bin *b = (struct bin *) bb;
if (b->mainControl != NULL)
uiControlSetParent(b->mainControl, NULL);
b->mainControl = mainControl;
if (b->mainControl != NULL)
uiControlSetParent(b->mainControl, uiContainer(b));
uiContainerUpdate(uiContainer(b));
}
static void binSetMargins(uiBin *bb, intmax_t left, intmax_t top, intmax_t right, intmax_t bottom)
{
struct bin *b = (struct bin *) bb;
b->marginLeft = left;
b->marginRight = right;
b->marginTop = top;
b->marginBottom = bottom;
uiContainerUpdate(uiContainer(b));
}
uiBin *newBin(void)
{
struct bin *b;
b = uiNew(struct bin);
uiMakeContainer(uiContainer(b));
b->baseDestroy = uiControl(b)->Destroy;
uiControl(b)->Destroy = binDestroy;
uiControl(b)->PreferredSize = binPreferredSize;
uiControl(b)->SysFunc = binSysFunc;
uiContainer(b)->ResizeChildren = binResizeChildren;
uiBin(b)->SetMainControl = binSetMainControl;
uiBin(b)->SetMargins = binSetMargins;
// these are defined by each OS's bin.c
uiBin(b)->HasOSParent = binHasOSParent;
uiBin(b)->SetOSParent = binSetOSParent;
uiBin(b)->RemoveOSParent = binRemoveOSParent;
uiBin(b)->ResizeRoot = binResizeRoot;
uiBin(b)->TranslateMargins = binTranslateMargins;
return uiBin(b);
}

11
ui.idl
View File

@ -59,6 +59,17 @@ interface Container from Control {
};
func MakeContainer(c *Container);
interface Bin from Container {
func SetMainControl(c *Control);
func SetMargins(left intmax_t, top intmax_t, right intmax_t, bottom intmax_t);
// defined by each OS
func HasOSParent(void) int;
func SetOSParent(parent uintptr_t);
func RemoveOSParent(void);
func ResizeRoot(x intmax_t, y intmax_t, width intmax_t, height intmax_t);
func TranslateMargins(left *intmax_t, top *intmax_t, right *intmax_t, bottom *intmax_t, d *Sizing);
};
interface Window from Control {
func Title(void) *char;
func SetTitle(title *const char);

View File

@ -10,10 +10,12 @@ extern void uiFree(void *);
extern void complain(const char *, ...);
extern uiContainer *newBin(void);
extern void binSetMainControl(uiContainer *, uiControl *);
extern void binSetMargins(uiContainer *, intmax_t, intmax_t, intmax_t, intmax_t);
extern void binSetParent(uiContainer *, uintptr_t);
extern uiBin *newBin(void);
extern int binHasOSParent(uiBin *);
extern void binSetOSParent(uiBin *, uintptr_t);
extern void binRemoveOSParent(uiBin *);
extern void binResizeRoot(uiBin *, intmax_t, intmax_t, intmax_t, intmax_t);
extern void binTranslateMargins(uiBin *, intmax_t *, intmax_t *, intmax_t *, intmax_t *, uiSizing *);
// array.c
struct ptrArray {

View File

@ -1,126 +1,42 @@
// 27 april 2015
#include "uipriv_windows.h"
struct bin {
uiContainer c;
void (*baseDestroy)(uiControl *);
uiControl *mainControl;
intmax_t marginLeft;
intmax_t marginTop;
intmax_t marginRight;
intmax_t marginBottom;
};
static void binDestroy(uiControl *c)
int binHasOSParent(uiBin *b)
{
struct bin *b = (struct bin *) c;
HWND hwnd;
// ensure clean removal by making sure the bin has no OS parent
hwnd = (HWND) uiControlHandle(uiControl(b));
if (GetAncestor(hwnd, GA_PARENT) != initialParent)
complain("attempt to destroy bin %p while it has an OS parent", b);
// don't chain up to base here; we need to destroy children ourselves first
if (b->mainControl != NULL) {
uiControlSetParent(b->mainControl, NULL);
uiControlDestroy(b->mainControl);
}
// NOW we can chain up to base
(*(b->baseDestroy))(uiControl(b));
uiFree(b);
return GetAncestor(hwnd, GA_PARENT) != initialParent;
}
static void binPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
void binSetOSParent(uiBin *b, uintptr_t osParent)
{
struct bin *b = (struct bin *) c;
intmax_t marginX, marginY;
HWND hwnd;
HWND parent = (HWND) osParent;
if (b->mainControl == NULL) {
*width = 0;
*height = 0;
return;
}
uiControlPreferredSize(b->mainControl, d, width, height);
marginX = uiWindowsDlgUnitsToX(b->marginLeft, d->Sys->BaseX) + uiWindowsDlgUnitsToX(b->marginRight, d->Sys->BaseX);
marginY = uiWindowsDlgUnitsToY(b->marginTop, d->Sys->BaseY) + uiWindowsDlgUnitsToY(b->marginBottom, d->Sys->BaseY);
*width += marginX;
*height += marginY;
hwnd = (HWND) uiControlHandle(uiControl(b));
if (SetParent(hwnd, parent) == 0)
logLastError("error setting bin OS parent in binSetOSParent()");
}
static void binSysFunc(uiControl *c, uiControlSysFuncParams *p)
void binRemoveOSParent(uiBin *b)
{
struct bin *b = (struct bin *) c;
if (b->mainControl != NULL)
uiControlSysFunc(b->mainControl, p);
binSetOSParent(b, (uintptr_t) initialParent);
}
static void binResizeChildren(uiContainer *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
void binResizeRoot(uiBin *b, intmax_t x, intmax_t y, intmax_t width, intmax_t height)
{
struct bin *b = (struct bin *) c;
intmax_t marginLeft, marginTop;
HWND hwnd;
if (b->mainControl == NULL)
return;
marginLeft = uiWindowsDlgUnitsToX(b->marginLeft, d->Sys->BaseX);
marginTop = uiWindowsDlgUnitsToY(b->marginTop, d->Sys->BaseY);
x += marginLeft;
y += marginTop;
width -= marginLeft + uiWindowsDlgUnitsToX(b->marginRight, d->Sys->BaseX);
height -= marginTop + uiWindowsDlgUnitsToY(b->marginBottom, d->Sys->BaseY);
uiControlResize(b->mainControl, x, y, width, height, d);
}
uiContainer *newBin(void)
{
struct bin *b;
b = uiNew(struct bin);
uiMakeContainer(uiContainer(b));
b->baseDestroy = uiControl(b)->Destroy;
uiControl(b)->Destroy = binDestroy;
uiControl(b)->PreferredSize = binPreferredSize;
uiControl(b)->SysFunc = binSysFunc;
uiContainer(b)->ResizeChildren = binResizeChildren;
return uiContainer(b);
}
void binSetMainControl(uiContainer *c, uiControl *mainControl)
{
struct bin *b = (struct bin *) c;
if (b->mainControl != NULL)
uiControlSetParent(b->mainControl, NULL);
b->mainControl = mainControl;
if (b->mainControl != NULL)
uiControlSetParent(b->mainControl, uiContainer(b));
hwnd = (HWND) uiControlHandle(uiControl(b));
moveWindow(hwnd, x, y, width, height);
uiContainerUpdate(uiContainer(b));
}
void binSetMargins(uiContainer *c, intmax_t left, intmax_t top, intmax_t right, intmax_t bottom)
void binTranslateMargins(uiBin *b, intmax_t *left, intmax_t *top, intmax_t *right, intmax_t *bottom, uiSizing *d)
{
struct bin *b = (struct bin *) c;
b->marginLeft = left;
b->marginRight = right;
b->marginTop = top;
b->marginBottom = bottom;
uiContainerUpdate(uiContainer(b));
}
void binSetParent(uiContainer *c, uintptr_t osParent)
{
struct bin *b = (struct bin *) c;
HWND hwnd;
HWND newParent = (HWND) osParent;
hwnd = (HWND) uiControlHandle(uiControl(b));
if (newParent == NULL)
newParent = initialParent;
if (SetParent(hwnd, newParent) == 0)
logLastError("error changing bin's parent in binSetParent()");
*left = uiWindowsDlgUnitsToX(*left, d->Sys->BaseX);
*top = uiWindowsDlgUnitsToY(*top, d->Sys->BaseY);
*right = uiWindowsDlgUnitsToX(*right, d->Sys->BaseX);
*bottom = uiWindowsDlgUnitsToY(*bottom, d->Sys->BaseY);
}