Moved the new control stuff back.

This commit is contained in:
Pietro Gagliardi 2015-05-29 14:56:11 -04:00
parent 1790de24c8
commit ecd14aaa12
14 changed files with 304 additions and 1140 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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.

View File

@ -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);

View File

@ -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;

View File

@ -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;
}