154 lines
3.6 KiB
C
154 lines
3.6 KiB
C
|
// 26 may 2015
|
||
|
#include "out/ui.h"
|
||
|
#include "uipriv.h"
|
||
|
|
||
|
struct controlBase {
|
||
|
uiControl *parent;
|
||
|
int hidden;
|
||
|
int disabled;
|
||
|
};
|
||
|
|
||
|
static uintmax_t type_uiControl = 0;
|
||
|
|
||
|
uintmax_t uiTypeControl(void)
|
||
|
{
|
||
|
if (type_uiControl == 0)
|
||
|
type_uiControl = uiRegisterType("uiControl", 0, 0);
|
||
|
return type_uiControl;
|
||
|
}
|
||
|
|
||
|
#define controlBase(c) ((struct controlBase *) (c->Internal))
|
||
|
|
||
|
static void controlBaseDestroy(uiControl *c)
|
||
|
{
|
||
|
struct controlBase *cb = controlBase(c);
|
||
|
|
||
|
if (cb->parent != NULL)
|
||
|
complain("attempt to destroy uiControl %p while it has a parent", c);
|
||
|
uiControlCommitDestroy(c);
|
||
|
uiFree(cb);
|
||
|
uiFree(c);
|
||
|
}
|
||
|
|
||
|
static uiControl *controlBaseParent(uiControl *c)
|
||
|
{
|
||
|
struct controlBase *cb = controlBase(c);
|
||
|
|
||
|
return cb->parent;
|
||
|
}
|
||
|
|
||
|
static void controlBaseSetParent(uiControl *c, uiControl *parent)
|
||
|
{
|
||
|
struct controlBase *cb = controlBase(c);
|
||
|
|
||
|
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);
|
||
|
// this must come first; GTK+ CommitSetParent() needs the old parent
|
||
|
uiControlCommitSetParent(c, parent);
|
||
|
cb->parent = parent;
|
||
|
// for situations such as where the old parent was disabled but the new one is not, etc.
|
||
|
uiControlUpdateState(c);
|
||
|
}
|
||
|
|
||
|
static void controlBaseQueueResize(uiControl *c)
|
||
|
{
|
||
|
queueResize(c);
|
||
|
}
|
||
|
|
||
|
static int controlBaseContainerVisible(uiControl *c)
|
||
|
{
|
||
|
struct controlBase *cb = controlBase(c);
|
||
|
|
||
|
if (cb->hidden)
|
||
|
return 0;
|
||
|
if (cb->parent == NULL)
|
||
|
return 1;
|
||
|
return uiControlContainerVisible(cb->parent);
|
||
|
}
|
||
|
|
||
|
static void controlBaseShow(uiControl *c)
|
||
|
{
|
||
|
struct controlBase *cb = controlBase(c);
|
||
|
|
||
|
cb->hidden = 0;
|
||
|
uiControlUpdateState(c);
|
||
|
}
|
||
|
|
||
|
static void controlBaseHide(uiControl *c)
|
||
|
{
|
||
|
struct controlBase *cb = controlBase(c);
|
||
|
|
||
|
cb->hidden = 1;
|
||
|
uiControlUpdateState(c);
|
||
|
}
|
||
|
|
||
|
static int controlBaseContainerEnabled(uiControl *c)
|
||
|
{
|
||
|
struct controlBase *cb = controlBase(c);
|
||
|
|
||
|
if (cb->disabled)
|
||
|
return 0;
|
||
|
if (cb->parent == NULL)
|
||
|
return 1;
|
||
|
return uiControlContainerEnabled(cb->parent);
|
||
|
}
|
||
|
|
||
|
static void controlBaseEnable(uiControl *c)
|
||
|
{
|
||
|
struct controlBase *cb = controlBase(c);
|
||
|
|
||
|
cb->disabled = 0;
|
||
|
uiControlUpdateState(c);
|
||
|
}
|
||
|
|
||
|
static void controlBaseDisable(uiControl *c)
|
||
|
{
|
||
|
struct controlBase *cb = controlBase(c);
|
||
|
|
||
|
cb->disabled = 1;
|
||
|
uiControlUpdateState(c);
|
||
|
}
|
||
|
|
||
|
static void controlBaseUpdateState(uiControl *c)
|
||
|
{
|
||
|
if (uiControlContainerVisible(c))
|
||
|
uiControlCommitShow(c);
|
||
|
else
|
||
|
uiControlCommitHide(c);
|
||
|
if (uiControlContainerEnabled(c))
|
||
|
uiControlCommitEnable(c);
|
||
|
else
|
||
|
uiControlCommitDisable(c);
|
||
|
uiControlContainerUpdateState(c);
|
||
|
// and queue a resize, just in case we showed/hid something
|
||
|
uiControlQueueResize(c);
|
||
|
}
|
||
|
|
||
|
static void controlBaseContainerUpdateState(uiControl *c)
|
||
|
{
|
||
|
// by default not a container; do nothing
|
||
|
}
|
||
|
|
||
|
uiControl *uiNewControl(uintmax_t type)
|
||
|
{
|
||
|
uiControl *c;
|
||
|
|
||
|
c = uiControl(newTyped(type));
|
||
|
uiControl(c)->Internal = uiNew(struct controlBase);
|
||
|
uiControl(c)->Destroy = controlBaseDestroy;
|
||
|
uiControl(c)->Parent = controlBaseParent;
|
||
|
uiControl(c)->SetParent = controlBaseSetParent;
|
||
|
uiControl(c)->QueueResize = controlBaseQueueResize;
|
||
|
uiControl(c)->ContainerVisible = controlBaseContainerVisible;
|
||
|
uiControl(c)->Show = controlBaseShow;
|
||
|
uiControl(c)->Hide = controlBaseHide;
|
||
|
uiControl(c)->ContainerEnabled = controlBaseContainerEnabled;
|
||
|
uiControl(c)->Enable = controlBaseEnable;
|
||
|
uiControl(c)->Disable = controlBaseDisable;
|
||
|
uiControl(c)->UpdateState = controlBaseUpdateState;
|
||
|
uiControl(c)->ContainerUpdateState = controlBaseContainerUpdateState;
|
||
|
return uiControl(c);
|
||
|
}
|