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.

cmGrTksbFltk.cpp 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. //| Copyright: (C) 2019-2020 Kevin Larke <contact AT larke DOT org>
  2. //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
  3. #include <FL/Fl.H>
  4. #include <Fl/fl_draw.h>
  5. #include <FL/Fl_Widget.H>
  6. #include <FL/Fl_Double_Window.H>
  7. #include <Fl/Fl_Output.H>
  8. #include <Fl/Fl_Menu_Bar.H>
  9. #include <vector>
  10. #include "Fl_CbLinker.h"
  11. #include "cmGlobal.h"
  12. #include "cmFloatTypes.h"
  13. #include "cmRpt.h"
  14. #include "cmErr.h"
  15. #include "cmCtx.h"
  16. #include "cmMem.h"
  17. #include "cmMallocDebug.h"
  18. #include "cmLinkedHeap.h"
  19. #include "cmText.h"
  20. #include "cmThread.h"
  21. #include "cmPrefs.h"
  22. #include "cmSymTbl.h"
  23. #include "cmTime.h"
  24. #include "cmMidi.h"
  25. #include "cmMidiFile.h"
  26. #include "cmAudioFile.h"
  27. #include "cmAudioFileMgr.h"
  28. #include "cmTimeLine.h"
  29. #include "cmScore.h"
  30. #include "cmTakeSeqBldr.h"
  31. #include "cmGr.h"
  32. #include "cmGrDevCtx.h"
  33. #include "cmGrPlot.h"
  34. #include "cmGrPage.h"
  35. #include "cmGrFltk.h"
  36. #include "gvHashFunc.h"
  37. #include "cmGrTksbFltk.h"
  38. #include "cmGrPlotAudio.h"
  39. #include "cmdIf.h"
  40. cmGrTksbFltk::cmGrTksbFltk(cmCtx_t* ctx, cmdIf* cp, Fl_Menu_Bar* menu, int x, int y, int w, int h)
  41. : cmGrPlotFltk(ctx,x,y,w,h),
  42. //_cmdIf(cp),
  43. _tksbH(cmTakeSeqBldrNullHandle),
  44. _menuBar(menu),
  45. _samplesMetricId(cmInvalidId),_secondsMetricId(cmInvalidId),
  46. //_objSecs(0),
  47. _objId(0),
  48. //_togFl(true),
  49. _lastBarPlotObjH(cmGrPlObjNullHandle),
  50. _nextTakeY(5),
  51. _curCbTId(kInvalidTId)
  52. {
  53. cmErrSetup(&_err,&ctx->rpt,"cmGrTksbFltk");
  54. _createMenu();
  55. if( cmGrPageIsValid(pageHandle()) == false )
  56. return;
  57. initViews(1,1);
  58. unsigned vwIdx = 0;
  59. cmGrPgH_t pgH = pageHandle();
  60. cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx);
  61. cmGrH_t cvH = cmGrViewGrHandle( vwH );
  62. cmGrAxH_t axH = cmGrAxNullHandle;
  63. cmGrVExt_t limExt;
  64. _samplesMetricId = cmGrPageLabelFuncRegister( pgH, gvRoundHashValueFunc, this, "Round" );
  65. _secondsMetricId = cmGrPageLabelFuncRegister( pgH, gvMinSecMsHashValueFunc, this, "Min:Sec:Ms" );
  66. unsigned pitchLabelFuncId = cmGrPageLabelFuncRegister( pgH, gvMidiSciPitchValueFunc, this, "Pitch" );
  67. cmGrVExtSetD(&limExt,0,0,0,127);
  68. cmGrObjSetWorldExt( cvH, cmGrRootObjH(cvH), &limExt );
  69. cmGrObjSetWorldLimitExt(cvH, cmGrRootObjH(cvH), &limExt, kTopGrFl | kBottomGrFl );
  70. axH = cmGrViewAxisHandle(vwH, kTopGrIdx);
  71. cmGrAxisSetCfg( axH, cmClrFlag(cmGrAxisCfg( axH ), kHashMarkGrFl | kHashLabelGrFl ));
  72. axH = cmGrViewAxisHandle(vwH, kLeftGrIdx );
  73. cmGrAxisSetLabelFunc( axH, pitchLabelFuncId );
  74. cmGrViewSetLabelFunc( vwH, kLeftGrIdx, pitchLabelFuncId );
  75. axH = cmGrViewAxisHandle(vwH, kRightGrIdx);
  76. cmGrAxisSetCfg( axH, cmClrFlag(cmGrAxisCfg( axH ), kHashLabelGrFl ));
  77. cmGrViewSetCfg( vwH, cmSetFlag(cmGrViewCfg(vwH),kSelectHorzGrFl) );
  78. }
  79. cmGrTksbFltk::~cmGrTksbFltk()
  80. {
  81. }
  82. void _cmGrTksbRecvScoreMsg( void* cbArg, const void* msg, unsigned msgByteCnt )
  83. {
  84. cmGrTksbFltk* thisPtr = (cmGrTksbFltk*)cbArg;
  85. thisPtr->recvScoreMsg(msg,msgByteCnt);
  86. }
  87. void cmGrTksbFltk::setTksbHandle( void* v )
  88. {
  89. _tksbH.h = v;
  90. if( cmTakeSeqBldrIsValid(_tksbH) == false )
  91. return;
  92. // load the score plot objects
  93. cmScoreSeqNotifyCb(cmTakeSeqBldrScoreHandle(_tksbH),_cmGrTksbRecvScoreMsg, this );
  94. // get the count of score-track takes
  95. unsigned n = cmTakeSeqBldrScTrkTakeCount(_tksbH);
  96. // for each score-track take
  97. for(unsigned i=0; i<n; ++i)
  98. {
  99. cmTksbScTrkTake_t r;
  100. // get the ith take
  101. if( cmTakeSeqBldrScTrkTake(_tksbH,i,&r) != kOkTsbRC )
  102. continue;
  103. // create the take plot-object
  104. _insertTake(&r);
  105. }
  106. }
  107. cmScMsgTypeId_t cmGrTksbFltk::recvScoreMsg( const void* msg, unsigned msgByteCnt )
  108. {
  109. cmScMsg_t m;
  110. cmScoreDecode(msg,msgByteCnt,&m);
  111. switch( m.typeId )
  112. {
  113. case kBeginMsgScId:
  114. {
  115. _objId = 0;
  116. _objSecs = 0;
  117. // remove all objects from all views
  118. //cmGrPageClear(pageHandle());
  119. //_srate = m.srate;
  120. //_updateSeqMenu(m.seqCnt,m.seqId);
  121. }
  122. break;
  123. case kEndMsgScId:
  124. //size(w(),h()+1);
  125. break;
  126. case kEventMsgScId:
  127. _insertEvent(&m.u.evt);
  128. break;
  129. case kSectionMsgScId:
  130. _insertSection(&m.u.sect);
  131. break;
  132. case kVarMsgScId:
  133. break;
  134. default:
  135. { assert(0); }
  136. }
  137. return m.typeId;
  138. }
  139. double cmGrTksbFltk::sampleRate() const
  140. {
  141. if( cmTakeSeqBldrIsValid(_tksbH) )
  142. return cmTakeSeqBldrSampleRate(_tksbH);
  143. return 0;
  144. }
  145. bool cmGrTksbFltk::on_plot_object( cmGrPlotCbArg_t* arg )
  146. {
  147. if( arg->selId!=kStateChangeGrPlId || cmIsNotFlag(arg->deltaFlags,kSelectGrPlFl) )
  148. return true;
  149. scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(arg->objH);
  150. unsigned state = cmGrPlotObjStateFlags(arg->objH);
  151. bool isSelectedFl = cmIsFlag( state, kSelectGrPlFl);
  152. if( sop == NULL )
  153. return true;
  154. //printf("SELECT:%i %i 0x%x\n",cmGrPlotObjId(arg->objH),isSelectedFl,state);
  155. if( sop->id==kTakeTksbId && sop->u.tlMarkerUid!=cmInvalidId )
  156. {
  157. if( isSelectedFl )
  158. cmTakeSeqBldrLoadTake(_tksbH,sop->u.tlMarkerUid,true);
  159. else
  160. cmTakeSeqBldrUnloadTake(_tksbH,sop->u.tlMarkerUid);
  161. setStatusText(cmTsPrintfS("%s", cmStringNullGuard(cmTakeSeqBldrScTrkTakeText(_tksbH,sop->u.tlMarkerUid))));
  162. _curCbTId = kRefreshTId;
  163. // callback to: kcApp::_ctl_cb(ctl_t* cp)
  164. callback()(this,user_data());
  165. }
  166. if( sop->id==kEventTksbId && sop->u.ep!=NULL && sop->u.ep->type==kBarEvtScId )
  167. {
  168. _lastBarPlotObjH = arg->objH;
  169. _curCbTId = kSelectTId;
  170. // callback to: kcApp::_ctl_cb(ctl_t* cp)
  171. callback()(this,user_data());
  172. }
  173. return true;
  174. }
  175. cmGrTksbFltk::cbTId_t cmGrTksbFltk::cbTypeId() const
  176. { return _curCbTId; }
  177. unsigned cmGrTksbFltk::scoreSelectedEleIndex() const
  178. {
  179. if( cmGrPlotObjIsValid(_lastBarPlotObjH) )
  180. {
  181. scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(_lastBarPlotObjH);
  182. if( sop!=NULL && sop->id==kEventTksbId && sop->u.ep != NULL && sop->u.ep->type == kBarEvtScId )
  183. {
  184. return sop->u.ep->locIdx;
  185. }
  186. }
  187. return cmInvalidIdx;
  188. }
  189. void cmGrTksbFltk::setScoreLocation( unsigned locIdx, unsigned vel, unsigned smpIdx )
  190. {
  191. }
  192. void cmGrTksbFltk::_insertSection( const cmScoreSection_t* m )
  193. {
  194. // The argument is a serialzed copy of a cmScoreSection_t record.
  195. // Convert it to a pointer to an actual object in the local score mgr.
  196. if( cmGrPageIsValid(pageHandle()) == false )
  197. return;
  198. m = cmScoreSection(cmTakeSeqBldrScoreHandle(_tksbH),m->index);
  199. assert(m!=NULL);
  200. const cmScoreEvt_t* ep = cmScoreEvt( cmTakeSeqBldrScoreHandle(_tksbH), m->begEvtIndex);
  201. assert( ep != NULL );
  202. cmGrPlH_t plH = plotHandle();
  203. cmGrPgH_t pgH = pageHandle();
  204. unsigned vwIdx = 0;
  205. cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx );
  206. cmGrH_t cvH = cmGrViewGrHandle( vwH );
  207. cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle;
  208. cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle;
  209. cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle;
  210. cmGrPlObjH_t objH = cmGrPlObjNullHandle;
  211. cmGrPlObjTypeId_t objTypeId = kLineGrPlId;
  212. cmReal_t x = ep->secs;
  213. cmReal_t y = 120;
  214. cmReal_t w = 0;
  215. cmReal_t h = 7;
  216. const cmChar_t* label = m->label;
  217. unsigned flags = kNoDragGrPlFl;
  218. cmGrVExt_t wext;
  219. scObj_t scObj(m);
  220. cmGrVExtSetNull(&wext);
  221. if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, cmGrVExtIsNull(&wext)?NULL:&wext ) != kOkGrPlRC )
  222. {
  223. cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on a score section.", cmStringNullGuard(label));
  224. return;
  225. }
  226. cmGrPlotObjAllocUser(objH,&scObj,sizeof(scObj));
  227. unsigned f = 0 ? (kNorthJsGrFl | kTopJsGrFl) : (kSouthJsGrFl | kBottomJsGrFl);
  228. cmGrPlotObjSetLabelAttr( objH, f | kWestJsGrFl | kTopJsGrFl | kRightJsGrFl, 0, kBlackGrId );
  229. cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kGreenGrId );
  230. //cmGrPlotObjSetPhysExt(objH, 1, 0, 1, 0 );
  231. cmGrPlotObjSetFontSize(objH,8);
  232. }
  233. void cmGrTksbFltk::_insertEvent( const cmScoreEvt_t* m )
  234. {
  235. // The argument is a serialzed copy of a cmScoreEvt record.
  236. // Convert it to a pointer to an actual object in the local score mgr.
  237. if( cmGrPageIsValid(pageHandle()) == false )
  238. return;
  239. // Get a pointer to the score event
  240. m = cmScoreEvt( cmTakeSeqBldrScoreHandle(_tksbH), m->index );
  241. assert(m!=NULL);
  242. cmGrPlH_t plH = plotHandle();
  243. cmGrPgH_t pgH = pageHandle();
  244. unsigned vwIdx = 0;
  245. cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx );
  246. cmGrH_t cvH = cmGrViewGrHandle( vwH );
  247. cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle;
  248. cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle;
  249. cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle;
  250. cmGrPlObjH_t objH = cmGrPlObjNullHandle;
  251. cmGrPlObjTypeId_t objTypeId = kVLineGrPlId;
  252. cmReal_t x = m->secs;
  253. cmReal_t y = 0;
  254. cmReal_t w = 0;
  255. cmReal_t h = 127;
  256. const cmChar_t* label = NULL;
  257. unsigned flags = kNoDragGrPlFl;
  258. int bufN = 7;
  259. cmChar_t buf[bufN+1];
  260. cmGrVExt_t wext;
  261. scObj_t scObj(m);
  262. cmGrVExtSetNull(&wext);
  263. switch( m->type )
  264. {
  265. case kNonEvtScId:
  266. objTypeId = kRectGrPlId;
  267. y = m->pitch;
  268. h = 1;
  269. w = m->durSecs;
  270. label = cmMidiToSciPitch(m->pitch,NULL,0);
  271. break;
  272. case kPedalEvtScId:
  273. objTypeId = kRectGrPlId;
  274. y = 108;
  275. h = 2;
  276. w = m->durSecs;
  277. label = "pedal";
  278. break;
  279. case kBarEvtScId:
  280. {
  281. buf[bufN] = 0;
  282. snprintf(buf,bufN,"%i",m->barNumb);
  283. objTypeId = kVLineGrPlId;
  284. label = buf;
  285. }
  286. break;
  287. default:
  288. return;
  289. }
  290. // create the plot object to represent this event
  291. if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, cmGrVExtIsNull(&wext)?NULL:&wext ) != kOkGrPlRC )
  292. {
  293. cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on a score event.", cmStringNullGuard(label));
  294. return;
  295. }
  296. // store the score event reference as custom data inside the plot object
  297. cmGrPlotObjAllocUser(objH,&scObj,sizeof(scObj));
  298. switch( m->type )
  299. {
  300. case kBarEvtScId:
  301. {
  302. unsigned f = _togFl ? (kNorthJsGrFl | kTopJsGrFl) : (kSouthJsGrFl | kBottomJsGrFl);
  303. cmGrPlotObjSetLabelAttr( objH, f | kWestJsGrFl | kTopJsGrFl | kRightJsGrFl, 0, kBlueGrId );
  304. cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kYellowGrId );
  305. cmGrPlotObjSetPhysExt(objH, 1, 0, 1, 0 );
  306. _togFl = !_togFl;
  307. }
  308. break;
  309. case kNonEvtScId:
  310. cmGrPlotObjSetLineColor( objH, kEnablePlGrId, cmGrPlotObjFillColor(objH,kEnablePlGrId) );
  311. cmGrPlotObjSetFontSize(objH,8);
  312. break;
  313. case kPedalEvtScId:
  314. cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kDeepPinkGrId );
  315. cmGrPlotObjSetFillColor(objH, kEnablePlGrId, kDeepPinkGrId );
  316. cmGrPlotObjSetFontSize(objH,8);
  317. break;
  318. default:
  319. break;
  320. }
  321. if( cmIsFlag(m->flags,kInvalidScFl) )
  322. {
  323. cmGrPlotObjSetFillColor(objH, kEnablePlGrId, kRedGrId );
  324. }
  325. }
  326. void cmGrTksbFltk::_insertTake( const cmTksbScTrkTake_t* take )
  327. {
  328. cmGrPlH_t plH = plotHandle();
  329. cmGrPgH_t pgH = pageHandle();
  330. unsigned vwIdx = 0;
  331. cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx );
  332. cmGrH_t cvH = cmGrViewGrHandle( vwH );
  333. cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle;
  334. cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle;
  335. cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle;
  336. cmGrPlObjH_t objH = cmGrPlObjNullHandle;
  337. cmGrPlObjTypeId_t objTypeId = kRectGrPlId;
  338. cmReal_t x = 0;
  339. cmReal_t y = 0;
  340. cmReal_t w = 0;
  341. cmReal_t h = 127;
  342. const cmChar_t* label = NULL;
  343. unsigned flags = kNoDragGrPlFl | kNoFillGrPlFl;
  344. int bufN = 7;
  345. cmChar_t buf[bufN+1];
  346. cmGrVExt_t wext;
  347. cmGrVExt_t vext;
  348. scObj_t scObj(take->tlMarkerUid);
  349. cmGrVExtSetNull(&wext);
  350. if( cmGrPlotObjIsValid(objH = _scEvtIdxToPlotObj( take->minScEvtIdx ))==false )
  351. return;
  352. cmGrPlotObjVExt( objH, &vext);
  353. x = cmGrVExtMinX(&vext);
  354. if( cmGrPlotObjIsValid(objH = _scEvtIdxToPlotObj( take->maxScEvtIdx )) == false )
  355. return;
  356. cmGrPlotObjVExt( objH, &vext);
  357. w = cmGrVExtMaxX(&vext) - x;
  358. h = 1;
  359. y = _nextTakeY;
  360. buf[bufN] = 0;
  361. snprintf(buf,bufN,"%i",(_nextTakeY-5)/2);
  362. label = buf;
  363. _nextTakeY += 2;
  364. if( _nextTakeY > 120 )
  365. _nextTakeY = 5;
  366. // create the plot object to represent this event
  367. if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, cmGrVExtIsNull(&wext)?NULL:&wext ) != kOkGrPlRC )
  368. {
  369. cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on score-track take.", cmStringNullGuard(label));
  370. return;
  371. }
  372. // store the score event reference as custom data inside the plot object
  373. cmGrPlotObjAllocUser(objH,&scObj,sizeof(scObj));
  374. cmGrPlotObjSetLineColor( objH, kFocusPlGrId, kRedGrId );
  375. cmGrPlotObjSetLineColor( objH, kSelectPlGrId, kDeepPinkGrId );
  376. cmGrPlotObjSetFontSize(objH,8);
  377. }
  378. #define cmMENU_TITLE "Bldr"
  379. void cmGrTksbFltk::_createMenu( )
  380. {
  381. int idx = _menuBar->add(cmMENU_TITLE,0,NULL,0,FL_SUBMENU);
  382. const char* titleArray[] = { "Pitch", "Attributes", "Dynamics", "Location", "Fraction", "Section Even", "Section Dyn", "Section Tempo" };
  383. bool onFl[] = { true, false, false, false, false, false, false, false };
  384. int i;
  385. for(i=0; i<kMenuItemCnt; ++i)
  386. {
  387. _menuArray[i].id = i;
  388. _menuArray[i].p = this;
  389. _menuBar->insert(idx+1+i,titleArray[i],0,_s_menuCallback, _menuArray + i, FL_MENU_TOGGLE );
  390. if( onFl[i] )
  391. {
  392. Fl_Menu_Item* mip = (Fl_Menu_Item*)_menuBar->menu() + idx + i + 1;
  393. mip->set();
  394. }
  395. }
  396. _menuBar->redraw();
  397. }
  398. bool cmGrTksbFltk::_isMenuChecked( int id )
  399. {
  400. unsigned i;
  401. // locate the menu item assoc'd with id
  402. for(i=0; i<kMenuItemCnt; ++i)
  403. if( _menuArray[i].id == id )
  404. break;
  405. assert( i < kMenuItemCnt );
  406. int menuIdx;
  407. if(( menuIdx = _menuBar->find_index(cmMENU_TITLE)) == -1 )
  408. return false;
  409. // The menu items and _menuArray[] were initialized in the same order
  410. // therefore the offset from the base of both should be the same.
  411. Fl_Menu_Item* mip = (Fl_Menu_Item*)_menuBar->menu() + menuIdx + i + 1;
  412. assert( (item_t*)mip->user_data() == _menuArray + i );
  413. return mip->value() != 0;
  414. }
  415. void cmGrTksbFltk::_setEventLabels()
  416. {
  417. enum { kPitchFl=0x01, kAttrFl=0x02, kDynFl=0x04, kLocFl=0x08, kFracFl };
  418. cmGrPlH_t plH = plotHandle();
  419. unsigned flags = 0;
  420. flags |= _isMenuChecked(kPitchMId) ? kPitchFl : 0;
  421. flags |= _isMenuChecked(kAttrMId) ? kAttrFl : 0;
  422. flags |= _isMenuChecked(kDynMId) ? kDynFl : 0;
  423. flags |= _isMenuChecked(kLocIdxMId) ? kLocFl : 0;
  424. flags |= _isMenuChecked(kFracMId) ? kFracFl : 0;
  425. unsigned n = cmGrPlotObjectCount(plH);
  426. unsigned i;
  427. for(i=0; i<n; ++i)
  428. {
  429. cmGrPlObjH_t poH = cmGrPlotObjectIndexToHandle(plH,i);
  430. if( cmGrPlotObjIsValid(poH) )
  431. {
  432. scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(poH);
  433. if( sop!=NULL && sop->id==kEventTksbId && sop->u.ep!=NULL && sop->u.ep->type==kNonEvtScId )
  434. {
  435. const cmScoreEvt_t* ep = sop->u.ep;
  436. int bufN = 255;
  437. cmChar_t buf[ bufN+1 ];
  438. buf[bufN] = 0;
  439. buf[0] = 0;
  440. if( cmIsFlag(flags,kPitchFl) )
  441. snprintf(buf+strlen(buf),bufN-strlen(buf),"%s ",cmMidiToSciPitch(ep->pitch,NULL,0));
  442. if( cmIsFlag(flags,kAttrFl) )
  443. {
  444. cmChar_t s[4];
  445. int j=0;
  446. if( cmIsFlag(ep->flags,kEvenScFl) )
  447. s[j++] = 'e';
  448. if( cmIsFlag(ep->flags,kDynScFl) )
  449. s[j++] = 'd';
  450. if( cmIsFlag(ep->flags,kTempoScFl) )
  451. s[j++] = 't';
  452. s[j] = 0;
  453. snprintf(buf+strlen(buf),bufN-strlen(buf),"%s ",s);
  454. }
  455. if( cmIsFlag(flags,kDynFl) && cmIsFlag(ep->flags,kDynScFl) )
  456. {
  457. snprintf(buf+strlen(buf),bufN-strlen(buf),"d:%i",ep->dynVal);
  458. if( ep->perfDynLvl != 0 )
  459. snprintf(buf+strlen(buf),bufN-strlen(buf),"|%i ",ep->perfDynLvl);
  460. else
  461. snprintf(buf+strlen(buf),bufN-strlen(buf)," ");
  462. }
  463. if( cmIsFlag(flags,kLocFl) )
  464. snprintf(buf+strlen(buf),bufN-strlen(buf),"loc:%i ",ep->locIdx);
  465. if( cmIsFlag(flags,kFracFl) && ep->frac != 0)
  466. snprintf(buf+strlen(buf),bufN-strlen(buf),"%5.3f ",ep->frac);
  467. cmGrPlotObjSetLabel(poH, buf );
  468. }
  469. }
  470. }
  471. }
  472. void cmGrTksbFltk::_setSectionLabels()
  473. {
  474. enum { kEvenFl=0x01, kDynFl=0x02, kTempoFl=0x04 };
  475. cmGrPlH_t plH = plotHandle();
  476. unsigned flags = 0;
  477. flags |= _isMenuChecked(kSectEvenMId) ? kEvenFl : 0;
  478. flags |= _isMenuChecked(kSectDynMId) ? kDynFl : 0;
  479. flags |= _isMenuChecked(kSectTempoMId) ? kTempoFl : 0;
  480. unsigned n = cmGrPlotObjectCount(plH);
  481. unsigned i;
  482. for(i=0; i<n; ++i)
  483. {
  484. cmGrPlObjH_t poH = cmGrPlotObjectIndexToHandle(plH,i);
  485. if( cmGrPlotObjIsValid(poH) )
  486. {
  487. scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(poH);
  488. if( sop!=NULL && sop->id==kSectionTksbId && sop->u.sp!=NULL )
  489. {
  490. const cmScoreSection_t* sp = sop->u.sp;
  491. int bufN = 255;
  492. cmChar_t buf[ bufN+1 ];
  493. buf[bufN] = 0;
  494. buf[0] = 0;
  495. snprintf(buf,bufN,"%s ",sp->label);
  496. if( cmIsFlag(flags,kEvenFl) && sp->vars[kEvenVarScId] != DBL_MAX)
  497. snprintf(buf+strlen(buf),bufN-strlen(buf),"e:%f ",sp->vars[kEvenVarScId]);
  498. if( cmIsFlag(flags,kDynFl) && sp->vars[kDynVarScId] != DBL_MAX)
  499. snprintf(buf+strlen(buf),bufN-strlen(buf),"d:%f ",sp->vars[kDynVarScId]);
  500. if( cmIsFlag(flags,kTempoFl) && sp->vars[kTempoVarScId] != DBL_MAX)
  501. snprintf(buf+strlen(buf),bufN-strlen(buf),"t:%f ",sp->vars[kTempoVarScId]);
  502. cmGrPlotObjSetLabel(poH, buf );
  503. }
  504. }
  505. }
  506. }
  507. void cmGrTksbFltk::_s_menuCallback(Fl_Widget* w, void* arg )
  508. {
  509. item_t* ip = (item_t*)arg;
  510. cmGrTksbFltk* p = ip->p;
  511. unsigned long id = ip->id;
  512. switch( id )
  513. {
  514. case kPitchMId:
  515. case kAttrMId:
  516. case kDynMId:
  517. case kLocIdxMId:
  518. case kFracMId:
  519. {
  520. p->_setEventLabels();
  521. p->redraw();
  522. }
  523. break;
  524. case kSectEvenMId:
  525. case kSectDynMId:
  526. case kSectTempoMId:
  527. {
  528. p->_setSectionLabels();
  529. p->redraw();
  530. }
  531. break;
  532. }
  533. }
  534. cmGrPlObjH_t cmGrTksbFltk::_scEvtIdxToPlotObj( unsigned scEvtIdx )
  535. {
  536. cmGrPlH_t plH = plotHandle();
  537. unsigned n = cmGrPlotObjectCount(plH);
  538. unsigned i;
  539. cmGrPlObjH_t poH;
  540. scObj_t* sop;
  541. for(i=0; i<n; ++i)
  542. if(cmGrPlotObjIsValid(poH = cmGrPlotObjectIndexToHandle(plH,i))
  543. && (sop = (scObj_t*)cmGrPlotObjUserPtr(poH)) != NULL
  544. && sop->id == kEventTksbId
  545. && sop->u.ep->index == scEvtIdx )
  546. {
  547. return poH;
  548. }
  549. return cmGrPlObjNullHandle;
  550. }