//| Copyright: (C) 2019-2020 Kevin Larke //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file. #include #include #include #include #include #include #include #include "Fl_Splitter.h" #include "Fl_CbLinker.h" #include "cmPrefix.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 "cmFileSys.h" #include "cmThread.h" #include "cmText.h" #include "cmPrefs.h" #include "cmSymTbl.h" #include "cmTime.h" #include "cmMidi.h" #include "cmMidiFile.h" #include "cmAudioFile.h" #include "cmAudioFileMgr.h" #include "cmTimeLine.h" #include "cmScore.h" #include "cmTakeSeqBldr.h" #include "cmGr.h" #include "cmGrDevCtx.h" #include "cmGrPlot.h" #include "cmGrPage.h" #include "cmGrFltk.h" #include "gvHashFunc.h" #include "cmGrTlFltk.h" #include "cmGrScFltk.h" #include "cmGrTksbFltk.h" #include "cmGrTksrFltk.h" #include "cmGr2dFltk.h" #include "cmdIf.h" #include "tlCtl.h" //---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- class tlStatusWnd : public Fl_Window { public: tlStatusWnd(int w, int h, const char* label); virtual ~tlStatusWnd(); void display( const char* msg ); virtual void draw(); private: char* _msg; enum { kBorder = 10 }; }; tlStatusWnd::tlStatusWnd(int w, int h, const char* label) : Fl_Window(w,h,label),_msg(NULL) { end(); clear_border(); } tlStatusWnd:: ~tlStatusWnd() { cmMemFree(_msg); } void tlStatusWnd::display( const char* msg ) { bool fl = false; int border = 2*kBorder; // store the string _msg = cmMemResizeStr(_msg,msg); // The offscreen drawing context is probably not necesary. // However if a font change was applied then it would guarantee that // fl_measure() used the correct font. Fl_Offscreen os = fl_create_offscreen(w(),h()); fl_begin_offscreen(os); // BEWARE: fl_measure uses 'ww' on input. int ww=0,hh=0; fl_measure(_msg,ww,hh,0); fl_end_offscreen(); fl_delete_offscreen(os); if( ww+border < w() ) ww = w(); else { ww += border; fl = true; } if( hh+border < h() ) hh = h(); else { hh = hh+border; fl = true; } if(fl) size(ww,hh); int xx = parent()->w()/2 - ww/2; int yy = parent()->h()/2 - hh/2; position(xx,yy); set_modal(); show(); } void tlStatusWnd::draw() { // BEWARE: fl_measure uses 'ww' on input. int ww=0,hh=0; fl_measure(_msg,ww,hh,0); int xx = w()/2 - ww/2; int yy = h()/2; fl_rect(0,0,w(),h()); fl_draw(_msg,xx,yy); } //---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- tlCtl::tlCtl( cmCtx_t* ctx, Fl_Window* app, Fl_Menu_Bar* menuBar, tlCtlRspdr* rspdr ) : _ctx(ctx),_rspdr(rspdr), _cmdIf(NULL),_tlCtlr(NULL),_scCtlr(NULL),_tksbCtlr(NULL),_tksrCtlr(NULL),_2dCtlr(NULL), _statusWnd(NULL),_menu(menuBar) { cmErrSetup(&_err,&ctx->rpt,"tlCtl"); _cmdIf = new cmdIf( ctx,this ); app->add(_statusWnd = new tlStatusWnd(app->w()/2,app->h()/2,"Status")); } tlCtl::~tlCtl() { delete _cmdIf; delete _tlCtlr; delete _scCtlr; delete _tksbCtlr; delete _tksrCtlr; delete _2dCtlr; delete _statusWnd; } Fl_Widget* tlCtl::initTimeLineCtlr( int x, int y, int w, int h ) { delete _tlCtlr; _tlCtlr = NULL; return _tlCtlr = new cmGrTlFltk(_ctx,_cmdIf,_menu,x,y,w,h); } Fl_Widget* tlCtl::initScoreCtlr( int x, int y, int w, int h ) { delete _scCtlr; _scCtlr = NULL; return _scCtlr = new cmGrScFltk(_ctx,_cmdIf,_menu,x,y,w,h); } Fl_Widget* tlCtl::initTakeSeqBldrCtlr( int x, int y, int w, int h ) { delete _tksbCtlr; _tksbCtlr = NULL; return _tksbCtlr = new cmGrTksbFltk(_ctx,_cmdIf,_menu,x,y,w,h); } Fl_Widget* tlCtl::initTakeSeqRendCtlr( int x, int y, int w, int h ) { delete _tksrCtlr; _tksrCtlr = NULL; return _tksrCtlr = new cmGrTksrFltk(_ctx,_cmdIf,_menu,x,y,w,h); } Fl_Widget* tlCtl::init2dCtlr( int x, int y, int w, int h ) { delete _2dCtlr; _2dCtlr = NULL; return _2dCtlr = new cmGr2dFltk(_ctx,_menu,x,y,w,h); } void tlCtl::openTlFile( const cmChar_t* fn ) { if( fn!=NULL && _tlCtlr != NULL ) _cmdIf->open(fn); } void tlCtl::openScoreFile( const cmChar_t* fn ) { if( fn!=NULL && _scCtlr != NULL ) _cmdIf->setScore(fn); } void tlCtl::openTakeSeqBldr( void* v ) { if( v!=NULL && _tksbCtlr != NULL ) _tksbCtlr->setTksbHandle(v); } void tlCtl::openTakeSeqRend( void* v ) { if( v!=NULL && _tksrCtlr != NULL ) _tksrCtlr->setTksbHandle(v); } void tlCtl::setAudioFilePath( const cmChar_t* path ) { if( path!=NULL ) _cmdIf->setAudioFilePath(path); } void tlCtl::setAudioFileCursor( unsigned smpIdx ) { if( _tlCtlr != NULL ) _tlCtlr->setAudioFileCursor(smpIdx); } void tlCtl::setTimeLineSelectBar( unsigned barNumb ) { if( _tlCtlr != NULL ) _tlCtlr->selectBar(barNumb); } void tlCtl::setScoreSelectBar( unsigned barNumb ) { if( _scCtlr != NULL ) _scCtlr->selectBar(barNumb); } void tlCtl::setScoreLocation( unsigned locIdx, unsigned smpIdx, unsigned pitch, unsigned vel ) { _cmdIf->setScoreLocation( locIdx, smpIdx, pitch, vel ); } void tlCtl::setScoreVarValue( unsigned locIdx, unsigned varId, double value ) { _cmdIf->setScoreVarValue( locIdx, varId, value ); } void tlCtl::setScoreDynLevel( unsigned evtIdx, unsigned dynLvl ) { _cmdIf->setScoreDynLevel(evtIdx,dynLvl); } void tlCtl::refreshTakeSeqRend() { if( _tksrCtlr != NULL ) _tksrCtlr->refresh(); } void tlCtl::onIdle() { _cmdIf->onIdle(); } void tlCtl::cmdIfShowStatusMsg( const char* msg ) { _statusWnd->display(msg); } void tlCtl::cmdIfHideStatus() { _statusWnd->hide(); _statusWnd->set_non_modal(); } void tlCtl::cmdIfErrorMsg( const char* msg ) { cmErrMsg(&_err,1,"%s",msg); } void tlCtl::cmdIfTimeLineMsg( const void* msg, unsigned msgByteCnt ) { switch( _tlCtlr->recvTimeLineMsg(msg,msgByteCnt) ) { case kInitMsgTlId: if( _rspdr!= NULL && _cmdIf->tlFileName() != NULL ) _rspdr->tlCtlNewTimeLineFile(this,_cmdIf->tlFileName()); break; case kDoneMsgTlId: if( _scCtlr != NULL && _tlCtlr != NULL ) _scCtlr->setSampleRate( _tlCtlr->sampleRate() ); _menu->parent()->redraw(); break; default: break; } } void tlCtl::cmdIfAudioFileLoad( unsigned fileId ) { _tlCtlr->recvAudioFileLoad(fileId); } void tlCtl::cmdIfScoreMsg( const void* msg, unsigned msgByteCnt ) { assert( _scCtlr != NULL ); switch( _scCtlr->recvScoreMsg(msg,msgByteCnt) ) { case kBeginMsgScId: if( _rspdr!= NULL && _cmdIf->scoreFileName() != NULL ) _rspdr->tlCtlNewScoreFile(this,_cmdIf->scoreFileName()); break; case kEndMsgScId: _scCtlr->setSampleRate( _tlCtlr->sampleRate() ); _scCtlr->redraw(); break; _menu->parent()->redraw(); default: break; } } void tlCtl::cmdIfOnTimeLineMarkerSelect( unsigned markerId ) { } void tlCtl::cmdIfOnTimeLineMidiEvtSelect( unsigned midiEvtId ) { } void tlCtl::cmdIfOnScoreBarSelect( unsigned scoreIndex ) { } unsigned tlCtl::timeLineSelectedMarkerId() const { if( _tlCtlr==NULL) return cmInvalidId; return _tlCtlr->timeLineSelectedMarkerId(); } unsigned tlCtl::scoreSelectedEleIndex() const { if(_scCtlr==NULL) return cmInvalidId; return _scCtlr->scoreSelectedEleIndex(); } unsigned tlCtl::tksbSelectedEleIndex() const { if(_tksbCtlr==NULL) return cmInvalidId; return _tksbCtlr->scoreSelectedEleIndex(); } void tlCtl::testStub() { _cmdIf->testStub(); }