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)
|
$(osHFILES)
|
||||||
|
|
||||||
baseCFILES = \
|
baseCFILES = \
|
||||||
|
bin.c \
|
||||||
box.c \
|
box.c \
|
||||||
ptrarray.c \
|
ptrarray.c \
|
||||||
shouldquit.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);
|
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 {
|
interface Window from Control {
|
||||||
func Title(void) *char;
|
func Title(void) *char;
|
||||||
func SetTitle(title *const 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 void complain(const char *, ...);
|
||||||
|
|
||||||
extern uiContainer *newBin(void);
|
extern uiBin *newBin(void);
|
||||||
extern void binSetMainControl(uiContainer *, uiControl *);
|
extern int binHasOSParent(uiBin *);
|
||||||
extern void binSetMargins(uiContainer *, intmax_t, intmax_t, intmax_t, intmax_t);
|
extern void binSetOSParent(uiBin *, uintptr_t);
|
||||||
extern void binSetParent(uiContainer *, 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
|
// array.c
|
||||||
struct ptrArray {
|
struct ptrArray {
|
||||||
|
|
122
windows/bin.c
122
windows/bin.c
|
@ -1,126 +1,42 @@
|
||||||
// 27 april 2015
|
// 27 april 2015
|
||||||
#include "uipriv_windows.h"
|
#include "uipriv_windows.h"
|
||||||
|
|
||||||
struct bin {
|
int binHasOSParent(uiBin *b)
|
||||||
uiContainer c;
|
|
||||||
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;
|
HWND hwnd;
|
||||||
|
|
||||||
// ensure clean removal by making sure the bin has no OS parent
|
|
||||||
hwnd = (HWND) uiControlHandle(uiControl(b));
|
hwnd = (HWND) uiControlHandle(uiControl(b));
|
||||||
if (GetAncestor(hwnd, GA_PARENT) != initialParent)
|
return 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
HWND hwnd;
|
||||||
intmax_t marginX, marginY;
|
HWND parent = (HWND) osParent;
|
||||||
|
|
||||||
if (b->mainControl == NULL) {
|
hwnd = (HWND) uiControlHandle(uiControl(b));
|
||||||
*width = 0;
|
if (SetParent(hwnd, parent) == 0)
|
||||||
*height = 0;
|
logLastError("error setting bin OS parent in binSetOSParent()");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void binSysFunc(uiControl *c, uiControlSysFuncParams *p)
|
void binRemoveOSParent(uiBin *b)
|
||||||
{
|
{
|
||||||
struct bin *b = (struct bin *) c;
|
binSetOSParent(b, (uintptr_t) initialParent);
|
||||||
|
|
||||||
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)
|
void binResizeRoot(uiBin *b, intmax_t x, intmax_t y, intmax_t width, intmax_t height)
|
||||||
{
|
{
|
||||||
struct bin *b = (struct bin *) c;
|
HWND hwnd;
|
||||||
intmax_t marginLeft, marginTop;
|
|
||||||
|
|
||||||
if (b->mainControl == NULL)
|
hwnd = (HWND) uiControlHandle(uiControl(b));
|
||||||
return;
|
moveWindow(hwnd, x, y, width, height);
|
||||||
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));
|
|
||||||
uiContainerUpdate(uiContainer(b));
|
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;
|
*left = uiWindowsDlgUnitsToX(*left, d->Sys->BaseX);
|
||||||
|
*top = uiWindowsDlgUnitsToY(*top, d->Sys->BaseY);
|
||||||
b->marginLeft = left;
|
*right = uiWindowsDlgUnitsToX(*right, d->Sys->BaseX);
|
||||||
b->marginRight = right;
|
*bottom = uiWindowsDlgUnitsToY(*bottom, d->Sys->BaseY);
|
||||||
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()");
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue