123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837 |
- //| Copyright: (C) 2019-2020 Kevin Larke <contact AT larke DOT org>
- //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
- #include <FL/Fl.H>
- #include <Fl/fl_draw.h>
- #include <FL/Fl_Widget.H>
- #include <FL/Fl_Double_Window.H>
- #include <Fl/Fl_Output.H>
- #include <Fl/Fl_Menu_Bar.H>
-
- #include <vector>
-
- #include "Fl_CbLinker.h"
-
- #include "cmGlobal.h"
- #include "cmFloatTypes.h"
- #include "cmRpt.h"
- #include "cmErr.h"
- #include "cmCtx.h"
- #include "cmMem.h"
- #include "cmMallocDebug.h"
- #include "cmLinkedHeap.h"
- #include "cmText.h"
- #include "cmThread.h"
- #include "cmPrefs.h"
- #include "cmTime.h"
- #include "cmMidi.h"
- #include "cmMidiFile.h"
- #include "cmAudioFile.h"
- #include "cmAudioFileMgr.h"
- #include "cmSymTbl.h"
- #include "cmTimeLine.h"
- #include "cmScore.h"
-
- #include "cmGr.h"
- #include "cmGrDevCtx.h"
- #include "cmGrPlot.h"
- #include "cmGrPage.h"
- #include "cmGrFltk.h"
-
- #include "gvHashFunc.h"
- #include "cmGrTlFltk.h"
- #include "cmGrPlotAudio.h"
- #include "cmdIf.h"
-
-
-
- cmGrTlFltk::cmGrTlFltk(cmCtx_t* ctx, cmdIf* cp, Fl_Menu_Bar* menu, int x, int y, int w, int h)
- : cmGrPlotFltk(ctx,x,y,w,h),_srate(0),_cmdIf(cp),_menuBar(menu),
- _seqMenuIdx(cmInvalidIdx),_seqCnt(0),_seqItemArray(NULL),
- _markCnt(0),
- _samplesMetricId(cmInvalidId),_secondsMetricId(cmInvalidId),
- _selMarkPlotObjH(cmGrPlObjNullHandle),
- _curSeqId(cmInvalidId)
- {
- _createMenu();
- //_seqMenuIdx = _menuBar->find_index("&Seq");
-
- cmErrSetup(&_err,&ctx->rpt,"cmGrTlFltk");
-
- if( cmGrPageIsValid(pageHandle()) == false )
- return;
-
- // set the arrangement of 'views' on the 'page'
- // (2 rows, 1 column)
- initViews(kViewCnt,1);
-
- unsigned vwIdx = kAudioVwIdx;
- cmGrPgH_t grPgH = pageHandle();
- cmGrVwH_t grVwH = cmGrPageViewHandle( grPgH, vwIdx);
- cmGrH_t grH = cmGrViewGrHandle( grVwH );
- cmGrAxH_t grAxH = cmGrAxNullHandle;
- cmGrVExt_t limExt;
-
- // register plot hash mark labelling functions
- _samplesMetricId = cmGrPageLabelFuncRegister( grPgH, _s_roundHashValueFunc, this, "Round" );
- _secondsMetricId = cmGrPageLabelFuncRegister( grPgH, _s_minSecMsHashValueFunc, this, "Min:Sec:Ms" );
- unsigned pitchLabelFuncId = cmGrPageLabelFuncRegister( grPgH, _s_midiSciPitchValueFunc, this, "Pitch" );
- //unsigned timeLabelFuncId = _secondsMetricId;
-
-
- cmGrVExtSetD(&limExt,0,-1,0,1);
- cmGrObjSetWorldLimitExt(grH, cmGrRootObjH(grH), &limExt, kTopGrFl | kBottomGrFl );
-
- grAxH = cmGrViewAxisHandle(grVwH, kBottomGrIdx);
- cmGrAxisSetCfg( grAxH, cmClrFlag(cmGrAxisCfg( grAxH ), kHashMarkGrFl | kHashLabelGrFl ));
-
- //grAxH = cmGrViewAxisHandle(grVwH, kTopGrIdx );
- //cmGrAxisSetLabelFunc( grAxH, timeLabelFuncId );
-
- grAxH = cmGrViewAxisHandle(grVwH, kRightGrIdx);
- cmGrAxisSetCfg( grAxH, cmClrFlag(cmGrAxisCfg( grAxH ), kHashLabelGrFl ));
-
- //cmGrViewSetLabelFunc( grVwH, kTopGrIdx, timeLabelFuncId );
- cmGrViewSetCfg( grVwH, cmSetFlag(cmGrViewCfg(grVwH),kSelectHorzGrFl) );
-
- vwIdx = kMidiVwIdx;
- grVwH = cmGrPageViewHandle( grPgH, vwIdx);
- grH = cmGrViewGrHandle( grVwH );
-
-
-
- cmGrVExtSetD(&limExt,0,0,0,127);
- cmGrObjSetWorldLimitExt(grH, cmGrRootObjH(grH), &limExt, kTopGrFl | kBottomGrFl );
-
- grAxH = cmGrViewAxisHandle(grVwH, kTopGrIdx);
- cmGrAxisSetCfg( grAxH, cmClrFlag(cmGrAxisCfg( grAxH ), kHashMarkGrFl | kHashLabelGrFl ));
-
- //grAxH = cmGrViewAxisHandle(grVwH, kBottomGrIdx );
- //cmGrAxisSetLabelFunc( grAxH, timeLabelFuncId );
-
- grAxH = cmGrViewAxisHandle(grVwH, kRightGrIdx);
- cmGrAxisSetCfg( grAxH, cmClrFlag(cmGrAxisCfg( grAxH ), kHashLabelGrFl ));
-
- grAxH = cmGrViewAxisHandle(grVwH, kLeftGrIdx );
- cmGrAxisSetLabelFunc( grAxH, pitchLabelFuncId );
-
- //cmGrViewSetLabelFunc( grVwH, kTopGrIdx, timeLabelFuncId );
- cmGrViewSetLabelFunc( grVwH, kLeftGrIdx, pitchLabelFuncId );
- cmGrViewSetCfg( grVwH, cmSetFlag(cmGrViewCfg(grVwH),kSelectHorzGrFl) );
-
- cmGrSetSync( grH, cmGrViewGrHandle( cmGrPageViewHandle( grPgH, kAudioVwIdx ) ), kWorldSyncGrFl | kViewSyncGrFl | kSelectSyncGrFl | kHorzSyncGrFl );
- cmGrSetSync( cmGrViewGrHandle( cmGrPageViewHandle( grPgH, kAudioVwIdx ) ), grH, kWorldSyncGrFl | kViewSyncGrFl | kSelectSyncGrFl | kHorzSyncGrFl );
-
- setTimeAxisMetric(kSecondsMetricId);
- }
-
- cmGrTlFltk::~cmGrTlFltk()
- {
- cmMemFree(_seqItemArray);
- }
-
- void cmGrTlFltk::_insertTimeLineObj( const cmTlUiMsg_t* m )
- {
- cmGrPlH_t plH = plotHandle();
- cmGrPgH_t pgH = pageHandle();
-
- cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle;
- cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle;
- cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle;
- cmGrPlObjH_t objH = cmGrPlObjNullHandle;
-
- const cmTlObj_t* top = _cmdIf->tlObjIdToPtr(m->objId);
-
- assert(top != NULL);
- if( top==NULL)
- return;
-
- unsigned parentObjId = (top!=NULL && top->ref!=NULL) ? top->ref->uid : cmInvalidId;
- const cmTlMidiEvt_t* mep = NULL;
- const cmTlAudioFile_t* afp = NULL;
- unsigned vwIdx = kAudioVwIdx;
- cmGrPlObjTypeId_t objTypeId = kRectGrPlId;
- cmReal_t x = top->begSmpIdx;
- cmReal_t y = -1.0;
- cmReal_t w = top->durSmpCnt;
- cmReal_t h = 2.0;
- const cmChar_t* label = top->name;
- unsigned flags = kNoDragGrPlFl;
- bool pedalFl = false;
- cmGrVExt_t wext;
-
- cmGrVExtSetNull(&wext);
-
- // convert cmTlUiMsg_t into parameters for a call to cmGrPlotObjCreate().
- switch( top->typeId )
- {
- case kMidiFileTlId:
- {
- vwIdx = kMidiVwIdx;
- y = 0;
- h = 127;
- flags |= kNoFillGrPlFl | kNoSelectGrPlFl;
-
- cmGrVExtSet(&wext,0,0,top->durSmpCnt,h);
-
- if( parentObjId != cmInvalidId )
- xAnchorObjH = cmGrPlotObjectIdToHandle( plH, parentObjId );
-
- //printf("midi file id:%i x:%f y:%f w:%f h:%f %s\n",m->objId,x,y,w,h,cmStringNullGuard(label));
- }
- break;
-
- case kMidiEvtTlId:
- {
- mep = _cmdIf->tlMidiEvtObjPtr(top);
- vwIdx = kMidiVwIdx;
- y = 127; // all non-note-on msg's get put to the top of the display
- h = 1;
- w = 100; // arbitrary msg duration
-
- xAnchorObjH = cmGrPlotObjectIdToHandle( plH, parentObjId );
- parentObjH = cmGrPlotObjectIdToHandle( plH, mep->midiFileObjId );
-
- assert( cmHandlesAreNotEqual(xAnchorObjH,cmGrPlObjNullHandle) );
- assert( cmHandlesAreNotEqual(parentObjH,cmGrPlObjNullHandle) );
-
- const cmMidiTrackMsg_t* mtm = mep->msg;
- cmMidiByte_t status = mtm->status;
-
- if( cmMidiIsNoteOn(status) )
- {
- y = mtm->u.chMsgPtr->d0;
- w = top->durSmpCnt;
- label = cmMidiToSciPitch(mtm->u.chMsgPtr->d0,NULL,0);
- }
- else
- {
- if( cmMidiIsSustainPedalDown(status,mtm->u.chMsgPtr->d0,mtm->u.chMsgPtr->d1) )
- {
- y = 64;
- w = top->durSmpCnt;
- flags += kNoFillGrPlFl;
- label = "Pedal";
- pedalFl= true;
- }
- else
- {
- if( status == kMetaStId )
- label = cmMidiMetaStatusToLabel(mtm->metaId);
- else
- label = cmMidiStatusToLabel(status);
- }
- }
-
- }
- break;
-
- case kAudioFileTlId:
- afp = _cmdIf->tlAudioFileObjPtr(top);
- if( parentObjId != cmInvalidId )
- xAnchorObjH = cmGrPlotObjectIdToHandle( plH, parentObjId );
- cmGrVExtSet(&wext,0,-1,top->durSmpCnt,h);
- //printf("audio file id:%i x:%f y:%f w:%f h:%f %s\n",m->objId,x,y,w,h,cmStringNullGuard(label));
- break;
-
- case kAudioEvtTlId:
- objTypeId = kVLineGrPlId;
- break;
-
- case kMarkerTlId:
- if( _cmdIf->tlMarkerObjPtr(top)->typeId == kMidiOnsetMarkTlId )
- vwIdx = kMidiVwIdx;
-
- objTypeId = kVLineGrPlId;
- xAnchorObjH = cmGrPlotObjectIdToHandle( plH, parentObjId );
- //flags |= kNoFillGrPlFl | kBorderSelGrPlFl | kNoFocusGrPlFl;
- w = 0;
- break;
-
- default:
- { assert(0); }
- }
-
- cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx );
- cmGrH_t cvH = cmGrViewGrHandle( vwH );
-
- //const cmChar_t* anchLabel = cmHandlesAreEqual(xAnchorObjH,cmGrPlObjNullHandle) ? NULL : cmGrPlotObjLabel(xAnchorObjH);
- //const cmChar_t* parentLabel = cmHandlesAreEqual(parentObjH,cmGrPlObjNullHandle) ? NULL : cmGrPlotObjLabel(parentObjH);
- //printf("type:%i id:%i x:%f y:%f w:%f h:%f %s parent:%s xachor:%s\n",m->typeId,m->objId,x,y,w,h,cmStringNullGuard(label),cmStringNullGuard(parentLabel),cmStringNullGuard(anchLabel));
-
- // Create the object
- if( cmGrPlotObjCreate(plH, cvH, &objH, m->objId, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, cmGrVExtIsNull(&wext)?NULL:&wext ) != kOkGrPlRC )
- {
- cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on the object labelled '%s'.", cmStringNullGuard(top->name));
- return;
- }
-
- // set the plot obj's user arg. to be the time line element pointer
- cmGrPlotObjSetUserPtr(objH,(void*)top);
-
- // if the sequence is changing then invalidate the currently selected marker object
- if( m->seqId != _curSeqId )
- {
- _curSeqId = m->seqId;
- _selMarkPlotObjH = cmGrPlObjNullHandle;
- }
-
- // Modify the objects attributes
- if( cmGrPlotObjIsValid(objH) )
- {
- switch( top->typeId )
- {
- case kMidiEvtTlId:
- cmGrPlotObjSetFontSize(objH,9);
-
- if( pedalFl )
- cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kGreenGrId );
- else
- cmGrPlotObjSetLineColor( objH, kEnablePlGrId, cmGrPlotObjFillColor(objH,kEnablePlGrId) );
-
- _setMidiEventLabels(objH,_getMenuCheckFlags());
- break;
-
- case kAudioFileTlId:
- if( afp->fn != NULL )
- _cmdIf->audioFileLoad(afp->fn,m->objId);
- break;
-
- case kMarkerTlId:
- {
- cmGrColor_t color = kBlackGrId;
- const cmTlMarker_t* mop = _cmdIf->tlMarkerObjPtr(top);
- switch( mop->typeId)
- {
- case kAudioMarkTlId:
- {
- unsigned n = cmGrColorMapEleCount( cvH, kGrDefaultColorMapId );
- unsigned ci = _markCnt++ % n;
- color = cmGrColorMap(cvH,kGrDefaultColorMapId)[ci];
- }
- break;
-
- case kAudioOnsetMarkTlId:
- color = kDarkRedGrId;
- break;
-
- case kMidiOnsetMarkTlId:
- color = kDarkBlueGrId;
- break;
-
- default:
- { assert(0); }
- }
-
- cmGrPlotObjSetLabelAttr( objH, kNorthJsGrFl | kWestJsGrFl | kTopJsGrFl | kRightJsGrFl, 0, color );
- cmGrPlotObjSetLineColor( objH, kEnablePlGrId, color );;
- cmGrPlotObjSetPhysExt(objH, 1, 0, 1, 0 );
-
- // create the marker end indicator
- objH = cmGrPlObjNullHandle;
- if( cmGrPlotObjCreate(plH, cvH, &objH, cmInvalidId, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags | kNoSelectGrPlFl, x+top->durSmpCnt, y, w, h, "", NULL ) != kOkGrPlRC )
- cmErrMsg(&_err,kInsertObjFailRC,"Insert failed ending marker line labelled '%s'.", cmStringNullGuard(top->name));
- else
- cmGrPlotObjSetLineColor( objH, kEnablePlGrId, color );
-
-
- }
- break;
-
- default:
- break;
- }
- }
- }
-
- cmTlUiMsgTypeId_t cmGrTlFltk::recvTimeLineMsg( const void* msg, unsigned msgByteCnt )
- {
- cmTlUiMsg_t m;
-
- cmTimeLineDecode(msg,msgByteCnt,&m);
-
- switch( m.msgId )
- {
- case kInitMsgTlId:
- {
- // remove all objects from all views
- cmGrPageClear(pageHandle());
- _srate = m.srate;
- _updateSeqMenu(m.seqCnt,m.seqId);
- }
- break;
-
- case kDoneMsgTlId:
- //size(w(),h()+1);
- break;
-
- case kFinalMsgTlId:
- break;
-
- case kInsertMsgTlId:
- _insertTimeLineObj(&m);
- break;
-
- default:
- { assert(0); }
- }
-
- return m.msgId;
- }
-
- void cmGrTlFltk::recvAudioFileLoad( unsigned fileId )
- {
- cmGrPlH_t plH = plotHandle();
- cmGrPlObjH_t grPlObjH = cmGrPlotObjectIdToHandle( plH, fileId );
- cmAfmFileH_t afH = _cmdIf->audioFileHandle( fileId );
- unsigned chIdx = 0;
-
- if( cmAfmFileIsValid(afH) == false )
- {
- cmErrMsg(&_err,kAudioObjFailRC,"Unable to locate audio file plot graphic object for id:%i.", fileId);
- return;
- }
-
- if( cmGrPlotAudioFileObjCreate( grPlObjH, afH, chIdx ) != kOkGrPlRC )
- {
- const cmChar_t* audioFn = cmAudioFileName(cmAfmFileHandle(afH));
- cmErrMsg(&_err,kAudioObjFailRC,"Create audio file graphic object failed for '%s'.", cmStringNullGuard(audioFn));
- return;
- }
-
- redraw();
- }
-
- void cmGrTlFltk::setTimeAxisMetric( timeAxisMetricId_t metricId )
- {
- unsigned timeLabelFuncId = cmInvalidId;
-
- switch( metricId )
- {
- case kSamplesMetricId: timeLabelFuncId = _samplesMetricId; break;
- case kSecondsMetricId: timeLabelFuncId = _secondsMetricId; break;
- default:
- { assert(0); }
- }
-
- cmGrPgH_t pgH = pageHandle();
- cmGrVwH_t vwH = cmGrPageViewHandle( pgH, kAudioVwIdx);
- cmGrAxH_t axH = cmGrViewAxisHandle( vwH, kTopGrIdx);
-
- cmGrViewSetLabelFunc( vwH, kTopGrIdx, timeLabelFuncId );
- cmGrAxisSetLabelFunc( axH, timeLabelFuncId );
-
- vwH = cmGrPageViewHandle( pgH, kMidiVwIdx);
- axH = cmGrViewAxisHandle( vwH, kBottomGrIdx);
- cmGrViewSetLabelFunc( vwH, kBottomGrIdx, timeLabelFuncId );
- cmGrAxisSetLabelFunc( axH, timeLabelFuncId );
- }
-
- void cmGrTlFltk::toggleMarkerText()
- {
- cmGrPlH_t plH = plotHandle();
- unsigned n = cmGrPlotObjectCount(plH);
- unsigned i;
- for(i=0; i<n; ++i)
- {
- cmGrPlObjH_t poH = cmGrPlotObjectIndexToHandle(plH,i);
- if( cmGrPlotObjIsValid(poH) )
- cmGrPlotObjTogCfgFlags(poH,kNoLabelGrPlFl);
- }
- redraw();
- }
-
-
- unsigned cmGrTlFltk::timeLineSelectedMarkerId() const
- {
- const cmTlObj_t* top;
-
- if( cmGrPlotObjIsValid(_selMarkPlotObjH)
- && cmIsFlag(cmGrPlotObjStateFlags(_selMarkPlotObjH),kSelectGrPlFl)
- && (top = (const cmTlObj_t*)cmGrPlotObjUserPtr(_selMarkPlotObjH)) != NULL
- && (top->typeId==kMarkerTlId || top->typeId==kMidiEvtTlId) )
- {
- return top->uid;
- }
- return cmInvalidId;
- }
-
- void cmGrTlFltk::setAudioFileCursor( unsigned smpIdx )
- {
- if( cmGrPlotObjIsValid(_selMarkPlotObjH) )
- {
- cmGrPlObjH_t poh;
- // get the audio file plot object handle
- if(cmGrPlotObjIsValid(poh = cmGrPlotObjXAnchor(_selMarkPlotObjH)))
- {
- cmGrVExt_t vext;
- cmGrVPt_t pt0,pt1;
-
- // get the canvas handle
- cmGrPgH_t pgH = pageHandle();
- cmGrVwH_t vwH = cmGrPageViewHandle( pgH, kAudioVwIdx );
- cmGrH_t cvH = cmGrViewGrHandle( vwH );
-
- cmGrPlotObjVExt(poh,&vext); // get the extents of the audio file object
- smpIdx += vext.loc.x; // offset the current sample index to put the index in global time
-
- cmGrViewExtents(cvH, &vext ); // get the current view extents
- cmGrVPtSet(&pt0,smpIdx,cmGrVExtMinY(&vext)); // setup the selection points
- cmGrVPtSet(&pt1,smpIdx,cmGrVExtMaxY(&vext));
-
- cmGrSetSelectPoints(cvH, &pt0, &pt1 ); // apply the selection points to form a cursor line
- }
- }
- }
-
- void cmGrTlFltk::selectBar( unsigned barNumb )
- {
- cmGrPlH_t plH = plotHandle();
- unsigned n = cmGrPlotObjectCount(plH);
- unsigned i;
-
- for(i=0; i<n; ++i)
- {
- cmGrPlObjH_t poH = cmGrPlotObjectIndexToHandle(plH,i);
- const cmTlMarker_t* mkp;
- const cmTlObj_t* top;
-
- if( cmGrPlotObjIsValid(poH)
- && (top = (const cmTlObj_t*)cmGrPlotObjUserPtr(poH)) != NULL
- && top->typeId == kMarkerTlId
- && (mkp = _cmdIf->tlMarkerObjPtr(top)) != NULL
- && mkp->bar == barNumb ) // <-------- there is an apparent weakness in selecting a marker based
- { // only on the bar number - because the intention is to pick a
- // bar line marker but it may be (i have not actually checked)
- // that other objects might have a given bar number but not be
- // a bar line object.
-
- unsigned flags = cmGrPlotObjStateFlags(poH);
-
- cmGrPlotObjSetStateFlags(poH,cmSetFlag(flags,kFocusGrPlFl | kSelectGrPlFl));
- redraw();
-
- _selMarkPlotObjH = poH;
-
- _cmdIf->onTimeLineMarkerSelected(mkp->obj.uid);
-
- }
- }
-
- }
-
- bool cmGrTlFltk::on_plot_object( cmGrPlotCbArg_t* arg )
- {
- if( arg->selId==kStateChangeGrPlId
- && cmIsFlag(arg->deltaFlags,kSelectGrPlFl)
- && cmIsFlag(cmGrPlotObjStateFlags(arg->objH),kSelectGrPlFl) )
- {
- const cmTlObj_t* top;
- if((top = (const cmTlObj_t*)cmGrPlotObjUserPtr(arg->objH)) != NULL)
- {
- const cmChar_t* s = NULL;
-
- switch(top->typeId)
- {
- case kAudioFileTlId:
- {
- const cmTlAudioFile_t* afp;
- if((afp = _cmdIf->tlAudioFileObjPtr(top)) != NULL && afp->fn != NULL)
- s = afp->fn;
- }
- break;
-
- case kMidiFileTlId:
- {
- const cmTlMidiFile_t* mfp;
- if((mfp = _cmdIf->tlMidiFileObjPtr(top)) != NULL && mfp->fn != NULL)
- s = mfp->fn;
- }
- break;
-
- case kMidiEvtTlId:
- {
- const cmTlMidiEvt_t* mep;
- if((mep = _cmdIf->tlMidiEvtObjPtr(top)) != NULL )
- {
- _selMarkPlotObjH = arg->objH;
-
- callback()(this,user_data());
-
- _cmdIf->onTimeLineMidiEvtSelected(mep->obj.uid);
- }
- }
- break;
-
- case kMarkerTlId:
- {
- const cmTlMarker_t* mkp;
- if((mkp = _cmdIf->tlMarkerObjPtr(top)) != NULL)
- {
- if(mkp->text != NULL)
- s = mkp->text;
-
- _selMarkPlotObjH = arg->objH;
-
- callback()(this,user_data());
-
- _cmdIf->onTimeLineMarkerSelected(mkp->obj.uid);
-
- }
- }
- break;
-
- default:
- break;
- }
-
- if( s == NULL )
- s = cmGrPlotObjLabel(arg->objH);
-
- if( s == NULL )
- s = "";
-
- setStatusText(s);
- }
- }
-
- return true;
- }
-
-
-
- void cmGrTlFltk::_s_seqMenuCallback( Fl_Widget* w, void* vp )
- {
- item_t* ip = (item_t*)vp;
- assert( ip->id < ip->p->_seqCnt );
- ip->p->_cmdIf->selectSequence(ip->id);
- }
-
- void cmGrTlFltk::_s_roundHashValueFunc( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value )
- {
- snprintf(label,labelCharCnt,"%i",(int)round(value));
- }
-
- void cmGrTlFltk::_s_minSecMsHashValueFunc( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value )
- {
- cmGrTlFltk* p = (cmGrTlFltk*)arg;
-
- int min=0,sec=0,ms=0;
-
- double smpPerMin = p->_srate * 60.0;
- double smpPerMs = p->_srate / 1000.0;
-
- if( value > smpPerMin )
- {
- min = (int)floor( value / smpPerMin );
- value -= min * smpPerMin;
- }
-
- if( value > p->_srate )
- {
- sec = (int)floor( value / p->_srate );
- value -= sec * p->_srate;
- }
-
-
- if( value > smpPerMs )
- {
- ms = (int)floor( value / smpPerMs );
- value -= ms * smpPerMs;
- }
-
- snprintf(label,labelCharCnt,"%i:%2i:%2i",min,sec,ms);
- }
-
- void cmGrTlFltk::_s_midiSciPitchValueFunc( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value )
- {
- assert( label != NULL && labelCharCnt > 0 );
-
- if( labelCharCnt > 0 )
- label[0] = 0;
-
- if( 0 <= value && value <= 127 )
- cmMidiToSciPitch((cmMidiByte_t)floor(value), label, labelCharCnt );
- else
- {
- if( labelCharCnt > 3 )
- strcpy(label,"?");
- }
- }
-
- void cmGrTlFltk::_updateSeqMenu(int newSeqCnt, unsigned seqId)
- {
- if(_seqMenuIdx == -1 )
- return;
-
- //const Fl_Menu_Item* seq_mip = _menuBar->menu() + _seqMenuIdx;
- //int sz = seq_mip->size();
-
- // if the count of time-line sequences does not match the new count of sequences
- if( 1 /*sz != newSeqCnt*/ )
- {
- int i;
- // erase the current sequence sub-menu
- _menuBar->clear_submenu(_seqMenuIdx);
-
- // create an array to link the menu items to the sequence control id's
- _seqItemArray = cmMemResizeZ(item_t,_seqItemArray,newSeqCnt);
-
- // create each menu items and item map record
- for(i=0; i<newSeqCnt; ++i)
- {
- _seqItemArray[i].id = i;
- _seqItemArray[i].p = this;
- _menuBar->insert(_seqMenuIdx + i + 1,cmTsPrintf("%i",i),0,_s_seqMenuCallback,_seqItemArray+i,FL_MENU_TOGGLE);
- }
-
- }
-
- // set the menu check boxes to indicate the selected sequence
- int i;
- for(i=0; i<newSeqCnt; ++i)
- {
- Fl_Menu_Item* mip = (Fl_Menu_Item*)_menuBar->menu() + _seqMenuIdx + i + 1;
- if( i == (int)seqId )
- mip->set();
- else
- mip->clear();
- }
-
- // track the current sequence count
- _seqCnt = newSeqCnt;
-
- }
-
- void cmGrTlFltk::_createMenu( )
- {
- _seqMenuIdx = _menuBar->add("Seq", 0,NULL,0,FL_SUBMENU);
- int idx = _menuBar->add("Time Line",0,NULL,0,FL_SUBMENU);
- const char* titleArray[] = { "Samples", "Seconds", "Marker Text", "Pitch", "Velocity","Id", "Gen Onset","Del Onset" };
- bool checkFl[] = { false, false, false, true, true, true, false, false };
- bool onFl[] = { false, false, false, true, false, false, false, false };
- int i;
- for(i=0; i<kMenuItemCnt; ++i)
- {
- int flag = checkFl[i] ? FL_MENU_TOGGLE : 0;
- _menuArray[i].id = i;
- _menuArray[i].p = this;
- _menuBar->insert(idx+1+i,titleArray[i],0,_s_menuCallback, _menuArray + i, flag );
-
- if( onFl[i] )
- {
- Fl_Menu_Item* mip = (Fl_Menu_Item*)_menuBar->menu() + idx + i + 1;
- mip->set();
- }
- }
- }
-
- bool cmGrTlFltk::_isMenuChecked( int id )
- {
- unsigned i;
- // locate the menu item assoc'd with id
- for(i=0; i<kMenuItemCnt; ++i)
- if( _menuArray[i].id == id )
- break;
-
- assert( i < kMenuItemCnt );
-
- int menuIdx;
- if(( menuIdx = _menuBar->find_index("Time Line")) == -1 )
- return false;
-
- // The menu items and _menuArray[] were initialized in the same order
- // therefore the offset from the base of both should be the same.
- Fl_Menu_Item* mip = (Fl_Menu_Item*)_menuBar->menu() + menuIdx + i + 1;
-
- assert( (item_t*)mip->user_data() == _menuArray + i );
-
- return mip->value() != 0;
- }
-
- unsigned cmGrTlFltk::_getMenuCheckFlags()
- {
- unsigned flags = 0;
- flags |= _isMenuChecked(kViewPitchMId) ? kPitchChkFl : 0;
- flags |= _isMenuChecked(kViewVelocityMId) ? kVelChkFl : 0;
- flags |= _isMenuChecked(kViewIdMId) ? kIdChkFl : 0;
- return flags;
- }
-
- void cmGrTlFltk::_setLabels()
- {
- cmGrPlH_t plH = plotHandle();
- unsigned flags = _getMenuCheckFlags();
- unsigned n = cmGrPlotObjectCount(plH);
- unsigned i;
- for(i=0; i<n; ++i)
- {
- cmGrPlObjH_t poH = cmGrPlotObjectIndexToHandle(plH,i);
- _setMidiEventLabels(poH,flags);
- }
- }
-
- void cmGrTlFltk::_setMidiEventLabels( cmGrPlObjH_t poH, unsigned flags)
- {
- cmTlObj_t* top;
- if( cmGrPlotObjIsValid(poH) && (top = (cmTlObj_t*)cmGrPlotObjUserPtr(poH))!=NULL && top->typeId==kMidiEvtTlId )
- {
- const cmMidiTrackMsg_t* mep = ((const cmTlMidiEvt_t*)top)->msg;
- if( mep->status == kNoteOnMdId )
- {
- int bufN = 255;
- cmChar_t buf[ bufN+1 ];
-
- buf[bufN] = 0;
- buf[0] = 0;
-
- if( cmIsFlag(flags,kPitchChkFl) )
- snprintf(buf+strlen(buf),bufN-strlen(buf),"%s ",cmMidiToSciPitch(mep->u.chMsgPtr->d0,NULL,0));
-
- if( cmIsFlag(flags,kVelChkFl) )
- snprintf(buf+strlen(buf),bufN-strlen(buf),"%i ",mep->u.chMsgPtr->d1);
-
- if( cmIsFlag(flags,kIdChkFl) )
- snprintf(buf+strlen(buf),bufN-strlen(buf),"%i ",mep->uid);
-
- cmGrPlotObjSetLabel(poH, buf );
- }
- }
- }
-
- void cmGrTlFltk::_s_menuCallback(Fl_Widget* w, void* arg )
- {
- item_t* ip = (item_t*)arg;
- cmGrTlFltk* p = ip->p;
- unsigned long id = ip->id;
-
- switch( id )
- {
- case kViewSamplesMId:
- case kViewSecondsMId:
- {
- cmGrTlFltk::timeAxisMetricId_t metricId = id==kViewSamplesMId ? cmGrTlFltk::kSamplesMetricId : cmGrTlFltk::kSecondsMetricId;
- p->setTimeAxisMetric( metricId );
- p->redraw();
- }
- break;
-
- case kViewMarkTextMId:
- p->toggleMarkerText();
- break;
-
- case kViewVelocityMId:
- case kViewPitchMId:
- case kViewIdMId:
- p->_setLabels();
- p->redraw();
- break;
-
- case kGenOnsetMarksMId:
- p->_cmdIf->generateOnsetMarks();
- break;
-
- case kDelOnsetMarksMId:
- p->_cmdIf->deleteOnsetMarks();
- break;
- }
- }
|