Moved the new control stuff back.
This commit is contained in:
parent
1790de24c8
commit
ecd14aaa12
210
redo/control.c
210
redo/control.c
|
@ -1,177 +1,141 @@
|
|||
// 6 april 2015
|
||||
// 26 may 2015
|
||||
#include "out/ui.h"
|
||||
#include "uipriv.h"
|
||||
|
||||
struct singleControl {
|
||||
void *internal;
|
||||
struct controlBase {
|
||||
uiControl *parent;
|
||||
int userHidden;
|
||||
int containerHidden;
|
||||
int userDisabled;
|
||||
int containerDisabled;
|
||||
int hidden;
|
||||
int disabled;
|
||||
};
|
||||
|
||||
static void singleDestroy(uiControl *c)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
#define controlBase(c) ((struct controlBase *) (c->Internal))
|
||||
|
||||
if (s->parent != NULL)
|
||||
complain("attempt to destroy a uiControl at %p while it still has a parent", c);
|
||||
osSingleDestroy(s->internal);
|
||||
uiFree(s);
|
||||
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 uintptr_t singleHandle(uiControl *c)
|
||||
static uiControl *controlBaseParent(uiControl *c)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
struct controlBase *cb = controlBase(c);
|
||||
|
||||
return osSingleHandle(s->internal);
|
||||
return cb->parent;
|
||||
}
|
||||
|
||||
static uiControl *singleParent(uiControl *c)
|
||||
static void controlBaseSetParent(uiControl *c, uiControl *parent)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
struct controlBase *cb = controlBase(c);
|
||||
|
||||
return s->parent;
|
||||
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;
|
||||
uiControlCommitSetParent(c, parent);
|
||||
// for situations such as where the old parent was disabled but the new one is not, etc.
|
||||
uiControlUpdateState(c);
|
||||
}
|
||||
|
||||
static void singleSetParent(uiControl *c, uiControl *parent)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
uiControl *oldparent;
|
||||
|
||||
oldparent = s->parent;
|
||||
s->parent = parent;
|
||||
osSingleSetParent(s->internal, oldparent, s->parent);
|
||||
}
|
||||
|
||||
static void singleResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
|
||||
osSingleResize(s->internal, x, y, width, height, d);
|
||||
}
|
||||
|
||||
static void singleQueueResize(uiControl *c)
|
||||
static void controlBaseQueueResize(uiControl *c)
|
||||
{
|
||||
queueResize(c);
|
||||
}
|
||||
|
||||
static uiSizing *singleSizing(uiControl *c)
|
||||
static int controlBaseContainerVisible(uiControl *c)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
struct controlBase *cb = controlBase(c);
|
||||
|
||||
return osSingleSizing(s->internal, c);
|
||||
if (cb->hidden)
|
||||
return 0;
|
||||
if (cb->parent == NULL)
|
||||
return 1;
|
||||
return uiControlContainerVisible(cb->parent);
|
||||
}
|
||||
|
||||
static int singleContainerVisible(uiControl *c)
|
||||
static void controlBaseShow(uiControl *c)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
struct controlBase *cb = controlBase(c);
|
||||
|
||||
return !s->userHidden && !s->containerHidden;
|
||||
cb->hidden = 0;
|
||||
uiControlUpdateState(c);
|
||||
}
|
||||
|
||||
static void singleShow(uiControl *c)
|
||||
static void controlBaseHide(uiControl *c)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
struct controlBase *cb = controlBase(c);
|
||||
|
||||
s->userHidden = 0;
|
||||
if (!s->containerHidden)
|
||||
osSingleShow(s->internal);
|
||||
if (s->parent != NULL)
|
||||
uiControlQueueResize(s->parent);
|
||||
cb->hidden = 1;
|
||||
uiControlUpdateState(c);
|
||||
}
|
||||
|
||||
static void singleHide(uiControl *c)
|
||||
static int controlBaseContainerEnabled(uiControl *c)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
struct controlBase *cb = controlBase(c);
|
||||
|
||||
s->userHidden = 1;
|
||||
osSingleHide(s->internal);
|
||||
if (s->parent != NULL)
|
||||
uiControlQueueResize(s->parent);
|
||||
if (cb->disabled)
|
||||
return 0;
|
||||
if (cb->parent == NULL)
|
||||
return 1;
|
||||
return uiControlContainerEnabled(cb->parent);
|
||||
}
|
||||
|
||||
static void singleContainerShow(uiControl *c)
|
||||
static void controlBaseEnable(uiControl *c)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
struct controlBase *cb = controlBase(c);
|
||||
|
||||
s->containerHidden = 0;
|
||||
if (!s->userHidden)
|
||||
osSingleShow(s->internal);
|
||||
if (s->parent != NULL)
|
||||
uiControlQueueResize(s->parent);
|
||||
cb->disabled = 0;
|
||||
uiControlUpdateState(c);
|
||||
}
|
||||
|
||||
static void singleContainerHide(uiControl *c)
|
||||
static void controlBaseDisable(uiControl *c)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
struct controlBase *cb = controlBase(c);
|
||||
|
||||
s->containerHidden = 1;
|
||||
osSingleHide(s->internal);
|
||||
if (s->parent != NULL)
|
||||
uiControlQueueResize(s->parent);
|
||||
cb->disabled = 1;
|
||||
uiControlUpdateState(c);
|
||||
}
|
||||
|
||||
static void singleEnable(uiControl *c)
|
||||
static void controlBaseUpdateState(uiControl *c)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
|
||||
s->userDisabled = 0;
|
||||
if (!s->containerDisabled)
|
||||
osSingleEnable(s->internal);
|
||||
if (uiControlContainerVisible(c))
|
||||
uiControlCommitShow(c);
|
||||
else
|
||||
uiControlCommitHide(c);
|
||||
if (uiControlContainerEnabled(c))
|
||||
uiControlCommitEnable(c);
|
||||
else
|
||||
uiControlCommitDisable(c);
|
||||
uiControlContainerUpdateState(c);
|
||||
}
|
||||
|
||||
static void singleDisable(uiControl *c)
|
||||
static void controlBaseContainerUpdateState(uiControl *c)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
|
||||
s->userDisabled = 1;
|
||||
osSingleDisable(s->internal);
|
||||
// by default not a container; do nothing
|
||||
}
|
||||
|
||||
static void singleContainerEnable(uiControl *c)
|
||||
uiControl *uiNewControl(uintmax_t type)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
uiControl *c;
|
||||
|
||||
s->containerDisabled = 0;
|
||||
if (!s->userDisabled)
|
||||
osSingleEnable(s->internal);
|
||||
}
|
||||
|
||||
static void singleContainerDisable(uiControl *c)
|
||||
{
|
||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
||||
|
||||
s->containerDisabled = 1;
|
||||
osSingleDisable(s->internal);
|
||||
}
|
||||
|
||||
void makeControl(uiControl *c, void *internal)
|
||||
{
|
||||
struct singleControl *s;
|
||||
|
||||
s = uiNew(struct singleControl);
|
||||
|
||||
s->internal = internal;
|
||||
|
||||
uiControl(c)->Internal = s;
|
||||
uiControl(c)->Destroy = singleDestroy;
|
||||
uiControl(c)->Handle = singleHandle;
|
||||
uiControl(c)->Parent = singleParent;
|
||||
uiControl(c)->SetParent = singleSetParent;
|
||||
// PreferredSize() implemented by subclasses
|
||||
uiControl(c)->Resize = singleResize;
|
||||
uiControl(c)->QueueResize = singleQueueResize;
|
||||
uiControl(c)->Sizing = singleSizing;
|
||||
uiControl(c)->ContainerVisible = singleContainerVisible;
|
||||
uiControl(c)->Show = singleShow;
|
||||
uiControl(c)->Hide = singleHide;
|
||||
uiControl(c)->ContainerShow = singleContainerShow;
|
||||
uiControl(c)->ContainerHide = singleContainerHide;
|
||||
uiControl(c)->Enable = singleEnable;
|
||||
uiControl(c)->Disable = singleDisable;
|
||||
uiControl(c)->ContainerEnable = singleContainerEnable;
|
||||
uiControl(c)->ContainerDisable = singleContainerDisable;
|
||||
// SysFunc and SetZOrder implemented by subclasses
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
// 26 may 2015
|
||||
#include "out/ui.h"
|
||||
#include "uipriv.h"
|
||||
|
||||
struct controlBase {
|
||||
uiControl *parent;
|
||||
int hidden;
|
||||
int disabled;
|
||||
};
|
||||
|
||||
#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);
|
||||
cb->parent = parent;
|
||||
uiControlCommitSetParent(c, 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
// 17 may 2015
|
||||
#include "out/ui.h"
|
||||
#include "uipriv.h"
|
||||
|
||||
struct typeinfo {
|
||||
const char *name;
|
||||
uintmax_t parent;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static struct ptrArray *types = NULL;
|
||||
|
||||
uintmax_t uiRegisterType(const char *name, uintmax_t parent, size_t size)
|
||||
{
|
||||
struct typeinfo *ti;
|
||||
|
||||
if (types == NULL) {
|
||||
types = newPtrArray();
|
||||
// reserve ID 0
|
||||
ptrArrayAppend(types, NULL);
|
||||
}
|
||||
ti = uiNew(struct typeinfo);
|
||||
ti->name = name;
|
||||
ti->parent = parent;
|
||||
ti->size = size;
|
||||
ptrArrayAppend(types, ti);
|
||||
return types->len - 1;
|
||||
}
|
||||
|
||||
void *uiIsA(void *p, uintmax_t id, int fail)
|
||||
{
|
||||
uiTyped *t;
|
||||
struct typeinfo *ti, *ti2;
|
||||
uintmax_t compareTo;
|
||||
|
||||
if (id == 0 || id >= types->len)
|
||||
complain("invalid type ID given to uiIsA()");
|
||||
t = (uiTyped *) p;
|
||||
compareTo = t->Type;
|
||||
if (compareTo == 0)
|
||||
complain("object %p has no type in uiIsA()", t);
|
||||
for (;;) {
|
||||
if (compareTo >= types->len)
|
||||
complain("invalid type ID in uiIsA()", t);
|
||||
if (compareTo == id)
|
||||
return t;
|
||||
ti = ptrArrayIndex(types, struct typeinfo *, compareTo);
|
||||
if (ti->parent == 0)
|
||||
break;
|
||||
compareTo = ti->parent;
|
||||
}
|
||||
if (fail) {
|
||||
ti = ptrArrayIndex(types, struct typeinfo *, id);
|
||||
ti2 = ptrArrayIndex(types, struct typeinfo *, t->Type);
|
||||
complain("object %p not a %s in uiIsA() (is a %s)", t, ti->name, ti2->name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO free type info
|
||||
|
||||
uiTyped *newTyped(uintmax_t type)
|
||||
{
|
||||
struct typeinfo *ti;
|
||||
uiTyped *instance;
|
||||
|
||||
if (type == 0 || id >= types->len)
|
||||
complain("invalid type ID given to newTyped()");
|
||||
ti = ptrArrayIndex(types, struct typeinfo *, type);
|
||||
instance = (uiTyped *) uiAlloc(ti->size, ti->name);
|
||||
instance->Type = type;
|
||||
return instance;
|
||||
}
|
|
@ -1,229 +0,0 @@
|
|||
// 6 april 2015
|
||||
|
||||
// This is not an IDL file for the conventional RPC or Microsoft IDLs.
|
||||
// Instead, this is for a custom IDL of my own creation.
|
||||
// You can find it at github.com/andlabs/pgidl
|
||||
|
||||
package ui {
|
||||
|
||||
raw "#include <stddef.h>";
|
||||
raw "#include <stdint.h>";
|
||||
|
||||
raw "#ifndef _UI_EXTERN";
|
||||
raw "#define _UI_EXTERN extern";
|
||||
raw "#endif";
|
||||
|
||||
struct InitOptions {
|
||||
field Size size_t;
|
||||
};
|
||||
|
||||
func Init(options *InitOptions) *const char;
|
||||
func Uninit(void);
|
||||
func FreeInitError(err *const char);
|
||||
|
||||
func Main(void);
|
||||
func Quit(void);
|
||||
|
||||
func OnShouldQuit(f *func(data *void) int, data *void);
|
||||
|
||||
func FreeText(text *char);
|
||||
|
||||
func RegisterType(name *const char, parent uintmax_t, size size_t) uintmax_t;
|
||||
func IsA(p *void, type uintmax_t, fail int) *void;
|
||||
struct Typed {
|
||||
field Type uintmax_t;
|
||||
};
|
||||
raw "#define uiTyped(this) ((uiTyped *) (this))";
|
||||
|
||||
raw "typedef struct uiSizingSys uiSizingSys;";
|
||||
|
||||
struct Sizing {
|
||||
field XPadding intmax_t;
|
||||
field YPadding intmax_t;
|
||||
field Sys *uiSizingSys;
|
||||
};
|
||||
|
||||
raw "typedef struct uiControlSysFuncParams uiControlSysFuncParams;";
|
||||
raw "#define uiControlSysFuncNop 0";
|
||||
|
||||
interface Control {
|
||||
field Internal *void; // for use by ui only
|
||||
func Destroy(void);
|
||||
func Handle(void) uintptr_t;
|
||||
func Parent(void) *Control;
|
||||
func SetParent(c *Control);
|
||||
func PreferredSize(d *Sizing, width *intmax_t, height *intmax_t);
|
||||
func Resize(x intmax_t, y intmax_t, width intmax_t, height intmax_t, d *Sizing);
|
||||
func QueueResize(void);
|
||||
func Sizing(void) *Sizing;
|
||||
func ContainerVisible(void) int;
|
||||
func Show(void);
|
||||
func Hide(void);
|
||||
func ContainerEnabled(void) int;
|
||||
func Enable(void);
|
||||
func Disable(void);
|
||||
func UpdateState(void);
|
||||
func SysFunc(p *uiControlSysFuncParams);
|
||||
func StartZOrder(p *uiControlSysFuncParams) int;
|
||||
func CommitDestroy(void);
|
||||
func CommitSetParent(uiControl *);
|
||||
func CommitShow(void);
|
||||
func CommitHide(void);
|
||||
func CommitEnable(void);
|
||||
func CommitDisable(void);
|
||||
func ContainerUpdateState(void);
|
||||
};
|
||||
|
||||
func NewControl(type uintmax_t) *Control;
|
||||
|
||||
raw "#define uiDefineControlType(typename, funcname, realtype) \";
|
||||
raw " static uintmax_t type_ ## typename = 0; \";
|
||||
raw " uintmax_t funcname(void) \";
|
||||
raw " { \";
|
||||
raw " if (type_ ## typename == 0) \";
|
||||
raw " type_ ## typename = uiRegisterType(#typename, uiTypeControl(), sizeof (realtype)); \";
|
||||
raw " return type_ ## typename; \";
|
||||
raw " }";
|
||||
|
||||
func FreeSizing(d *Sizing);
|
||||
|
||||
func MakeContainer(c *Control);
|
||||
|
||||
interface Window from Control {
|
||||
func Title(void) *char;
|
||||
func SetTitle(title *const char);
|
||||
func OnClosing(f *func(w *Window, data *void) int, data *void);
|
||||
func SetChild(c *Control);
|
||||
func Margined(void) int;
|
||||
func SetMargined(margined int);
|
||||
func ResizeChild(void);
|
||||
};
|
||||
func NewWindow(title *const char, width int, height int, hasMenubar int) *Window;
|
||||
|
||||
interface Button from Control {
|
||||
func Text(void) *char;
|
||||
func SetText(text *const char);
|
||||
func OnClicked(f *func(b *Button, data *void), data *void);
|
||||
};
|
||||
func NewButton(text *const char) *Button;
|
||||
|
||||
interface Box from Control {
|
||||
func Append(c *Control, stretchy int);
|
||||
func Delete(index uintmax_t);
|
||||
func Padded(void) int;
|
||||
func SetPadded(padded int);
|
||||
};
|
||||
func NewHorizontalBox(void) *Box;
|
||||
func NewVerticalBox(void) *Box;
|
||||
|
||||
interface Entry from Control {
|
||||
func Text(void) *char;
|
||||
func SetText(text *const char);
|
||||
func OnChanged(f *func(e *Entry, data *void), data *void);
|
||||
func ReadOnly(void) int;
|
||||
func SetReadOnly(readonly int);
|
||||
};
|
||||
func NewEntry(void) *Entry;
|
||||
|
||||
interface Checkbox from Control {
|
||||
func Text(void) *char;
|
||||
func SetText(text *const char);
|
||||
func OnToggled(f *func(c *Checkbox, data *void), data *void);
|
||||
func Checked(void) int;
|
||||
func SetChecked(checked int);
|
||||
};
|
||||
func NewCheckbox(text *const char) *Checkbox;
|
||||
|
||||
interface Label from Control {
|
||||
func Text(void) *char;
|
||||
func SetText(text *const char);
|
||||
};
|
||||
func NewLabel(text *const char) *Label;
|
||||
|
||||
interface Tab from Control {
|
||||
func Append(name *const char, c *Control);
|
||||
func InsertAt(name *const char, before uintmax_t, c *Control);
|
||||
func Delete(index uintmax_t);
|
||||
func NumPages(void) uintmax_t;
|
||||
func Margined(page uintmax_t) int;
|
||||
func SetMargined(page uintmax_t, margined int);
|
||||
};
|
||||
func NewTab(void) *Tab;
|
||||
|
||||
interface Group from Control {
|
||||
// TODO text and settext
|
||||
func SetChild(c *Control);
|
||||
// TODO margined and setmargined
|
||||
};
|
||||
func NewGroup(text *const char) *Group;
|
||||
|
||||
// spinbox/slider rules:
|
||||
// setting value outside of range will automatically clamp
|
||||
// initial value is minimum
|
||||
// TODO what happens if max > min? max == min?
|
||||
|
||||
interface Spinbox from Control {
|
||||
func Value(void) intmax_t;
|
||||
func SetValue(value intmax_t);
|
||||
func OnChanged(f *func(s *Spinbox, data *void), data *void);
|
||||
};
|
||||
func NewSpinbox(min intmax_t, max intmax_t) *Spinbox;
|
||||
|
||||
interface ProgressBar from Control {
|
||||
// TODO Value()
|
||||
func SetValue(n int);
|
||||
};
|
||||
func NewProgressBar(void) *ProgressBar;
|
||||
|
||||
interface Slider from Control {
|
||||
func Value(void) intmax_t;
|
||||
func SetValue(value intmax_t);
|
||||
func OnChanged(f *func(s *Slider, data *void), data *void);
|
||||
};
|
||||
func NewSlider(min intmax_t, max intmax_t) *Slider;
|
||||
|
||||
interface Separator from Control {
|
||||
};
|
||||
func NewHorizontalSeparator(void) *Separator;
|
||||
|
||||
interface Combobox from Control {
|
||||
func Append(text *const char);
|
||||
};
|
||||
func NewCombobox(void) *Combobox;
|
||||
func NewEditableCombobox(void) *Combobox;
|
||||
|
||||
interface RadioButtons from Control {
|
||||
func Append(text *const char);
|
||||
};
|
||||
func NewRadioButtons(void) *RadioButtons;
|
||||
|
||||
interface DateTimePicker from Control {
|
||||
};
|
||||
func NewDateTimePicker(void) *DateTimePicker;
|
||||
func NewDatePicker(void) *DateTimePicker;
|
||||
func NewTimePicker(void) *DateTimePicker;
|
||||
|
||||
interface Menu {
|
||||
func AppendItem(name *const char) *MenuItem;
|
||||
func AppendCheckItem(name *const char) *MenuItem;
|
||||
func AppendQuitItem(void) *MenuItem;
|
||||
func AppendPreferencesItem(void) *MenuItem;
|
||||
func AppendAboutItem(void) *MenuItem;
|
||||
func AppendSeparator(void);
|
||||
};
|
||||
func NewMenu(name *const char) *Menu;
|
||||
|
||||
interface MenuItem {
|
||||
func Enable(void);
|
||||
func Disable(void);
|
||||
func OnClicked(f *func(sender *MenuItem, window *Window, data *void), data *void);
|
||||
func Checked(void) int;
|
||||
func SetChecked(checked int);
|
||||
};
|
||||
|
||||
func OpenFile(void) *char;
|
||||
func SaveFile(void) *char;
|
||||
func MsgBox(title *const char, description *const char);
|
||||
func MsgBoxError(title *const char, description *const char);
|
||||
|
||||
};
|
|
@ -1,69 +0,0 @@
|
|||
// 7 april 2015
|
||||
|
||||
/*
|
||||
This file assumes that you have included <windows.h> and "ui.h" beforehand. It provides API-specific functions for interfacing with foreign controls in Windows.
|
||||
*/
|
||||
|
||||
#ifndef __UI_UI_WINDOWS_H__
|
||||
#define __UI_UI_WINDOWS_H__
|
||||
|
||||
// TODO write comments for these
|
||||
_UI_EXTERN HWND uiWindowsUtilCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, HINSTANCE hInstance, LPVOID lpParam, BOOL useStandardControlFont);
|
||||
_UI_EXTERN void uiWindowsUtilDestroy(HWND hwnd);
|
||||
_UI_EXTERN void uiWindowsUtilSetParent(HWND hwnd, uiControl *parent);
|
||||
_UI_EXTERN void uiWindowsUtilResize(HWND hwnd, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d);
|
||||
_UI_EXTERN void uiWIndowsUtilShow(HWND hwnd);
|
||||
_UI_EXTERN void uiWindowsUtilHide(HWND hwnd);
|
||||
_UI_EXTERN void uiWIndowsUtilEnable(HWND hwnd);
|
||||
_UI_EXTERN void uiWindowsUtilDisable(HWND hwnd);
|
||||
_UI_EXTERN void uiWindowsUtilSysFunc(HWND hwnd, uiControlSysFuncParams *p);
|
||||
_UI_EXTERN void uiWindowsUtilStartZOrder(HWND hwnd, uiControlSysFuncParams *p);
|
||||
_UI_EXTERN uiControl *uiWindowsNewSingleHWNDControl(uintmax_t type);
|
||||
|
||||
// This contains the Windows-specific parts of the uiSizing structure.
|
||||
// BaseX and BaseY are the dialog base units.
|
||||
// InternalLeading is the standard control font's internal leading; labels in uiForms use this for correct Y positioning.
|
||||
// CoordFrom and CoordTo are the window handles to convert coordinates passed to uiControlResize() from and to (viaa MapWindowRect()) before passing to one of the Windows API resizing functions.
|
||||
struct uiSizingSys {
|
||||
int BaseX;
|
||||
int BaseY;
|
||||
LONG InternalLeading;
|
||||
HWND CoordFrom;
|
||||
HWND CoordTo;
|
||||
};
|
||||
// Use these in your preferredSize() implementation with baseX and baseY.
|
||||
#define uiWindowsDlgUnitsToX(dlg, baseX) MulDiv((dlg), baseX, 4)
|
||||
#define uiWindowsDlgUnitsToY(dlg, baseY) MulDiv((dlg), baseY, 8)
|
||||
// Use this as your control's Sizing() implementation.
|
||||
extern uiSizing *uiWindowsSizing(uiControl *);
|
||||
|
||||
// and use this if you need the text of the window width
|
||||
_UI_EXTERN intmax_t uiWindowsWindowTextWidth(HWND hwnd);
|
||||
|
||||
// these functions get and set the window text for such a uiControl
|
||||
// the value returned should be freed with uiFreeText()
|
||||
_UI_EXTERN char *uiWindowsControlText(uiControl *);
|
||||
_UI_EXTERN void uiWindowsControlSetText(uiControl *, const char *);
|
||||
|
||||
struct uiControlSysFuncParams {
|
||||
int Func;
|
||||
BOOL HasTabStops;
|
||||
HWND InsertAfter;
|
||||
};
|
||||
|
||||
enum {
|
||||
// These should enable and disable the uiControl while preserving the user enable/disable setting.
|
||||
// These are needed because while disabling a parent window does cause children to stop receiving events, they are not shown as disabled, which is not what we want.
|
||||
uiWindowsSysFuncContainerEnable,
|
||||
uiWindowsSysFuncContainerDisable,
|
||||
// This is interpreted by controls that are tab stops; the control should set HasTabStops to TRUE if so, and *LEAVE IT ALONE* if not.
|
||||
// You only need this if implementing your own uiControl.
|
||||
// Controls created with uiWindowsMakeControl() check for the window being enabled and the presence of WS_TABSTOP.
|
||||
// The name is "has tab stops" because it is used by uiTabs to say "does the current tab page have tab stops?".
|
||||
uiWindowsSysFuncHasTabStops,
|
||||
// This tells the current control to set its Z order to be after the control in the InsertAfter field.
|
||||
// You should also set your own handle to the InsertAfter field for the next control.
|
||||
uiWindowsSysFuncSetZOrder,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||
// 6 april 2015
|
||||
#include <stdlib.h>
|
||||
|
||||
#define uthash_fatal(msg) complain("uthash failed: %s", (msg))
|
||||
#define uthash_malloc(sz) uiAlloc((sz), "(uthash internal)")
|
||||
#define uthash_free(ptr,sz) uiFree((ptr))
|
||||
#include "uthash/uthash.h"
|
||||
|
||||
extern uiInitOptions options;
|
||||
|
||||
extern void *uiAlloc(size_t, const char *);
|
||||
#define uiNew(T) ((T *) uiAlloc(sizeof (T), #T))
|
||||
extern void *uiRealloc(void *, size_t, const char *);
|
||||
extern void uiFree(void *);
|
||||
|
||||
extern void complain(const char *, ...);
|
||||
|
||||
extern void queueResize(uiControl *);
|
||||
|
||||
// ptrarray.c
|
||||
struct ptrArray {
|
||||
void **ptrs;
|
||||
uintmax_t len;
|
||||
uintmax_t cap;
|
||||
};
|
||||
struct ptrArray *newPtrArray(void);
|
||||
void ptrArrayDestroy(struct ptrArray *);
|
||||
void ptrArrayAppend(struct ptrArray *, void *);
|
||||
void ptrArrayInsertAt(struct ptrArray *, uintmax_t, void *);
|
||||
void ptrArrayDelete(struct ptrArray *, uintmax_t);
|
||||
#define ptrArrayIndex(p, T, i) ((T) ((p)->ptrs[(i)]))
|
||||
|
||||
// shouldquit.c
|
||||
extern int shouldQuit(void);
|
||||
|
||||
// types.c
|
||||
extern uiTyped *newTyped(uintmax_t type);
|
|
@ -1,108 +0,0 @@
|
|||
// 7 april 2015
|
||||
#include "uipriv_windows.h"
|
||||
|
||||
struct button {
|
||||
uiButton b;
|
||||
HWND hwnd;
|
||||
void (*onClicked)(uiButton *, void *);
|
||||
void *onClickedData;
|
||||
void (*baseCommitDestroy)(uiControl *);
|
||||
};
|
||||
|
||||
uiDefineControlType(uiButton, uiTypeButton, struct button)
|
||||
|
||||
static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
|
||||
{
|
||||
struct button *b = (struct button *) c;
|
||||
|
||||
if (code != BN_CLICKED)
|
||||
return FALSE;
|
||||
(*(b->onClicked))(uiButton(b), b->onClickedData);
|
||||
*lResult = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void buttonCommitDestroy(uiControl *c)
|
||||
{
|
||||
struct button *b = (struct button *) c;
|
||||
|
||||
uiWindowsUnregisterWM_COMMANDHandler(b->hwnd);
|
||||
(*(b->baseCommitDestroy))(uiControl(b));
|
||||
}
|
||||
|
||||
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
||||
#define buttonHeight 14
|
||||
|
||||
static void buttonPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height)
|
||||
{
|
||||
struct button *b = (struct button *) c;
|
||||
SIZE size;
|
||||
|
||||
// try the comctl32 version 6 way
|
||||
size.cx = 0; // explicitly ask for ideal size
|
||||
size.cy = 0;
|
||||
if (SendMessageW(b->hwnd, BCM_GETIDEALSIZE, 0, (LPARAM) (&size)) != FALSE) {
|
||||
*width = size.cx;
|
||||
*height = size.cy;
|
||||
return;
|
||||
}
|
||||
|
||||
// that didn't work; fall back to using Microsoft's metrics
|
||||
// Microsoft says to use a fixed width for all buttons; this isn't good enough
|
||||
// use the text width instead, with some edge padding
|
||||
*width = uiWindowsWindowTextWidth(b->hwnd) + (2 * GetSystemMetrics(SM_CXEDGE));
|
||||
*height = uiWindowsDlgUnitsToY(buttonHeight, d->Sys->BaseY);
|
||||
}
|
||||
|
||||
static void defaultOnClicked(uiButton *b, void *data)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
static char *buttonText(uiButton *b)
|
||||
{
|
||||
return uiWindowsControlText(uiControl(b));
|
||||
}
|
||||
|
||||
static void buttonSetText(uiButton *b, const char *text)
|
||||
{
|
||||
uiWindowsControlSetText(uiControl(b), text);
|
||||
}
|
||||
|
||||
static void buttonOnClicked(uiButton *bb, void (*f)(uiButton *, void *), void *data)
|
||||
{
|
||||
struct button *b = (struct button *) bb;
|
||||
|
||||
b->onClicked = f;
|
||||
b->onClickedData = data;
|
||||
}
|
||||
|
||||
uiButton *uiNewButton(const char *text)
|
||||
{
|
||||
struct button *b;
|
||||
WCHAR *wtext;
|
||||
|
||||
b = (struct button *) uiWindowsNewControl(uiTypeButton());
|
||||
|
||||
wtext = toUTF16(text);
|
||||
b->hwnd = uiWindowsUtilCreateControlHWND(0,
|
||||
L"button", wtext,
|
||||
BS_PUSHBUTTON | WS_TABSTOP,
|
||||
hInstance, NULL,
|
||||
TRUE);
|
||||
uiFree(wtext);
|
||||
|
||||
uiWindowsRegisterWM_COMMANDHandler(b->hwnd, onWM_COMMAND, uiControl(b));
|
||||
|
||||
b->onClicked = defaultOnClicked;
|
||||
|
||||
uiControl(b)->PreferredSize = buttonPreferredSize;
|
||||
b->baseCommitDestroy = uiControl(b)->CommitDestroy;
|
||||
uiControl(b)->CommitDestroy = buttonCommitDestroy;
|
||||
|
||||
uiButton(b)->Text = buttonText;
|
||||
uiButton(b)->SetText = buttonSetText;
|
||||
uiButton(b)->OnClicked = buttonOnClicked;
|
||||
|
||||
return uiButton(b);
|
||||
}
|
|
@ -1,163 +0,0 @@
|
|||
// 27 may 2015
|
||||
#include "uipriv_windows.h"
|
||||
|
||||
// TODO Edit ,s/Util/HWND/g ?
|
||||
|
||||
HWND uiWindowsUtilCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, HINSTANCE hInstance, LPVOID lpParam, BOOL useStandardControlFont)
|
||||
{
|
||||
HWND hwnd;
|
||||
|
||||
hwnd = CreateWindowExW(dwExStyle,
|
||||
lpClassName, lpWIndowName,
|
||||
dwStyle | WS_CHILD | WS_VISIBLE,
|
||||
0, 0,
|
||||
// use a nonzero initial size just in case some control breaks with a zero initial size
|
||||
100, 100,
|
||||
utilWindow, NULL, hInstance, lpParam);
|
||||
if (hwnd == NULL)
|
||||
logLastError("error creating window in uiWindowsUtilCreateControlHWND()");
|
||||
if (useStandardControlFont)
|
||||
SendMessageW(hwnd, WM_SETFONT, (WPARAM) hMessageFont, (LPARAM) TRUE);
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
#define HWND(c) ((HWND) uiControlHandle((c)))
|
||||
|
||||
void uiWindowsUtilDestroy(HWND hwnd)
|
||||
{
|
||||
if (DestroyWindow(hwnd) == 0)
|
||||
logLastError("error destroying window in uiWindowsUtilDestroyWindow()");
|
||||
}
|
||||
|
||||
static void singleHWNDCommitDestroy(uiControl *c)
|
||||
{
|
||||
uiWindowsUtilDestroy(HWND(c));
|
||||
}
|
||||
|
||||
void uiWindowsUtilSetParent(HWND hwnd, uiControl *parent)
|
||||
{
|
||||
HWND newParent;
|
||||
|
||||
newParent = utilWindow;
|
||||
if (parent != NULL)
|
||||
newParent = HWND(parent);
|
||||
if (SetParent(hwnd, newParent) == 0)
|
||||
logLastError("error changing window parent in uiWindowsUtilSetParent()");
|
||||
}
|
||||
|
||||
static void singleHWNDCommitSetParent(uiControl *c, uiControl *parent)
|
||||
{
|
||||
uiWindowsUtilSetParent(HWND(c), parent);
|
||||
}
|
||||
|
||||
void uiWindowsUtilResize(HWND hwnd, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
|
||||
{
|
||||
moveWindow(hwnd, x, y, width, height, d);
|
||||
}
|
||||
|
||||
static void singleHWNDResize(HWND hwnd, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
|
||||
{
|
||||
uiWindowsUtilResize(HWND(c), x, y, width, height, d);
|
||||
}
|
||||
|
||||
static uiSizing *singleHWNDSizing(uiControl *c)
|
||||
{
|
||||
// TODO change this to take a HWND and the parent
|
||||
return uiWindowsSizing(c);
|
||||
}
|
||||
|
||||
void uiWIndowsUtilShow(HWND hwnd)
|
||||
{
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
}
|
||||
|
||||
static void singleHWNDCommitShow(uiControl *c)
|
||||
{
|
||||
uiWindowsUtilShow(HWND(c));
|
||||
}
|
||||
|
||||
void uiWindowsUtilHide(HWND hwnd)
|
||||
{
|
||||
ShowWindow(hwnd, SW_HIDE);
|
||||
}
|
||||
|
||||
static void singleHWNDCommitHide(uiControl *c)
|
||||
{
|
||||
uiWindowsUtilHide(HWND(c));
|
||||
}
|
||||
|
||||
void uiWIndowsUtilEnable(HWND hwnd)
|
||||
{
|
||||
EnableWindow(hwnd, TRUE);
|
||||
}
|
||||
|
||||
static void singleHWNDCommitEnable(uiControl *c)
|
||||
{
|
||||
uiWindowsUtilEnable(HWND(c));
|
||||
}
|
||||
|
||||
void uiWindowsUtilDisable(HWND hwnd)
|
||||
{
|
||||
EnableWindow(hwnd, FALSE);
|
||||
}
|
||||
|
||||
static void singleHWNDCommitDisable(uiControl *c)
|
||||
{
|
||||
uiWindowsUtilDisable(HWND(c));
|
||||
}
|
||||
|
||||
void uiWindowsUtilSysFunc(HWND hwnd, uiControlSysFuncParams *p)
|
||||
{
|
||||
switch (p->Func) {
|
||||
case uiControlSysFuncNop:
|
||||
return;
|
||||
case uiWindowsSysFuncHasTabStops:
|
||||
if ((getStyle(hwnd) & WS_TABSTOP) != 0)
|
||||
p->HasTabStops = TRUE;
|
||||
return;
|
||||
case uiWindowsSysFuncSetZOrder:
|
||||
setWindowInsertAfter(hwnd, p->InsertAfter);
|
||||
p->InsertAfter = hwnd;
|
||||
return;
|
||||
}
|
||||
complain("unknown uiControlSysFunc() function %d in uiWindowsUtilSysFunc()", p->Func);
|
||||
}
|
||||
|
||||
static void singleHWNDSysFunc(uiControl *c, uiControlSysFuncParams *p)
|
||||
{
|
||||
uiWindowsUtilSysFunc(HWND(c), p);
|
||||
}
|
||||
|
||||
void uiWindowsUtilStartZOrder(HWND hwnd, uiControlSysFuncParams *p)
|
||||
{
|
||||
HWND insertAfter;
|
||||
|
||||
// see http://stackoverflow.com/questions/30491418/
|
||||
insertAfter = GetWindow(hwnd, GW_HWNDPREV);
|
||||
if (insertAfter == NULL)
|
||||
logLastError("error getting insert after window in uiWindowsUtilStartZOrder()");
|
||||
p->InsertAfter = insertAfter;
|
||||
}
|
||||
|
||||
static void singleHWNDStartZOrder(uiControl *c, uiControlSysFuncParams *p)
|
||||
{
|
||||
uiWindowsUtilStartZOrder(HWND(c), p);
|
||||
}
|
||||
|
||||
uiControl *uiWindowsNewSingleHWNDControl(uintmax_t type)
|
||||
{
|
||||
uiControl *c;
|
||||
|
||||
c = uiNewControl(type);
|
||||
uiControl(c)->CommitDestroy = singleHWNDCommitDestroy;
|
||||
uiControl(c)->CommitSetParent = singleHWNDCommitSetParent;
|
||||
uiControl(c)->Resize = singleHWNDResize;
|
||||
uiControl(c)->Sizing = singleHWNDSizing;
|
||||
uiControl(c)->CommitShow = singleHWNDCommitShow;
|
||||
uiControl(c)->CommitHide = singleHWNDCommitHide
|
||||
uiControl(c)->CommitEnable = singleHWNDCommitEnable;
|
||||
uiControl(c)->CommitDisable = singleHWNDCommitDisable;
|
||||
uiControl(c)->SysFunc = singleHWNDSysFunc;
|
||||
uiControl(c)->StartZOrder = singleHWNDStartZOrder;
|
||||
return c;
|
||||
}
|
17
redo/types.c
17
redo/types.c
|
@ -5,11 +5,12 @@
|
|||
struct typeinfo {
|
||||
const char *name;
|
||||
uintmax_t parent;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static struct ptrArray *types = NULL;
|
||||
|
||||
uintmax_t uiRegisterType(const char *name, uintmax_t parent)
|
||||
uintmax_t uiRegisterType(const char *name, uintmax_t parent, size_t size)
|
||||
{
|
||||
struct typeinfo *ti;
|
||||
|
||||
|
@ -21,6 +22,7 @@ uintmax_t uiRegisterType(const char *name, uintmax_t parent)
|
|||
ti = uiNew(struct typeinfo);
|
||||
ti->name = name;
|
||||
ti->parent = parent;
|
||||
ti->size = size;
|
||||
ptrArrayAppend(types, ti);
|
||||
return types->len - 1;
|
||||
}
|
||||
|
@ -56,3 +58,16 @@ void *uiIsA(void *p, uintmax_t id, int fail)
|
|||
}
|
||||
|
||||
// TODO free type info
|
||||
|
||||
uiTyped *newTyped(uintmax_t type)
|
||||
{
|
||||
struct typeinfo *ti;
|
||||
uiTyped *instance;
|
||||
|
||||
if (type == 0 || id >= types->len)
|
||||
complain("invalid type ID given to newTyped()");
|
||||
ti = ptrArrayIndex(types, struct typeinfo *, type);
|
||||
instance = (uiTyped *) uiAlloc(ti->size, ti->name);
|
||||
instance->Type = type;
|
||||
return instance;
|
||||
}
|
||||
|
|
26
redo/ui.idl
26
redo/ui.idl
|
@ -28,7 +28,7 @@ func OnShouldQuit(f *func(data *void) int, data *void);
|
|||
|
||||
func FreeText(text *char);
|
||||
|
||||
func RegisterType(name *const char, parent uintmax_t) uintmax_t;
|
||||
func RegisterType(name *const char, parent uintmax_t, size size_t) uintmax_t;
|
||||
func IsA(p *void, type uintmax_t, fail int) *void;
|
||||
struct Typed {
|
||||
field Type uintmax_t;
|
||||
|
@ -59,16 +59,32 @@ interface Control {
|
|||
func ContainerVisible(void) int;
|
||||
func Show(void);
|
||||
func Hide(void);
|
||||
func ContainerShow(void);
|
||||
func ContainerHide(void);
|
||||
func ContainerEnabled(void) int;
|
||||
func Enable(void);
|
||||
func Disable(void);
|
||||
func ContainerEnable(void);
|
||||
func ContainerDisable(void);
|
||||
func UpdateState(void);
|
||||
func SysFunc(p *uiControlSysFuncParams);
|
||||
func StartZOrder(p *uiControlSysFuncParams) int;
|
||||
func CommitDestroy(void);
|
||||
func CommitSetParent(uiControl *);
|
||||
func CommitShow(void);
|
||||
func CommitHide(void);
|
||||
func CommitEnable(void);
|
||||
func CommitDisable(void);
|
||||
func ContainerUpdateState(void);
|
||||
};
|
||||
|
||||
func NewControl(type uintmax_t) *Control;
|
||||
|
||||
raw "#define uiDefineControlType(typename, funcname, realtype) \";
|
||||
raw " static uintmax_t type_ ## typename = 0; \";
|
||||
raw " uintmax_t funcname(void) \";
|
||||
raw " { \";
|
||||
raw " if (type_ ## typename == 0) \";
|
||||
raw " type_ ## typename = uiRegisterType(#typename, uiTypeControl(), sizeof (realtype)); \";
|
||||
raw " return type_ ## typename; \";
|
||||
raw " }";
|
||||
|
||||
func FreeSizing(d *Sizing);
|
||||
|
||||
func MakeContainer(c *Control);
|
||||
|
|
|
@ -7,26 +7,18 @@ This file assumes that you have included <windows.h> and "ui.h" beforehand. It p
|
|||
#ifndef __UI_UI_WINDOWS_H__
|
||||
#define __UI_UI_WINDOWS_H__
|
||||
|
||||
// uiWindowsMakeControl() initializes the given uiControl with the given Windows API control inside.
|
||||
// You will need to provide the preferredSize() method yourself.
|
||||
typedef struct uiWindowsMakeControlParams uiWindowsMakeControlParams;
|
||||
struct uiWindowsMakeControlParams {
|
||||
// These match the CreateWindowExW() function.
|
||||
DWORD dwExStyle;
|
||||
LPCWSTR lpClassName;
|
||||
LPCWSTR lpWindowName;
|
||||
DWORD dwStyle; // WS_CHILD and WS_VISIBLE are automatically applied.
|
||||
HINSTANCE hInstance;
|
||||
LPVOID lpParam;
|
||||
|
||||
// Set this to non-FALSE to use the standard control font used by other ui controls.
|
||||
BOOL useStandardControlFont;
|
||||
|
||||
// This is called when the widget is ready to be destroyed.
|
||||
void (*onDestroy)(void *data);
|
||||
void *onDestroyData;
|
||||
};
|
||||
_UI_EXTERN void uiWindowsMakeControl(uiControl *c, uiWindowsMakeControlParams *p);
|
||||
// TODO write comments for these
|
||||
_UI_EXTERN HWND uiWindowsUtilCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, HINSTANCE hInstance, LPVOID lpParam, BOOL useStandardControlFont);
|
||||
_UI_EXTERN void uiWindowsUtilDestroy(HWND hwnd);
|
||||
_UI_EXTERN void uiWindowsUtilSetParent(HWND hwnd, uiControl *parent);
|
||||
_UI_EXTERN void uiWindowsUtilResize(HWND hwnd, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d);
|
||||
_UI_EXTERN void uiWIndowsUtilShow(HWND hwnd);
|
||||
_UI_EXTERN void uiWindowsUtilHide(HWND hwnd);
|
||||
_UI_EXTERN void uiWIndowsUtilEnable(HWND hwnd);
|
||||
_UI_EXTERN void uiWindowsUtilDisable(HWND hwnd);
|
||||
_UI_EXTERN void uiWindowsUtilSysFunc(HWND hwnd, uiControlSysFuncParams *p);
|
||||
_UI_EXTERN void uiWindowsUtilStartZOrder(HWND hwnd, uiControlSysFuncParams *p);
|
||||
_UI_EXTERN uiControl *uiWindowsNewSingleHWNDControl(uintmax_t type);
|
||||
|
||||
// This contains the Windows-specific parts of the uiSizing structure.
|
||||
// BaseX and BaseY are the dialog base units.
|
||||
|
|
|
@ -15,6 +15,8 @@ extern void uiFree(void *);
|
|||
|
||||
extern void complain(const char *, ...);
|
||||
|
||||
extern void queueResize(uiControl *);
|
||||
|
||||
// ptrarray.c
|
||||
struct ptrArray {
|
||||
void **ptrs;
|
||||
|
@ -29,16 +31,7 @@ void ptrArrayDelete(struct ptrArray *, uintmax_t);
|
|||
#define ptrArrayIndex(p, T, i) ((T) ((p)->ptrs[(i)]))
|
||||
|
||||
// shouldquit.c
|
||||
int shouldQuit(void);
|
||||
extern int shouldQuit(void);
|
||||
|
||||
// control.c
|
||||
extern void osSingleDestroy(void *);
|
||||
extern uintptr_t osSingleHandle(void *);
|
||||
extern void osSingleSetParent(void *, uiControl *, uiControl *);
|
||||
extern void osSingleResize(void *, intmax_t, intmax_t, intmax_t, intmax_t, uiSizing *);
|
||||
extern uiSizing *osSingleSizing(void *, uiControl *);
|
||||
extern void osSingleShow(void *);
|
||||
extern void osSingleHide(void *);
|
||||
extern void osSingleEnable(void *);
|
||||
extern void osSingleDisable(void *);
|
||||
extern void makeControl(uiControl *, void *);
|
||||
// types.c
|
||||
extern uiTyped *newTyped(uintmax_t type);
|
||||
|
|
|
@ -6,8 +6,11 @@ struct button {
|
|||
HWND hwnd;
|
||||
void (*onClicked)(uiButton *, void *);
|
||||
void *onClickedData;
|
||||
void (*baseCommitDestroy)(uiControl *);
|
||||
};
|
||||
|
||||
uiDefineControlType(uiButton, uiTypeButton, struct button)
|
||||
|
||||
static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
|
||||
{
|
||||
struct button *b = (struct button *) c;
|
||||
|
@ -19,12 +22,12 @@ static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void onDestroy(void *data)
|
||||
static void buttonCommitDestroy(uiControl *c)
|
||||
{
|
||||
struct button *b = (struct button *) data;
|
||||
struct button *b = (struct button *) c;
|
||||
|
||||
uiWindowsUnregisterWM_COMMANDHandler(b->hwnd);
|
||||
uiFree(b);
|
||||
(*(b->baseCommitDestroy))(uiControl(b));
|
||||
}
|
||||
|
||||
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
||||
|
@ -77,31 +80,25 @@ static void buttonOnClicked(uiButton *bb, void (*f)(uiButton *, void *), void *d
|
|||
uiButton *uiNewButton(const char *text)
|
||||
{
|
||||
struct button *b;
|
||||
uiWindowsMakeControlParams p;
|
||||
WCHAR *wtext;
|
||||
|
||||
b = uiNew(struct button);
|
||||
uiTyped(b)->Type = uiTypeButton();
|
||||
b = (struct button *) uiWindowsNewControl(uiTypeButton());
|
||||
|
||||
p.dwExStyle = 0;
|
||||
p.lpClassName = L"button";
|
||||
wtext = toUTF16(text);
|
||||
p.lpWindowName = wtext;
|
||||
p.dwStyle = BS_PUSHBUTTON | WS_TABSTOP;
|
||||
p.hInstance = hInstance;
|
||||
p.lpParam = NULL;
|
||||
p.useStandardControlFont = TRUE;
|
||||
p.onDestroy = onDestroy;
|
||||
p.onDestroyData = b;
|
||||
uiWindowsMakeControl(uiControl(b), &p);
|
||||
b->hwnd = uiWindowsUtilCreateControlHWND(0,
|
||||
L"button", wtext,
|
||||
BS_PUSHBUTTON | WS_TABSTOP,
|
||||
hInstance, NULL,
|
||||
TRUE);
|
||||
uiFree(wtext);
|
||||
|
||||
b->hwnd = (HWND) uiControlHandle(uiControl(b));
|
||||
uiWindowsRegisterWM_COMMANDHandler(b->hwnd, onWM_COMMAND, uiControl(b));
|
||||
|
||||
b->onClicked = defaultOnClicked;
|
||||
|
||||
uiControl(b)->PreferredSize = buttonPreferredSize;
|
||||
b->baseCommitDestroy = uiControl(b)->CommitDestroy;
|
||||
uiControl(b)->CommitDestroy = buttonCommitDestroy;
|
||||
|
||||
uiButton(b)->Text = buttonText;
|
||||
uiButton(b)->SetText = buttonSetText;
|
||||
|
|
|
@ -1,156 +1,163 @@
|
|||
// 6 april 2015
|
||||
// 27 may 2015
|
||||
#include "uipriv_windows.h"
|
||||
|
||||
struct singleHWND {
|
||||
uiControl *c;
|
||||
// TODO Edit ,s/Util/HWND/g ?
|
||||
|
||||
HWND uiWindowsUtilCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, HINSTANCE hInstance, LPVOID lpParam, BOOL useStandardControlFont)
|
||||
{
|
||||
HWND hwnd;
|
||||
void (*onDestroy)(void *);
|
||||
void *onDestroyData;
|
||||
};
|
||||
|
||||
void osSingleDestroy(void *internal)
|
||||
{
|
||||
struct singleHWND *s = (struct singleHWND *) internal;
|
||||
|
||||
(*(s->onDestroy))(s->onDestroyData);
|
||||
if (DestroyWindow(s->hwnd) == 0)
|
||||
logLastError("error destroying control in singleDestroy()");
|
||||
uiFree(s);
|
||||
}
|
||||
|
||||
uintptr_t osSingleHandle(void *internal)
|
||||
{
|
||||
struct singleHWND *s = (struct singleHWND *) internal;
|
||||
|
||||
return (uintptr_t) (s->hwnd);
|
||||
}
|
||||
|
||||
void osSingleSetParent(void *internal, uiControl *oldParent, uiControl *newParent)
|
||||
{
|
||||
struct singleHWND *s = (struct singleHWND *) internal;
|
||||
HWND newParentHWND;
|
||||
|
||||
newParentHWND = utilWindow;
|
||||
if (newParent != NULL)
|
||||
newParentHWND = (HWND) uiControlHandle(newParent);
|
||||
if (SetParent(s->hwnd, newParentHWND) == NULL)
|
||||
logLastError("error setting control parent in osSingleSetParent()");
|
||||
}
|
||||
|
||||
void osSingleResize(void *internal, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
|
||||
{
|
||||
struct singleHWND *s = (struct singleHWND *) internal;
|
||||
|
||||
moveWindow(s->hwnd, x, y, width, height, d);
|
||||
}
|
||||
|
||||
uiSizing *osSingleSizing(void *internal, uiControl *c)
|
||||
{
|
||||
return uiWindowsSizing(c);
|
||||
}
|
||||
|
||||
void osSingleShow(void *internal)
|
||||
{
|
||||
struct singleHWND *s = (struct singleHWND *) internal;
|
||||
|
||||
ShowWindow(s->hwnd, SW_SHOW);
|
||||
}
|
||||
|
||||
void osSingleHide(void *internal)
|
||||
{
|
||||
struct singleHWND *s = (struct singleHWND *) internal;
|
||||
|
||||
ShowWindow(s->hwnd, SW_HIDE);
|
||||
}
|
||||
|
||||
void osSingleEnable(void *internal)
|
||||
{
|
||||
struct singleHWND *s = (struct singleHWND *) internal;
|
||||
|
||||
EnableWindow(s->hwnd, TRUE);
|
||||
}
|
||||
|
||||
void osSingleDisable(void *internal)
|
||||
{
|
||||
struct singleHWND *s = (struct singleHWND *) internal;
|
||||
|
||||
EnableWindow(s->hwnd, FALSE);
|
||||
}
|
||||
|
||||
// TODO integrate these two with the main control.c
|
||||
static void singleSysFunc(uiControl *c, uiControlSysFuncParams *p)
|
||||
{
|
||||
struct singleHWND *s = (struct singleHWND *) (c->Internal);
|
||||
|
||||
switch (p->Func) {
|
||||
case uiWindowsSysFuncHasTabStops:
|
||||
if (IsWindowEnabled(s->hwnd) != 0)
|
||||
if ((getStyle(s->hwnd) & WS_TABSTOP) != 0)
|
||||
p->HasTabStops = TRUE;
|
||||
return;
|
||||
case uiWindowsSysFuncSetZOrder:
|
||||
// TODO
|
||||
return;
|
||||
}
|
||||
complain("unknown p->Func %d in singleSysFunc()", p->Func);
|
||||
}
|
||||
|
||||
static int singleStartZOrder(uiControl *c, uiControlSysFuncParams *p)
|
||||
{
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uiWindowsMakeControl(uiControl *c, uiWindowsMakeControlParams *p)
|
||||
{
|
||||
struct singleHWND *s;
|
||||
|
||||
s = uiNew(struct singleHWND);
|
||||
s->c = c;
|
||||
s->hwnd = CreateWindowExW(p->dwExStyle,
|
||||
p->lpClassName, p->lpWindowName,
|
||||
p->dwStyle | WS_CHILD | WS_VISIBLE,
|
||||
hwnd = CreateWindowExW(dwExStyle,
|
||||
lpClassName, lpWIndowName,
|
||||
dwStyle | WS_CHILD | WS_VISIBLE,
|
||||
0, 0,
|
||||
// use a nonzero initial size just in case some control breaks with a zero initial size
|
||||
100, 100,
|
||||
utilWindow, NULL, p->hInstance, p->lpParam);
|
||||
if (s->hwnd == NULL)
|
||||
logLastError("error creating control in uiWindowsMakeControl()");
|
||||
|
||||
s->onDestroy = p->onDestroy;
|
||||
s->onDestroyData = p->onDestroyData;
|
||||
|
||||
if (p->useStandardControlFont)
|
||||
SendMessageW(s->hwnd, WM_SETFONT, (WPARAM) hMessageFont, (LPARAM) TRUE);
|
||||
|
||||
makeControl(uiControl(c), s);
|
||||
|
||||
// PreferredSize() implemented by the individual controls
|
||||
uiControl(c)->SysFunc = singleSysFunc;
|
||||
uiControl(c)->StartZOrder = singleStartZOrder;
|
||||
utilWindow, NULL, hInstance, lpParam);
|
||||
if (hwnd == NULL)
|
||||
logLastError("error creating window in uiWindowsUtilCreateControlHWND()");
|
||||
if (useStandardControlFont)
|
||||
SendMessageW(hwnd, WM_SETFONT, (WPARAM) hMessageFont, (LPARAM) TRUE);
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
char *uiWindowsControlText(uiControl *c)
|
||||
#define HWND(c) ((HWND) uiControlHandle((c)))
|
||||
|
||||
void uiWindowsUtilDestroy(HWND hwnd)
|
||||
{
|
||||
HWND hwnd;
|
||||
WCHAR *wtext;
|
||||
char *text;
|
||||
|
||||
hwnd = (HWND) uiControlHandle(c);
|
||||
wtext = windowText(hwnd);
|
||||
text = toUTF8(wtext);
|
||||
uiFree(wtext);
|
||||
return text;
|
||||
if (DestroyWindow(hwnd) == 0)
|
||||
logLastError("error destroying window in uiWindowsUtilDestroyWindow()");
|
||||
}
|
||||
|
||||
void uiWindowsControlSetText(uiControl *c, const char *text)
|
||||
static void singleHWNDCommitDestroy(uiControl *c)
|
||||
{
|
||||
HWND hwnd;
|
||||
WCHAR *wtext;
|
||||
|
||||
hwnd = (HWND) uiControlHandle(c);
|
||||
wtext = toUTF16(text);
|
||||
if (SetWindowTextW(hwnd, wtext) == 0)
|
||||
logLastError("error setting control text in uiWindowsControlSetText()");
|
||||
uiFree(wtext);
|
||||
uiWindowsUtilDestroy(HWND(c));
|
||||
}
|
||||
|
||||
void uiWindowsUtilSetParent(HWND hwnd, uiControl *parent)
|
||||
{
|
||||
HWND newParent;
|
||||
|
||||
newParent = utilWindow;
|
||||
if (parent != NULL)
|
||||
newParent = HWND(parent);
|
||||
if (SetParent(hwnd, newParent) == 0)
|
||||
logLastError("error changing window parent in uiWindowsUtilSetParent()");
|
||||
}
|
||||
|
||||
static void singleHWNDCommitSetParent(uiControl *c, uiControl *parent)
|
||||
{
|
||||
uiWindowsUtilSetParent(HWND(c), parent);
|
||||
}
|
||||
|
||||
void uiWindowsUtilResize(HWND hwnd, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
|
||||
{
|
||||
moveWindow(hwnd, x, y, width, height, d);
|
||||
}
|
||||
|
||||
static void singleHWNDResize(HWND hwnd, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d)
|
||||
{
|
||||
uiWindowsUtilResize(HWND(c), x, y, width, height, d);
|
||||
}
|
||||
|
||||
static uiSizing *singleHWNDSizing(uiControl *c)
|
||||
{
|
||||
// TODO change this to take a HWND and the parent
|
||||
return uiWindowsSizing(c);
|
||||
}
|
||||
|
||||
void uiWIndowsUtilShow(HWND hwnd)
|
||||
{
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
}
|
||||
|
||||
static void singleHWNDCommitShow(uiControl *c)
|
||||
{
|
||||
uiWindowsUtilShow(HWND(c));
|
||||
}
|
||||
|
||||
void uiWindowsUtilHide(HWND hwnd)
|
||||
{
|
||||
ShowWindow(hwnd, SW_HIDE);
|
||||
}
|
||||
|
||||
static void singleHWNDCommitHide(uiControl *c)
|
||||
{
|
||||
uiWindowsUtilHide(HWND(c));
|
||||
}
|
||||
|
||||
void uiWIndowsUtilEnable(HWND hwnd)
|
||||
{
|
||||
EnableWindow(hwnd, TRUE);
|
||||
}
|
||||
|
||||
static void singleHWNDCommitEnable(uiControl *c)
|
||||
{
|
||||
uiWindowsUtilEnable(HWND(c));
|
||||
}
|
||||
|
||||
void uiWindowsUtilDisable(HWND hwnd)
|
||||
{
|
||||
EnableWindow(hwnd, FALSE);
|
||||
}
|
||||
|
||||
static void singleHWNDCommitDisable(uiControl *c)
|
||||
{
|
||||
uiWindowsUtilDisable(HWND(c));
|
||||
}
|
||||
|
||||
void uiWindowsUtilSysFunc(HWND hwnd, uiControlSysFuncParams *p)
|
||||
{
|
||||
switch (p->Func) {
|
||||
case uiControlSysFuncNop:
|
||||
return;
|
||||
case uiWindowsSysFuncHasTabStops:
|
||||
if ((getStyle(hwnd) & WS_TABSTOP) != 0)
|
||||
p->HasTabStops = TRUE;
|
||||
return;
|
||||
case uiWindowsSysFuncSetZOrder:
|
||||
setWindowInsertAfter(hwnd, p->InsertAfter);
|
||||
p->InsertAfter = hwnd;
|
||||
return;
|
||||
}
|
||||
complain("unknown uiControlSysFunc() function %d in uiWindowsUtilSysFunc()", p->Func);
|
||||
}
|
||||
|
||||
static void singleHWNDSysFunc(uiControl *c, uiControlSysFuncParams *p)
|
||||
{
|
||||
uiWindowsUtilSysFunc(HWND(c), p);
|
||||
}
|
||||
|
||||
void uiWindowsUtilStartZOrder(HWND hwnd, uiControlSysFuncParams *p)
|
||||
{
|
||||
HWND insertAfter;
|
||||
|
||||
// see http://stackoverflow.com/questions/30491418/
|
||||
insertAfter = GetWindow(hwnd, GW_HWNDPREV);
|
||||
if (insertAfter == NULL)
|
||||
logLastError("error getting insert after window in uiWindowsUtilStartZOrder()");
|
||||
p->InsertAfter = insertAfter;
|
||||
}
|
||||
|
||||
static void singleHWNDStartZOrder(uiControl *c, uiControlSysFuncParams *p)
|
||||
{
|
||||
uiWindowsUtilStartZOrder(HWND(c), p);
|
||||
}
|
||||
|
||||
uiControl *uiWindowsNewSingleHWNDControl(uintmax_t type)
|
||||
{
|
||||
uiControl *c;
|
||||
|
||||
c = uiNewControl(type);
|
||||
uiControl(c)->CommitDestroy = singleHWNDCommitDestroy;
|
||||
uiControl(c)->CommitSetParent = singleHWNDCommitSetParent;
|
||||
uiControl(c)->Resize = singleHWNDResize;
|
||||
uiControl(c)->Sizing = singleHWNDSizing;
|
||||
uiControl(c)->CommitShow = singleHWNDCommitShow;
|
||||
uiControl(c)->CommitHide = singleHWNDCommitHide
|
||||
uiControl(c)->CommitEnable = singleHWNDCommitEnable;
|
||||
uiControl(c)->CommitDisable = singleHWNDCommitDisable;
|
||||
uiControl(c)->SysFunc = singleHWNDSysFunc;
|
||||
uiControl(c)->StartZOrder = singleHWNDStartZOrder;
|
||||
return c;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue