//| Copyright: (C) 2019-2020 Kevin Larke //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file. #ifndef kcApp_h #define kcApp_h extern "C" struct cmApBufState_str; class Fl_Menu_Bar; class Fl_HSplitter; class Fl_Text_Buffer; class Fl_Text_Display; class Fl_Box; class Fl_Tabs; class Fl_Check_Button; class Fl_Value_Slider; class Fl_Menu_Button; class Fl_File_Btn; class Fl_Select_Browser; class Fl_Valuator; class Fl_Value_Input; class Fl_Progress; enum { kOkKmRC, kEngFailKmRC, kMemFailKmRC, kFileSysFailKmRC, kQueueFailKmRC, kTextSysFailKmRC, kPrefsFailKmRC, kMlistLoadFailKmRC, kJsonFailKmRC, kDeserialFailKmRC, kPrintQueFailKmRC, }; class kcApp : public Fl_Double_Window, public tlCtlRspdr { public: typedef unsigned kcKmRC_t; kcApp(cmCtx_t* ctx, cmPrH_t prH, cmTsMp1cH_t printQH, int w, int h, const cmChar_t* title, cmAiH_t aiH, int argc, char* argv[] ); virtual ~kcApp(); void resize(int x, int y, int w, int h); virtual void tlCtlNewTimeLineFile( tlCtl* tlCtl, const cmChar_t* fn ); virtual void tlCtlNewScoreFile( tlCtl* tlCtl, const cmChar_t* fn ); void print( const char* fmt, ... ); void vprint( const char* fmt, va_list vl ); private: enum { kMenuH = 30, kStatusH = 30, kIndH = 25, kIndW = 25, kSsPhaseMax = 20 }; enum { kSldrTypeId, kNumbTypeId, kTextTypeId, kButnTypeId, kChckTypeId, kLablTypeId, kFnamTypeId, kMlstTypeId, kMetrTypeId, kTmlnTypeId, kScorTypeId, kTksbTypeId, kTksrTypeId, kTwodTypeId, kSldrMinArgIdx = 0, kSldrMaxArgIdx = 1, kSldrStpArgIdx = 2, kSldrValArgIdx = 3, kSldrLblArgIdx = 4, kSldrVarCnt = 5, kTextValArgIdx = 0, kTextLblArgIdx = 1, kTextVarCnt = 2, kButnValArgIdx = 0, kButnLblArgIdx = 1, kButnVarCnt = 2, kLablValArgIdx = 0, kLablAlignArgIdx= 1, kLablVarCnt = 2, kChckValArgIdx = 0, kChckLblArgIdx = 1, kChckVarCnt = 2, kFnamValArgIdx = 0, kFnamPatArgIdx = 1, kFnamDirArgIdx = 2, kFnamVarCnt = 3, kMlstHgtArgIdx = 0, kMlstSelArgIdx = 1, kMlstLstArgIdx = 2, kMlstVarCnt = 3, kMetrMinArgIdx = 0, kMetrMaxArgIdx = 1, kMetrValArgIdx = 2, kMetrLblArgIdx = 3, kMetrVarCnt = 4, kTmlnFileArgIdx= 0, kTmlnPathArgIdx= 1, kTmlnSelArgIdx = 2, kTmlnMeasArgIdx= 3, kTmlnCursArgIdx= 4, kTmlnVarCnt = 5, kScorFileArgIdx = 0, kScorSelArgIdx = 1, kScorSmpIdxArgIdx = 2, kScorPitchArgIdx = 3, kScorVelArgIdx = 4, kScorLocIdxArgIdx = 5, kScorEvtIdxArgIdx = 6, kScorDynArgIdx = 7, kScorValTypeArgIdx = 8, kScorValueArgIdx = 9, kScorMeasArgIdx = 10, kScorVarCnt = 11, kTksbFileArgIdx = 0, kTksbPtrArgIdx = 1, kTksbSelArgIdx = 2, kTksbRefreshArgIdx = 3, kTksbVarCnt = 4, kTksrPtrArgIdx = 0, kTksrRefreshArgIdx = 1, kTksrSelArgIdx = 2, kTksrVarCnt = 3, kTwodXArgIdx = 0, kTwodYArgIdx = 1, kTwodRadiusArgIdx = 2, kTwodAngleArgIdx = 3, kTwodVarCnt = 4 }; enum { kEnableBtnId = 1, kAudDevRptBtnId, kAudioSysCfgBtnId, kInAudDevBtnId, kOutAudDevBtnId, kPgmBtnId, kSubSystemIdxBtnId, kSrateBtnId, kTestBtnId, kPrintPgmBtnId, kAboutMenuId, kQuitMenuId }; enum { k44100SrateIdx, k48000SrateIdx, k96000SrateIdx }; typedef struct sldr_str { union { Fl_Value_Slider* sldr; Fl_Value_Input* numb; } u; Fl_Valuator* val; double defaultVal; unsigned varIdArray[ kSldrVarCnt ]; } sldr_t; typedef struct text_str { Fl_Input* text; char* val; unsigned varIdArray[ kTextVarCnt ]; } text_t; typedef struct butn_str { Fl_Button* butn; double val; unsigned varIdArray[ kButnVarCnt ]; } butn_t; typedef struct chck_str { Fl_Check_Button* chck; double val; unsigned varIdArray[ kChckVarCnt ]; } chck_t; typedef struct labl_str { Fl_Box* box; unsigned varIdArray[ kLablVarCnt ]; } labl_t; typedef struct fname_str { Fl_File_Btn* fnam; unsigned varIdArray[ kFnamVarCnt ]; } fnam_t; typedef struct mlst_str { Fl_Select_Browser* mlst; Fl_Menu_Button* mbtn; int sel; unsigned varIdArray[ kMlstVarCnt ]; } mlst_t; typedef struct metr_str { Fl_Progress* prog; unsigned varIdArray[ kMetrVarCnt ]; } metr_t; typedef struct tmln_str { tlCtl* tlctl; char* val; unsigned varIdArray[ kTmlnVarCnt ]; } tmln_t; typedef struct scor_str { tlCtl* tlctl; unsigned smpIdx; unsigned pitch; unsigned vel; unsigned evtIdx; unsigned locIdx; unsigned varId; unsigned varIdArray[ kScorVarCnt ]; } scor_t; typedef struct tksb_str { tlCtl* tlctl; unsigned varIdArray[ kTksbVarCnt ]; } tksb_t; typedef struct tksr_str { tlCtl* tlctl; unsigned varIdArray[ kTksrVarCnt ]; } tksr_t; typedef struct twod_str { tlCtl* tlctl; unsigned varIdArray[ kTwodVarCnt ]; } twod_t; typedef struct ctl_str { kcApp* thisPtr; unsigned asSubIdx; unsigned typeId; unsigned instId; Fl_Widget* wdgtPtr; bool mstrFl; union { sldr_t sldr; text_t text; butn_t butn; chck_t chck; labl_t labl; fnam_t fnam; mlst_t mlst; metr_t metr; tmln_t tmln; scor_t scor; tksb_t tksb; tksr_t tksr; twod_t twod; } u; struct ctl_str* linkPtr; } ctl_t; typedef struct page_str { Fl_Group* grp; struct page_str* link; page_str() : grp(NULL), link(NULL) {} } page_t; enum { kUpdateSsIdx, kWakeupSsIdx, kMsgSsIdx, kAudioCbSsIdx, kProgSsCnt }; // each audio sub-system is represented by an ss_t record in _ssArray[_ssCnt] typedef struct ss_str { Fl_Progress* prog[kProgSsCnt]; // status indicator controls unsigned cnt[kProgSsCnt]; // previous status count value } ss_t; cmCtx_t* _ctx; cmPrH_t _prH; cmAiH_t _aiH; Fl_Menu_Bar* _menu; Fl_Text_Display* _con; Fl_Tabs* _tabs; Fl_Group* _mstr_grp; Fl_Menu_Button* _as_btn; Fl_Menu_Button* _ai_btn; Fl_Menu_Button* _ao_btn; Fl_Menu_Button* _pgm_btn; Fl_Menu_Button* _ss_btn; Fl_Menu_Button* _sr_btn; Fl_Check_Button* _ena_chk; page_t* _pageList; ctl_t* _ctlList; bool _stopTimerFl; bool _newPageFl; unsigned _incrColW; unsigned _colW; bool _horzBordFl; unsigned _horzBord; unsigned _ssCnt; // count of audio system sub-systems (set in _handleSsInitMsg()) ss_t* _ssArray; int _ssPhase; bool _ssUpdateFl; cmTsMp1cH_t _printqH; // thread-safe queue for controlling access to the output console from multiple threads int _printFl; tlCtl* _tlCtl; void _createSetupDlg(Fl_Group* grp); void _createMenu( int w, int h ); page_t* _createPage( const char* title ); unsigned _getCtlCount() const; void _clearCtlList(bool mstrFl); void _clearSsArray(); void _getNewCtlPosn( const cmDspUiHdr_t* m, int& x, int& y, int& w, int& h ); ctl_t* _findCtl( unsigned instId, unsigned asSubIdx, unsigned mstrFl=false ); ctl_t* _createCtl( const cmDspUiHdr_t* m, unsigned typeId, int& x, int& y, int& w, int& h, bool posnFl=true ); void _insertNewCtl( ctl_t* cp, const cmDspUiHdr_t* m, Fl_Widget* wdgt, unsigned* varIdArray, unsigned varIdCnt ); void _createSlider( const cmDspUiHdr_t* m ); void _setSldrValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createText( const cmDspUiHdr_t* m ); void _setTextValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createFnameCtl( const cmDspUiHdr_t* m ); void _setFnamValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createMlistCtl( const cmDspUiHdr_t* m ); kcKmRC_t _loadMlist( ctl_t* cp, const cmJsonNode_t* np ); void _setMlistValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createMeter( const cmDspUiHdr_t* m ); void _setMeterValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createButton( const cmDspUiHdr_t* m ); void _setButtonValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createCheck( const cmDspUiHdr_t* m ); void _setCheckValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createLabel( const cmDspUiHdr_t* m ); void _setLabelValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createTmln( const cmDspUiHdr_t* m ); void _setTmlnValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createScor( const cmDspUiHdr_t* m ); void _setScorValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createTksb( const cmDspUiHdr_t* m ); void _setTksbValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createTksr( const cmDspUiHdr_t* m ); void _setTksrValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _createTwod( const cmDspUiHdr_t* m ); void _setTwodValue( ctl_t* cp, unsigned instVarId, const cmDspValue_t* vp ); void _newColumn( const cmDspUiHdr_t* m ); void _insertAudioSysCfgLabel(unsigned long idx, const cmChar_t* label ); void _setDfltAudioSysCfg(unsigned long idx, const cmChar_t* label ); void _insertDeviceLabel( unsigned long idx, bool inputFl, const cmChar_t* label ); void _insertProgramLabel( unsigned long idx, const cmChar_t* label ); void _setDfltProgram(unsigned long idx, const cmChar_t* label ); void _insertSubSysCnt( unsigned long subSysCnt ); unsigned _getCurAudioSubSysIdx(); void _setMenuButton( Fl_Menu_Button* b, unsigned value, const char* dfltLabel ); void _setDeviceMenuButton( unsigned asSubIdx, bool inputFl, unsigned devIdx ); void _setSampleRateBtn( unsigned value ); void _updateMeters( unsigned asSubIdx, unsigned devIdx, unsigned inFl, const double* meterArray, unsigned meterCnt ); void _updateSsStatusIndicator( unsigned asSubIdx, unsigned indicatorIdx, unsigned cnt ); void _printStatusCounts(); void _clearStatusIndicators(); void _sendMasterUiMsg( unsigned asSubIdx, unsigned selId, unsigned instId, unsigned instVarId, const cmDspValue_t* v ); void _sendMasterUiValue(unsigned asSubIdx, unsigned instId, const double* v, unsigned vn, const cmChar_t* text ); void _createMasterCtl( unsigned asSubIdx, unsigned selId, unsigned instId, unsigned varCnt, const double* dv, unsigned dn, const cmChar_t* label); void _onRecvValue( const cmDspUiHdr_t* m ); void _getEngMsg(); public: void _handleStatusMsg( const cmAudioSysStatus_t* st, const double* iMeterArray, const double* oMeterArray ); void _handleSsInitMsg( const cmAudioSysSsInitMsg_t* m, const cmChar_t* inDevLabel, const cmChar_t* outDevLabel ); void _handleUiMsg( const cmDspUiHdr_t* m ); private: static kcApp* _getApp( Fl_Widget* w ); void _onCloseApp(); void _testStub(); void _printPgm(); // main app callback static void _s_callback(Fl_Widget* wp, void* data); void _callback(void* data); // timer callback static void _s_status_timeout_cb(void* userPtr); bool _status_timeout_cb(); static void _s_menu_cb(Fl_Widget *w, void *data); static void _s_btn_cb(Fl_Widget* w, long data); void _btn_cb(Fl_Widget* w, long arg); static void _s_ctl_cb(Fl_Widget* w, void* data); void _ctl_cb(ctl_t* cp); static void _s_tab_cb(Fl_Widget* w, void* data); void _tab_cb(Fl_Widget* w); // static void _s_print( void* userPtr, const char* text ); // called internally by cmTsQueueDequeue() to send text to _print() static cmRC_t _s_print_queue_cb(void* userCbPtr, unsigned msgByteCnt, const void* msgDataPtr ); // called periodically to check the print queue for waiting text. void _checkPrintQueue(); // send a string of text directly to the output console window void _print( const char* text ); }; #endif