123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- #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
-
- TODO:
- 0) 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 to 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.7
-
- 6) 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 );
-
- // 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 );
-
- // 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
- //
-
-
- cmUiRC_t cmUiCreatePanel( cmUiH_t uiH, unsigned newPanelId, const cmChar_t* label );
-
- cmUiRC_t cmUiCreateBtn( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags );
- cmUiRC_t cmUiCreateCheck( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, bool dflt );
- cmUiRC_t cmUiCreateLabel( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags );
- cmUiRC_t cmUiCreateText( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* text );
- cmUiRC_t cmUiCreateNumber( cmUiH_t uiH, 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 panelId, unsigned id, const cmChar_t* label, unsigned flags, double min, double max, double incr, double dflt );
- cmUiRC_t cmUiCreateVSlider( cmUiH_t uiH, 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 panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt );
- cmUiRC_t cmUiCreateHMeter( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt );
- cmUiRC_t cmUiCreateVMeter( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt );
- cmUiRC_t cmUiCreateFileBtn( cmUiH_t uiH, 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 panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* dfltDir );
- cmUiRC_t cmUiCreateMenuBtn( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags );
- cmUiRC_t cmUiCreateMenuBtnV( cmUiH_t uiH, 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 panelId, unsigned id, const cmChar_t* lavel, unsigned flags, const cmChar_t* label0, unsigned id0, ... );
- cmUiRC_t cmUiCreateMenuBtnJson( cmUiH_t uiH, 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 panelId, unsigned id, const cmChar_t* label, unsigned flags, unsigned visibleRowCnt );
- cmUiRC_t cmUiCreateListV( cmUiH_t uiH, 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 panelId, unsigned id, const cmChar_t* label, unsigned flags, unsigned visibleRowCnt, const cmChar_t* label0, unsigned id0, ... );
- cmUiRC_t cmUiCreateListJson( cmUiH_t uiH, 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 panelId, unsigned id, const cmChar_t* text, unsigned eleId );
-
- // If 'id' identifies a panel then all control belonging to the panel
- // will also be destroyed.
- cmUiRC_t cmUiDestroyCtl( cmUiH_t uiH, unsigned id );
-
- // Returns true if the control exists.
- // For panels set id=panelId.
- bool cmUiCtlExists( cmUiH_t uiH, unsigned panelId, unsigned id );
-
- // Destroy all the controls in a panel.
- cmUiRC_t cmUiClearPanel( cmUiH_t uiH, unsigned panelId );
-
-
- // 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 panelId );
- bool cmUiSetFillRows( cmUiH_t uiH, 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 panelId );
- void cmUiPlaceBelow( cmUiH_t uiH, unsigned panelId );
-
- // Place the next control at the base column below the previous ctl.
- void cmUiNewLine( cmUiH_t uiH, 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 panelId );
- int cmUiSetBaseCol( cmUiH_t uiH, unsigned panelId, int x );
-
-
- // Set/Get current base row and return previous value.
- int cmUiBaseRow( cmUiH_t uiH, unsigned panelId );
- int cmUiSetBaseRow( cmUiH_t uiH, 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 panelId );
- int cmUiH( cmUiH_t uiH, unsigned panelId );
- int cmUiSetW( cmUiH_t uiH, unsigned panelId, int w );
- int cmUiSetH( cmUiH_t uiH, unsigned panelId, int h );
- void cmUiSetWH( cmUiH_t uiH, 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 panelId );
- int cmUiNextH( cmUiH_t uiH, unsigned panelId );
- void cmUiSetNextW( cmUiH_t uiH, unsigned panelId, int w );
- void cmUiSetNextH( cmUiH_t uiH, unsigned panelId, int h );
- void cmUiSetNextWH( cmUiH_t uiH, unsigned panelId, int w, int h );
-
- // Get/Set the default inter-control borders
- // Set returns previous value.
- int cmUiHBorder( cmUiH_t uiH, unsigned panelId );
- int cmUiVBorder( cmUiH_t uiH, unsigned panelId );
- int cmUiSetHBorder( cmUiH_t uiH, unsigned panelId, int w );
- int cmUiSetVBorder( cmUiH_t uiH, unsigned panelId, int h );
-
- // Get/Set the 'next' inter-control borders
- // Set returns previous value.
- int cmUiNextHBorder( cmUiH_t uiH, unsigned panelId );
- int cmUiNextVBorder( cmUiH_t uiH, unsigned panelId );
- int cmUiSetNextHBorder( cmUiH_t uiH, unsigned panelId, int w );
- int cmUiSetNextVBorder( cmUiH_t uiH, 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 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 panelId, int* xRef, int* yRef, int* wRef, int* hRef );
- int cmUiPrevL( cmUiH_t uiH, unsigned panelId );
- int cmUiPrevT( cmUiH_t uiH, unsigned panelId );
- int cmUiPrevR( cmUiH_t uiH, unsigned panelId );
- int cmUiPrevB( cmUiH_t uiH, unsigned panelId );
- int cmUiPrevW( cmUiH_t uiH, unsigned panelId );
- int cmUiPrevH( cmUiH_t uiH, unsigned panelId );
-
-
- //
- // Get/set the value of UI control.
- //
-
- // TODO:
- // 1) Still need functions for setting auxilliary values like
- // min,max,etc..
- // 2) A coherent model needs to be selected for determining
- // how local values get set. As it is local values are
- // only set via callbacs from the UI driver.
-
- // Set the value associated with a control.
- // These functions would be better named 'cmUiSendXXX()' since
- // they don't actually set the local value but rather call the
- // driver to set the UI value. The driver may then respond with
- // a callback which will set the local value. One advantage of
- // this is that the value will be filtered according to the
- // ui's rules (e.g. min, max .... )
- cmUiRC_t cmUiSetInt( cmUiH_t uiH, unsigned id, int v );
- cmUiRC_t cmUiSetUInt( cmUiH_t uiH, unsigned id, unsigned v );
- cmUiRC_t cmUiSetDouble( cmUiH_t uiH, unsigned id, double v );
- cmUiRC_t cmUiSetString( cmUiH_t uiH, unsigned id, const cmChar_t* v );
-
- // 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 id );
- unsigned cmUiUInt( cmUiH_t uiH, unsigned id );
- double cmUiDouble( cmUiH_t uiH, unsigned id );
- const cmChar_t* cmUiString( cmUiH_t uiH, unsigned id );
-
- // 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
|