Programmable real-time audio signal processing application
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.

cmUiDrvrFltk.cpp 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. #include <FL/Fl.H>
  2. #include <FL/Fl_Widget.H>
  3. #include <FL/Fl_Group.H>
  4. #include <FL/Fl_Tabs.H>
  5. #include <FL/Fl_Button.H>
  6. #include <FL/Fl_Check_Button.H>
  7. #include <FL/Fl_Box.H>
  8. #include <Fl/Fl_Input.H>
  9. #include <Fl/Fl_Value_Input.H>
  10. #include <Fl/Fl_Value_Slider.H>
  11. #include <Fl/Fl_Progress.H>
  12. #include <Fl/Fl_Menu_Button.H>
  13. #include <Fl/Fl_Select_Browser.H>
  14. #include <Fl/Fl_Text_Display.H>
  15. #include <FL/fl_draw.H>
  16. #include "Fl_File_Btn.h"
  17. #include "Fl_Vert_Progress.h"
  18. #include "cmGlobal.h"
  19. #include "cmRpt.h"
  20. #include "cmErr.h"
  21. #include "cmCtx.h"
  22. #include "cmMem.h"
  23. #include "cmMallocDebug.h"
  24. #include "cmRtSysMsg.h"
  25. #include "cmUiDrvr.h"
  26. #include "cmUiDrvrFltk.h"
  27. cmUiDrvrFltk::cmUiDrvrFltk(cmCtx_t* ctx, Fl_Tabs* tabs, cmUiDriverFunc_t cbFunc, void* cbArg)
  28. : _tabs(NULL),_cbFunc(NULL),_cbArgs(NULL),_panels(NULL)
  29. {
  30. cmErrSetup(&_err,&ctx->rpt,"cmUiDrvrFltk");
  31. setBaseWindow(tabs);
  32. setCallback(cbFunc,cbArg);
  33. }
  34. void cmUiDrvrFltk::setBaseWindow( Fl_Tabs* tabs )
  35. {
  36. _tabs = tabs;
  37. if( _tabs != NULL )
  38. _tabs->callback(_s_tab_cb,this);
  39. }
  40. void cmUiDrvrFltk::setCallback( cmUiDriverFunc_t cbFunc, void* cbArg )
  41. {
  42. _cbFunc = cbFunc;
  43. _cbArgs = cbArg;
  44. }
  45. cmUiDrvrFltk::~cmUiDrvrFltk()
  46. {
  47. _destroyAllPanels(false);
  48. }
  49. cmUiRC_t cmUiDrvrFltk::cmUiDriverFunc( void* cbArg, const cmUiDriverArg_t* args )
  50. {
  51. cmUiDrvrFltk* p = (cmUiDrvrFltk*)cbArg;
  52. cmUiRC_t rc = kOkUiRC;
  53. switch(args->dId)
  54. {
  55. case kInvalidDId:
  56. break;
  57. case kCreateCtlDId:
  58. rc = p->_createCtl(args);
  59. break;
  60. case kDestroyCtlDId:
  61. rc = p->_destroyCtl(args->appId,args->panelId,args->usrId,true);
  62. break;
  63. case kSetValDId:
  64. rc = p->_setValueCtl(args);
  65. break;
  66. case kEnableDId:
  67. rc = p->_enableCtl(args);
  68. break;
  69. //case kDestroyAllDId:
  70. //rc = p->_destroyAllPanels(true);
  71. //break;
  72. case kMaxDId:
  73. assert(0);
  74. break;
  75. }
  76. return rc;
  77. }
  78. void cmUiDrvrFltk::_insertNewCtl( panel_t* pp, ctl_t* ctl, Fl_Widget* wp, unsigned flags )
  79. {
  80. ctl->wdgt = wp;
  81. if( ctl->usrId != cmInvalidId )
  82. {
  83. ctl->link = pp->ctls;
  84. pp->ctls = ctl;
  85. wp->callback( _s_ctl_cb, ctl );
  86. }
  87. pp->grp->add(wp);
  88. int align_flags = 0;
  89. if( cmIsFlag(flags,kLeftUiFl)) align_flags |= FL_ALIGN_LEFT;
  90. if( cmIsFlag(flags,kTopUiFl)) align_flags |= FL_ALIGN_TOP;
  91. if( cmIsFlag(flags,kRightUiFl)) align_flags |= FL_ALIGN_RIGHT;
  92. if( cmIsFlag(flags,kBottomUiFl)) align_flags |= FL_ALIGN_BOTTOM;
  93. if( cmIsFlag(flags,kHCtrUiFl)) align_flags |= FL_ALIGN_CENTER;
  94. if( cmIsFlag(flags,kInsideUiFl)) align_flags |= FL_ALIGN_INSIDE;
  95. if( cmIsFlag(flags,kVCtrUiFl)) align_flags = cmClrFlag(align_flags,FL_ALIGN_TOP | FL_ALIGN_BOTTOM);
  96. wp->align(align_flags);
  97. int when_flags = 0;
  98. if( cmIsFlag(flags,kSendChangeFl)) when_flags |= FL_WHEN_CHANGED;
  99. if( cmIsFlag(flags,kSendEnterFl)) when_flags |= FL_WHEN_ENTER_KEY;
  100. if( cmIsFlag(flags,kSendFocusFl)) when_flags |= FL_WHEN_RELEASE;
  101. if( cmIsFlag(flags,kSendNoChangeFl)) when_flags |= FL_WHEN_NOT_CHANGED;
  102. if( when_flags != 0 )
  103. wp->when(when_flags);
  104. }
  105. bool cmUiDrvrFltk::_hasNoAlignFlags( unsigned flags ) const
  106. {
  107. return !cmIsFlag(flags, kLeftUiFl | kTopUiFl | kRightUiFl | kBottomUiFl | kVCtrUiFl | kHCtrUiFl );
  108. }
  109. cmUiRC_t cmUiDrvrFltk::_createCtl( const cmUiDriverArg_t* a )
  110. {
  111. cmUiRC_t rc;
  112. panel_t* pp;
  113. panel_t* prvPnl;
  114. // if this is a panel create request
  115. if( a->cId == kPanelUiCId )
  116. return _createPanel(a);
  117. // locate the new control's panel
  118. if((rc = _findPanel(a->appId,a->panelId,pp,prvPnl)) != kOkUiRC )
  119. return rc;
  120. // allocate the control record
  121. ctl_t* ctl ;
  122. if( a->usrId == cmInvalidId )
  123. ctl = &_dummy;
  124. else
  125. ctl = cmMemAllocZ(ctl_t,1);
  126. ctl->cId = a->cId;
  127. ctl->pnl = pp;
  128. ctl->usrId = a->usrId;
  129. ctl->flags = a->flags;
  130. int x = a->x + pp->x_offs;
  131. int y = a->y + pp->y_offs;
  132. // cache the event callback arg record so that it
  133. // does not have to be filled on every callback.
  134. cmUiDriverArgSetup(&ctl->cbArg,a->hdr.rtSubIdx,kUiDrvrSelRtId,kInvalidDId,pp->appId,a->usrId,pp->usrId,a->cId,0,0,0,NULL,x,y,a->w,a->h);
  135. //printf("%i %i %i %i\n",x,y,a->w,a->h);
  136. switch(a->cId)
  137. {
  138. case kInvalidUiCId:
  139. assert(0);
  140. break;
  141. case kPanelUiCId:
  142. break;
  143. case kBtnUiCId:
  144. ctl->u.btn = new Fl_Button(x,y,a->w,a->h,a->sval);
  145. _insertNewCtl(pp,ctl,ctl->u.btn,a->flags);
  146. ctl->cbArg.flags |= kIvalUiFl;
  147. break;
  148. case kCheckUiCId:
  149. ctl->u.chk = new Fl_Check_Button(x,y,a->w,a->h,a->sval);
  150. _insertNewCtl(pp,ctl,ctl->u.chk,a->flags);
  151. ctl->cbArg.flags |= kIvalUiFl;
  152. ctl->u.chk->value(a->ival);
  153. break;
  154. case kMenuBtnUiCId:
  155. ctl->u.mbt = new Fl_Menu_Button(x,y,a->w,a->h,a->sval!=NULL ? a->sval : NULL);
  156. _insertNewCtl(pp,ctl,ctl->u.mbt,a->flags);
  157. ctl->cbArg.flags |= kIvalUiFl;
  158. ctl->u.mbt->value(0);
  159. break;
  160. case kListUiCId:
  161. ctl->u.lst = new Fl_Select_Browser(x,y,a->w,a->h);
  162. _insertNewCtl(pp,ctl,ctl->u.lst,a->flags);
  163. ctl->cbArg.flags |= kIvalUiFl;
  164. break;
  165. case kLabelUiCId:
  166. {
  167. unsigned flags = a->flags;
  168. ctl->u.lbl = new Fl_Box(x,y,a->w,a->h);
  169. ctl->u.lbl->copy_label(a->sval);
  170. if( _hasNoAlignFlags(flags) )
  171. flags |= kHCtrUiFl | kInsideUiFl;
  172. _insertNewCtl(pp,ctl,ctl->u.lbl,flags);
  173. }
  174. break;
  175. case kStringUiCId:
  176. {
  177. unsigned flags = a->flags;
  178. ctl->u.str = new Fl_Input(x,y,a->w/2,a->h);
  179. ctl->u.str->copy_label(a->sval);
  180. if( _hasNoAlignFlags(flags) )
  181. flags |= kRightUiFl;
  182. _insertNewCtl(pp,ctl,ctl->u.str,flags);
  183. ctl->cbArg.flags |= kSvalUiFl;
  184. }
  185. break;
  186. case kConsoleUiCId:
  187. {
  188. unsigned flags = a->flags;
  189. ctl->u.con = new Fl_Text_Display(x,y,a->w,a->h);
  190. ctl->u.con->buffer(new Fl_Text_Buffer());
  191. ctl->u.con->textsize(12);
  192. ctl->u.con->textfont(FL_COURIER);
  193. ctl->u.con->copy_label(a->sval);
  194. if( _hasNoAlignFlags(flags) )
  195. flags |= kRightUiFl;
  196. _insertNewCtl(pp,ctl,ctl->u.con,flags);
  197. ctl->cbArg.flags |= kSvalUiFl;
  198. }
  199. break;
  200. case kSliderUiCId:
  201. {
  202. unsigned flags = a->flags;
  203. int w = a->w;
  204. int h = a->h;
  205. if( cmIsFlag(flags,kHorzUiFl) )
  206. {
  207. if( _hasNoAlignFlags(flags) )
  208. flags |= kRightUiFl;
  209. w /= 2;
  210. }
  211. if( cmIsFlag(flags,kVertUiFl) )
  212. {
  213. if( _hasNoAlignFlags(flags) )
  214. flags |= kTopUiFl | kHCtrUiFl;
  215. if( a->sval != NULL )
  216. {
  217. int hh,ww;
  218. fl_measure(a->sval,ww,hh);
  219. if( flags & kTopUiFl )
  220. {
  221. y += hh;
  222. h -= hh;
  223. }
  224. if( flags & kBottomUiFl)
  225. h -= hh;
  226. }
  227. }
  228. ctl->u.sld = new Fl_Value_Slider(x,y,w,h);
  229. ctl->u.sld->copy_label(a->sval);
  230. if( cmIsFlag(flags,kHorzUiFl) )
  231. ctl->u.sld->type(FL_HOR_NICE_SLIDER);
  232. if( cmIsFlag(flags,kVertUiFl) )
  233. ctl->u.sld->type(FL_VERT_NICE_SLIDER);
  234. _insertNewCtl(pp,ctl,ctl->u.sld,flags);
  235. ctl->cbArg.flags |= kFvalUiFl;
  236. }
  237. break;
  238. case kNumberUiCId:
  239. {
  240. unsigned flags = a->flags;
  241. ctl->u.num = new Fl_Value_Input(x,y,a->w/2,a->h);
  242. ctl->u.num->copy_label(a->sval);
  243. if( _hasNoAlignFlags(flags) )
  244. flags |= kRightUiFl;
  245. _insertNewCtl(pp,ctl,ctl->u.num,flags);
  246. ctl->cbArg.flags |= kFvalUiFl;
  247. ctl->u.num->when(FL_WHEN_ENTER_KEY | FL_WHEN_NOT_CHANGED );
  248. }
  249. break;
  250. case kProgressUiCId:
  251. {
  252. unsigned flags = a->flags;
  253. ctl->u.prg = new Fl_Progress(x,y,a->w/2,a->h);
  254. ctl->u.prg->copy_label(a->sval);
  255. if( _hasNoAlignFlags(flags) )
  256. flags |= kRightUiFl;
  257. _insertNewCtl(pp,ctl,ctl->u.prg,flags);
  258. ctl->u.prg->color( fl_rgb_color((unsigned char)256),fl_rgb_color((unsigned char)128));
  259. }
  260. break;
  261. case kMeterUiCId:
  262. {
  263. unsigned flags = a->flags;
  264. if( cmIsFlag(flags,kVertUiFl) )
  265. {
  266. ctl->u.mtr = new Fl_Vert_Progress(x,y,a->w/2,a->h);
  267. ctl->u.mtr->color( fl_rgb_color((unsigned char)256),fl_rgb_color((unsigned char)128));
  268. }
  269. else
  270. {
  271. ctl->u.mtr = new Fl_Progress(x,y,a->w,a->h);
  272. ctl->u.mtr->color( fl_rgb_color((unsigned char)256),fl_rgb_color((unsigned char)128));
  273. }
  274. ctl->u.mtr->copy_label(a->sval);
  275. if( _hasNoAlignFlags(flags) )
  276. flags |= kRightUiFl;
  277. _insertNewCtl(pp,ctl,ctl->u.mtr,flags);
  278. }
  279. break;
  280. case kFilenameUiCId:
  281. case kDirUiCId:
  282. {
  283. unsigned flags = a->cId==kDirUiCId ? Fl_File_Btn::kDir_Type_Id : Fl_File_Btn::kFile_Type_Id;
  284. ctl->u.fnb = new Fl_File_Btn(flags,"",x,y,a->w,a->h,a->sval);
  285. flags = a->flags;
  286. if( _hasNoAlignFlags(flags) )
  287. flags |= kRightUiFl;
  288. _insertNewCtl(pp,ctl,ctl->u.fnb,flags);
  289. ctl->cbArg.flags |= kSvalUiFl;
  290. }
  291. break;
  292. case kMaxUiCId:
  293. assert(0);
  294. break;
  295. }
  296. pp->grp->redraw();
  297. return rc;
  298. }
  299. cmUiRC_t cmUiDrvrFltk::_setValueCtl( const cmUiDriverArg_t* a )
  300. {
  301. cmUiRC_t rc;
  302. panel_t* pp = NULL;
  303. panel_t* prvPnl = NULL;
  304. ctl_t* ctl = NULL;
  305. ctl_t* prvCtl = NULL;
  306. if((rc = _findPanel(a->appId,a->panelId,pp,prvPnl)) != kOkUiRC )
  307. return rc;
  308. if((rc= _findCtl(pp, a->usrId, ctl, prvCtl )) != kOkUiRC )
  309. return rc;
  310. switch( a->cId )
  311. {
  312. case kInvalidUiCId:
  313. break;
  314. case kPanelUiCId:
  315. break;
  316. case kBtnUiCId:
  317. if( cmIsFlag(a->flags,kLblUiFl) )
  318. ctl->u.btn->copy_label(a->sval);
  319. break;
  320. case kCheckUiCId:
  321. switch( a->flags & (kLblUiFl | kValUiFl) )
  322. {
  323. case kValUiFl: ctl->u.chk->value(a->ival); break;
  324. case kLblUiFl: ctl->u.chk->copy_label(a->sval); break;
  325. }
  326. break;
  327. case kMenuBtnUiCId:
  328. switch( a->flags & (kAppendUiFl | kClearUiFl | kValUiFl) )
  329. {
  330. case kValUiFl:
  331. if( a->ival < ctl->u.mbt->size() )
  332. {
  333. ctl->u.mbt->value(a->ival);
  334. if( ctl->u.mbt->mvalue() != NULL)
  335. ctl->u.mbt->copy_label( ctl->u.mbt->mvalue()->label());
  336. }
  337. break;
  338. case kClearUiFl:
  339. ctl->u.mbt->clear();
  340. ctl->u.mbt->copy_label("");
  341. break;
  342. case kAppendUiFl:
  343. {
  344. int n;
  345. ctl->u.mbt->add( a->sval,0,ctl->u.mbt->callback(),ctl->u.mbt->user_data(),0);
  346. n = ctl->u.mbt->size();
  347. if( (n) == 2 )
  348. {
  349. ctl->u.mbt->value(0);
  350. if( ctl->u.mbt->mvalue() != NULL)
  351. {
  352. const char* s = ctl->u.mbt->mvalue()->label();
  353. ctl->u.mbt->copy_label( s);
  354. }
  355. }
  356. }
  357. break;
  358. }
  359. break;
  360. case kListUiCId:
  361. switch( a->flags & (kAppendUiFl | kClearUiFl | kValUiFl) )
  362. {
  363. case kValUiFl: ctl->u.lst->value(a->ival); break;
  364. case kAppendUiFl: ctl->u.lst->add( a->sval ); break;
  365. case kClearUiFl: ctl->u.lst->clear(); break;
  366. }
  367. break;
  368. case kLabelUiCId:
  369. ctl->u.str->value(a->sval);
  370. break;
  371. case kStringUiCId:
  372. switch( a->flags & (kLblUiFl | kValUiFl) )
  373. {
  374. case kValUiFl: ctl->u.str->value(a->sval); break;
  375. case kLblUiFl: ctl->u.str->copy_label(a->sval); break;
  376. }
  377. break;
  378. case kConsoleUiCId:
  379. switch( a->flags & (kLblUiFl | kValUiFl) )
  380. {
  381. case kValUiFl: if(a->sval!=NULL) ctl->u.con->insert(a->sval); break;
  382. case kLblUiFl: ctl->u.str->copy_label(a->sval); break;
  383. }
  384. break;
  385. case kSliderUiCId:
  386. case kNumberUiCId:
  387. {
  388. Fl_Valuator* vp = static_cast<Fl_Valuator*>(ctl->wdgt);
  389. // Correct for problem where the vertical slider values go up as the
  390. // slider knob is dragged down.
  391. bool invertFl = a->cId == kSliderUiCId && cmIsFlag(ctl->flags,kVertUiFl);
  392. switch(a->flags & (kNumMask | kLblUiFl | kMinUiFl | kMaxUiFl))
  393. {
  394. case kLblUiFl: ctl->u.num->copy_label(a->sval); break;
  395. case kValUiFl: vp->value(a->fval); break;
  396. case kIncUiFl: vp->step(a->fval); break;
  397. case kMinUiFl: invertFl ? vp->maximum(a->fval) : vp->minimum(a->fval); break;
  398. case kMaxUiFl: invertFl ? vp->minimum(a->fval) : vp->maximum(a->fval); break;
  399. }
  400. }
  401. break;
  402. case kProgressUiCId:
  403. switch( a->flags & (kLblUiFl | kValUiFl | kMinUiFl | kMaxUiFl) )
  404. {
  405. case kValUiFl: ctl->u.prg->value(a->ival); break;
  406. case kLblUiFl: ctl->u.prg->copy_label(a->sval); break;
  407. case kMinUiFl: ctl->u.prg->minimum(a->ival); break;
  408. case kMaxUiFl: ctl->u.prg->maximum(a->ival); break;
  409. }
  410. break;
  411. case kMeterUiCId:
  412. switch( a->flags & (kLblUiFl | kValUiFl | kMinUiFl | kMaxUiFl) )
  413. {
  414. case kValUiFl: ctl->u.mtr->value(a->ival); ctl->u.mtr->redraw(); break;
  415. case kLblUiFl: ctl->u.mtr->copy_label(a->sval); break;
  416. case kMinUiFl: ctl->u.prg->minimum(a->ival); break;
  417. case kMaxUiFl: ctl->u.prg->maximum(a->ival); break;
  418. }
  419. break;
  420. case kFilenameUiCId:
  421. case kDirUiCId:
  422. switch(a->flags & (kFnMask | kValUiFl | kFnPatUiFl | kFnDirUiFl) )
  423. {
  424. case kValUiFl:
  425. ctl->u.fnb->filename(a->sval);
  426. break;
  427. case kFnPatUiFl: ctl->u.fnb->pattern_string(a->sval); break;
  428. case kFnDirUiFl:
  429. ctl->u.fnb->type( ctl->u.fnb->type()==Fl_File_Btn::kFile_Type_Id ? Fl_File_Btn::kDir_Type_Id : Fl_File_Btn::kFile_Type_Id );
  430. break;
  431. }
  432. break;
  433. case kMaxUiCId:
  434. assert(0);
  435. break;
  436. }
  437. // echo the result back to the UI
  438. //if( cmIsFlag(a->flags,kValUiFl|kAppendUiFl) )
  439. // _cbFunc(_cbArgs,a);
  440. return rc;
  441. }
  442. cmUiRC_t cmUiDrvrFltk::_enableCtl( const cmUiDriverArg_t* a )
  443. {
  444. cmUiRC_t rc;
  445. panel_t* pp = NULL;
  446. panel_t* prvPnl = NULL;
  447. ctl_t* ctl = NULL;
  448. ctl_t* prvCtl = NULL;
  449. if((rc = _findPanel(a->appId,a->panelId,pp,prvPnl)) != kOkUiRC )
  450. return rc;
  451. if((rc= _findCtl(pp, a->usrId, ctl, prvCtl )) != kOkUiRC )
  452. return rc;
  453. if( a->ival )
  454. ctl->wdgt->activate();
  455. else
  456. ctl->wdgt->deactivate();
  457. _doCb(ctl,kEnableDId,0);
  458. return rc;
  459. }
  460. cmUiRC_t cmUiDrvrFltk::_destroyCtl( unsigned appId, unsigned panelId, unsigned usrId, bool deleteWindowEleFlag )
  461. {
  462. cmUiRC_t rc = kOkUiRC;
  463. panel_t* pp = NULL;
  464. panel_t* prvPnl = NULL;
  465. // locate the panel assoc'd with the ctl
  466. if((rc = _findPanel(appId,panelId,pp,prvPnl,true)) != kOkUiRC )
  467. return rc;
  468. // if the panel is the ctl to delete ...
  469. if( usrId == pp->usrId )
  470. {
  471. // ... unlink the panel
  472. if( prvPnl!=NULL)
  473. prvPnl->link = pp->link;
  474. else
  475. {
  476. assert(_panels == pp );
  477. _panels = pp->link;
  478. }
  479. }
  480. return _destroyCtl(pp,usrId,deleteWindowEleFlag);
  481. }
  482. cmUiRC_t cmUiDrvrFltk::_destroyCtl( panel_t* pp, unsigned usrId, bool deleteWindowEleFlag )
  483. {
  484. cmUiRC_t rc = kOkUiRC;
  485. ctl_t* ctl = NULL;
  486. ctl_t* prvCtl = NULL;
  487. // if the panel is the ctl to delete
  488. if( usrId == pp->usrId )
  489. {
  490. return _destroyPanel(pp,deleteWindowEleFlag);
  491. }
  492. // locate the control on the panel
  493. if((rc = _findCtl(pp,usrId,ctl,prvCtl,true)) != kOkUiRC )
  494. return rc;
  495. // unlink the control
  496. if( prvCtl!=NULL)
  497. prvCtl->link = ctl->link;
  498. else
  499. {
  500. assert( pp->ctls == ctl );
  501. pp->ctls = ctl->link;
  502. }
  503. // delete the window element
  504. if( deleteWindowEleFlag)
  505. delete ctl->wdgt;
  506. // release the control recd
  507. cmMemFree(ctl);
  508. return rc;
  509. }
  510. cmUiRC_t cmUiDrvrFltk::_createPanel( const cmUiDriverArg_t* a )
  511. {
  512. int tx,ty,tw,th;
  513. _tabs->client_area(tx,ty,tw,th);
  514. panel_t* pnl = cmMemAllocZ(panel_t,1);
  515. pnl->drvr = this;
  516. pnl->grp = new Fl_Group(tx,ty,tw,th,a->sval);
  517. pnl->grp->user_data(pnl);
  518. pnl->appId = a->appId;
  519. pnl->usrId = a->usrId;
  520. pnl->x_offs = tx + 2;
  521. pnl->y_offs = ty + 2;
  522. pnl->link = _panels;
  523. _panels = pnl;
  524. pnl->grp->end();
  525. if( cmIsFlag(a->flags,kPrependUiFl) )
  526. _tabs->insert(*pnl->grp,0);
  527. else
  528. _tabs->add(pnl->grp);
  529. // cache the event callback arg record so that it
  530. // does not have to be filled on every callback.
  531. cmUiDriverArgSetup(&pnl->cbArg,a->hdr.rtSubIdx,kUiDrvrSelRtId,kSetValDId,a->appId,a->usrId,a->usrId,kPanelUiCId,kIvalUiFl,0,0,NULL,tx,ty,tw,th);
  532. _tabs->redraw();
  533. return kOkUiRC;
  534. }
  535. cmUiRC_t cmUiDrvrFltk::_destroyAllPanels( bool deleteWindowEleFlag )
  536. {
  537. cmUiRC_t rc = kOkUiRC;
  538. while( _panels != NULL )
  539. {
  540. cmUiRC_t rc0;
  541. if((rc0 = _destroyCtl(_panels->appId,_panels->usrId,_panels->usrId,deleteWindowEleFlag)) != kOkUiRC )
  542. rc = rc0;
  543. }
  544. return rc;
  545. }
  546. cmUiRC_t cmUiDrvrFltk::_destroyPanel(panel_t* pp, bool deleteWindowEleFlag)
  547. {
  548. cmUiRC_t rc = kOkUiRC;
  549. // delete the FLTK panel itself
  550. if( deleteWindowEleFlag )
  551. {
  552. delete pp->grp;
  553. deleteWindowEleFlag = false;
  554. }
  555. while( pp->ctls != NULL )
  556. {
  557. cmUiRC_t rc0;
  558. if((rc0 = _destroyCtl(pp,pp->ctls->usrId,deleteWindowEleFlag)) != kOkUiRC )
  559. rc = rc0;
  560. }
  561. cmMemFree(pp);
  562. return rc;
  563. }
  564. cmUiRC_t cmUiDrvrFltk::_findPanel( unsigned appId, unsigned usrId, panel_t*& ppRef, panel_t*& prvPnl, bool errFl )
  565. {
  566. ppRef = NULL;
  567. prvPnl = NULL;
  568. panel_t* pp = _panels;
  569. for(; pp!=NULL; pp=pp->link)
  570. {
  571. if(pp->appId==appId && pp->usrId==usrId )
  572. {
  573. ppRef = pp;
  574. return kOkUiRC;
  575. }
  576. prvPnl = pp;
  577. }
  578. if( errFl )
  579. cmErrMsg(&_err,kPanelNotFoundUiRC,"Panel not found for id=%i.",usrId);
  580. return kPanelNotFoundUiRC;
  581. }
  582. cmUiRC_t cmUiDrvrFltk::_findCtl( panel_t* pp, unsigned usrId, ctl_t*& ctlRef, ctl_t*& prvCtlRef, bool errFl )
  583. {
  584. ctlRef = NULL;
  585. prvCtlRef = NULL;
  586. ctl_t* cp = pp->ctls;
  587. for(; cp!=NULL; cp=cp->link)
  588. {
  589. if( cp->usrId == usrId )
  590. {
  591. ctlRef = cp;
  592. return kOkUiRC;
  593. }
  594. prvCtlRef = cp;
  595. }
  596. if( errFl )
  597. cmErrMsg(&_err,kCtlNotFoundUiRC,"Control %i not found in panel %i.",usrId,pp->usrId);
  598. return kCtlNotFoundUiRC;
  599. }
  600. void cmUiDrvrFltk::_doCb( ctl_t* ctl, cmUiDId_t dId, unsigned flags )
  601. {
  602. cmUiDriverArg_t* a = &ctl->cbArg;
  603. unsigned orgFlags = a->flags;
  604. a->flags |= flags;
  605. a->dId = dId;
  606. _cbFunc(_cbArgs,&ctl->cbArg);
  607. a->flags = orgFlags;
  608. a->dId = kInvalidDId;
  609. }
  610. void cmUiDrvrFltk::_s_ctl_cb(Fl_Widget* wp, void* arg )
  611. {
  612. ctl_t* ctl = (ctl_t*)arg;
  613. cmUiDrvrFltk* p = ctl->pnl->drvr;
  614. cmUiDriverArg_t* a = &ctl->cbArg;
  615. bool callbackFl = true;
  616. unsigned flags = kValUiFl;
  617. switch( ctl->cId )
  618. {
  619. case kInvalidUiCId:
  620. assert(0);
  621. callbackFl = false;
  622. break;
  623. case kPanelUiCId:
  624. callbackFl = false;
  625. break;
  626. case kBtnUiCId:
  627. break;
  628. case kCheckUiCId:
  629. a->ival = ctl->u.chk->value();
  630. flags |= kIvalUiFl;
  631. break;
  632. case kMenuBtnUiCId:
  633. if( ctl->u.mbt->mvalue() != NULL && ctl->u.mbt->mvalue()->label() != NULL )
  634. ctl->u.mbt->copy_label(ctl->u.mbt->mvalue()->label());
  635. a->ival = ctl->u.mbt->value();
  636. flags |= kIvalUiFl;
  637. break;
  638. case kListUiCId:
  639. a->ival = ctl->u.lst->value() - 1;
  640. flags |= kIvalUiFl;
  641. break;
  642. case kLabelUiCId:
  643. callbackFl = false;
  644. break;
  645. case kStringUiCId:
  646. a->sval = ctl->u.str->value();
  647. flags |= kSvalUiFl;
  648. break;
  649. case kConsoleUiCId:
  650. callbackFl = false;
  651. break;
  652. case kSliderUiCId:
  653. a->fval = ctl->u.sld->value();
  654. flags |= kFvalUiFl;
  655. break;
  656. case kNumberUiCId:
  657. a->fval = ctl->u.num->value();
  658. flags |= kFvalUiFl;
  659. break;
  660. case kProgressUiCId:
  661. callbackFl = false;
  662. break;
  663. case kMeterUiCId:
  664. callbackFl = false;
  665. break;
  666. case kFilenameUiCId:
  667. a->sval = ctl->u.fnb->filename();
  668. flags |= kSvalUiFl;
  669. break;
  670. case kDirUiCId:
  671. a->sval = ctl->u.fnb->filename();
  672. flags |= kSvalUiFl;
  673. break;
  674. case kMaxUiCId:
  675. callbackFl = false;
  676. assert(0);
  677. break;
  678. }
  679. if( callbackFl )
  680. p->_doCb(ctl,kSetValDId,flags);
  681. }
  682. void cmUiDrvrFltk::_s_tab_cb(Fl_Widget* wp, void* arg )
  683. {
  684. cmUiDrvrFltk* p = (cmUiDrvrFltk*)arg;
  685. Fl_Widget* w = p->_tabs->value();
  686. panel_t* pp = p->_panels;
  687. for(; pp!=NULL; pp=pp->link)
  688. {
  689. // if this is the panel being selected then send a 1 otherwise send a 0.
  690. pp->cbArg.flags = cmSetFlag(pp->cbArg.flags, kIvalUiFl );
  691. pp->cbArg.dId = kSetValDId;
  692. pp->cbArg.ival = w->user_data() == pp->grp->user_data();
  693. p->_cbFunc(p->_cbArgs,&pp->cbArg);
  694. pp->cbArg.flags = cmClrFlag(pp->cbArg.flags, kIvalUiFl );
  695. pp->cbArg.dId = kInvalidDId;
  696. }
  697. }