Started the new uiControl infrastructure.
This commit is contained in:
parent
19f563a2ac
commit
dda30cdb3c
144
common/control.c
144
common/control.c
|
@ -2,23 +2,9 @@
|
||||||
#include "../ui.h"
|
#include "../ui.h"
|
||||||
#include "uipriv.h"
|
#include "uipriv.h"
|
||||||
|
|
||||||
struct controlBase {
|
|
||||||
uiControl *parent;
|
|
||||||
int hidden;
|
|
||||||
int disabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define controlBase(c) ((struct controlBase *) (c->Internal))
|
|
||||||
|
|
||||||
void uiControlDestroy(uiControl *c)
|
void uiControlDestroy(uiControl *c)
|
||||||
{
|
{
|
||||||
struct controlBase *cb = controlBase(c);
|
(*(c->Destroy))(c);
|
||||||
|
|
||||||
if (cb->parent != NULL)
|
|
||||||
complain("attempt to destroy uiControl %p while it has a parent", c);
|
|
||||||
(*(c->CommitDestroy))(c);
|
|
||||||
uiFree(cb);
|
|
||||||
uiFree(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t uiControlHandle(uiControl *c)
|
uintptr_t uiControlHandle(uiControl *c)
|
||||||
|
@ -28,114 +14,57 @@ uintptr_t uiControlHandle(uiControl *c)
|
||||||
|
|
||||||
uiControl *uiControlParent(uiControl *c)
|
uiControl *uiControlParent(uiControl *c)
|
||||||
{
|
{
|
||||||
struct controlBase *cb = controlBase(c);
|
return (*(c->Parent))(c);
|
||||||
|
|
||||||
return cb->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO ask the control instead
|
|
||||||
int isToplevel(uiControl *c)
|
|
||||||
{
|
|
||||||
return c->TypeSignature == uiWindowSignature;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiControlSetParent(uiControl *c, uiControl *parent)
|
void uiControlSetParent(uiControl *c, uiControl *parent)
|
||||||
{
|
{
|
||||||
struct controlBase *cb = controlBase(c);
|
(*(c->SetParent))(c, parent);
|
||||||
|
|
||||||
if (isToplevel(c))
|
|
||||||
complain("cannot set a parent on a toplevel (uiWindow)");
|
|
||||||
if (parent != NULL && cb->parent != NULL)
|
|
||||||
complain("attempt to reparent uiControl %p (has parent %p, attempt to give parent %p)", c, cb->parent, parent);
|
|
||||||
if (parent == NULL && cb->parent == NULL)
|
|
||||||
complain("attempt to double unparent uiControl %p", c);
|
|
||||||
cb->parent = parent;
|
|
||||||
// for situations such as where the old parent was disabled but the new one is not, etc.
|
|
||||||
controlUpdateState(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// only to be called by the immediate parent of a control
|
void uiControlUpdateChildren(uiControl *c)
|
||||||
int controlSelfVisible(uiControl *c)
|
|
||||||
{
|
{
|
||||||
struct controlBase *cb = controlBase(c);
|
(*(c->UpdateChildren))(c);
|
||||||
|
|
||||||
return !cb->hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int controlContainerVisible(uiControl *c)
|
int uiControlToplevel(uiControl *c)
|
||||||
{
|
{
|
||||||
struct controlBase *cb = controlBase(c);
|
return (*(c->Toplevel))(c);
|
||||||
|
}
|
||||||
|
|
||||||
if (cb->hidden)
|
int uiControlVisible(uiControl *c)
|
||||||
return 0;
|
{
|
||||||
if (cb->parent == NULL)
|
return (*(c->Visible))(c);
|
||||||
return 1;
|
|
||||||
return controlContainerVisible(cb->parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiControlShow(uiControl *c)
|
void uiControlShow(uiControl *c)
|
||||||
{
|
{
|
||||||
struct controlBase *cb = controlBase(c);
|
(*(c->Show))(c);
|
||||||
|
|
||||||
cb->hidden = 0;
|
|
||||||
controlUpdateState(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiControlHide(uiControl *c)
|
void uiControlHide(uiControl *c)
|
||||||
{
|
{
|
||||||
struct controlBase *cb = controlBase(c);
|
(*(c->Hide))(c);
|
||||||
|
|
||||||
cb->hidden = 1;
|
|
||||||
controlUpdateState(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int controlContainerEnabled(uiControl *c)
|
int uiControlEnabled(uiControl *c)
|
||||||
{
|
{
|
||||||
struct controlBase *cb = controlBase(c);
|
return (*(c->Enabled))(c);
|
||||||
|
|
||||||
if (cb->disabled)
|
|
||||||
return 0;
|
|
||||||
if (cb->parent == NULL)
|
|
||||||
return 1;
|
|
||||||
return controlContainerEnabled(cb->parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiControlEnable(uiControl *c)
|
void uiControlEnable(uiControl *c)
|
||||||
{
|
{
|
||||||
struct controlBase *cb = controlBase(c);
|
(*(c->Enable))(c);
|
||||||
|
|
||||||
cb->disabled = 0;
|
|
||||||
controlUpdateState(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiControlDisable(uiControl *c)
|
void uiControlDisable(uiControl *c)
|
||||||
{
|
{
|
||||||
struct controlBase *cb = controlBase(c);
|
(*(c->Disable))(c);
|
||||||
|
|
||||||
cb->disabled = 1;
|
|
||||||
controlUpdateState(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void controlUpdateState(uiControl *c)
|
|
||||||
{
|
|
||||||
if (controlContainerVisible(c))
|
|
||||||
(*(c->CommitShow))(c);
|
|
||||||
else
|
|
||||||
(*(c->CommitHide))(c);
|
|
||||||
if (controlContainerEnabled(c))
|
|
||||||
osCommitEnable(c);
|
|
||||||
else
|
|
||||||
osCommitDisable(c);
|
|
||||||
(*(c->ContainerUpdateState))(c);
|
|
||||||
// and queue a resize, just in case we showed/hid something
|
|
||||||
// for instance, on Windows uiBox, if we don't do this, hiding a control will show empty space until the window is resized
|
|
||||||
//TODO uiControlQueueResize(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define uiControlSignature 0x7569436F
|
#define uiControlSignature 0x7569436F
|
||||||
|
|
||||||
// TODO should this be public?
|
uiControl *uiAllocControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr)
|
||||||
uiControl *newControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr)
|
|
||||||
{
|
{
|
||||||
uiControl *c;
|
uiControl *c;
|
||||||
|
|
||||||
|
@ -146,3 +75,40 @@ uiControl *newControl(size_t size, uint32_t OSsig, uint32_t typesig, const char
|
||||||
c->Internal = uiNew(struct controlBase);
|
c->Internal = uiNew(struct controlBase);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uiFreeControl(uiControl *c)
|
||||||
|
{
|
||||||
|
uiFree(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO except where noted, replace complain() with userbug()
|
||||||
|
|
||||||
|
void uiControlVerifyDestroy(uiControl *c)
|
||||||
|
{
|
||||||
|
if (uiControlParent(c) != NULL)
|
||||||
|
complain("attempt to destroy uiControl %p while it has a parent", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void uiControlVerifySetParent(uiControl *c, uiControl *parent)
|
||||||
|
{
|
||||||
|
uiControl *curParent;
|
||||||
|
|
||||||
|
if (uiControlToplevel(c))
|
||||||
|
complain("cannot set a parent on a toplevel (uiWindow)");
|
||||||
|
curParent = uiControlParent(c);
|
||||||
|
if (parent != NULL && curParent != NULL)
|
||||||
|
complain("attempt to reparent uiControl %p (has parent %p, attempt to give parent %p)", c, curParent, parent);
|
||||||
|
if (parent == NULL && curParent == NULL)
|
||||||
|
// TODO implbug()
|
||||||
|
complain("attempt to double unparent uiControl %p — likely an implementation bug ", c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int uiControlEnabledToUser(uiControl *c)
|
||||||
|
{
|
||||||
|
while (c != NULL) {
|
||||||
|
if (!uiControlEnabled(c))
|
||||||
|
return 0;
|
||||||
|
c = uiControlParent(c);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -74,5 +74,5 @@ void uiDarwinSetControlFont(NSControl *c, NSControlSize size)
|
||||||
|
|
||||||
uiDarwinControl *uiDarwinNewControl(size_t n, uint32_t typesig, const char *typenamestr)
|
uiDarwinControl *uiDarwinNewControl(size_t n, uint32_t typesig, const char *typenamestr)
|
||||||
{
|
{
|
||||||
return uiDarwinControl(newControl(n, uiDarwinControlSignature, typesig, typenamestr));
|
return uiDarwinControl(uiAllocControl(n, uiDarwinControlSignature, typesig, typenamestr));
|
||||||
}
|
}
|
||||||
|
|
4
ui.h
4
ui.h
|
@ -77,6 +77,10 @@ _UI_EXTERN void uiControlDisable(uiControl *);
|
||||||
_UI_EXTERN uiControl *uiAllocControl(size_t n, uint32_t OSsig, uint32_t typesig, const char *typenamestr);
|
_UI_EXTERN uiControl *uiAllocControl(size_t n, uint32_t OSsig, uint32_t typesig, const char *typenamestr);
|
||||||
_UI_EXTERN void uiFreeControl(uiControl *);
|
_UI_EXTERN void uiFreeControl(uiControl *);
|
||||||
|
|
||||||
|
_UI_EXTERN void uiControlVerifyDestroy(uiControl *);
|
||||||
|
_UI_EXTERN void uiControlVerifySetParent(uiControl *);
|
||||||
|
_UI_EXTERN int uiControlEnabledToUser(uiControl *);
|
||||||
|
|
||||||
typedef struct uiWindow uiWindow;
|
typedef struct uiWindow uiWindow;
|
||||||
#define uiWindow(this) ((uiWindow *) (this))
|
#define uiWindow(this) ((uiWindow *) (this))
|
||||||
_UI_EXTERN char *uiWindowTitle(uiWindow *w);
|
_UI_EXTERN char *uiWindowTitle(uiWindow *w);
|
||||||
|
|
|
@ -34,5 +34,5 @@ void uiUnixFinishControl(uiControl *c)
|
||||||
|
|
||||||
uiUnixControl *uiUnixNewControl(size_t n, uint32_t typesig, const char *typenamestr)
|
uiUnixControl *uiUnixNewControl(size_t n, uint32_t typesig, const char *typenamestr)
|
||||||
{
|
{
|
||||||
return uiUnixControl(newControl(n, uiUnixControlSignature, typesig, typenamestr));
|
return uiUnixControl(uiAllocControl(n, uiUnixControlSignature, typesig, typenamestr));
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,5 +66,5 @@ void uiWindowsRearrangeControlIDsZOrder(uiControl *c)
|
||||||
|
|
||||||
uiWindowsControl *uiWindowsNewControl(size_t n, uint32_t typesig, const char *typenamestr)
|
uiWindowsControl *uiWindowsNewControl(size_t n, uint32_t typesig, const char *typenamestr)
|
||||||
{
|
{
|
||||||
return uiWindowsControl(newControl(n, uiWindowsControlSignature, typesig, typenamestr));
|
return uiWindowsControl(uiAllocControl(n, uiWindowsControlSignature, typesig, typenamestr));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue