393 rader
20 KiB
C
393 rader
20 KiB
C
#ifndef cmUi_h
|
|
#define cmUi_h
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
/*
|
|
cmUI implements a platform independent UI control manager
|
|
for multiple simultaneous applications. In this context
|
|
an 'application' can be seen as a plug-in style program.
|
|
|
|
The goal of the manager is to support the easy construction
|
|
of panels of graphic user interface controls.
|
|
|
|
|
|
|
|
Operation:
|
|
|
|
1) A cmUi manager is allocated by the master program. See cmUiAlloc().
|
|
|
|
2) The master program then assigns a 'driver' to implmenent
|
|
the commands issued by cmUi. All commands can be
|
|
described using the cmUiDriverArg_t record.
|
|
|
|
3) The master program then registers client applications with
|
|
the cmUi manager by calling cmUiCreateApp().
|
|
|
|
4) Prior to calling any of the client application functions
|
|
the master or client app. must call cmUiSetAppId(). This
|
|
function sets the current application id and thereby slightly
|
|
simplifies the client app interface by not requiring the
|
|
app id be passed with every client app. function call.
|
|
|
|
5) Once the current app. id is set with cmUiSetAppId()
|
|
the client app can make multiple calls to the cmUi manager
|
|
to create or query controls.
|
|
|
|
6) Calls to create controls result in callbacks to the
|
|
driver function which manages the actual windowing and
|
|
initial event handling.
|
|
|
|
7) Events generated by the driver based graphic controls
|
|
are routed back to the cmUi manager through calls to
|
|
cmUiOnDriverEvent().
|
|
|
|
8) The cmUiOnDriverEvent() internally caches the
|
|
state/value of the control based on the event information
|
|
and calls the 'cbFunc' function registered with the
|
|
cmUi manager by cmUiAlloc(). This call is intended to
|
|
notify the client applications of changes in the state/value
|
|
of a user interface control.
|
|
|
|
Notes:
|
|
1) Application id's must be unique among all applications.
|
|
Control id's must be unique among all controls assigned
|
|
to the same application. Both application and control id's
|
|
are used internally as array indexes they should therefore
|
|
be the low, positive, and densely packed integers.
|
|
|
|
2) All communication between the cmUi and the driver,
|
|
and all callbacks from the cmUi to the master app.
|
|
use the cmUiDriverArg_t structure
|
|
|
|
3) The panel tabs act like radio buttons. When a tab is
|
|
selected the clicked tab generates one event for each
|
|
tab (cId=kPanelUiCId usrId=panelId) w/ ival=1 for the
|
|
selected tab and ival=0 for all other tabs.
|
|
|
|
TODO:
|
|
0) [DONE] Remove the 'cbArg' from the cmUiDriverArg_t record and
|
|
pass it as a separate paramenter in the cmUiDriverFunc_t calls.
|
|
|
|
1) The controls should be based on a multilevel tree model
|
|
not the simple two layer panel->controls framework used now.
|
|
|
|
2) Given that access to the control values can be non-blocked
|
|
and fast many controls won't need to report changes back to
|
|
the client - the client can simply read the control value
|
|
as necessary directly from the cmUi manager. To decrease
|
|
event processing overhead controls should therefore be
|
|
flagged as 'callback/no-callback'. Some controls like
|
|
buttons should default to turning the flag on, while other
|
|
controls, like numbers, should default to turning it off.
|
|
|
|
3) Implement support for the creation of arrays of controls.
|
|
This can be implemented with a scheme similar to 'next rect'.
|
|
cmUiSetupArray(uiH,panelId,baseCtlId,cnt).
|
|
|
|
4) Come up with a threading model. For example maybe
|
|
control creation should use a blocking scheme since it is
|
|
generally too time consuming to do during real-time operation
|
|
anyway. If the control flow generated from driver event
|
|
callbacks then allows value, but not structural changes,
|
|
then non blocking will be necessary.
|
|
|
|
5) The cmUiDriverArg_t structure is used for both
|
|
commands to the driver and callbacks from the driver.
|
|
Many of the fields are not use for event callbacks.
|
|
Which fields are used under which circumstances should
|
|
be documented. This would allow decreasing the size
|
|
of the record during serialization.
|
|
|
|
6) [DONE] Write a serialization/deserialization routines for cmUiDriverArg_t.
|
|
unsigned cmUiDriverArgSerialBufByteCount(const cmUiDriverArg_t* a);
|
|
cmUiRC_t cmUiDriverArgSerialize( const cmUiDriverArg_t* a, char* buf, bufByteCnt );
|
|
cmUiRC_t cmUiDriverArgDeserialize( cmUiDriverArg_t* a, const char* buf, bufByteCnt );
|
|
|
|
7) There is no duplex model for validating and then displaying the
|
|
value of a control.
|
|
|
|
*/
|
|
|
|
typedef cmHandle_t cmUiH_t;
|
|
|
|
|
|
extern cmUiH_t cmUiNullHandle;
|
|
|
|
//=============================================================================================
|
|
//
|
|
// Master program API
|
|
//
|
|
|
|
// Allocate the cmUi manager. If the driver function is not
|
|
// yet available then set drvrFunc to NULL and use
|
|
// cmUiSetDriver() to set the driver function at a later
|
|
// time. cmUiAlloc() stores but does not call the driver
|
|
// and so it is not needed when the cmUI manager is
|
|
// constructed - however it must be set prior to making
|
|
// any other calls to the manager.
|
|
cmUiRC_t cmUiAlloc(
|
|
cmCtx_t* ctx,
|
|
cmUiH_t* hp,
|
|
cmUiDriverFunc_t drvrFunc, // UI driver function
|
|
void* drvrArg,
|
|
cmUiDriverFunc_t cbFunc, // client event callback function
|
|
void* cbArg );
|
|
|
|
// Release all apps but assume that the driver has already
|
|
// been released.
|
|
cmUiRC_t cmUiFree( cmUiH_t* hp );
|
|
|
|
// Validate the cmUiH_t handle.
|
|
bool cmUiIsValid( cmUiH_t h );
|
|
|
|
// Set the driver function. This function allows the driver
|
|
// set in cmUiAlloc() to be replaced or set following the
|
|
// call to cmUiAlloc().
|
|
//
|
|
// By setting the driver function to
|
|
// NULL the application can prevent callback to the driver.
|
|
// This is useful if the driver has been release prior
|
|
// to the UI manager begining destroyed.
|
|
void cmUiSetDriver( cmUiH_t h, cmUiDriverFunc_t drvrFunc, void* drvrArg );
|
|
|
|
// Register a client application with the cmUi manager.
|
|
// 'appId' must not have been used by any other previously registered.
|
|
// application.
|
|
// Automatically sets and restores the ambient appId.
|
|
// In a plug-in context this function is generally called
|
|
// just prior a instantiating a plug-in object.
|
|
cmUiRC_t cmUiCreateApp( cmUiH_t uiH, unsigned appId, unsigned asSubIdx );
|
|
|
|
// Return true if 'appId' is active.
|
|
bool cmUiAppIsActive( cmUiH_t uiH, unsigned appId );
|
|
|
|
|
|
// Notify the cmUi manager that the resources associated
|
|
// with a client application can be released.
|
|
// Automatically sets and restores the ambient appId.
|
|
cmUiRC_t cmUiDestroyApp( cmUiH_t uiH, unsigned appId );
|
|
|
|
// Release all apps.
|
|
// Automatically sets and restores the ambient appId.
|
|
cmUiRC_t cmUiDestroyAllApps( cmUiH_t h );
|
|
|
|
|
|
// The master program sets the ambient 'appId' prior to passing control
|
|
// to a client which will make User API calls. By making the
|
|
// 'appId' an ambient parameter the User API calls are slightly
|
|
// simplified because they do not have to include it in each of the
|
|
// function calls.
|
|
//cmUiRC_t cmUiSetAppId( cmUiH_t uiH, unsigned appId );
|
|
//unsigned cmUiAppId( cmUiH_t uiH );
|
|
|
|
unsigned cmUiAppIdToAsSubIndex( cmUiH_t uiH, unsigned appId );
|
|
|
|
// Return the count of app's.
|
|
unsigned cmUiAppCount( cmUiH_t uiH );
|
|
|
|
|
|
// Callbacks from the driver arrive via this function.
|
|
cmUiRC_t cmUiOnDriverEvent( cmUiH_t uiH, const cmUiDriverArg_t* p );
|
|
|
|
|
|
//=============================================================================================
|
|
//
|
|
// Client Application API
|
|
//
|
|
|
|
// See above note on panel tabs acting like radio buttons.
|
|
cmUiRC_t cmUiCreatePanel( cmUiH_t uiH, unsigned appId, unsigned newPanelId, const cmChar_t* label, unsigned flags );
|
|
|
|
cmUiRC_t cmUiCreateBtn( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags );
|
|
cmUiRC_t cmUiCreateCheck( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, bool dflt );
|
|
cmUiRC_t cmUiCreateLabel( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags );
|
|
cmUiRC_t cmUiCreateString( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* text );
|
|
cmUiRC_t cmUiCreateConsole( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* text );
|
|
cmUiRC_t cmUiCreateNumber( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, double min, double max, double incr, double dflt );
|
|
cmUiRC_t cmUiCreateHSlider( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, double min, double max, double incr, double dflt );
|
|
cmUiRC_t cmUiCreateVSlider( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, double min, double max, double incr, double dflt );
|
|
cmUiRC_t cmUiCreateProgress( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt );
|
|
cmUiRC_t cmUiCreateHMeter( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt );
|
|
cmUiRC_t cmUiCreateVMeter( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt );
|
|
cmUiRC_t cmUiCreateFileBtn( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* dfltDir, const cmChar_t* patStr );
|
|
cmUiRC_t cmUiCreateDirBtn( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* dfltDir );
|
|
cmUiRC_t cmUiCreateMenuBtn( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags );
|
|
cmUiRC_t cmUiCreateMenuBtnV( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* lavel, unsigned flags, const cmChar_t* label0, unsigned id0, va_list vl );
|
|
cmUiRC_t cmUiCreateMenuBtnA( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* lavel, unsigned flags, const cmChar_t* label0, unsigned id0, ... );
|
|
cmUiRC_t cmUiCreateMenuBtnJson( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* lavel, unsigned flags, const cmJsonNode_t* root, const cmChar_t* memberLabel );
|
|
cmUiRC_t cmUiCreateList( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, unsigned visibleRowCnt );
|
|
cmUiRC_t cmUiCreateListV( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, unsigned visibleRowCnt, const cmChar_t* label0, unsigned id0, va_list vl );
|
|
cmUiRC_t cmUiCreateListA( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, unsigned visibleRowCnt, const cmChar_t* label0, unsigned id0, ... );
|
|
cmUiRC_t cmUiCreateListJson( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, unsigned visibleRowCnt, const cmJsonNode_t* root, const cmChar_t* memberLabel );
|
|
|
|
// If 'id' identifies a 'list' control use tabs as column separators.
|
|
cmUiRC_t cmUiAppendListEle( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, const cmChar_t* text, unsigned eleId );
|
|
|
|
// Remove all the elements of a list control.
|
|
cmUiRC_t cmUiClearList( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id );
|
|
|
|
// Enable/Disable a control
|
|
cmUiRC_t cmUiEnableCtl( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id, bool enableFl );
|
|
|
|
// Enable/disable all controls on a panel except those included in the var args list.
|
|
// Terminate the var args list with cmInvalidId.
|
|
cmUiRC_t cmUiEnableAllExceptV( cmUiH_t uiH, unsigned appId, unsigned panelId, bool enableFl, va_list vl );
|
|
cmUiRC_t cmUiEnableAllExcept( cmUiH_t uiH, unsigned appId, unsigned panelId, bool enableFl, ... );
|
|
|
|
// If 'id' identifies a panel then all control belonging to the panel
|
|
// will also be destroyed.
|
|
cmUiRC_t cmUiDestroyCtl( cmUiH_t uiH, unsigned appId, unsigned id );
|
|
|
|
// Returns true if the control exists.
|
|
// For panels set id=panelId.
|
|
//bool cmUiCtlExists( cmUiH_t uiH, unsigned appId, unsigned panelId, unsigned id );
|
|
|
|
// Destroy all the controls in a panel.
|
|
cmUiRC_t cmUiClearPanel( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
|
|
cmUiRC_t cmUiSelectPanel( cmUiH_t uiH, const cmChar_t* label );
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
// Location:
|
|
|
|
// 1) If a 'next rect' is set the control will be placed according to it.
|
|
// 2) If cmUiSetBaseCol() was set then the control will be placed at the
|
|
// base col and base row.
|
|
// 3) If cmUiPlaceRight() or cmUIPlaceBelow() have been called since the
|
|
// previous control was created then the new control will be placed
|
|
// accordingly.
|
|
// 4) The control will be placed according to the 'fill rows' flag.
|
|
// If not set (default) the new control will be placed in the
|
|
// base column below the previous control.
|
|
// If 'fill rows' is set the new control will be placed on the
|
|
// same row to the right of the previous control.
|
|
// If there is no previous control then it will be placed
|
|
// in the base column and base row.
|
|
|
|
// Get/Set the fill directions. If the 'fill columns' flag is enabled
|
|
// then the next control is placed below the previous control otherwise
|
|
// the next control is placed to the right of the next control.
|
|
bool cmUiFillRows( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
bool cmUiSetFillRows( cmUiH_t uiH, unsigned appId, unsigned panelId, bool enableFl );
|
|
|
|
|
|
// Place the next control to the right/below of the previous ctl.
|
|
// These flags override the current fill row/col setting.
|
|
// Note that 'place right' and 'place below' are mutually
|
|
// exclusive. Enabling one disables the other.
|
|
void cmUiPlaceRight( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
void cmUiPlaceBelow( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
|
|
// Place the next control at the base column below the previous ctl.
|
|
void cmUiNewLine( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
|
|
// Set/Get current base col and return previous value. Place the next
|
|
// control on the base row.
|
|
int cmUiBaseCol( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiSetBaseCol( cmUiH_t uiH, unsigned appId, unsigned panelId, int x );
|
|
|
|
|
|
// Set/Get current base row and return previous value.
|
|
int cmUiBaseRow( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiSetBaseRow( cmUiH_t uiH, unsigned appId, unsigned panelId, int y );
|
|
|
|
// Size:
|
|
// 1) If a 'next rect' is set the control will be placed according
|
|
// to it.
|
|
// 2) If a 'next w/h' is set the control will be placed according
|
|
// to it. The 'next w/h' setting is only active for the
|
|
// next control created.
|
|
// 3) The w/h of the new control will be set to the default w/h.
|
|
//
|
|
|
|
// Get/Set the default control width and height.
|
|
// Set returns previous value.
|
|
int cmUiW( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiH( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiSetW( cmUiH_t uiH, unsigned appId, unsigned panelId, int w );
|
|
int cmUiSetH( cmUiH_t uiH, unsigned appId, unsigned panelId, int h );
|
|
void cmUiSetWH( cmUiH_t uiH, unsigned appId, unsigned panelId, int w, int h );
|
|
|
|
// Get/Set the control width and height for only the next control.
|
|
// Set returns previous value.
|
|
int cmUiNextW( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiNextH( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
void cmUiSetNextW( cmUiH_t uiH, unsigned appId, unsigned panelId, int w );
|
|
void cmUiSetNextH( cmUiH_t uiH, unsigned appId, unsigned panelId, int h );
|
|
void cmUiSetNextWH( cmUiH_t uiH, unsigned appId, unsigned panelId, int w, int h );
|
|
|
|
// Get/Set the default inter-control borders
|
|
// Set returns previous value.
|
|
int cmUiHBorder( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiVBorder( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiSetHBorder( cmUiH_t uiH, unsigned appId, unsigned panelId, int w );
|
|
int cmUiSetVBorder( cmUiH_t uiH, unsigned appId, unsigned panelId, int h );
|
|
|
|
// Get/Set the 'next' inter-control borders
|
|
// Set returns previous value.
|
|
int cmUiNextHBorder( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiNextVBorder( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiSetNextHBorder( cmUiH_t uiH, unsigned appId, unsigned panelId, int w );
|
|
int cmUiSetNextVBorder( cmUiH_t uiH, unsigned appId, unsigned panelId, int h );
|
|
|
|
// Place the next control at the following coordinates. The
|
|
// specified coordinates are only active during the next
|
|
// cmUiCreateXXX() call. Setting the 'next rect' overrides all
|
|
// other layout directives.
|
|
cmUiRC_t cmUiNextRect( cmUiH_t uiH, unsigned appId, unsigned panelId, int x, int y, int w, int h );
|
|
|
|
// Get the location/size of the previously created control.
|
|
// All ref. args are optional.
|
|
cmUiRC_t cmUiPrevRect( cmUiH_t uiH, unsigned appId, unsigned panelId, int* xRef, int* yRef, int* wRef, int* hRef );
|
|
int cmUiPrevL( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiPrevT( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiPrevR( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiPrevB( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiPrevW( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
int cmUiPrevH( cmUiH_t uiH, unsigned appId, unsigned panelId );
|
|
|
|
//------------------------------------------------------------------------------------------
|
|
//
|
|
// Get/set the value of UI control.
|
|
//
|
|
|
|
// TODO:
|
|
// + Need functions for setting auxilliary values like
|
|
// min,max,etc..
|
|
|
|
// Set the value associated with a control.
|
|
// Set the local value of the specified control and then
|
|
// send the value to the UI driver so that the UI reflects this value.
|
|
cmUiRC_t cmUiSetInt( cmUiH_t uiH, unsigned appId, unsigned id, int v );
|
|
cmUiRC_t cmUiSetUInt( cmUiH_t uiH, unsigned appId, unsigned id, unsigned v );
|
|
cmUiRC_t cmUiSetDouble( cmUiH_t uiH, unsigned appId, unsigned id, double v );
|
|
cmUiRC_t cmUiSetString( cmUiH_t uiH, unsigned appId, unsigned id, const cmChar_t* v );
|
|
cmUiRC_t cmUiSetVPrintf(cmUiH_t uiH, unsigned appId, unsigned id, const cmChar_t* fmt, va_list vl );
|
|
cmUiRC_t cmUiSetPrintf( cmUiH_t uiH, unsigned appId, unsigned id, const cmChar_t* fmt, ... );
|
|
|
|
// Get the value associated with a control. These functions return
|
|
// the control value cached in the local control, they do not need
|
|
// to call the driver and are therefore very fast.
|
|
int cmUiInt( cmUiH_t uiH, unsigned appId, unsigned id );
|
|
unsigned cmUiUInt( cmUiH_t uiH, unsigned appId, unsigned id );
|
|
double cmUiDouble( cmUiH_t uiH, unsigned appId, unsigned id );
|
|
const cmChar_t* cmUiString( cmUiH_t uiH, unsigned appId, unsigned id );
|
|
|
|
unsigned cmUiListEleCount( cmUiH_t uiH, unsigned appId, unsigned id );
|
|
unsigned cmUiListEleId( cmUiH_t uiH, unsigned appId, unsigned id, unsigned index );
|
|
const cmChar_t* cmUiListEleLabel( cmUiH_t uiH, unsigned appId, unsigned id, unsigned index );
|
|
unsigned cmUiListEleLabelToIndex( cmUiH_t uiH, unsigned appId, unsigned id, const cmChar_t* label );
|
|
|
|
// Query/set the current error state.
|
|
cmUiRC_t cmUiLastRC( cmUiH_t uiH );
|
|
cmUiRC_t cmUiSetRC( cmUiH_t uiH, cmUiRC_t rc );
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|