libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

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. }