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.

cmUi.c 40KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701
  1. #include "cmGlobal.h"
  2. #include "cmRpt.h"
  3. #include "cmErr.h"
  4. #include "cmCtx.h"
  5. #include "cmMem.h"
  6. #include "cmMallocDebug.h"
  7. #include "cmArray.h"
  8. #include "cmJson.h"
  9. #include "cmUiDrvr.h"
  10. #include "cmUi.h"
  11. typedef struct
  12. {
  13. int x;
  14. int y;
  15. int w;
  16. int h;
  17. } cmUiRect_t;
  18. enum
  19. {
  20. kUseRectUiFl = 0x01,
  21. kPlaceRightUiFl = 0x02, // place only next control to right of prev control
  22. kPlaceBelowUiFl = 0x04, // place only next control to below prev control
  23. kPlaceBaseRowUiFl = 0x08, // place only next control at base row
  24. kNextWHUiFl = 0x10, // size next control according to nextW,nextH
  25. kFillRowsUiFl = 0x20, // current dflt fill direction
  26. };
  27. typedef struct cmUiApp_str
  28. {
  29. unsigned appId; // app id and index into cmUI_t.appArrH[].
  30. bool activeFl; // true if this app recd is active and valid
  31. cmArrayH_t ctlArrH; // cmUiCtl_t[]
  32. cmArrayH_t pnlArrH; // cmUiPanel_t[]
  33. } cmUiApp_t;
  34. typedef struct cmUiPanel_str
  35. {
  36. cmUiApp_t* appPtr; // owner app.
  37. unsigned flags; // See kXXXUiFl above
  38. unsigned usrId; // app. supplied id
  39. cmUiRect_t rect; // rect to position next control (only used if kUseRectUiFl is set)
  40. cmUiRect_t prevRect;
  41. int baseCol;
  42. int baseRow;
  43. int dfltW;
  44. int dfltH;
  45. int nextW;
  46. int nextH;
  47. int dfltHBorder;
  48. int dfltVBorder;
  49. int nextHBorder;
  50. int nextVBorder;
  51. } cmUiPanel_t;
  52. typedef struct cmUiCtl_str
  53. {
  54. cmUiCId_t cId; // control type and used to decode the value union below.
  55. unsigned usrId; // control instance id and index into cmUiApp_t.ctlArrH[].
  56. unsigned panelId; // panel this ctl belongs to
  57. cmArrayH_t idArrH; // id's associated with each sub-element of this control (used by menu's, list's, etc...)
  58. // current value of this control
  59. union
  60. {
  61. int ival;
  62. double fval;
  63. cmChar_t* sval;
  64. cmUiPanel_t* pnl;
  65. } u;
  66. int (*getInt)( struct cmUiCtl_str* c );
  67. double (*getDbl)( struct cmUiCtl_str* c );
  68. const cmChar_t* (*getStr)( struct cmUiCtl_str* c );
  69. void (*setInt)( struct cmUiCtl_str* c, int v );
  70. void (*setDbl)( struct cmUiCtl_str* c, double v );
  71. void (*setStr)( struct cmUiCtl_str* c, const cmChar_t* s );
  72. } cmUiCtl_t;
  73. typedef struct
  74. {
  75. cmErr_t err; //
  76. cmCtx_t* ctx; // Global context.
  77. cmUiDriverFunc_t drvr; // Driver callback function
  78. void* drvrArg; // Driver callback function arg.
  79. int panelW; // Panel width.
  80. int panelH; // Panel height
  81. unsigned curAppId; // Id of application currently receiveing commands/queries.
  82. cmUiDriverFunc_t cbFunc; // Client callback function
  83. void * cbArg; //
  84. cmArrayH_t appArrH; // cmUiApp_t[]
  85. } cmUi_t;
  86. cmUiH_t cmUiNullHandle = cmSTATIC_NULL_HANDLE;
  87. cmUi_t* _cmUiHandleToPtr( cmUiH_t h )
  88. {
  89. cmUi_t* p = (cmUi_t*)h.h;
  90. assert(p != NULL );
  91. return p;
  92. }
  93. void _cmUiDriverArgInit( cmUiDriverArg_t* a, cmUi_t* p, cmUiDId_t dId, cmUiCId_t cId, unsigned panelId, unsigned usrId )
  94. {
  95. memset(a,0,sizeof(*a));
  96. a->cbArg = p->drvrArg;
  97. a->dId = dId;
  98. a->cId = cId;
  99. a->appId = p->curAppId;
  100. a->panelId = panelId;
  101. a->usrId = usrId;
  102. a->flags = 0;
  103. a->x = -1;
  104. a->y = -1;
  105. a->w = -1;
  106. a->h = -1;
  107. a->ival = 0;
  108. a->fval = 0;
  109. a->sval = NULL;
  110. }
  111. //---------------------------------------------------------------
  112. // int accessors
  113. int _cmUiGetIntFromInt( cmUiCtl_t* ctl )
  114. { return ctl->u.ival; }
  115. double _cmUiGetDblFromInt( cmUiCtl_t* ctl )
  116. { return ctl->u.ival; }
  117. const cmChar_t* _cmUiGetStrFromInt( cmUiCtl_t* ctl )
  118. { assert(0); return ""; }
  119. void _cmUiSetIntFromInt( cmUiCtl_t* ctl, int v )
  120. { ctl->u.ival = v; }
  121. void _cmUiSetIntFromDbl( cmUiCtl_t* ctl, double v )
  122. { ctl->u.ival = round(v); }
  123. void _cmUiSetIntFromStr( cmUiCtl_t* ctl, const cmChar_t* v )
  124. { assert(0); }
  125. void _cmUiSetIntAccessors( cmUiCtl_t* ctl )
  126. {
  127. ctl->getInt = _cmUiGetIntFromInt;
  128. ctl->getDbl = _cmUiGetDblFromInt;
  129. ctl->getStr = _cmUiGetStrFromInt;
  130. ctl->setInt = _cmUiSetIntFromInt;
  131. ctl->setDbl = _cmUiSetIntFromDbl;
  132. ctl->setStr = _cmUiSetIntFromStr;
  133. }
  134. //---------------------------------------------------------------
  135. // double accessors
  136. int _cmUiGetIntFromDbl( cmUiCtl_t* ctl )
  137. { return round(ctl->u.fval); }
  138. double _cmUiGetDblFromDbl( cmUiCtl_t* ctl )
  139. { return ctl->u.fval; }
  140. const cmChar_t* _cmUiGetStrFromDbl( cmUiCtl_t* ctl )
  141. { assert(0); return ""; }
  142. void _cmUiSetDblFromInt( cmUiCtl_t* ctl, int v )
  143. { ctl->u.fval = v; }
  144. void _cmUiSetDblFromDbl( cmUiCtl_t* ctl, double v )
  145. { ctl->u.fval = v; }
  146. void _cmUiSetDblFromStr( cmUiCtl_t* ctl, const cmChar_t* v )
  147. { assert(0); }
  148. void _cmUiSetDblAccessors( cmUiCtl_t* ctl )
  149. {
  150. ctl->getInt = _cmUiGetIntFromDbl;
  151. ctl->getDbl = _cmUiGetDblFromDbl;
  152. ctl->getStr = _cmUiGetStrFromDbl;
  153. ctl->setInt = _cmUiSetDblFromInt;
  154. ctl->setDbl = _cmUiSetDblFromDbl;
  155. ctl->setStr = _cmUiSetDblFromStr;
  156. }
  157. //---------------------------------------------------------------
  158. // string accessors
  159. int _cmUiGetIntFromStr( cmUiCtl_t* ctl )
  160. { assert(0); return -1; }
  161. double _cmUiGetDblFromStr( cmUiCtl_t* ctl )
  162. { assert(0); return -1; }
  163. const cmChar_t* _cmUiGetStrFromStr( cmUiCtl_t* ctl )
  164. { return ctl->u.sval; }
  165. void _cmUiSetStrFromInt( cmUiCtl_t* ctl, int v )
  166. { assert(0); }
  167. void _cmUiSetStrFromDbl( cmUiCtl_t* ctl, double v )
  168. { assert(0); }
  169. void _cmUiSetStrFromStr( cmUiCtl_t* ctl, const cmChar_t* v )
  170. { ctl->u.sval = cmMemResizeStr(ctl->u.sval, v==NULL ? "" : v); }
  171. void _cmUiSetStrAccessors( cmUiCtl_t* ctl )
  172. {
  173. ctl->getInt = _cmUiGetIntFromStr;
  174. ctl->getDbl = _cmUiGetDblFromStr;
  175. ctl->getStr = _cmUiGetStrFromStr;
  176. ctl->setInt = _cmUiSetStrFromInt;
  177. ctl->setDbl = _cmUiSetStrFromDbl;
  178. ctl->setStr = _cmUiSetStrFromStr;
  179. }
  180. //---------------------------------------------------------------
  181. cmUiRC_t _cmUiFindApp( cmUi_t* p, unsigned appId, cmUiApp_t** appRef, bool errFl )
  182. {
  183. cmUiRC_t rc = kOkUiRC;
  184. cmUiApp_t* ap = NULL;
  185. // verify that the appId is a valid index
  186. if( appId < cmArrayCount(p->appArrH) )
  187. ap = cmArrayPtr(cmUiApp_t,p->appArrH,appId);
  188. // if the app record was not already allocated
  189. if( ap != NULL && ap->activeFl == false )
  190. ap = NULL;
  191. // report errors
  192. if( ap == NULL )
  193. {
  194. rc = kAppNotFoundUiRC;
  195. if( errFl )
  196. cmErrMsg(&p->err,rc,"App %i not found.", appId );
  197. }
  198. *appRef = ap;
  199. return rc;
  200. }
  201. cmUiRC_t _cmUiFindCtl( cmUi_t* p, unsigned usrId, cmUiCtl_t** ctlRef, bool errFl )
  202. {
  203. cmUiRC_t rc = kOkUiRC;
  204. cmUiApp_t* ap = NULL;
  205. cmUiCtl_t* ctl = NULL;
  206. // find the app this ctl belongs to
  207. if(( rc =_cmUiFindApp(p,p->curAppId,&ap,errFl)) != kOkUiRC )
  208. goto errLabel;
  209. // verify that the usrId is a valid index
  210. if( usrId < cmArrayCount(ap->ctlArrH) )
  211. ctl = cmArrayPtr(cmUiCtl_t,ap->ctlArrH,usrId);
  212. // verify that the usrId of the recd matches the requested usr id
  213. if( ctl!=NULL && ctl->usrId != usrId )
  214. ctl = NULL;
  215. // report errors
  216. if( ctl==NULL )
  217. {
  218. rc = kCtlNotFoundUiRC;
  219. if( errFl )
  220. cmErrMsg(&p->err,rc,"Control %i not found.",usrId);
  221. }
  222. errLabel:
  223. *ctlRef = ctl;
  224. return rc;
  225. }
  226. cmUiRC_t _cmUiFastFindCtl( cmUi_t* p, unsigned usrId, cmUiCtl_t** ctlRef, bool errFl )
  227. {
  228. assert( p->curAppId < cmArrayCount(p->appArrH) );
  229. cmUiApp_t* ap = cmArrayPtr(cmUiApp_t,p->appArrH,p->curAppId);
  230. assert( ap->activeFl && usrId < cmArrayCount(ap->ctlArrH) );
  231. *ctlRef = cmArrayPtr(cmUiCtl_t,ap->ctlArrH,usrId);
  232. assert( (*ctlRef)->usrId == usrId );
  233. return kOkUiRC;
  234. }
  235. cmUiRC_t _cmUiFindPanel( cmUi_t* p, unsigned panelId, cmUiPanel_t** ppRef, bool errFl )
  236. {
  237. cmUiRC_t rc = kOkUiRC;
  238. cmUiApp_t* ap = NULL;
  239. unsigned i,n;
  240. *ppRef = NULL;
  241. // find the app this ctl belongs to
  242. if(( rc =_cmUiFindApp(p,p->curAppId,&ap,errFl)) != kOkUiRC )
  243. goto errLabel;
  244. n = cmArrayCount(ap->pnlArrH);
  245. for(i=0; i<n; ++i)
  246. if( (*ppRef = cmArrayPtr(cmUiPanel_t,ap->pnlArrH,i))->usrId == panelId )
  247. break;
  248. errLabel:
  249. if(*ppRef == NULL)
  250. {
  251. rc = kPanelNotFoundUiRC;
  252. if( errFl )
  253. cmErrMsg(&p->err,rc,"Panel %i was not found.",panelId);
  254. }
  255. return rc;
  256. }
  257. cmUiRC_t _cmUiCallDriver( cmUi_t* p, cmUiDriverArg_t* a )
  258. {
  259. cmUiRC_t rc = kOkUiRC;
  260. if( p->drvr != NULL )
  261. if((rc = p->drvr(a)) != kOkUiRC )
  262. rc = cmErrMsg(&p->err,kDrvrErrUiRC,"UI manager driver error.");
  263. return rc;
  264. }
  265. cmUiRC_t _cmUiDestroyDrvrCtl( cmUi_t* p, cmUiCId_t cId, unsigned panelId, unsigned usrId )
  266. {
  267. cmUiDriverArg_t a;
  268. _cmUiDriverArgInit(&a, p, kDestroyCtlDId, cId, panelId, usrId );
  269. return _cmUiCallDriver(p,&a);
  270. }
  271. cmUiRC_t _cmUiDestroyCtl( cmUi_t* p, cmUiCtl_t* ctl )
  272. {
  273. cmUiRC_t rc = kOkUiRC;
  274. rc =_cmUiDestroyDrvrCtl(p,ctl->cId,ctl->panelId,ctl->usrId);
  275. switch(ctl->cId)
  276. {
  277. case kLabelUiCId:
  278. case kTextUiCId:
  279. case kFilenameUiCId:
  280. case kDirUiCId:
  281. cmMemFree(ctl->u.sval);
  282. break;
  283. default:
  284. break;
  285. }
  286. ctl->usrId = cmInvalidId;
  287. ctl->panelId = cmInvalidId;
  288. cmArrayRelease(&ctl->idArrH);
  289. return rc;
  290. }
  291. cmUiRC_t _cmUiDestroyPanel( cmUi_t* p, unsigned panelId )
  292. {
  293. cmUiRC_t rc = kOkUiRC;
  294. cmUiPanel_t* pp = NULL;
  295. // get the panel recd ptr
  296. if((rc = _cmUiFindPanel(p,panelId,&pp,true)) != kOkUiRC )
  297. return rc;
  298. cmUiApp_t* ap = pp->appPtr;
  299. // notify the driver to destroy the panel
  300. if((rc = _cmUiDestroyDrvrCtl(p,kPanelUiCId,panelId,panelId)) != kOkUiRC )
  301. return rc;
  302. cmUiCtl_t* ctl = NULL;
  303. unsigned i = 0;
  304. unsigned n = cmArrayCount(ap->ctlArrH);
  305. cmUiRC_t rc0;
  306. // Destroy all controls that belong to this panel.
  307. // Notice that _cmUiDestroyCtl() does not need to call the driver
  308. // because destroying the drivers panel has implicitely also
  309. // destroyed all the contols assigned to it.
  310. for(i=0; i<n; ++i)
  311. if( _cmUiFindCtl(p,i,&ctl,false) == kOkUiRC && ctl != NULL && ctl->panelId == panelId)
  312. if((rc0 = _cmUiDestroyCtl(p,ctl)) != kOkUiRC )
  313. rc = rc0;
  314. // release the panel record
  315. pp->appPtr = NULL;
  316. pp->usrId = cmInvalidId;
  317. return rc;
  318. }
  319. cmUiRC_t _cmUiDestroyApp( cmUi_t* p, unsigned appId, bool errFl )
  320. {
  321. cmUiRC_t rc = kOkUiRC;
  322. cmUiRC_t rc0;
  323. cmUiApp_t* ap;
  324. unsigned orgAppId = p->curAppId;
  325. p->curAppId = appId;
  326. // find the app to destroy
  327. if( _cmUiFindApp(p,appId,&ap,false) != kOkUiRC )
  328. {
  329. if( errFl )
  330. rc = cmErrMsg(&p->err,kAppNotFoundUiRC,"The app %i was not found for destruction.",appId);
  331. goto errLabel;
  332. }
  333. assert( ap != NULL );
  334. // destroy all panels owned by this app
  335. unsigned i;
  336. unsigned n = cmArrayCount(ap->pnlArrH);
  337. for(i=0; i<n; ++i)
  338. {
  339. cmUiPanel_t* pp = cmArrayPtr(cmUiPanel_t,ap->pnlArrH,i);
  340. if( pp->usrId != cmInvalidId )
  341. if((rc0 = _cmUiDestroyPanel(p,pp->usrId)) != kOkUiRC )
  342. rc = rc0;
  343. }
  344. ap->appId = -1;
  345. ap->activeFl = false;
  346. cmArrayRelease(&ap->ctlArrH);
  347. cmArrayRelease(&ap->pnlArrH);
  348. errLabel:
  349. p->curAppId = orgAppId;
  350. return rc;
  351. }
  352. cmUiRC_t _cmUiDestroyAllApps( cmUi_t* p )
  353. {
  354. cmUiRC_t rc = kOkUiRC;
  355. unsigned n = cmArrayCount(p->appArrH);
  356. unsigned i;
  357. for(i=0; i<n; ++i)
  358. {
  359. cmUiRC_t rc0;
  360. if((rc0 = _cmUiDestroyApp(p,i,false)) != kOkUiRC )
  361. rc = rc0;
  362. }
  363. cmArrayClear(p->appArrH,false);
  364. return rc;
  365. }
  366. cmUiRC_t _cmUiGetCtlXYWH( cmUi_t* p, cmUiDriverArg_t* a, cmUiPanel_t* pp )
  367. {
  368. if( cmIsFlag(pp->flags,kUseRectUiFl ) )
  369. {
  370. pp->flags = cmClrFlag(pp->flags,kUseRectUiFl);
  371. a->x = pp->rect.x;
  372. a->y = pp->rect.y;
  373. a->w = pp->rect.w;
  374. a->h = pp->rect.h;
  375. return kOkUiRC;
  376. }
  377. if( pp->prevRect.x == -1 )
  378. pp->prevRect.x = pp->baseCol;
  379. if( pp->prevRect.y == -1 )
  380. pp->prevRect.y = pp->baseRow;
  381. if( pp->prevRect.w == -1 )
  382. pp->prevRect.w = 0;
  383. if( pp->prevRect.h == -1 )
  384. pp->prevRect.h = 0;
  385. // Get direction flag. Fill across rows? or down columns?
  386. bool fillRowFl = cmIsFlag(pp->flags,kFillRowsUiFl);
  387. // the 'place to right' flag overrides the directon flag for just this instance
  388. if( cmIsFlag(pp->flags,kPlaceRightUiFl ) )
  389. fillRowFl = true;
  390. // the 'place under' flag overides the direction flag for just this instance
  391. if( cmIsFlag(pp->flags,kPlaceBelowUiFl ) )
  392. fillRowFl = false;
  393. // set x coord - if filling acros rows ...
  394. if( fillRowFl )
  395. a->x = pp->prevRect.x + pp->prevRect.w + pp->nextHBorder;
  396. else
  397. a->x = pp->baseCol; // ... or down columns
  398. // if a new column was set then move to the base row
  399. if( cmIsFlag(pp->flags,kPlaceBaseRowUiFl) )
  400. a->y = pp->baseRow;
  401. else
  402. {
  403. // set y coord - if filling acros rows ...
  404. if( fillRowFl )
  405. a->y = pp->prevRect.y;
  406. else
  407. a->y = pp->prevRect.y + pp->prevRect.h + pp->nextVBorder; // ... or down columns
  408. }
  409. a->w = pp->nextW;
  410. a->h = pp->nextH;
  411. pp->prevRect.x = a->x;
  412. pp->prevRect.y = a->y;
  413. pp->prevRect.w = a->w;
  414. pp->prevRect.h = a->h;
  415. pp->nextW = pp->dfltW;
  416. pp->nextH = pp->dfltH;
  417. pp->nextHBorder= pp->dfltHBorder;
  418. pp->nextVBorder= pp->dfltVBorder;
  419. pp->flags = cmClrFlag(pp->flags,kNextWHUiFl | kPlaceRightUiFl | kPlaceBelowUiFl | kPlaceBaseRowUiFl );
  420. return kOkUiRC;
  421. }
  422. cmUiRC_t _cmUiCreateCtl( cmUi_t* p, cmUiDriverArg_t* a, unsigned panelId, cmUiCId_t cId, unsigned usrId, const cmChar_t* label, unsigned flags, cmUiCtl_t** ctlRef )
  423. {
  424. cmUiRC_t rc;
  425. cmUiPanel_t* pp = NULL;
  426. cmUiApp_t* ap = NULL;
  427. if( ctlRef != NULL )
  428. *ctlRef = NULL;
  429. // initialize the driver arg record
  430. _cmUiDriverArgInit(a, p, kCreateCtlDId, cId, panelId, usrId );
  431. // locate the app
  432. if((rc = _cmUiFindApp(p,p->curAppId,&ap,true)) != kOkUiRC )
  433. return rc;
  434. // locate the panel the control belongs to
  435. if((rc = _cmUiFindPanel(p,panelId,&pp,true)) != kOkUiRC )
  436. return rc;
  437. // calc the control location - for non-panel controls or
  438. // for panel controls using the custom 'next rect'.
  439. if( cId != kPanelUiCId || cmIsFlag(pp->flags,kUseRectUiFl ) )
  440. if((rc = _cmUiGetCtlXYWH(p,a,pp)) != kOkUiRC )
  441. return rc;
  442. // get the new ctl record
  443. cmUiCtl_t* ctl = cmArrayClr(cmUiCtl_t,ap->ctlArrH,usrId);
  444. // setup the new ctl record
  445. ctl->cId = cId;
  446. ctl->usrId = usrId;
  447. ctl->panelId = panelId;
  448. cmArrayAlloc(p->ctx,&ctl->idArrH,sizeof(unsigned));
  449. a->sval = label;
  450. a->flags = flags;
  451. if( ctlRef != NULL )
  452. *ctlRef = ctl;
  453. return _cmUiCallDriver(p,a);
  454. }
  455. cmUiRC_t cmUiAlloc(
  456. cmCtx_t* ctx,
  457. cmUiH_t* uiHPtr,
  458. cmUiDriverFunc_t drvrFunc,
  459. void* drvrArg,
  460. cmUiDriverFunc_t cbFunc,
  461. void * cbArg)
  462. {
  463. cmUiRC_t rc;
  464. if((rc = cmUiFree(uiHPtr)) != kOkUiRC )
  465. return rc;
  466. cmUi_t* p = cmMemAllocZ(cmUi_t,1);
  467. cmErrSetup(&p->err,&ctx->rpt,"cmUi");
  468. p->ctx = ctx;
  469. p->drvr = drvrFunc;
  470. p->drvrArg = drvrArg;
  471. p->cbFunc = cbFunc;
  472. p->cbArg = cbArg;
  473. p->panelW = 1000;
  474. p->panelH = 500;
  475. cmArrayAlloc(p->ctx,&p->appArrH,sizeof(cmUiApp_t));
  476. uiHPtr->h = p;
  477. return rc;
  478. }
  479. cmUiRC_t cmUiFree( cmUiH_t* hp )
  480. {
  481. cmUiRC_t rc = kOkUiRC;
  482. if( hp == NULL || cmUiIsValid(*hp)==false )
  483. return kOkUiRC;
  484. cmUi_t* p = _cmUiHandleToPtr(*hp);
  485. if((rc = _cmUiDestroyAllApps(p)) != kOkUiRC )
  486. return rc;
  487. cmArrayRelease(&p->appArrH);
  488. cmMemFree(p);
  489. hp->h = NULL;
  490. return rc;
  491. }
  492. bool cmUiIsValid( cmUiH_t h )
  493. { return h.h != NULL; }
  494. void cmUiSetDriver( cmUiH_t h, cmUiDriverFunc_t drvrFunc, void* drvrArg )
  495. {
  496. cmUi_t* p = _cmUiHandleToPtr(h);
  497. p->drvr = drvrFunc;
  498. p->drvrArg = drvrArg;
  499. }
  500. cmUiRC_t cmUiCreateApp( cmUiH_t h, unsigned appId )
  501. {
  502. cmUiRC_t rc = kOkUiRC;
  503. if( cmUiIsValid(h)==false)
  504. return rc;
  505. cmUi_t* p = _cmUiHandleToPtr(h);
  506. cmUiApp_t* ap = NULL;
  507. // verify that the requested app does not exist
  508. if( _cmUiFindApp(p,appId, &ap, false ) == kOkUiRC )
  509. return cmErrMsg(&p->err,kInvalidIdUiRC,"The id (%i) of the new application is already in use.",appId);
  510. ap = cmArrayClr(cmUiApp_t,p->appArrH,appId);
  511. ap->appId = appId;
  512. ap->activeFl = true;
  513. cmArrayAlloc(p->ctx,&ap->ctlArrH,sizeof(cmUiCtl_t));
  514. cmArrayAlloc(p->ctx,&ap->pnlArrH,sizeof(cmUiPanel_t));
  515. return rc;
  516. }
  517. cmUiRC_t cmUiDestroyApp( cmUiH_t h, unsigned appId )
  518. {
  519. if( cmUiIsValid(h)==false)
  520. return kOkUiRC;
  521. cmUi_t* p = _cmUiHandleToPtr(h);
  522. return _cmUiDestroyApp(p,appId,true);
  523. }
  524. cmUiRC_t cmUiDestroyAllApps( cmUiH_t h )
  525. {
  526. if( cmUiIsValid(h)==false)
  527. return kOkUiRC;
  528. cmUi_t* p = _cmUiHandleToPtr(h);
  529. return _cmUiDestroyAllApps(p);
  530. }
  531. cmUiRC_t cmUiSetAppId( cmUiH_t h, unsigned appId )
  532. {
  533. cmUiRC_t rc = kOkUiRC;
  534. if( cmUiIsValid(h)==false)
  535. return rc;
  536. cmUi_t* p = _cmUiHandleToPtr(h);
  537. cmUiApp_t* ap = NULL;
  538. // verify that the requested app exists
  539. if( appId != cmInvalidId )
  540. if((rc = _cmUiFindApp(p,appId, &ap, true )) != kOkUiRC )
  541. return rc;
  542. p->curAppId = appId;
  543. return rc;
  544. }
  545. unsigned cmUiAppCount( cmUiH_t h )
  546. {
  547. if( cmUiIsValid(h)==false)
  548. return 0;
  549. cmUi_t* p = _cmUiHandleToPtr(h);
  550. return cmArrayCount(p->appArrH);
  551. }
  552. cmUiRC_t cmUiOnDriverEvent( cmUiH_t h, const cmUiDriverArg_t* arg )
  553. {
  554. cmUiRC_t rc = kOkUiRC;
  555. cmUi_t* p = _cmUiHandleToPtr(h);
  556. cmUiDriverArg_t a = *arg;
  557. cmUiCtl_t* ctl;
  558. if((rc = cmUiSetAppId(h,arg->appId)) != kOkUiRC )
  559. return rc;
  560. a.cbArg = p->cbArg;
  561. if((rc = _cmUiFindCtl(p,a.usrId,&ctl,true)) != kOkUiRC )
  562. goto errLabel;
  563. switch( a.cId )
  564. {
  565. case kInvalidUiCId: break;
  566. case kPanelUiCId: break;
  567. case kBtnUiCId: break;
  568. case kCheckUiCId:
  569. ctl->u.ival = a.ival;
  570. break;
  571. case kMenuBtnUiCId:
  572. case kListUiCId:
  573. {
  574. ctl->u.ival = a.ival;
  575. if(a.ival >= cmArrayCount(ctl->idArrH))
  576. {
  577. rc = cmErrMsg(&p->err,kInvalidIdUiRC,"Invalid menu or list driver element id=%i element count:%i.",a.ival,cmArrayCount(ctl->idArrH));
  578. goto errLabel;
  579. }
  580. a.ival = cmArrayEle(unsigned,ctl->idArrH,a.ival);
  581. //a.ival = ctl->id_arr[ a.ival ];
  582. }
  583. break;
  584. case kLabelUiCId:
  585. ctl->u.sval = cmMemResizeStr(ctl->u.sval,cmStringNullGuard(a.sval));
  586. break;
  587. case kTextUiCId:
  588. ctl->u.sval = cmMemResizeStr(ctl->u.sval,cmStringNullGuard(a.sval));
  589. break;
  590. case kSliderUiCId:
  591. case kNumberUiCId:
  592. ctl->u.fval = a.fval;
  593. a.cId = kNumberUiCId; // sliders callback the client as numbers
  594. break;
  595. case kProgressUiCId:
  596. ctl->u.ival = a.ival;
  597. break;
  598. case kMeterUiCId:
  599. ctl->u.fval = a.fval;
  600. break;
  601. case kFilenameUiCId:
  602. ctl->u.sval = cmMemResizeStr(ctl->u.sval,cmStringNullGuard(a.sval));
  603. break;
  604. case kDirUiCId:
  605. ctl->u.sval = cmMemResizeStr(ctl->u.sval,cmStringNullGuard(a.sval));
  606. break;
  607. }
  608. rc = p->cbFunc(&a);
  609. errLabel:
  610. cmUiSetAppId(h,cmInvalidId);
  611. return rc;
  612. }
  613. cmUiRC_t cmUiCreatePanel( cmUiH_t uiH, unsigned newPanelId, const cmChar_t* label )
  614. {
  615. cmUiRC_t rc;
  616. cmUiDriverArg_t a;
  617. cmUi_t* p = _cmUiHandleToPtr(uiH);
  618. cmUiCtl_t* ctl = NULL;
  619. cmUiApp_t* ap = NULL;
  620. if(( rc = _cmUiFindApp(p,p->curAppId,&ap,true)) != kOkUiRC )
  621. return rc;
  622. cmUiPanel_t* pp = cmArrayPush(ap->pnlArrH,NULL,1);
  623. assert( pp != NULL );
  624. pp->appPtr = ap;
  625. pp->usrId = newPanelId;
  626. pp->baseCol = 2;
  627. pp->baseRow = 0;
  628. pp->dfltW = 150;
  629. pp->dfltH = 25;
  630. pp->nextW = pp->dfltW;
  631. pp->nextH = pp->dfltH;
  632. pp->dfltHBorder= 2;
  633. pp->dfltVBorder= 2;
  634. pp->nextHBorder= pp->dfltHBorder;
  635. pp->nextVBorder= pp->dfltVBorder;
  636. pp->prevRect.x = -1;
  637. pp->prevRect.y = -1;
  638. pp->prevRect.w = -1;
  639. pp->prevRect.h = -1;
  640. if((rc = _cmUiCreateCtl(p, &a, newPanelId, kPanelUiCId, newPanelId, label, 0, NULL )) != kOkUiRC )
  641. {
  642. // TODO - destroy panel record here
  643. return rc;
  644. }
  645. _cmUiFindCtl(p,newPanelId,&ctl,true);
  646. assert(ctl!=NULL);
  647. ctl->u.pnl = pp;
  648. return rc;
  649. }
  650. cmUiRC_t cmUiCreateBtn( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags )
  651. {
  652. cmUiRC_t rc;
  653. cmUi_t* p = _cmUiHandleToPtr(uiH);
  654. cmUiDriverArg_t a;
  655. cmUiCtl_t* c;
  656. if((rc = _cmUiCreateCtl(p,&a,panelId,kBtnUiCId,id,label,flags,&c)) == kOkUiRC )
  657. {
  658. _cmUiSetIntAccessors(c);
  659. }
  660. return rc;
  661. }
  662. cmUiRC_t cmUiCreateCheck( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, bool dflt )
  663. {
  664. cmUiRC_t rc;
  665. cmUi_t* p = _cmUiHandleToPtr(uiH);
  666. cmUiDriverArg_t a;
  667. cmUiCtl_t* c;
  668. a.ival = dflt;
  669. if((rc = _cmUiCreateCtl(p,&a,panelId,kCheckUiCId,id,label,flags,&c)) == kOkUiRC )
  670. _cmUiSetIntAccessors(c);
  671. return rc;
  672. }
  673. cmUiRC_t cmUiCreateLabel( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags )
  674. {
  675. cmUiRC_t rc;
  676. cmUi_t* p = _cmUiHandleToPtr(uiH);
  677. cmUiDriverArg_t a;
  678. cmUiCtl_t* c;
  679. if((rc = _cmUiCreateCtl(p,&a,panelId,kLabelUiCId,id,label,flags,&c)) == kOkUiRC )
  680. _cmUiSetStrAccessors(c);
  681. return rc;
  682. }
  683. cmUiRC_t cmUiCreateText( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* text )
  684. {
  685. cmUiRC_t rc = kOkUiRC;
  686. cmUi_t* p = _cmUiHandleToPtr(uiH);
  687. cmUiDriverArg_t a;
  688. cmUiCtl_t* c;
  689. if(( rc = _cmUiCreateCtl(p,&a,panelId,kTextUiCId,id,label,flags,&c)) == kOkUiRC )
  690. {
  691. _cmUiSetStrAccessors(c);
  692. a.dId = kSetValDId;
  693. a.flags = kValUiFl;
  694. a.sval = text;
  695. rc = _cmUiCallDriver(p,&a);
  696. }
  697. return rc;
  698. }
  699. cmUiRC_t _cmUiCreateNumber( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, double min, double max, double incr, double dflt )
  700. {
  701. cmUiRC_t rc = kOkUiRC;
  702. cmUi_t* p = _cmUiHandleToPtr(uiH);
  703. cmUiDriverArg_t a;
  704. cmUiCId_t cid = kNumberUiCId;
  705. cmUiCtl_t* c;
  706. cmUiPanel_t* pp;
  707. if( cmIsFlag(flags,kVertUiFl|kHorzUiFl) )
  708. {
  709. if( cmIsFlag(flags,kVertUiFl) )
  710. {
  711. if((rc = _cmUiFindPanel(p,panelId,&pp,true)) != kOkUiRC )
  712. return rc;
  713. // if the size of the control was not excplicitly set
  714. // then swap width and height
  715. if( cmIsNotFlag(pp->flags,kNextWHUiFl) && cmIsNotFlag(pp->flags,kUseRectUiFl) )
  716. cmUiSetNextWH( uiH, panelId, cmUiH(uiH,panelId), cmUiW(uiH,panelId) );
  717. }
  718. cid = kSliderUiCId;
  719. }
  720. if(( rc = _cmUiCreateCtl(p,&a,panelId,cid,id,label,flags,&c)) == kOkUiRC )
  721. {
  722. cmUiRC_t rc0;
  723. _cmUiSetDblAccessors(c);
  724. a.dId = kSetValDId;
  725. a.flags = kMinUiFl;
  726. a.fval = min;
  727. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  728. rc = rc0;
  729. a.flags = kMaxUiFl;
  730. a.fval = max;
  731. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  732. rc = rc0;
  733. a.flags = kIncUiFl;
  734. a.fval = incr;
  735. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  736. rc = rc0;
  737. a.flags = kValUiFl;
  738. a.fval = dflt;
  739. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  740. rc = rc0;
  741. }
  742. return rc;
  743. }
  744. cmUiRC_t cmUiCreateNumber( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, double min, double max, double incr, double dflt )
  745. {
  746. return _cmUiCreateNumber(uiH,panelId,id,label,flags,min,max,incr,dflt);
  747. }
  748. cmUiRC_t cmUiCreateHSlider( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, double min, double max, double incr, double dflt )
  749. {
  750. return _cmUiCreateNumber(uiH,panelId,id,label,flags | kHorzUiFl, min,max,incr,dflt);
  751. }
  752. cmUiRC_t cmUiCreateVSlider( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, double min, double max, double incr, double dflt )
  753. {
  754. return _cmUiCreateNumber(uiH,panelId,id,label,flags | kVertUiFl, min,max,incr,dflt);
  755. }
  756. cmUiRC_t cmUiCreateProgress(cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt )
  757. {
  758. cmUiRC_t rc = kOkUiRC;
  759. cmUi_t* p = _cmUiHandleToPtr(uiH);
  760. cmUiDriverArg_t a;
  761. cmUiCtl_t* c;
  762. if(( rc = _cmUiCreateCtl(p,&a,panelId,kProgressUiCId,id,label,flags,&c)) == kOkUiRC )
  763. {
  764. cmUiRC_t rc0;
  765. _cmUiSetIntAccessors(c);
  766. a.dId = kSetValDId;
  767. a.flags = kMinUiFl;
  768. a.ival = min;
  769. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  770. rc = rc0;
  771. a.flags = kMaxUiFl;
  772. a.ival = max;
  773. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  774. rc = rc0;
  775. a.flags = kValUiFl;
  776. a.ival = dflt;
  777. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  778. rc = rc0;
  779. }
  780. return rc;
  781. }
  782. cmUiRC_t _cmUiCreateMeter( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt)
  783. {
  784. cmUiRC_t rc;
  785. cmUi_t* p = _cmUiHandleToPtr(uiH);
  786. cmUiDriverArg_t a;
  787. cmUiCtl_t* c;
  788. cmUiPanel_t* pp;
  789. if( cmIsFlag(flags,kVertUiFl) )
  790. {
  791. if((rc = _cmUiFindPanel(p,panelId,&pp,true)) != kOkUiRC )
  792. return rc;
  793. // if the size of the control has not been explicitely set
  794. // then swap height and width for vertical meters.
  795. if( cmIsNotFlag(pp->flags,kNextWHUiFl) && cmIsNotFlag(pp->flags,kUseRectUiFl) )
  796. cmUiSetNextWH( uiH, panelId, cmUiH(uiH,panelId), cmUiW(uiH,panelId) );
  797. }
  798. if((rc = _cmUiCreateCtl(p,&a,panelId,kMeterUiCId,id,label,flags,&c)) == kOkUiRC )
  799. {
  800. cmUiRC_t rc0;
  801. _cmUiSetIntAccessors(c);
  802. a.dId = kSetValDId;
  803. a.flags = kMinUiFl;
  804. a.ival = min;
  805. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  806. rc = rc0;
  807. a.flags = kMaxUiFl;
  808. a.ival = max;
  809. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  810. rc = rc0;
  811. a.flags = kValUiFl;
  812. a.ival = dflt;
  813. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  814. rc = rc0;
  815. }
  816. return rc;
  817. }
  818. cmUiRC_t cmUiCreateHMeter( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt )
  819. {
  820. return _cmUiCreateMeter(uiH,panelId,id,label,flags | kHorzUiFl,min,max,dflt);
  821. }
  822. cmUiRC_t cmUiCreateVMeter( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, int min, int max, int dflt )
  823. {
  824. return _cmUiCreateMeter(uiH,panelId,id,label,flags | kVertUiFl,min,max,dflt);
  825. }
  826. cmUiRC_t cmUiCreateFileBtn(cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* dfltDir, const cmChar_t* patStr )
  827. {
  828. cmUiRC_t rc = kOkUiRC;
  829. cmUi_t* p = _cmUiHandleToPtr(uiH);
  830. cmUiDriverArg_t a;
  831. cmUiCtl_t* c;
  832. if(( rc = _cmUiCreateCtl(p,&a,panelId,kFilenameUiCId,id,label,flags,&c)) == kOkUiRC )
  833. {
  834. cmUiRC_t rc0;
  835. _cmUiSetStrAccessors(c);
  836. if( dfltDir != NULL )
  837. {
  838. a.dId = kSetValDId;
  839. a.flags = kValUiFl;
  840. a.sval = dfltDir;
  841. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  842. rc = rc0;
  843. }
  844. if( patStr != NULL )
  845. {
  846. a.dId = kSetValDId;
  847. a.flags = kFnPatUiFl;
  848. a.sval = patStr;
  849. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  850. rc = rc0;
  851. }
  852. }
  853. return rc;
  854. }
  855. cmUiRC_t cmUiCreateDirBtn( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* dfltDir )
  856. {
  857. cmUiRC_t rc = kOkUiRC;
  858. cmUi_t* p = _cmUiHandleToPtr(uiH);
  859. cmUiDriverArg_t a;
  860. cmUiCtl_t* c;
  861. if(( rc = _cmUiCreateCtl(p,&a,panelId,kDirUiCId,id,label,flags,&c)) == kOkUiRC )
  862. {
  863. cmUiRC_t rc0;
  864. _cmUiSetStrAccessors(c);
  865. if( dfltDir != NULL )
  866. {
  867. a.dId = kSetValDId;
  868. a.flags = kValUiFl;
  869. a.sval = dfltDir;
  870. if((rc0 = _cmUiCallDriver(p,&a)) != kOkUiRC )
  871. rc = rc0;
  872. }
  873. }
  874. return rc;
  875. }
  876. cmUiRC_t cmUiCreateMenuBtn( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags )
  877. {
  878. cmUiRC_t rc;
  879. cmUi_t* p = _cmUiHandleToPtr(uiH);
  880. cmUiDriverArg_t a;
  881. cmUiCtl_t* c;
  882. if((rc = _cmUiCreateCtl(p,&a,panelId,kMenuBtnUiCId,id,label,flags,&c)) == kOkUiRC )
  883. _cmUiSetIntAccessors(c);
  884. return rc;
  885. }
  886. cmUiRC_t cmUiCreateMenuBtnV(cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* label0, unsigned id0, va_list vl )
  887. {
  888. cmUiRC_t rc = kOkUiRC;
  889. // TODO:
  890. return rc;
  891. }
  892. cmUiRC_t cmUiCreateMenuBtnA(cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, const cmChar_t* label0, unsigned id0, ... )
  893. {
  894. va_list vl;
  895. va_start(vl,id0);
  896. cmUiRC_t rc = cmUiCreateMenuBtnV(uiH,panelId,id,label,flags,label0,id0,vl);
  897. va_end(vl);
  898. return rc;
  899. }
  900. cmUiRC_t cmUiCreateMenuBtnJson(cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* lavel, unsigned flags, const cmJsonNode_t* root, const cmChar_t* memberLabel )
  901. {
  902. cmUiRC_t rc = kOkUiRC;
  903. // TODO:
  904. return rc;
  905. }
  906. cmUiRC_t cmUiCreateList(cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, unsigned visibleRowCnt )
  907. {
  908. cmUi_t* p = _cmUiHandleToPtr(uiH);
  909. cmUiRC_t rc;
  910. cmUiDriverArg_t a;
  911. cmUiCtl_t* c;
  912. cmUiPanel_t* pp;
  913. if((rc = _cmUiFindPanel(p,panelId,&pp,true)) != kOkUiRC )
  914. return rc;
  915. if( cmIsNotFlag(pp->flags,kNextWHUiFl) )
  916. cmUiSetNextWH( uiH, panelId, cmUiNextW(uiH,panelId), cmUiH(uiH,panelId) * visibleRowCnt );
  917. if((rc = _cmUiCreateCtl(p,&a,panelId,kListUiCId,id,label,flags,&c)) == kOkUiRC )
  918. _cmUiSetIntAccessors(c);
  919. return rc;
  920. }
  921. 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 )
  922. {
  923. cmUiRC_t rc = kOkUiRC;
  924. // TODO:
  925. return rc;
  926. }
  927. cmUiRC_t cmUiCreateListA( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* label, unsigned flags, unsigned visibleRowCnt, const cmChar_t* label0, unsigned id0, ... )
  928. {
  929. va_list vl;
  930. va_start(vl,id0);
  931. cmUiRC_t rc = cmUiCreateListV(uiH,panelId,id,label,flags,visibleRowCnt,label0,id0,vl);
  932. va_end(vl);
  933. return rc;
  934. }
  935. 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 )
  936. {
  937. cmUiRC_t rc = kOkUiRC;
  938. // TODO:
  939. return rc;
  940. }
  941. cmUiRC_t cmUiAppendListEle( cmUiH_t uiH, unsigned panelId, unsigned id, const cmChar_t* text, unsigned eleId )
  942. {
  943. cmUiRC_t rc = kOkUiRC;
  944. cmUi_t* p = _cmUiHandleToPtr(uiH);
  945. cmUiCtl_t* ctl = NULL;
  946. cmUiDriverArg_t a;
  947. if((rc = _cmUiFindCtl(p,id,&ctl,true)) != kOkUiRC )
  948. return rc;
  949. if( ctl->cId != kListUiCId && ctl->cId != kMenuBtnUiCId )
  950. return cmErrMsg(&p->err,kInvalidCtlOpUiRC,"List elements may only be set on 'list' and 'menu button' controls.");
  951. _cmUiDriverArgInit(&a, p, kSetValDId, ctl->cId, panelId, id );
  952. //if( ctl->id_arr == NULL || ctl->id_cnt == ctl->id_alloc )
  953. // ctl->id_arr = cmMemResizeZ(unsigned,ctl->id_arr,ctl->id_alloc+=10);
  954. //ctl->id_arr[ ctl->id_cnt++ ] = eleId;
  955. cmArrayPush(ctl->idArrH,&eleId,1);
  956. //a.dId = kSetValDId;
  957. //a.cId = ctl->cId;
  958. //a.panelId = panelId;
  959. //a.usrId = id;
  960. a.flags = kAppendUiFl;
  961. a.sval = text;
  962. a.ival = eleId;
  963. return _cmUiCallDriver(p,&a);
  964. }
  965. cmUiRC_t cmUiDestroyCtl( cmUiH_t uiH, unsigned id )
  966. {
  967. cmUiRC_t rc = kOkUiRC;
  968. cmUi_t* p = _cmUiHandleToPtr(uiH);
  969. cmUiCtl_t* ctl = NULL;
  970. if((rc = _cmUiFindCtl(p,id,&ctl,true)) == kOkUiRC )
  971. {
  972. if( ctl->cId == kPanelUiCId )
  973. _cmUiDestroyPanel(p,ctl->usrId);
  974. else
  975. rc = _cmUiDestroyCtl(p,ctl);
  976. }
  977. return rc;
  978. }
  979. bool cmUiCtlExists( cmUiH_t uiH, unsigned panelId, unsigned id )
  980. {
  981. cmUi_t* p = _cmUiHandleToPtr(uiH);
  982. if( panelId == id )
  983. {
  984. cmUiPanel_t* pp=NULL;
  985. return _cmUiFindPanel(p, panelId, &pp, false ) == kOkUiRC;
  986. }
  987. cmUiCtl_t* ctl=NULL;
  988. return _cmUiFindCtl(p,id,&ctl,false) == kOkUiRC;
  989. }
  990. cmUiRC_t cmUiClearPanel( cmUiH_t uiH, unsigned panelId )
  991. {
  992. cmUiRC_t rc = kOkUiRC;
  993. cmUi_t* p = _cmUiHandleToPtr(uiH);
  994. cmUiPanel_t* pp = NULL;
  995. // get the panel recd ptr
  996. if((rc = _cmUiFindPanel(p,panelId,&pp,true)) != kOkUiRC )
  997. return rc;
  998. cmUiApp_t* ap = pp->appPtr;
  999. cmUiCtl_t* ctl = NULL;
  1000. unsigned i = 0;
  1001. unsigned n = cmArrayCount(ap->ctlArrH);
  1002. cmUiRC_t rc0;
  1003. // Destroy all controls that belong to this panel.
  1004. for(i=0; i<n; ++i)
  1005. if( _cmUiFindCtl(p,i,&ctl,false) == kOkUiRC && ctl != NULL && ctl->panelId == panelId && ctl->usrId != panelId)
  1006. if((rc0 = _cmUiDestroyCtl(p,ctl)) != kOkUiRC )
  1007. rc = rc0;
  1008. return rc;
  1009. }
  1010. cmUiRC_t cmUiNextRect( cmUiH_t uiH, unsigned panelId, int x, int y, int w, int h )
  1011. {
  1012. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1013. cmUiPanel_t* pp;
  1014. cmUiRC_t rc;
  1015. if((rc = _cmUiFindPanel(p, panelId, &pp, true)) != kOkUiRC )
  1016. return rc;
  1017. pp->rect.x = x;
  1018. pp->rect.y = y;
  1019. pp->rect.w = w;
  1020. pp->rect.h = h;
  1021. pp->flags = cmSetFlag(pp->flags,kUseRectUiFl);
  1022. return rc;
  1023. }
  1024. bool cmUiFillRows( cmUiH_t uiH, unsigned panelId )
  1025. {
  1026. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1027. cmUiPanel_t* pp;
  1028. if( _cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1029. return false;
  1030. return cmIsFlag(pp->flags,kFillRowsUiFl);
  1031. }
  1032. bool cmUiSetFillRows( cmUiH_t uiH, unsigned panelId, bool enableFl )
  1033. {
  1034. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1035. cmUiPanel_t* pp;
  1036. if( _cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1037. return false;
  1038. bool retFl = cmIsFlag(pp->flags,kFillRowsUiFl);
  1039. pp->flags = cmEnaFlag(pp->flags,kFillRowsUiFl,enableFl);
  1040. return retFl;
  1041. }
  1042. int cmUiBaseCol( cmUiH_t uiH, unsigned panelId, int x )
  1043. {
  1044. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1045. cmUiPanel_t* pp;
  1046. if( _cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1047. return -1;
  1048. int bc = pp->baseCol;
  1049. pp->baseCol = x;
  1050. pp->flags = cmSetFlag(pp->flags,kPlaceBaseRowUiFl);
  1051. return bc;
  1052. }
  1053. void cmUiPlaceRight( cmUiH_t uiH, unsigned panelId )
  1054. {
  1055. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1056. cmUiPanel_t* pp;
  1057. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1058. return;
  1059. pp->flags = cmClrFlag(pp->flags,kPlaceBelowUiFl);
  1060. pp->flags = cmSetFlag(pp->flags,kPlaceRightUiFl);
  1061. }
  1062. void cmUiPlaceBelow( cmUiH_t uiH, unsigned panelId )
  1063. {
  1064. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1065. cmUiPanel_t* pp;
  1066. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1067. return;
  1068. pp->flags = cmClrFlag(pp->flags,kPlaceRightUiFl);
  1069. pp->flags = cmSetFlag(pp->flags,kPlaceBelowUiFl);
  1070. }
  1071. int cmUiBaseRow( cmUiH_t uiH, unsigned panelId, int y )
  1072. {
  1073. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1074. cmUiPanel_t* pp;
  1075. cmUiRC_t rc;
  1076. if((rc = _cmUiFindPanel(p, panelId, &pp, true)) != kOkUiRC )
  1077. return -1;
  1078. int br = pp->baseRow;
  1079. pp->baseRow = y;
  1080. return br;
  1081. }
  1082. int cmUiW( cmUiH_t uiH, unsigned panelId )
  1083. {
  1084. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1085. cmUiPanel_t* pp;
  1086. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1087. return -1;
  1088. return pp->dfltW;
  1089. }
  1090. int cmUiH( cmUiH_t uiH, unsigned panelId )
  1091. {
  1092. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1093. cmUiPanel_t* pp;
  1094. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1095. return -1;
  1096. return pp->dfltH;
  1097. }
  1098. void cmUiSetWH( cmUiH_t uiH, unsigned panelId, int w, int h )
  1099. {
  1100. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1101. cmUiPanel_t* pp;
  1102. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1103. return;
  1104. pp->dfltW = w;
  1105. pp->dfltH = h;
  1106. }
  1107. int cmUiNextW( cmUiH_t uiH, unsigned panelId )
  1108. {
  1109. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1110. cmUiPanel_t* pp;
  1111. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1112. return -1;
  1113. return pp->nextW;
  1114. }
  1115. int cmUiNextH( cmUiH_t uiH, unsigned panelId )
  1116. {
  1117. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1118. cmUiPanel_t* pp;
  1119. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1120. return -1;
  1121. return pp->nextH;
  1122. }
  1123. void cmUiSetNextWH( cmUiH_t uiH, unsigned panelId, int w, int h )
  1124. {
  1125. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1126. cmUiPanel_t* pp;
  1127. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1128. return;
  1129. pp->nextW = w;
  1130. pp->nextH = h;
  1131. pp->flags = cmSetFlag(pp->flags,kNextWHUiFl);
  1132. }
  1133. int cmUiHBorder( cmUiH_t uiH, unsigned panelId )
  1134. {
  1135. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1136. cmUiPanel_t* pp;
  1137. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1138. return -1;
  1139. return pp->dfltHBorder;
  1140. }
  1141. int cmUiVBorder( cmUiH_t uiH, unsigned panelId )
  1142. {
  1143. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1144. cmUiPanel_t* pp;
  1145. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1146. return -1;
  1147. return pp->dfltVBorder;
  1148. }
  1149. int cmUiSetHBorder( cmUiH_t uiH, unsigned panelId, int w )
  1150. {
  1151. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1152. cmUiPanel_t* pp;
  1153. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1154. return -1;
  1155. int rv = pp->dfltHBorder;
  1156. pp->dfltHBorder = w;
  1157. return rv;
  1158. }
  1159. int cmUiSetVBorder( cmUiH_t uiH, unsigned panelId, int h )
  1160. {
  1161. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1162. cmUiPanel_t* pp;
  1163. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1164. return -1;
  1165. int rv = pp->dfltVBorder;
  1166. pp->dfltVBorder = h;
  1167. return rv;
  1168. }
  1169. int cmUiNextHBorder( cmUiH_t uiH, unsigned panelId )
  1170. {
  1171. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1172. cmUiPanel_t* pp;
  1173. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1174. return -1;
  1175. return pp->nextHBorder;
  1176. }
  1177. int cmUiNextVBorder( cmUiH_t uiH, unsigned panelId )
  1178. {
  1179. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1180. cmUiPanel_t* pp;
  1181. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1182. return -1;
  1183. return pp->nextVBorder;
  1184. }
  1185. int cmUiSetNextHBorder( cmUiH_t uiH, unsigned panelId, int w )
  1186. {
  1187. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1188. cmUiPanel_t* pp;
  1189. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1190. return -1;
  1191. int rv = pp->nextHBorder;
  1192. pp->nextHBorder = w;
  1193. return rv;
  1194. }
  1195. int cmUiSetNextVBorder( cmUiH_t uiH, unsigned panelId, int h )
  1196. {
  1197. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1198. cmUiPanel_t* pp;
  1199. if(_cmUiFindPanel(p, panelId, &pp, true) != kOkUiRC )
  1200. return -1;
  1201. int rv = pp->nextVBorder;
  1202. pp->nextVBorder = h;
  1203. return rv;
  1204. }
  1205. cmUiRC_t cmUiSetInt( cmUiH_t uiH, unsigned id, int v )
  1206. {
  1207. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1208. cmUiCtl_t* ctl;
  1209. cmUiRC_t rc;
  1210. cmUiDriverArg_t a;
  1211. if((rc = _cmUiFastFindCtl(p,id,&ctl,true)) != kOkUiRC )
  1212. return rc;
  1213. // TODO: cache the cmUiDriverArg_t for this control in the ctl_t
  1214. // object to avoid having to recreate the arg. recd on every call.
  1215. _cmUiDriverArgInit(&a, p, kSetValDId, ctl->cId, ctl->panelId, id );
  1216. a.ival = v;
  1217. a.flags |= kValUiFl;
  1218. return _cmUiCallDriver(p,&a);
  1219. }
  1220. cmUiRC_t cmUiSetUInt( cmUiH_t uiH, unsigned id, unsigned v )
  1221. {
  1222. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1223. cmUiCtl_t* ctl;
  1224. cmUiRC_t rc;
  1225. cmUiDriverArg_t a;
  1226. if((rc = _cmUiFastFindCtl(p,id,&ctl,true)) != kOkUiRC )
  1227. return rc;
  1228. _cmUiDriverArgInit(&a, p, kSetValDId, ctl->cId, ctl->panelId, id );
  1229. a.ival = (int)v;
  1230. a.flags |= kValUiFl;
  1231. return _cmUiCallDriver(p,&a);
  1232. }
  1233. cmUiRC_t cmUiSetDouble( cmUiH_t uiH, unsigned id, double v )
  1234. {
  1235. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1236. cmUiCtl_t* ctl;
  1237. cmUiRC_t rc;
  1238. cmUiDriverArg_t a;
  1239. if((rc = _cmUiFastFindCtl(p,id,&ctl,true)) != kOkUiRC )
  1240. return rc;
  1241. _cmUiDriverArgInit(&a, p, kSetValDId, ctl->cId, ctl->panelId, id );
  1242. a.fval = v;
  1243. a.flags |= kValUiFl;
  1244. return _cmUiCallDriver(p,&a);
  1245. }
  1246. cmUiRC_t cmUiSetString( cmUiH_t uiH, unsigned id, const cmChar_t* v )
  1247. {
  1248. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1249. cmUiCtl_t* ctl;
  1250. cmUiRC_t rc;
  1251. cmUiDriverArg_t a;
  1252. if((rc = _cmUiFastFindCtl(p,id,&ctl,true)) != kOkUiRC )
  1253. return rc;
  1254. _cmUiDriverArgInit(&a, p, kSetValDId, ctl->cId, ctl->panelId, id );
  1255. a.sval = v;
  1256. a.flags |= kValUiFl;
  1257. return _cmUiCallDriver(p,&a);
  1258. }
  1259. int cmUiInt( cmUiH_t uiH, unsigned id )
  1260. {
  1261. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1262. cmUiCtl_t* ctl;
  1263. cmUiRC_t rc;
  1264. if((rc = _cmUiFastFindCtl(p,id,&ctl,true)) != kOkUiRC )
  1265. return 0;
  1266. return ctl->getInt(ctl);
  1267. }
  1268. unsigned cmUiUInt( cmUiH_t uiH, unsigned id )
  1269. {
  1270. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1271. cmUiCtl_t* ctl;
  1272. cmUiRC_t rc;
  1273. if((rc = _cmUiFastFindCtl(p,id,&ctl,true)) != kOkUiRC )
  1274. return 0;
  1275. return ctl->getInt(ctl);
  1276. }
  1277. double cmUiDouble( cmUiH_t uiH, unsigned id )
  1278. {
  1279. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1280. cmUiCtl_t* ctl;
  1281. cmUiRC_t rc;
  1282. if((rc = _cmUiFastFindCtl(p,id,&ctl,true)) != kOkUiRC )
  1283. return 0;
  1284. return ctl->getDbl(ctl);
  1285. }
  1286. const cmChar_t* cmUiString( cmUiH_t uiH, unsigned id )
  1287. {
  1288. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1289. cmUiCtl_t* ctl;
  1290. cmUiRC_t rc;
  1291. if((rc = _cmUiFastFindCtl(p,id,&ctl,true)) != kOkUiRC )
  1292. return 0;
  1293. return ctl->getStr(ctl);
  1294. }
  1295. cmUiRC_t cmUiLastRC( cmUiH_t uiH )
  1296. {
  1297. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1298. return cmErrLastRC(&p->err);
  1299. }
  1300. cmUiRC_t cmUiSetRC( cmUiH_t uiH, cmUiRC_t rc )
  1301. {
  1302. cmUi_t* p = _cmUiHandleToPtr(uiH);
  1303. return cmErrSetRC(&p->err, rc);
  1304. }