libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. #ifndef cmUi_h
  2. #define cmUi_h
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. /*
  7. cmUI implements a platform independent UI control manager
  8. for multiple simultaneous applications. In this context
  9. an 'application' can be seen as a plug-in style program.
  10. The goal of the manager is to support the easy construction
  11. of panels of graphic user interface controls.
  12. Operation:
  13. 1) A cmUi manager is allocated by the master program. See cmUiAlloc().
  14. 2) The master program then assigns a 'driver' to implmenent
  15. the commands issued by cmUi. All commands can be
  16. described using the cmUiDriverArg_t record.
  17. 3) The master program then registers client applications with
  18. the cmUi manager by calling cmUiCreateApp().
  19. 4) Prior to calling any of the client application functions
  20. the master or client app. must call cmUiSetAppId(). This
  21. function sets the current application id and thereby slightly
  22. simplifies the client app interface by not requiring the
  23. app id be passed with every client app. function call.
  24. 5) Once the current app. id is set with cmUiSetAppId()
  25. the client app can make multiple calls to the cmUi manager
  26. to create or query controls.
  27. 6) Calls to create controls result in callbacks to the
  28. driver function which manages the actual windowing and
  29. initial event handling.
  30. 7) Events generated by the driver based graphic controls
  31. are routed back to the cmUi manager through calls to
  32. cmUiOnDriverEvent().
  33. 8) The cmUiOnDriverEvent() internally caches the
  34. state/value of the control based on the event information
  35. and calls the 'cbFunc' function registered with the
  36. cmUi manager by cmUiAlloc(). This call is intended to
  37. notify the client applications of changes in the state/value
  38. of a user interface control.
  39. Notes:
  40. 1) Application id's must be unique among all applications.
  41. Control id's must be unique among all controls assigned
  42. to the same application. Both application and control id's
  43. are used internally as array indexes they should therefore
  44. be the low, positive, and densely packed integers.
  45. 2) All communication between the cmUi and the driver,
  46. and all callbacks from the cmUi to the master app.
  47. use the cmUiDriverArg_t structure
  48. TODO:
  49. 0) Remove the 'cbArg' from the cmUiDriverArg_t record and
  50. pass it as a separate paramenter in the cmUiDriverFunc_t calls.
  51. 1) The controls should be based on a multilevel tree model
  52. not the simple two layer panel->controls framework used now.
  53. 2) Given that access to the control values can be non-blocked
  54. and fast many controls won't need to report changes back to
  55. the client - the client can simply read the control value
  56. as necessary directly from the cmUi manager. To decrease
  57. event processing overhead controls should therefore be
  58. flagged as 'callback/no-callback'. Some controls like
  59. buttons should default to turning the flag on, while other
  60. controls, like numbers, should default to turning it off.
  61. 3) Implement support for the creation of arrays of controls.
  62. This can be implemented with a scheme similar to 'next rect'.
  63. cmUiSetupArray(uiH,panelId,baseCtlId,cnt).
  64. 4) Come up with a threading model. For example maybe
  65. control creation should use a blocking scheme since it is
  66. generally to time consuming to do during real-time operation
  67. anyway. If the control flow generated from driver event
  68. callbacks then allows value, but not structural changes,
  69. then non blocking will be necessary.
  70. 5) The cmUiDriverArg_t structure is used for both
  71. commands to the driver and callbacks from the driver.
  72. Many of the fields are not use for event callbacks.
  73. Which fields are used under which circumstances should
  74. be documented. This would allow decreasing the size
  75. of the record during serialization.7
  76. 6) Write a serialization/deserialization routines for cmUiDriverArg_t.
  77. unsigned cmUiDriverArgSerialBufByteCount(const cmUiDriverArg_t* a);
  78. cmUiRC_t cmUiDriverArgSerialize( const cmUiDriverArg_t* a, char* buf, bufByteCnt );
  79. cmUiRC_t cmUiDriverArgDeserialize( cmUiDriverArg_t* a, const char* buf, bufByteCnt );
  80. 7) There is no duplex model for validating and then displaying the
  81. value of a control.
  82. */
  83. typedef cmHandle_t cmUiH_t;
  84. extern cmUiH_t cmUiNullHandle;
  85. //=============================================================================================
  86. //
  87. // Master program API
  88. //
  89. // Allocate the cmUi manager. If the driver function is not
  90. // yet available then set drvrFunc to NULL and use
  91. // cmUiSetDriver() to set the driver function at a later
  92. // time. cmUiAlloc() stores but does not call the driver
  93. // and so it is not needed when the cmUI manager is
  94. // constructed - however it must be set prior to making
  95. // any other calls to the manager.
  96. cmUiRC_t cmUiAlloc(
  97. cmCtx_t* ctx,
  98. cmUiH_t* hp,
  99. cmUiDriverFunc_t drvrFunc, // UI driver function
  100. void* drvrArg,
  101. cmUiDriverFunc_t cbFunc, // client event callback function
  102. void* cbArg );
  103. // Release all apps but assume that the driver has already
  104. // been released.
  105. cmUiRC_t cmUiFree( cmUiH_t* hp );
  106. // Validate the cmUiH_t handle.
  107. bool cmUiIsValid( cmUiH_t h );
  108. // Set the driver function. This function allows the driver
  109. // set in cmUiAlloc() to be replaced or set following the
  110. // call to cmUiAlloc().
  111. //
  112. // By setting the driver function to
  113. // NULL the application can prevent callback to the driver.
  114. // This is useful if the driver has been release prior
  115. // to the UI manager begining destroyed.
  116. void cmUiSetDriver( cmUiH_t h, cmUiDriverFunc_t drvrFunc, void* drvrArg );
  117. // Register a client application with the cmUi manager.
  118. // 'appId' must not have been used by any other previously registered.
  119. // application.
  120. // Automatically sets and restores the ambient appId.
  121. // In a plug-in context this function is generally called
  122. // just prior a instantiating a plug-in object.
  123. cmUiRC_t cmUiCreateApp( cmUiH_t uiH, unsigned appId );
  124. // Notify the cmUi manager that the resources associated
  125. // with a client application can be released.
  126. // Automatically sets and restores the ambient appId.
  127. cmUiRC_t cmUiDestroyApp( cmUiH_t uiH, unsigned appId );
  128. // Release all apps.
  129. // Automatically sets and restores the ambient appId.
  130. cmUiRC_t cmUiDestroyAllApps( cmUiH_t h );
  131. // The master program sets the ambient 'appId' prior to passing control
  132. // to a client which will make User API calls. By making the
  133. // 'appId' an ambient parameter the User API calls are slightly
  134. // simplified because they do not have to include it in each of the
  135. // function calls.
  136. cmUiRC_t cmUiSetAppId( cmUiH_t uiH, unsigned appId );
  137. // Return the count of app's.
  138. unsigned cmUiAppCount( cmUiH_t uiH );
  139. // Callbacks from the driver arrive via this function.
  140. cmUiRC_t cmUiOnDriverEvent( cmUiH_t uiH, const cmUiDriverArg_t* p );
  141. //=============================================================================================
  142. //
  143. // Client Application API
  144. //
  145. cmUiRC_t cmUiCreatePanel( cmUiH_t uiH, unsigned newPanelId, const cmChar_t* label );
  146. cmUiRC_t cmUiCreateBtn( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags );
  147. cmUiRC_t cmUiCreateCheck( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, bool dflt );
  148. cmUiRC_t cmUiCreateLabel( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags );
  149. cmUiRC_t cmUiCreateText( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* text );
  150. cmUiRC_t cmUiCreateNumber( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, double min, double max, double incr, double dflt );
  151. cmUiRC_t cmUiCreateHSlider( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, double min, double max, double incr, double dflt );
  152. cmUiRC_t cmUiCreateVSlider( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, double min, double max, double incr, double dflt );
  153. cmUiRC_t cmUiCreateProgress( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt );
  154. cmUiRC_t cmUiCreateHMeter( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt );
  155. cmUiRC_t cmUiCreateVMeter( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt );
  156. cmUiRC_t cmUiCreateFileBtn( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* dfltDir, const cmChar_t* patStr );
  157. cmUiRC_t cmUiCreateDirBtn( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* dfltDir );
  158. cmUiRC_t cmUiCreateMenuBtn( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags );
  159. 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 );
  160. cmUiRC_t cmUiCreateMenuBtnA( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* lavel, unsigned flags, const cmChar_t* label0, unsigned id0, ... );
  161. cmUiRC_t cmUiCreateMenuBtnJson( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* lavel, unsigned flags, const cmJsonNode_t* root, const cmChar_t* memberLabel );
  162. cmUiRC_t cmUiCreateList( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, unsigned visibleRowCnt );
  163. 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 );
  164. cmUiRC_t cmUiCreateListA( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, unsigned visibleRowCnt, const cmChar_t* label0, unsigned id0, ... );
  165. 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 );
  166. // If 'id' identifies a 'list' control use tabs as column separators.
  167. cmUiRC_t cmUiAppendListEle( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* text, unsigned eleId );
  168. // If 'id' identifies a panel then all control belonging to the panel
  169. // will also be destroyed.
  170. cmUiRC_t cmUiDestroyCtl( cmUiH_t uiH, unsigned id );
  171. // Returns true if the control exists.
  172. // For panels set id=panelId.
  173. bool cmUiCtlExists( cmUiH_t uiH, unsigned panelId, unsigned id );
  174. // Destroy all the controls in a panel.
  175. cmUiRC_t cmUiClearPanel( cmUiH_t uiH, unsigned panelId );
  176. // Location:
  177. // 1) If a 'next rect' is set the control will be placed according to it.
  178. // 2) If cmUiSetBaseCol() was set then the control will be placed at the
  179. // base col and base row.
  180. // 3) If cmUiPlaceRight() or cmUIPlaceBelow() have been called since the
  181. // previous control was created then the new control will be placed
  182. // accordingly.
  183. // 4) The control will be placed according to the 'fill rows' flag.
  184. // If not set (default) the new control will be placed in the
  185. // base column below the previous control.
  186. // If 'fill rows' is set the new control will be placed on the
  187. // same row to the right of the previous control.
  188. // If there is no previous control then it will be placed
  189. // in the base column and base row.
  190. // Get/Set the fill directions. If the 'fill columns' flag is enabled
  191. // then the next control is placed below the previous control otherwise
  192. // the next control is placed to the right of the next control.
  193. bool cmUiFillRows( cmUiH_t uiH, unsigned panelId );
  194. bool cmUiSetFillRows( cmUiH_t uiH, unsigned panelId, bool enableFl );
  195. // Place the next control to the right/below of the previous ctl.
  196. // These flags override the current fill row/col setting.
  197. // Note that 'place right' and 'place below' are mutually
  198. // exclusive. Enabling one disables the other.
  199. void cmUiPlaceRight( cmUiH_t uiH, unsigned panelId );
  200. void cmUiPlaceBelow( cmUiH_t uiH, unsigned panelId );
  201. // Set current base col and return previous value. Place the next
  202. // control on the base row.
  203. int cmUiBaseCol( cmUiH_t uiH, unsigned panelId, int x );
  204. // Set current base row and return previous value.
  205. int cmUiBaseRow( cmUiH_t uiH, unsigned panelId, int y );
  206. // Size:
  207. // 1) If a 'next rect' is set the control will be placed according
  208. // to it.
  209. // 2) If a 'next w/h' is set the control will be placed according
  210. // to it. The 'next w/h' setting is only active for the
  211. // next control created.
  212. // 3) The w/h of the new control will be set to the default w/h.
  213. //
  214. // Get/Set the default control width and height.
  215. // Set returns previous value.
  216. int cmUiW( cmUiH_t uiH, unsigned panelId );
  217. int cmUiH( cmUiH_t uiH, unsigned panelId );
  218. void cmUiSetWH( cmUiH_t uiH, unsigned panelId, int w, int h );
  219. // Get/Set the control width and height for only the next control.
  220. // Set returns previous value.
  221. int cmUiNextW( cmUiH_t uiH, unsigned panelId );
  222. int cmUiNextH( cmUiH_t uiH, unsigned panelId );
  223. void cmUiSetNextWH( cmUiH_t uiH, unsigned panelId, int w, int h );
  224. // Get/Set the default inter-control borders
  225. // Set returns previous value.
  226. int cmUiHBorder( cmUiH_t uiH, unsigned panelId );
  227. int cmUiVBorder( cmUiH_t uiH, unsigned panelId );
  228. int cmUiSetHBorder( cmUiH_t uiH, unsigned panelId, int w );
  229. int cmUiSetVBorder( cmUiH_t uiH, unsigned panelId, int h );
  230. // Get/Set the 'next' inter-control borders
  231. // Set returns previous value.
  232. int cmUiNextHBorder( cmUiH_t uiH, unsigned panelId );
  233. int cmUiNextVBorder( cmUiH_t uiH, unsigned panelId );
  234. int cmUiSetNextHBorder( cmUiH_t uiH, unsigned panelId, int w );
  235. int cmUiSetNextVBorder( cmUiH_t uiH, unsigned panelId, int h );
  236. // Place the next control at the following coordinates. The
  237. // specified coordinates are only active during the next
  238. // cmUiCreateXXX() call. Setting the 'next rect' overrides all
  239. // other layout directives.
  240. cmUiRC_t cmUiNextRect( cmUiH_t uiH, unsigned panelId, int x, int y, int w, int h );
  241. //
  242. // Get/set the value of UI control.
  243. //
  244. // TODO:
  245. // 1) Still need functions for setting auxilliary values like
  246. // min,max,etc..
  247. // 2) A coherent model needs to be selected for determining
  248. // how local values get set. As it is local values are
  249. // only set via callbacs from the UI driver.
  250. // Set the value associated with a control.
  251. // These functions would be better named 'cmUiSendXXX()' since
  252. // they don't actually set the local value but rather call the
  253. // driver to set the UI value. The driver may then respond with
  254. // a callback which will set the local value. One advantage of
  255. // this is that the value will be filtered according to the
  256. // ui's rules (e.g. min, max .... )
  257. cmUiRC_t cmUiSetInt( cmUiH_t uiH, unsigned id, int v );
  258. cmUiRC_t cmUiSetUInt( cmUiH_t uiH, unsigned id, unsigned v );
  259. cmUiRC_t cmUiSetDouble( cmUiH_t uiH, unsigned id, double v );
  260. cmUiRC_t cmUiSetString( cmUiH_t uiH, unsigned id, const cmChar_t* v );
  261. // Get the value associated with a control. These functions return
  262. // the control value cached in the local control, they do not need
  263. // to call the driver and are therefore very fast.
  264. int cmUiInt( cmUiH_t uiH, unsigned id );
  265. unsigned cmUiUInt( cmUiH_t uiH, unsigned id );
  266. double cmUiDouble( cmUiH_t uiH, unsigned id );
  267. const cmChar_t* cmUiString( cmUiH_t uiH, unsigned id );
  268. // Query/set the current error state.
  269. cmUiRC_t cmUiLastRC( cmUiH_t uiH );
  270. cmUiRC_t cmUiSetRC( cmUiH_t uiH, cmUiRC_t rc );
  271. #ifdef __cplusplus
  272. }
  273. #endif
  274. #endif