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:
parent
4a0e231247
commit
a2cf4908a3
|
@ -23,6 +23,7 @@ baseHFILES = \
|
|||
$(osHFILES)
|
||||
|
||||
baseCFILES = \
|
||||
bin.c \
|
||||
box.c \
|
||||
ptrarray.c \
|
||||
shouldquit.c \
|
||||
|
|
|
@ -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
11
ui.idl
|
@ -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);
|
||||
|
|
10
uipriv.h
10
uipriv.h
|
@ -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 {
|
||||
|
|
122
windows/bin.c
122
windows/bin.c
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue