Programmable real-time audio signal processing application
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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