diff --git a/doc/controls.md b/doc/controls.md index 8ec7616c..fc4a3d2c 100644 --- a/doc/controls.md +++ b/doc/controls.md @@ -18,7 +18,7 @@ uint32_t uiControlType(void); `uiControl` is an opaque type that describes a control. -`uiControlType()` is the type identifier of a `uiControl` as passed to `uiControlCheckType()`. You rarely need to call this directly; the `uiControl()` conversion macro does this for you. +`uiControlType()` is the type identifier of a `uiControl` as passed to `uiCheckControlType()`. You rarely need to call this directly; the `uiControl()` conversion macro does this for you. ### `uiControlVtable` @@ -36,6 +36,32 @@ Each method takes at least two parameters. The first, `c`, is the `uiControl` it Each method is named for the `uiControl` function that it implements. As such, details on how to implement these methods are documented alongside those functions. For instance, instructions on implementing `Free()` are given under the documentation for `uiControlFree()`. The only exception is `Init()`, which is discussed under `uiNewControl()` below. +### `uiRegisterControlType()` + +```c +uint32_t uiRegisterControlType(uiControlVtable *vtable, uiControlOSVtable *osVtable, size_t implDataSize); +``` + +`uiRegisterControlType()` registers a new `uiControl` type with the given vtables and returns its ID as passed to `uiNewControl()`. `implDataSize` is the size of the implementation data struct that is created by `uiNewControl()`. + +`uiControlVtable` describes the functions of a `uiControl` common between platforms, and is discussed on this page. `uiControlOSVtable` describes functionst hat vary from OS to OS, and are described in the respective OS-specific uiControl implementation pages. + +It is a programmer error to specify `NULL` for either vtable. An `implDataSize` of 0 is legal; the implementation data pointer will be `NULL`. This is not particularly useful, however. It is also a programmer error to specify `NULL` for any of the methods in either vtable — that is, all methods are required. + +### `uiCheckControlType()` + +```c +void *uiCheckControlType(void *c, uint32_t type); +``` + +`uiCheckControlType()` checks whether `c` is a `uiControl`, and if so, whether it is of the type specified by `type`. If `c` is `NULL`, or if either of the above conditions is false, a programmer error is raised. If the conditions are met, the function returns `c` unchanged. + +This function is intended to be used to implement a macro that converts an arbitrary `uiControl` pointer into a specific type. For instance, `uiButton` exposes its type ID as a function `uiButtonType()`, and provides the macro `uiButton()` that does the actual conversion as so: + +```c +#define uiButton(c) ((uiButton *) uiCheckControlType((c), uiButtonType())) +``` + ### `uiNewControl()` ```c diff --git a/ui.h b/ui.h index 9575402f..0391516c 100644 --- a/ui.h +++ b/ui.h @@ -63,6 +63,7 @@ uiprivExtern void uiEventSetHandlerBlocked(uiEvent *e, int id, bool blocked); typedef struct uiControl uiControl; typedef struct uiControlVtable uiControlVtable; +typedef struct uiControlOSVtable uiControlOSVtable; uiprivExtern uint32_t uiControlType(void); #define uiControl(obj) ((uiControl *) uiCheckControlType((obj), uiControlType())) @@ -72,6 +73,9 @@ struct uiControlVtable { void (*Free)(uiControl *c, void *implData); }; +uiprivExtern uint32_t uiRegisterControlType(uiControlVtable *vtable, uiControlOSVtable *osVtable, size_t implDataSize); +uiprivExtern void *uiCheckControlType(void *c, uint32_t type); + uiprivExtern uiControl *uiNewControl(uint32_t type, void *initData); uiprivExtern void uiControlFree(uiControl *c);