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 "out/ui.h"
|
||||||
#include "uipriv.h"
|
#include "uipriv.h"
|
||||||
|
|
||||||
struct singleControl {
|
struct controlBase {
|
||||||
void *internal;
|
|
||||||
uiControl *parent;
|
uiControl *parent;
|
||||||
int userHidden;
|
int hidden;
|
||||||
int containerHidden;
|
int disabled;
|
||||||
int userDisabled;
|
|
||||||
int containerDisabled;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void singleDestroy(uiControl *c)
|
#define controlBase(c) ((struct controlBase *) (c->Internal))
|
||||||
{
|
|
||||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
|
||||||
|
|
||||||
if (s->parent != NULL)
|
static void controlBaseDestroy(uiControl *c)
|
||||||
complain("attempt to destroy a uiControl at %p while it still has a parent", c);
|
{
|
||||||
osSingleDestroy(s->internal);
|
struct controlBase *cb = controlBase(c);
|
||||||
uiFree(s);
|
|
||||||
|
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)
|
static void controlBaseQueueResize(uiControl *c)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
queueResize(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;
|
cb->hidden = 1;
|
||||||
if (!s->containerHidden)
|
uiControlUpdateState(c);
|
||||||
osSingleShow(s->internal);
|
|
||||||
if (s->parent != NULL)
|
|
||||||
uiControlQueueResize(s->parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
if (cb->disabled)
|
||||||
osSingleHide(s->internal);
|
return 0;
|
||||||
if (s->parent != NULL)
|
if (cb->parent == NULL)
|
||||||
uiControlQueueResize(s->parent);
|
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;
|
cb->disabled = 0;
|
||||||
if (!s->userHidden)
|
uiControlUpdateState(c);
|
||||||
osSingleShow(s->internal);
|
|
||||||
if (s->parent != NULL)
|
|
||||||
uiControlQueueResize(s->parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
cb->disabled = 1;
|
||||||
osSingleHide(s->internal);
|
uiControlUpdateState(c);
|
||||||
if (s->parent != NULL)
|
|
||||||
uiControlQueueResize(s->parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void singleEnable(uiControl *c)
|
static void controlBaseUpdateState(uiControl *c)
|
||||||
{
|
{
|
||||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
if (uiControlContainerVisible(c))
|
||||||
|
uiControlCommitShow(c);
|
||||||
s->userDisabled = 0;
|
else
|
||||||
if (!s->containerDisabled)
|
uiControlCommitHide(c);
|
||||||
osSingleEnable(s->internal);
|
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);
|
// by default not a container; do nothing
|
||||||
|
|
||||||
s->userDisabled = 1;
|
|
||||||
osSingleDisable(s->internal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void singleContainerEnable(uiControl *c)
|
uiControl *uiNewControl(uintmax_t type)
|
||||||
{
|
{
|
||||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
uiControl *c;
|
||||||
|
|
||||||
s->containerDisabled = 0;
|
c = uiControl(newTyped(type));
|
||||||
if (!s->userDisabled)
|
uiControl(c)->Internal = uiNew(struct controlBase);
|
||||||
osSingleEnable(s->internal);
|
uiControl(c)->Destroy = controlBaseDestroy;
|
||||||
}
|
uiControl(c)->Parent = controlBaseParent;
|
||||||
|
uiControl(c)->SetParent = controlBaseSetParent;
|
||||||
static void singleContainerDisable(uiControl *c)
|
uiControl(c)->QueueResize = controlBaseQueueResize;
|
||||||
{
|
uiControl(c)->ContainerVisible = controlBaseContainerVisible;
|
||||||
struct singleControl *s = (struct singleControl *) (c->Internal);
|
uiControl(c)->Show = controlBaseShow;
|
||||||
|
uiControl(c)->Hide = controlBaseHide;
|
||||||
s->containerDisabled = 1;
|
uiControl(c)->ContainerEnabled = controlBaseContainerEnabled;
|
||||||
osSingleDisable(s->internal);
|
uiControl(c)->Enable = controlBaseEnable;
|
||||||
}
|
uiControl(c)->Disable = controlBaseDisable;
|
||||||
|
uiControl(c)->UpdateState = controlBaseUpdateState;
|
||||||
void makeControl(uiControl *c, void *internal)
|
uiControl(c)->ContainerUpdateState = controlBaseContainerUpdateState;
|
||||||
{
|
return uiControl(c);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
struct typeinfo {
|
||||||
const char *name;
|
const char *name;
|
||||||
uintmax_t parent;
|
uintmax_t parent;
|
||||||
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ptrArray *types = NULL;
|
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;
|
struct typeinfo *ti;
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ uintmax_t uiRegisterType(const char *name, uintmax_t parent)
|
||||||
ti = uiNew(struct typeinfo);
|
ti = uiNew(struct typeinfo);
|
||||||
ti->name = name;
|
ti->name = name;
|
||||||
ti->parent = parent;
|
ti->parent = parent;
|
||||||
|
ti->size = size;
|
||||||
ptrArrayAppend(types, ti);
|
ptrArrayAppend(types, ti);
|
||||||
return types->len - 1;
|
return types->len - 1;
|
||||||
}
|
}
|
||||||
|
@ -56,3 +58,16 @@ void *uiIsA(void *p, uintmax_t id, int fail)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO free type info
|
// 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 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;
|
func IsA(p *void, type uintmax_t, fail int) *void;
|
||||||
struct Typed {
|
struct Typed {
|
||||||
field Type uintmax_t;
|
field Type uintmax_t;
|
||||||
|
@ -59,16 +59,32 @@ interface Control {
|
||||||
func ContainerVisible(void) int;
|
func ContainerVisible(void) int;
|
||||||
func Show(void);
|
func Show(void);
|
||||||
func Hide(void);
|
func Hide(void);
|
||||||
func ContainerShow(void);
|
func ContainerEnabled(void) int;
|
||||||
func ContainerHide(void);
|
|
||||||
func Enable(void);
|
func Enable(void);
|
||||||
func Disable(void);
|
func Disable(void);
|
||||||
func ContainerEnable(void);
|
func UpdateState(void);
|
||||||
func ContainerDisable(void);
|
|
||||||
func SysFunc(p *uiControlSysFuncParams);
|
func SysFunc(p *uiControlSysFuncParams);
|
||||||
func StartZOrder(p *uiControlSysFuncParams) int;
|
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 FreeSizing(d *Sizing);
|
||||||
|
|
||||||
func MakeContainer(c *Control);
|
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__
|
#ifndef __UI_UI_WINDOWS_H__
|
||||||
#define __UI_UI_WINDOWS_H__
|
#define __UI_UI_WINDOWS_H__
|
||||||
|
|
||||||
// uiWindowsMakeControl() initializes the given uiControl with the given Windows API control inside.
|
// TODO write comments for these
|
||||||
// You will need to provide the preferredSize() method yourself.
|
_UI_EXTERN HWND uiWindowsUtilCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, HINSTANCE hInstance, LPVOID lpParam, BOOL useStandardControlFont);
|
||||||
typedef struct uiWindowsMakeControlParams uiWindowsMakeControlParams;
|
_UI_EXTERN void uiWindowsUtilDestroy(HWND hwnd);
|
||||||
struct uiWindowsMakeControlParams {
|
_UI_EXTERN void uiWindowsUtilSetParent(HWND hwnd, uiControl *parent);
|
||||||
// These match the CreateWindowExW() function.
|
_UI_EXTERN void uiWindowsUtilResize(HWND hwnd, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d);
|
||||||
DWORD dwExStyle;
|
_UI_EXTERN void uiWIndowsUtilShow(HWND hwnd);
|
||||||
LPCWSTR lpClassName;
|
_UI_EXTERN void uiWindowsUtilHide(HWND hwnd);
|
||||||
LPCWSTR lpWindowName;
|
_UI_EXTERN void uiWIndowsUtilEnable(HWND hwnd);
|
||||||
DWORD dwStyle; // WS_CHILD and WS_VISIBLE are automatically applied.
|
_UI_EXTERN void uiWindowsUtilDisable(HWND hwnd);
|
||||||
HINSTANCE hInstance;
|
_UI_EXTERN void uiWindowsUtilSysFunc(HWND hwnd, uiControlSysFuncParams *p);
|
||||||
LPVOID lpParam;
|
_UI_EXTERN void uiWindowsUtilStartZOrder(HWND hwnd, uiControlSysFuncParams *p);
|
||||||
|
_UI_EXTERN uiControl *uiWindowsNewSingleHWNDControl(uintmax_t type);
|
||||||
// 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);
|
|
||||||
|
|
||||||
// This contains the Windows-specific parts of the uiSizing structure.
|
// This contains the Windows-specific parts of the uiSizing structure.
|
||||||
// BaseX and BaseY are the dialog base units.
|
// BaseX and BaseY are the dialog base units.
|
||||||
|
|
|
@ -15,6 +15,8 @@ extern void uiFree(void *);
|
||||||
|
|
||||||
extern void complain(const char *, ...);
|
extern void complain(const char *, ...);
|
||||||
|
|
||||||
|
extern void queueResize(uiControl *);
|
||||||
|
|
||||||
// ptrarray.c
|
// ptrarray.c
|
||||||
struct ptrArray {
|
struct ptrArray {
|
||||||
void **ptrs;
|
void **ptrs;
|
||||||
|
@ -29,16 +31,7 @@ void ptrArrayDelete(struct ptrArray *, uintmax_t);
|
||||||
#define ptrArrayIndex(p, T, i) ((T) ((p)->ptrs[(i)]))
|
#define ptrArrayIndex(p, T, i) ((T) ((p)->ptrs[(i)]))
|
||||||
|
|
||||||
// shouldquit.c
|
// shouldquit.c
|
||||||
int shouldQuit(void);
|
extern int shouldQuit(void);
|
||||||
|
|
||||||
// control.c
|
// types.c
|
||||||
extern void osSingleDestroy(void *);
|
extern uiTyped *newTyped(uintmax_t type);
|
||||||
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 *);
|
|
||||||
|
|
|
@ -6,8 +6,11 @@ struct button {
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
void (*onClicked)(uiButton *, void *);
|
void (*onClicked)(uiButton *, void *);
|
||||||
void *onClickedData;
|
void *onClickedData;
|
||||||
|
void (*baseCommitDestroy)(uiControl *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uiDefineControlType(uiButton, uiTypeButton, struct button)
|
||||||
|
|
||||||
static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
|
static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
|
||||||
{
|
{
|
||||||
struct button *b = (struct button *) c;
|
struct button *b = (struct button *) c;
|
||||||
|
@ -19,12 +22,12 @@ static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult)
|
||||||
return TRUE;
|
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);
|
uiWindowsUnregisterWM_COMMANDHandler(b->hwnd);
|
||||||
uiFree(b);
|
(*(b->baseCommitDestroy))(uiControl(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
// from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
// 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)
|
uiButton *uiNewButton(const char *text)
|
||||||
{
|
{
|
||||||
struct button *b;
|
struct button *b;
|
||||||
uiWindowsMakeControlParams p;
|
|
||||||
WCHAR *wtext;
|
WCHAR *wtext;
|
||||||
|
|
||||||
b = uiNew(struct button);
|
b = (struct button *) uiWindowsNewControl(uiTypeButton());
|
||||||
uiTyped(b)->Type = uiTypeButton();
|
|
||||||
|
|
||||||
p.dwExStyle = 0;
|
|
||||||
p.lpClassName = L"button";
|
|
||||||
wtext = toUTF16(text);
|
wtext = toUTF16(text);
|
||||||
p.lpWindowName = wtext;
|
b->hwnd = uiWindowsUtilCreateControlHWND(0,
|
||||||
p.dwStyle = BS_PUSHBUTTON | WS_TABSTOP;
|
L"button", wtext,
|
||||||
p.hInstance = hInstance;
|
BS_PUSHBUTTON | WS_TABSTOP,
|
||||||
p.lpParam = NULL;
|
hInstance, NULL,
|
||||||
p.useStandardControlFont = TRUE;
|
TRUE);
|
||||||
p.onDestroy = onDestroy;
|
|
||||||
p.onDestroyData = b;
|
|
||||||
uiWindowsMakeControl(uiControl(b), &p);
|
|
||||||
uiFree(wtext);
|
uiFree(wtext);
|
||||||
|
|
||||||
b->hwnd = (HWND) uiControlHandle(uiControl(b));
|
|
||||||
uiWindowsRegisterWM_COMMANDHandler(b->hwnd, onWM_COMMAND, uiControl(b));
|
uiWindowsRegisterWM_COMMANDHandler(b->hwnd, onWM_COMMAND, uiControl(b));
|
||||||
|
|
||||||
b->onClicked = defaultOnClicked;
|
b->onClicked = defaultOnClicked;
|
||||||
|
|
||||||
uiControl(b)->PreferredSize = buttonPreferredSize;
|
uiControl(b)->PreferredSize = buttonPreferredSize;
|
||||||
|
b->baseCommitDestroy = uiControl(b)->CommitDestroy;
|
||||||
|
uiControl(b)->CommitDestroy = buttonCommitDestroy;
|
||||||
|
|
||||||
uiButton(b)->Text = buttonText;
|
uiButton(b)->Text = buttonText;
|
||||||
uiButton(b)->SetText = buttonSetText;
|
uiButton(b)->SetText = buttonSetText;
|
||||||
|
|
|
@ -1,156 +1,163 @@
|
||||||
// 6 april 2015
|
// 27 may 2015
|
||||||
#include "uipriv_windows.h"
|
#include "uipriv_windows.h"
|
||||||
|
|
||||||
struct singleHWND {
|
// TODO Edit ,s/Util/HWND/g ?
|
||||||
uiControl *c;
|
|
||||||
|
HWND uiWindowsUtilCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, HINSTANCE hInstance, LPVOID lpParam, BOOL useStandardControlFont)
|
||||||
|
{
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
void (*onDestroy)(void *);
|
|
||||||
void *onDestroyData;
|
|
||||||
};
|
|
||||||
|
|
||||||
void osSingleDestroy(void *internal)
|
hwnd = CreateWindowExW(dwExStyle,
|
||||||
{
|
lpClassName, lpWIndowName,
|
||||||
struct singleHWND *s = (struct singleHWND *) internal;
|
dwStyle | WS_CHILD | WS_VISIBLE,
|
||||||
|
|
||||||
(*(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,
|
|
||||||
0, 0,
|
0, 0,
|
||||||
// use a nonzero initial size just in case some control breaks with a zero initial size
|
// use a nonzero initial size just in case some control breaks with a zero initial size
|
||||||
100, 100,
|
100, 100,
|
||||||
utilWindow, NULL, p->hInstance, p->lpParam);
|
utilWindow, NULL, hInstance, lpParam);
|
||||||
if (s->hwnd == NULL)
|
if (hwnd == NULL)
|
||||||
logLastError("error creating control in uiWindowsMakeControl()");
|
logLastError("error creating window in uiWindowsUtilCreateControlHWND()");
|
||||||
|
if (useStandardControlFont)
|
||||||
s->onDestroy = p->onDestroy;
|
SendMessageW(hwnd, WM_SETFONT, (WPARAM) hMessageFont, (LPARAM) TRUE);
|
||||||
s->onDestroyData = p->onDestroyData;
|
return hwnd;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *uiWindowsControlText(uiControl *c)
|
#define HWND(c) ((HWND) uiControlHandle((c)))
|
||||||
|
|
||||||
|
void uiWindowsUtilDestroy(HWND hwnd)
|
||||||
{
|
{
|
||||||
HWND hwnd;
|
if (DestroyWindow(hwnd) == 0)
|
||||||
WCHAR *wtext;
|
logLastError("error destroying window in uiWindowsUtilDestroyWindow()");
|
||||||
char *text;
|
|
||||||
|
|
||||||
hwnd = (HWND) uiControlHandle(c);
|
|
||||||
wtext = windowText(hwnd);
|
|
||||||
text = toUTF8(wtext);
|
|
||||||
uiFree(wtext);
|
|
||||||
return text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiWindowsControlSetText(uiControl *c, const char *text)
|
static void singleHWNDCommitDestroy(uiControl *c)
|
||||||
{
|
{
|
||||||
HWND hwnd;
|
uiWindowsUtilDestroy(HWND(c));
|
||||||
WCHAR *wtext;
|
}
|
||||||
|
|
||||||
hwnd = (HWND) uiControlHandle(c);
|
void uiWindowsUtilSetParent(HWND hwnd, uiControl *parent)
|
||||||
wtext = toUTF16(text);
|
{
|
||||||
if (SetWindowTextW(hwnd, wtext) == 0)
|
HWND newParent;
|
||||||
logLastError("error setting control text in uiWindowsControlSetText()");
|
|
||||||
uiFree(wtext);
|
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