Add tlCtl and libcmpp to this repo.
This commit is contained in:
parent
1a16a3d5d8
commit
f2ea644147
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,7 +1,5 @@
|
||||
# directories to ignore
|
||||
libcm
|
||||
libcmpp
|
||||
tlCtl
|
||||
|
||||
.deps
|
||||
autom4te.cache
|
||||
|
@ -55,8 +55,8 @@ endif
|
||||
endif
|
||||
|
||||
if OS_OSX
|
||||
AM_CPPFLAGS += -I/opt/local/include
|
||||
AM_LDFLAGS += -L/opt/local/lib
|
||||
AM_CPPFLAGS += -I/opt/local/include # Search macports directory for fftw headers
|
||||
AM_LDFLAGS += -L/opt/local/lib # and libraries.
|
||||
AM_LDFLAGS += -framework Cocoa -framework CoreAudio -framework CoreMIDI -framework Carbon -framework Accelerate
|
||||
endif
|
||||
|
||||
|
1
src/libcmpp/.gitignore
vendored
Normal file
1
src/libcmpp/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
Makefile.in
|
18
src/libcmpp/Makefile.am
Normal file
18
src/libcmpp/Makefile.am
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
cmppSRC = src/libcmpp/fltk/Fl_CbLinker.cpp src/libcmpp/fltk/Fl_Splitter.cpp
|
||||
cmppHDR = src/libcmpp/fltk/Fl_CbLinker.h src/libcmpp/fltk/Fl_Splitter.h
|
||||
|
||||
cmppSRC += src/libcmpp/fltk/cmGrFltk.cpp
|
||||
cmppHDR += src/libcmpp/fltk/cmGrFltk.h
|
||||
|
||||
cmppHDR += src/libcmpp/fltk/Fl_File_Btn.h src/libcmpp/fltk/Fl_Vert_Progress.h
|
||||
cmppSRC += src/libcmpp/fltk/Fl_File_Btn.cpp src/libcmpp/fltk/Fl_Vert_Progress.cpp
|
||||
|
||||
cmppHDR += src/libcmpp/fltk/Fl_DevCfgGroup.h
|
||||
cmppSRC += src/libcmpp/fltk/Fl_DevCfgGroup.cpp
|
||||
|
||||
cmppHDR += src/libcmpp/fltk/cmUiDrvrFltk.h
|
||||
cmppSRC += src/libcmpp/fltk/cmUiDrvrFltk.cpp
|
||||
|
||||
|
82
src/libcmpp/fltk/Fl_CbLinker.cpp
Normal file
82
src/libcmpp/fltk/Fl_CbLinker.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Widget.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <FL/Fl_Scrollbar.H>
|
||||
#include <FL/Fl_Menu_Button.H>
|
||||
#include <FL/Fl_Menu_Item.H>
|
||||
|
||||
#include <vector>
|
||||
#include <assert.h>
|
||||
#include "Fl_CbLinker.h"
|
||||
|
||||
|
||||
Fl_CbLinker::Fl_CbLinker()
|
||||
{}
|
||||
|
||||
Fl_CbLinker::~Fl_CbLinker()
|
||||
{
|
||||
unsigned i;
|
||||
for(i=0; i<_ctlV.size(); ++i)
|
||||
delete _ctlV[i];
|
||||
}
|
||||
|
||||
void Fl_CbLinker::registerCtl( Fl_Button* c, unsigned id )
|
||||
{
|
||||
ctl_t* r;
|
||||
_ctlV.push_back( r = new ctl_t(this,c,id) );
|
||||
c->callback(_s_callback,r);
|
||||
}
|
||||
|
||||
void Fl_CbLinker::registerCtl( Fl_Scrollbar* c, unsigned id )
|
||||
{
|
||||
ctl_t* r;
|
||||
_ctlV.push_back( r = new ctl_t(this,c,id) );
|
||||
c->callback(_s_callback,r);
|
||||
}
|
||||
|
||||
void Fl_CbLinker::registerCtl( Fl_Menu_Button* c, unsigned id )
|
||||
{
|
||||
ctl_t* r;
|
||||
_ctlV.push_back( r = new ctl_t(this,c,id) );
|
||||
c->callback(_s_callback,r);
|
||||
}
|
||||
|
||||
void Fl_CbLinker::registerCtl( Fl_Menu_Item* c, unsigned id )
|
||||
{
|
||||
ctl_t* r;
|
||||
_ctlV.push_back( r = new ctl_t(this,c,id) );
|
||||
c->callback(_s_callback,r);
|
||||
}
|
||||
|
||||
void Fl_CbLinker::onButton( Fl_Button* c, unsigned id )
|
||||
{}
|
||||
|
||||
void Fl_CbLinker::onScrollbar( Fl_Scrollbar* c, unsigned id )
|
||||
{}
|
||||
|
||||
void Fl_CbLinker::onMenuBtn( Fl_Menu_Button* c, unsigned id )
|
||||
{}
|
||||
|
||||
void Fl_CbLinker::onMenuItem( Fl_Menu_Item* c, unsigned id )
|
||||
{}
|
||||
|
||||
|
||||
void Fl_CbLinker::_s_callback( Fl_Widget* w, void* arg )
|
||||
{
|
||||
ctl_t* r = static_cast<ctl_t*>(arg);
|
||||
|
||||
unsigned i;
|
||||
for(i=0; i<r->thisPtr->_ctlV.size(); ++i)
|
||||
if( r->thisPtr->_ctlV[i] == arg )
|
||||
{
|
||||
switch( r->typeId )
|
||||
{
|
||||
case kButtonTId: r->thisPtr->onButton( r->u.btn, r->ctlId); break;
|
||||
case kScrollbarTId: r->thisPtr->onScrollbar( r->u.sb, r->ctlId); break;
|
||||
case kMenuBtnTId: r->thisPtr->onMenuBtn( r->u.mbtn, r->ctlId); break;
|
||||
case kMenuItemTId: r->thisPtr->onMenuItem( r->u.mitem, r->ctlId); break;
|
||||
default:
|
||||
{ assert(0); }
|
||||
}
|
||||
}
|
||||
}
|
72
src/libcmpp/fltk/Fl_CbLinker.h
Normal file
72
src/libcmpp/fltk/Fl_CbLinker.h
Normal file
@ -0,0 +1,72 @@
|
||||
#ifndef Fl_CbLinker_h
|
||||
#define Fl_CbLinker_h
|
||||
|
||||
class Fl_Widget;
|
||||
class Fl_Button;
|
||||
class Fl_Scrollbar;
|
||||
class Fl_Menu_Button;
|
||||
struct Fl_Menu_Item;
|
||||
|
||||
/*
|
||||
This class solves the problem of linking static control callback functions
|
||||
to an object instance.
|
||||
|
||||
registerCtl() creates a record which links a control to an instance
|
||||
of a Fl_CbLinker. The control is then given a static callback function:
|
||||
_s_callback(). When _s_callback() is called from the control event
|
||||
handler it links locates the controls link record an calls the
|
||||
appropriate handler (e.g. onButton(), onScrollBar(), etc.)
|
||||
*/
|
||||
|
||||
class Fl_CbLinker
|
||||
{
|
||||
public:
|
||||
Fl_CbLinker();
|
||||
virtual ~Fl_CbLinker();
|
||||
|
||||
void registerCtl( Fl_Button* c, unsigned id );
|
||||
void registerCtl( Fl_Scrollbar* c, unsigned id );
|
||||
void registerCtl( Fl_Menu_Button* c, unsigned id );
|
||||
void registerCtl( Fl_Menu_Item* c, unsigned id );
|
||||
|
||||
virtual void onButton( Fl_Button* c, unsigned id );
|
||||
virtual void onScrollbar( Fl_Scrollbar* c, unsigned id );
|
||||
virtual void onMenuBtn( Fl_Menu_Button* c, unsigned id );
|
||||
virtual void onMenuItem( Fl_Menu_Item* c, unsigned id );
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kButtonTId,
|
||||
kScrollbarTId,
|
||||
kMenuBtnTId,
|
||||
kMenuItemTId
|
||||
};
|
||||
|
||||
typedef struct ctl_str
|
||||
{
|
||||
Fl_CbLinker* thisPtr;
|
||||
unsigned typeId;
|
||||
unsigned ctlId;
|
||||
union
|
||||
{
|
||||
Fl_Button* btn;
|
||||
Fl_Scrollbar* sb;
|
||||
Fl_Menu_Button* mbtn;
|
||||
Fl_Menu_Item* mitem;
|
||||
Fl_Widget* w;
|
||||
} u;
|
||||
|
||||
ctl_str( Fl_CbLinker* t, Fl_Button* c, unsigned id) : thisPtr(t), typeId(kButtonTId), ctlId(id) { u.btn=c; }
|
||||
ctl_str( Fl_CbLinker* t, Fl_Scrollbar* c, unsigned id ) : thisPtr(t), typeId(kScrollbarTId),ctlId(id) { u.sb=c; }
|
||||
ctl_str( Fl_CbLinker* t, Fl_Menu_Button* c, unsigned id ) : thisPtr(t), typeId(kMenuBtnTId), ctlId(id) { u.mbtn=c; }
|
||||
ctl_str( Fl_CbLinker* t, Fl_Menu_Item* c, unsigned id ) : thisPtr(t), typeId(kMenuItemTId), ctlId(id) { u.mitem=c; }
|
||||
|
||||
} ctl_t;
|
||||
|
||||
std::vector< ctl_t* > _ctlV;
|
||||
|
||||
static void _s_callback( Fl_Widget* w, void* arg );
|
||||
};
|
||||
|
||||
#endif
|
1135
src/libcmpp/fltk/Fl_DevCfgGroup.cpp
Normal file
1135
src/libcmpp/fltk/Fl_DevCfgGroup.cpp
Normal file
File diff suppressed because it is too large
Load Diff
168
src/libcmpp/fltk/Fl_DevCfgGroup.h
Normal file
168
src/libcmpp/fltk/Fl_DevCfgGroup.h
Normal file
@ -0,0 +1,168 @@
|
||||
#ifndef Fl_DevCfgGroup_h
|
||||
#define Fl_DevCfgGroup_h
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Fl_DevCfgGroup : public Fl_Group
|
||||
{
|
||||
public:
|
||||
Fl_DevCfgGroup(cmDevCfgH_t dcH, int x, int y, int w, int h, const char* label );
|
||||
virtual ~Fl_DevCfgGroup();
|
||||
|
||||
void onEnableAudio(bool enableFl );
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kInvalidCId,
|
||||
kLocLabelCId,
|
||||
kLocMenuCId,
|
||||
kLocStringCId,
|
||||
kLocStoreBtnCId,
|
||||
kLocDeleteBtnCId,
|
||||
|
||||
kMidiLabelCId,
|
||||
kMidiCfgMenuCId,
|
||||
kMidiDeleteBtnCId,
|
||||
kMidiCfgStringCId,
|
||||
kMidiApplyBtnCId,
|
||||
kMidiCfgDescCId,
|
||||
kMidiDevMenuCId,
|
||||
kMidiDevLabelCId,
|
||||
kMidiPortMenuCId,
|
||||
kMidiPortLabelCId,
|
||||
kMidiInputCheckCId,
|
||||
|
||||
kAudioLabelCId,
|
||||
kAudioCfgMenuCId,
|
||||
kAudioDeleteBtnCId,
|
||||
kAudioCfgDescCId,
|
||||
kAudioCfgStringCId,
|
||||
kAudioApplyBtnCId,
|
||||
kAudioInDevMenuCId,
|
||||
kAudioInDevLabelCId,
|
||||
kAudioOutDevMenuCId,
|
||||
kAudioOutDevLabelCId,
|
||||
kAudioMsgQueSizeValCId,
|
||||
kAudioDevFpCValCId,
|
||||
kAudioDspFpCValCId,
|
||||
kAudioBufCntValCId,
|
||||
kAudioSrateMenuCId,
|
||||
kAudioSyncInCheckCId,
|
||||
kAudioNetNodeStringCId,
|
||||
kAudioBcastAddrStringCId,
|
||||
kAudioIpAddrStringCId,
|
||||
kAudioIpPortValCId,
|
||||
kAudioActiveCheckCId,
|
||||
|
||||
/*
|
||||
kNetLabelCId,
|
||||
kNetCfgMenuCId,
|
||||
kNetDeleteBtnCId,
|
||||
kNetCfgDescCId,
|
||||
kNetCfgStringCId,
|
||||
kNetApplyBtnCId,
|
||||
kNetSockAddrStringCId,
|
||||
kNetPortNumbValCId,
|
||||
kNetLocalCheckCId,
|
||||
kNetActiveCheckCId
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned id;
|
||||
Fl_DevCfgGroup* p;
|
||||
union
|
||||
{
|
||||
Fl_Button* btn;
|
||||
Fl_Check_Button* chk;
|
||||
Fl_Box* box;
|
||||
Fl_Menu_Button* mbt;
|
||||
Fl_Input* inp;
|
||||
Fl_Value_Input* val;
|
||||
} u;
|
||||
|
||||
} ctl_t;
|
||||
|
||||
cmDevCfgH_t _dcH;
|
||||
std::vector< ctl_t* > _ctlV;
|
||||
|
||||
bool _loadLocBtn();
|
||||
void _recallLoc();
|
||||
void _storeLoc();
|
||||
void _deleteLoc();
|
||||
|
||||
void _loadMidiDevBtn();
|
||||
void _loadMidiPortBtn();
|
||||
void _loadAudioDevBtn( unsigned id, unsigned devIdx );
|
||||
void _loadAudioSrateBtn();
|
||||
void _loadCfgMenu(cmTypeDcmId_t typeId, unsigned menuCtlId, unsigned deleteCtlId );
|
||||
void _syncLoc();
|
||||
void _createMidiCfg();
|
||||
void _createAudioCfg();
|
||||
//void _createNetCfg();
|
||||
void _deleteCfg( cmTypeDcmId_t typeId, unsigned menuCtlId, unsigned inpCtlCId, unsigned descCtlId, unsigned storeCtlId, unsigned deleteCtlId );
|
||||
void _recallCfg( cmTypeDcmId_t typeId, unsigned menuCtlId, unsigned strCtlId, unsigned descCtlId, unsigned storeCtlId );
|
||||
|
||||
// Attempt to set the menu to index 'val' otherwise attempt to set it to 'dfltVal'
|
||||
// Finish by updating the label.
|
||||
void _restoreMenuValue( unsigned menuCtlId, int val, int dfltVal=0 );
|
||||
|
||||
// Get the current string value of the menu btn.
|
||||
const char* _menuBtnValueStr( unsigned menuCtlId );
|
||||
|
||||
// Copy the menu btn's current string value to the label (and the input control)
|
||||
void _setMenuBtnLabel( unsigned menuCtlId, unsigned inpCtlId = cmInvalidId );
|
||||
|
||||
// Set the menu buttons value to 'string' and update the menu btn's label
|
||||
void _setMenuBtnWithString( unsigned menuCtlId, const char* string );
|
||||
void _setCheckCtl( unsigned ctlId, int val );
|
||||
void _setValueCtl( unsigned ctlId, double val );
|
||||
void _setInputCtl( unsigned ctlId, const cmChar_t* val );
|
||||
|
||||
const cmChar_t* _getMenuCtl( unsigned ctlId );
|
||||
const cmChar_t* _getInputCtl( unsigned ctlId );
|
||||
double _getValueCtl( unsigned ctlId );
|
||||
bool _getCheckCtl( unsigned ctlId );
|
||||
|
||||
double _getSrate();
|
||||
void _setSrate( double srate );
|
||||
|
||||
void _enableStoreBtn( unsigned ctlId );
|
||||
|
||||
ctl_t* _idToCtl(unsigned id);
|
||||
|
||||
|
||||
static void _s_ctl_cb( Fl_Widget* w, void* arg );
|
||||
|
||||
};
|
||||
|
||||
// Init:
|
||||
// 1) Load all menu X btns and set to first entry.
|
||||
// 2) set cfg string X to string value of cfg menu
|
||||
// 3) update desc and X fields.
|
||||
//
|
||||
// Cfg:
|
||||
// Store:
|
||||
// 1) call cmDevCfgNameX( cfg_label ) successfully
|
||||
// 2) reload cfg menu
|
||||
// 3) set cfg menu label to new cfg_label
|
||||
//
|
||||
// Recall:
|
||||
// 1) set cfg menu X label
|
||||
// 2) set cfg string X to string value of cfg menu
|
||||
// 3) update desc and X fields
|
||||
//
|
||||
// Delete:
|
||||
// 1) call cmDevDeleteX( cfg_label ) sucessfuly.
|
||||
// 2) reload cfg menu and set to first entry
|
||||
// 3) set cfg string X to string value of cfg menu
|
||||
// 4) update desc and X fields
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
|
||||
#endif
|
105
src/libcmpp/fltk/Fl_File_Btn.cpp
Normal file
105
src/libcmpp/fltk/Fl_File_Btn.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
#include <Fl/Fl.H>
|
||||
#include <Fl/Fl_Button.H>
|
||||
#include <Fl/Fl_File_Chooser.H>
|
||||
#include <Fl/Fl_Output.H>
|
||||
#include <Fl/Fl_Group.H>
|
||||
#include "Fl_File_Btn.h"
|
||||
|
||||
Fl_File_Btn::Fl_File_Btn( int xx, int yy, int ww, int hh, const char* l )
|
||||
: Fl_Group(xx,yy,ww,hh,l),
|
||||
_patStr(NULL),_typeId(kFile_Type_Id),_btn(NULL),_out(NULL)
|
||||
{
|
||||
_init();
|
||||
end();
|
||||
}
|
||||
|
||||
Fl_File_Btn::Fl_File_Btn( unsigned typeId, const char* patStr, int xx, int yy, int ww, int hh, const char* l )
|
||||
: Fl_Group(xx,yy,ww,hh,l),
|
||||
_patStr(NULL),_typeId(typeId),_btn(NULL),_out(NULL)
|
||||
{
|
||||
_init();
|
||||
type(typeId);
|
||||
pattern_string(patStr);
|
||||
end();
|
||||
}
|
||||
|
||||
Fl_File_Btn::~Fl_File_Btn()
|
||||
{ delete[] _patStr; }
|
||||
|
||||
unsigned Fl_File_Btn::type()
|
||||
{ return _typeId; }
|
||||
|
||||
void Fl_File_Btn::type( unsigned typeId )
|
||||
{
|
||||
switch(typeId)
|
||||
{
|
||||
case kFile_Type_Id:
|
||||
_btn->label("File");
|
||||
_typeId = typeId;
|
||||
break;
|
||||
|
||||
case kDir_Type_Id:
|
||||
_btn->label("Dir");
|
||||
_typeId = typeId;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
const char* Fl_File_Btn::pattern_string()
|
||||
{ return _patStr; }
|
||||
|
||||
void Fl_File_Btn::pattern_string( const char* pat)
|
||||
{
|
||||
delete[] _patStr;
|
||||
if( pat != NULL )
|
||||
{
|
||||
_patStr = new char[ strlen(pat) + 1];
|
||||
strcpy(_patStr,pat);
|
||||
}
|
||||
}
|
||||
|
||||
void Fl_File_Btn::btn_width( int ww )
|
||||
{
|
||||
_btn->resize(_btn->x(),_btn->y(),ww,_btn->h());
|
||||
_out->resize(_btn->x() + _btn->w() + 2, _out->y(), w() - _btn->w() - 2, _out->h());
|
||||
}
|
||||
|
||||
int Fl_File_Btn::btn_width()
|
||||
{ return _btn->w(); }
|
||||
|
||||
void Fl_File_Btn::filename( const char* fn )
|
||||
{ _out->value(fn); _out->redraw(); }
|
||||
|
||||
const char* Fl_File_Btn::filename() const
|
||||
{ return _out->value(); }
|
||||
|
||||
|
||||
void Fl_File_Btn::_s_btn_cb(Fl_Widget* w, void* data)
|
||||
{ ((Fl_File_Btn*)data)->_btn_cb(); }
|
||||
|
||||
void Fl_File_Btn::_btn_cb()
|
||||
{
|
||||
char* fn;
|
||||
if( _typeId == kFile_Type_Id )
|
||||
fn = fl_file_chooser("Select a file",_patStr,_out->value(),0);
|
||||
else
|
||||
fn = fl_dir_chooser("Select a directory",_out->value(),0);
|
||||
|
||||
if( fn != NULL )
|
||||
{
|
||||
_out->value(fn);
|
||||
do_callback(this,user_data());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Fl_File_Btn::_init()
|
||||
{
|
||||
_btn = new Fl_Button(x(),y(),40,h(),_typeId==kFile_Type_Id ? "File" : "Dir");
|
||||
_btn->callback(_s_btn_cb,this);
|
||||
|
||||
_out = new Fl_Output(x() + _btn->w() + 2, y(), w() - _btn->w(), h());
|
||||
|
||||
}
|
47
src/libcmpp/fltk/Fl_File_Btn.h
Normal file
47
src/libcmpp/fltk/Fl_File_Btn.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef Fl_File_Btn_h
|
||||
#define Fl_File_Btn_h
|
||||
|
||||
class Fl_Button;
|
||||
class Fl_Output;
|
||||
|
||||
class Fl_File_Btn : public Fl_Group
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kFile_Type_Id,
|
||||
kDir_Type_Id
|
||||
};
|
||||
|
||||
Fl_File_Btn( int x, int y, int w, int h, const char* l = 0 );
|
||||
|
||||
Fl_File_Btn( unsigned typeId, const char* patStr, int x, int y, int w, int h, const char* l = 0 );
|
||||
virtual ~Fl_File_Btn();
|
||||
|
||||
unsigned type();
|
||||
void type( unsigned typeId );
|
||||
|
||||
const char* pattern_string();
|
||||
void pattern_string( const char* pat);
|
||||
|
||||
void btn_width( int w );
|
||||
int btn_width();
|
||||
|
||||
void filename( const char* fn );
|
||||
const char* filename() const;
|
||||
|
||||
private:
|
||||
char* _patStr;
|
||||
unsigned _typeId;
|
||||
Fl_Button* _btn;
|
||||
Fl_Output* _out;
|
||||
|
||||
static void _s_btn_cb(Fl_Widget* w, void* data);
|
||||
void _btn_cb();
|
||||
|
||||
void _init();
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
273
src/libcmpp/fltk/Fl_Splitter.cpp
Normal file
273
src/libcmpp/fltk/Fl_Splitter.cpp
Normal file
@ -0,0 +1,273 @@
|
||||
// Code based on: http://www.mail-archive.com/fltk@easysw.com/msg04573.html
|
||||
// Lucas Sanner/Ian MacArthur
|
||||
|
||||
#include "Fl_Splitter.h"
|
||||
|
||||
void Fl_HSplitter::draw()
|
||||
{
|
||||
Fl_Group::draw();
|
||||
Fl_Color c = fl_color();
|
||||
fl_color(FL_BLACK);
|
||||
fl_line_style( FL_DOT, 1);
|
||||
|
||||
if(splitFl && Fl::event_button1() != 0)
|
||||
{
|
||||
fl_push_clip(x(), y(), w(), h());
|
||||
|
||||
yPos = Fl::event_y();
|
||||
|
||||
if(Fl::event_y() > h() - (border * 2))
|
||||
yPos = h() - (border * 2);
|
||||
|
||||
if(Fl::event_y() < y() + (border * 2))
|
||||
yPos = y() + (border * 2);
|
||||
|
||||
fl_line( x() + border, yPos - 1, x() + w() - (border*2), yPos - 1 );
|
||||
fl_line( x() + border, yPos , x() + w() - (border*2), yPos );
|
||||
fl_line( x() + border, yPos + 1, x() + w() - (border*2), yPos + 1 );
|
||||
|
||||
/*
|
||||
fl_line(
|
||||
x() + border,
|
||||
yPos,
|
||||
x() + w() - (border*2),
|
||||
yPos );
|
||||
|
||||
fl_line(
|
||||
x() + border,
|
||||
yPos + 1,
|
||||
x() + w() - (border*2),
|
||||
yPos + 1 );
|
||||
*/
|
||||
|
||||
fl_pop_clip();
|
||||
}
|
||||
else
|
||||
{
|
||||
fl_push_clip(x(), y(), w(), h());
|
||||
fl_pop_clip();
|
||||
}
|
||||
|
||||
fl_color(c);
|
||||
fl_line_style(0);
|
||||
}
|
||||
|
||||
int Fl_HSplitter::handle(int e)
|
||||
{
|
||||
int ret = Fl_Group::handle(e);
|
||||
|
||||
switch(e)
|
||||
{
|
||||
case FL_MOVE:
|
||||
|
||||
if(hCtnl - border < Fl::event_y() && Fl::event_y() < hCtnl + border)
|
||||
{
|
||||
fl_cursor(FL_CURSOR_NS);
|
||||
splitFl = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fl_cursor(FL_CURSOR_DEFAULT);
|
||||
splitFl = false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
case FL_PUSH:
|
||||
|
||||
if(Fl::event_button() == FL_LEFT_MOUSE && splitFl)
|
||||
{
|
||||
redraw();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
case FL_RELEASE:
|
||||
|
||||
if(Fl::event_button() == FL_LEFT_MOUSE && splitFl)
|
||||
{
|
||||
c0->resize(x(), y(), w(), yPos - y());
|
||||
hCtnl = yPos;
|
||||
c1->resize(x(),hCtnl, w(), h() - (yPos - y()));
|
||||
|
||||
if( stretchTopFl )
|
||||
init_sizes();
|
||||
|
||||
splitFl = false;
|
||||
redraw();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
case FL_DRAG:
|
||||
|
||||
if(splitFl && Fl::event_state(FL_BUTTON1) != 0)
|
||||
redraw();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
Fl_HSplitter::Fl_HSplitter(int x, int y, int w, int h, int h1, const char *l, bool stretchBotFl)
|
||||
: Fl_Group(x, y, w, h, l)
|
||||
{
|
||||
int h2 = h - h1;
|
||||
|
||||
begin();
|
||||
c0 = new Splitter_Container(x, y, w, h1);
|
||||
//c0->color((Fl_Color) FL_RED);
|
||||
end();
|
||||
|
||||
begin();
|
||||
c1 = new Splitter_Container(x, y + h1, w, h2);
|
||||
//c1->color((Fl_Color) FL_BLUE);
|
||||
end();
|
||||
|
||||
hCtnl = y + h1;
|
||||
splitFl = false;
|
||||
stretchTopFl = !stretchBotFl;
|
||||
border = Fl::box_dy(FL_DOWN_BOX);
|
||||
|
||||
if( stretchTopFl )
|
||||
resizable(c0);
|
||||
}
|
||||
|
||||
void Fl_HSplitter::resize(int x, int y, int w, int h)
|
||||
{
|
||||
Fl_Group::resize(x, y, w, h);
|
||||
|
||||
if( stretchTopFl )
|
||||
{
|
||||
hCtnl = c0->h() + y;
|
||||
yPos = hCtnl;
|
||||
//printf("hCtnl:%i\n",hCtnl);
|
||||
}
|
||||
else
|
||||
{
|
||||
c0->resize(x, y, w, hCtnl - y);
|
||||
c1->resize(x, hCtnl, w, h - (hCtnl - y));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Fl_VSplitter::draw()
|
||||
{
|
||||
Fl_Group::draw();
|
||||
Fl_Color c = fl_color();
|
||||
fl_color(FL_BLACK);
|
||||
fl_line_style( FL_DOT, 1);
|
||||
|
||||
if(splitFl && Fl::event_button1() != 0)
|
||||
{
|
||||
fl_push_clip(x(), y(), w(), h());
|
||||
|
||||
xPos = Fl::event_x();
|
||||
|
||||
if(Fl::event_x() > w() - (border * 2))
|
||||
xPos = w() - (border * 2);
|
||||
|
||||
if(Fl::event_x() < x() + (border * 2))
|
||||
xPos = x() + (border * 2);
|
||||
|
||||
fl_line(xPos - 1, y() + border, xPos - 1, y() + h() - (border * 2));
|
||||
fl_line(xPos, y() + border, xPos, y() + h() - (border * 2));
|
||||
fl_line(xPos + 1, y() + border, xPos + 1, y() + h() - (border * 2));
|
||||
|
||||
fl_pop_clip();
|
||||
}
|
||||
else
|
||||
{
|
||||
fl_push_clip(x(), y(), w(), h());
|
||||
fl_pop_clip();
|
||||
}
|
||||
|
||||
fl_color(c);
|
||||
fl_line_style(0); // restore line style to defaults
|
||||
}
|
||||
|
||||
int Fl_VSplitter::handle(int e)
|
||||
{
|
||||
int ret = Fl_Group::handle(e);
|
||||
|
||||
switch(e)
|
||||
{
|
||||
case FL_MOVE:
|
||||
|
||||
if(Fl::event_x() > wCtn1 - border && Fl::event_x() < wCtn1 + border)
|
||||
{
|
||||
fl_cursor(FL_CURSOR_WE);
|
||||
splitFl = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
fl_cursor(FL_CURSOR_DEFAULT);
|
||||
splitFl = false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
case FL_PUSH:
|
||||
|
||||
if(Fl::event_button() == FL_LEFT_MOUSE && splitFl)
|
||||
{
|
||||
redraw();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
case FL_RELEASE:
|
||||
|
||||
if(Fl::event_button() == FL_LEFT_MOUSE && splitFl)
|
||||
{
|
||||
c0->resize(x(), y(), xPos, h());
|
||||
wCtn1 = xPos;
|
||||
c1->resize(wCtn1, y(), w() - wCtn1, h());
|
||||
splitFl = false;
|
||||
redraw();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
case FL_DRAG:
|
||||
|
||||
if(splitFl && Fl::event_state(FL_BUTTON1) != 0)
|
||||
redraw();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
Fl_VSplitter::Fl_VSplitter(int x, int y, int w, int h, const char *l)
|
||||
: Fl_Group(x, y, w, h, l)
|
||||
{
|
||||
begin();
|
||||
c0 = new Splitter_Container(x, y, w / 2, h);
|
||||
//c0->color((Fl_Color) FL_RED);
|
||||
end();
|
||||
|
||||
begin();
|
||||
c1 = new Splitter_Container(x + (w / 2), y, w / 2, h);
|
||||
//c1->color((Fl_Color) FL_BLUE);
|
||||
end();
|
||||
|
||||
wCtn1 = w / 2;
|
||||
splitFl = false;
|
||||
|
||||
border = Fl::box_dx(FL_DOWN_BOX);
|
||||
|
||||
}
|
||||
|
||||
void Fl_VSplitter::resize_splitter(int x, int y, int w, int h)
|
||||
{
|
||||
resize(x, y, w, h);
|
||||
c0->resize(x, y, wCtn1, h);
|
||||
c1->resize(wCtn1, y, w - wCtn1, h);
|
||||
}
|
||||
|
70
src/libcmpp/fltk/Fl_Splitter.h
Normal file
70
src/libcmpp/fltk/Fl_Splitter.h
Normal file
@ -0,0 +1,70 @@
|
||||
// Code based on: http://www.mail-archive.com/fltk@easysw.com/msg04573.html
|
||||
// Lucas Sanner/Ian MacArthur
|
||||
|
||||
#ifndef Fl_Splitter_h
|
||||
#define Fl_Splitter_h
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Group.H>
|
||||
#include <FL/Fl_Box.H>
|
||||
#include <FL/fl_draw.H>
|
||||
|
||||
|
||||
class Splitter_Container : public Fl_Group
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
Splitter_Container(int x, int y, int w, int h, char *l = NULL)
|
||||
: Fl_Group(x, y, w, h, l)
|
||||
{
|
||||
box(FL_NO_BOX); // do not draw the background
|
||||
}
|
||||
};
|
||||
|
||||
class Fl_HSplitter : public Fl_Group
|
||||
{
|
||||
int hCtnl; // window coord's of the horzontal splitter
|
||||
int border; // splitter divider height
|
||||
int yPos; // window posn where divider was last draw
|
||||
bool splitFl; // set if split cursor is enabled
|
||||
bool stretchTopFl; // set to make top container stretch when splitter is resized
|
||||
//int hh2;
|
||||
|
||||
virtual void draw();
|
||||
|
||||
int handle(int e);
|
||||
|
||||
public:
|
||||
|
||||
Splitter_Container *c0, *c1;
|
||||
|
||||
Fl_HSplitter(int x, int y, int w, int h, int h1, const char *l=NULL, bool stretchBotFl=false);
|
||||
|
||||
virtual void resize(int x, int y, int w, int h);
|
||||
|
||||
};
|
||||
|
||||
|
||||
class Fl_VSplitter : public Fl_Group
|
||||
{
|
||||
|
||||
int wCtn1, border, xPos;
|
||||
bool splitFl;
|
||||
|
||||
void draw();
|
||||
int handle(int e);
|
||||
|
||||
public:
|
||||
|
||||
Splitter_Container *c0, *c1;
|
||||
|
||||
Fl_VSplitter(int x, int y, int w, int h, const char *l = NULL);
|
||||
|
||||
void resize_splitter(int x, int y, int w, int h);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
66
src/libcmpp/fltk/Fl_Vert_Progress.cpp
Normal file
66
src/libcmpp/fltk/Fl_Vert_Progress.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/fl_draw.H>
|
||||
#include <Fl/Fl_Progress.H>
|
||||
#include "Fl_Vert_Progress.h"
|
||||
|
||||
Fl_Vert_Progress::Fl_Vert_Progress(int x, int y, int w, int h, const char* l)
|
||||
: Fl_Progress(x,y,w,h)
|
||||
{
|
||||
}
|
||||
|
||||
// This member function is a slight variation on a verbatim
|
||||
// copy of Fl_Progress.cxx from the FLTK source library.
|
||||
void Fl_Vert_Progress::draw()
|
||||
{
|
||||
int progress; // Size of progress bar...
|
||||
int bx, by, bw, bh; // Box areas...
|
||||
int tx, tw; // Temporary X + width
|
||||
|
||||
// Get the box borders...
|
||||
bx = Fl::box_dx(box());
|
||||
by = Fl::box_dy(box());
|
||||
bw = Fl::box_dw(box());
|
||||
bh = Fl::box_dh(box());
|
||||
|
||||
tx = x() + bx;
|
||||
tw = w() - bw;
|
||||
|
||||
// Draw the progress bar...
|
||||
if (maximum() > minimum())
|
||||
progress = (int)(h() * (value() - minimum()) / (maximum() - minimum()) + 0.5f);
|
||||
else
|
||||
progress = 0;
|
||||
|
||||
// Draw the box and label...
|
||||
if (progress > 0)
|
||||
{
|
||||
Fl_Color c = labelcolor();
|
||||
labelcolor(fl_contrast(labelcolor(), selection_color()));
|
||||
|
||||
fl_push_clip(x(), y() + h() - (progress + by), w(), progress + by);
|
||||
|
||||
draw_box(box(), x(), y(), w(), h(), active_r() ? selection_color() : fl_inactive(selection_color()));
|
||||
|
||||
draw_label(tx, y() + by, tw, h() - bh);
|
||||
|
||||
fl_pop_clip();
|
||||
|
||||
labelcolor(c);
|
||||
|
||||
if (progress<h())
|
||||
{
|
||||
fl_push_clip(x(), y(), w(), h()-progress);
|
||||
|
||||
draw_box(box(), x(), y(), w(), h(), active_r() ? color() : fl_inactive(color()));
|
||||
|
||||
draw_label(tx, y() + by, tw, h() - bh);
|
||||
|
||||
fl_pop_clip();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_box(box(), x(), y(), w(), h(), active_r() ? color() : fl_inactive(color()));
|
||||
draw_label(tx, y() + by, tw, h() - bh);
|
||||
}
|
||||
}
|
14
src/libcmpp/fltk/Fl_Vert_Progress.h
Normal file
14
src/libcmpp/fltk/Fl_Vert_Progress.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef Fl_Vert_Progress_h
|
||||
#define Fl_Vert_Progress_h
|
||||
|
||||
class Fl_Vert_Progress : public Fl_Progress
|
||||
{
|
||||
protected:
|
||||
virtual void draw();
|
||||
public:
|
||||
Fl_Vert_Progress(int x, int y, int w, int h, const char* l=0);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
1546
src/libcmpp/fltk/cmGrFltk.cpp
Normal file
1546
src/libcmpp/fltk/cmGrFltk.cpp
Normal file
File diff suppressed because it is too large
Load Diff
242
src/libcmpp/fltk/cmGrFltk.h
Normal file
242
src/libcmpp/fltk/cmGrFltk.h
Normal file
@ -0,0 +1,242 @@
|
||||
#ifndef cmGrFltk_h
|
||||
#define cmGrFltk_h
|
||||
|
||||
class Fl_Group;
|
||||
class Fl_Output;
|
||||
class Fl_Scrollbar;
|
||||
|
||||
class cmGrDevDrvFltk
|
||||
{
|
||||
public:
|
||||
|
||||
cmGrDevDrvFltk();
|
||||
virtual ~cmGrDevDrvFltk(){}
|
||||
|
||||
|
||||
static bool create( void* user, unsigned w, unsigned h );
|
||||
static void destroy( void* user );
|
||||
|
||||
static void begin_draw( void* arg );
|
||||
static void end_draw( void* arg );
|
||||
static void draw( void* arg, int x, int y );
|
||||
|
||||
static void set_color( void* user, const cmGrColor_t c );
|
||||
static void get_color( void* user, cmGrColor_t* c );
|
||||
|
||||
static void set_font_family( void* user, unsigned fontId );
|
||||
static unsigned get_font_family( void* user );
|
||||
|
||||
static void set_font_style( void* user, unsigned style );
|
||||
static unsigned get_font_style( void* user );
|
||||
|
||||
static void set_font_size( void* user, unsigned size );
|
||||
static unsigned get_font_size( void* user );
|
||||
|
||||
static void set_pen_style( void* user, unsigned styleFlags );
|
||||
static unsigned get_pen_style( void* user );
|
||||
|
||||
static void set_pen_width( void* user, unsigned w );
|
||||
static unsigned get_pen_width( void* user );
|
||||
|
||||
static void draw_line( void* user, int x0, int y0, int x1, int y1 );
|
||||
static void draw_rect( void* user, int x0, int y0, unsigned w, unsigned h );
|
||||
static void fill_rect( void* user, int x0, int y0, unsigned w, unsigned h );
|
||||
static void draw_ellipse( void* user, int x0, int y0, unsigned w, unsigned h );
|
||||
static void fill_ellipse( void* user, int x0, int y0, unsigned w, unsigned h );
|
||||
static void draw_diamond( void* user, int x0, int y0, unsigned w, unsigned h );
|
||||
static void fill_diamond( void* user, int x0, int y0, unsigned w, unsigned h );
|
||||
static void draw_triangle( void* user, int x0, int y0, unsigned w, unsigned h, unsigned dirFlag );
|
||||
static void fill_triangle( void* user, int x0, int y0, unsigned w, unsigned h, unsigned dirFlag );
|
||||
|
||||
static void draw_text( void* user, const char* text, int x, int y );
|
||||
static void draw_text_rot( void* user, const char* text, int x, int y, int angle );
|
||||
static void measure_text( void* user, const char* text, unsigned* w, unsigned* h );
|
||||
|
||||
static void read_image( void* user, unsigned char* p, int x, int y, unsigned w, unsigned h );
|
||||
static void draw_image( void* user, const unsigned char* p, int x, int y, unsigned w, unsigned h );
|
||||
|
||||
bool is_initialized() const;
|
||||
|
||||
cmGrDev_t d;
|
||||
|
||||
private:
|
||||
|
||||
unsigned _fltk_pen_width;
|
||||
unsigned _fltk_pen_style;
|
||||
unsigned _fltk_font_size;
|
||||
unsigned _w;
|
||||
unsigned _h;
|
||||
|
||||
static void _get_font_family_style( unsigned* fontId, unsigned* style );
|
||||
static void _set_font_family_style( void* user, unsigned fontId, unsigned style );
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Canvas Object
|
||||
|
||||
class cmGrViewFltk : public Fl_Widget
|
||||
{
|
||||
public:
|
||||
cmGrViewFltk( cmCtx_t* ctx, cmGrH_t grH, int x, int y, int w, int h );
|
||||
virtual ~cmGrViewFltk();
|
||||
|
||||
virtual int handle(int event);
|
||||
virtual void resize(int x, int y, int w, int h );
|
||||
void setGrH( cmGrH_t grH );
|
||||
|
||||
private:
|
||||
virtual void draw();
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned idx;
|
||||
unsigned fltk_code;
|
||||
char ch;
|
||||
cmGrKeyCodeId_t gr_code;
|
||||
} keyMap_t;
|
||||
|
||||
cmGrH_t _grH;
|
||||
cmGrDevDrvFltk _dd;
|
||||
cmGrDcH_t _dcH;
|
||||
static keyMap_t _keymap[];
|
||||
|
||||
const keyMap_t* _getGrKeyCode( unsigned fltk_code );
|
||||
cmGrKeyCodeId_t _eventKeyCode( );
|
||||
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Container for multiple plots
|
||||
|
||||
class cmGrPageFltk : public Fl_Group
|
||||
{
|
||||
public:
|
||||
cmGrPageFltk( cmCtx_t* ctx, cmGrPgH_t pgH, int x, int y, int w, int h );
|
||||
virtual ~cmGrPageFltk();
|
||||
|
||||
virtual void createView( unsigned vwIdx );
|
||||
|
||||
virtual void destroyView( unsigned vwIdx );
|
||||
|
||||
virtual cmGrDcH_t devCtxHandle();
|
||||
|
||||
virtual cmGrViewFltk* viewWidget( unsigned vwIdx );
|
||||
|
||||
virtual void resize(int x, int y, int w, int h );
|
||||
|
||||
private:
|
||||
virtual void draw();
|
||||
|
||||
cmGrDevDrvFltk _dd;
|
||||
cmCtx_t* _ctx;
|
||||
cmGrPgH_t _pgH;
|
||||
cmGrDcH_t _dcH;
|
||||
cmGrViewFltk** _vwV;
|
||||
unsigned _vwN;
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Contains a single cmGrPageFltk and a control panel
|
||||
|
||||
class cmGrPlotFltk : public Fl_Group
|
||||
{
|
||||
public:
|
||||
cmGrPlotFltk( cmCtx_t* ctx, int x, int y, int w, int h, int rn=1, int cn=1, int textSz=10 );
|
||||
virtual ~cmGrPlotFltk();
|
||||
|
||||
virtual void resize(int x, int y, int w, int h );
|
||||
|
||||
cmGrPgH_t pageHandle();
|
||||
cmGrPlH_t plotHandle();
|
||||
cmGrDcH_t dcHandle();
|
||||
|
||||
virtual void initViews( int rn, int cn );
|
||||
virtual void setStatusText( const cmChar_t* s );
|
||||
|
||||
virtual void on_button( unsigned id );
|
||||
virtual void on_scroll( Fl_Scrollbar* sb, unsigned id );
|
||||
virtual void on_view_create( unsigned viewIdx );
|
||||
virtual void on_view_destroy( unsigned viewIdx );
|
||||
virtual void rpt_local_pt( cmGrH_t grH );
|
||||
virtual void rpt_global_pt( cmGrH_t grH );
|
||||
virtual void on_phys_change( cmGrH_t grH );
|
||||
virtual void on_view_change( cmGrH_t grH );
|
||||
virtual void on_select_change( cmGrH_t grH );
|
||||
virtual void on_focused_plot( cmGrH_t grH );
|
||||
virtual void on_key_event( cmGrH_t grH, unsigned eventFlags, cmGrKeyCodeId_t keycode );
|
||||
virtual bool on_plot_object( cmGrPlotCbArg_t* arg );
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kHBord = 0, // dist between vertical elements (cols)
|
||||
kVBord = 0, // dist between horz elements (rows)
|
||||
kBtnH = 20, // control height
|
||||
kBtnW = 50, // button width
|
||||
kOutW = 100, // output width
|
||||
kLblW = 20, // output label width,
|
||||
kScrD = 20 // scroll bar thickness
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kHScrollId,
|
||||
kVScrollId,
|
||||
kShowAllId,
|
||||
kReportId,
|
||||
kZoomInId,
|
||||
kZoomOutId,
|
||||
kZoomInXId,
|
||||
kZoomInYId,
|
||||
kZoomOutXId,
|
||||
kZoomOutYId,
|
||||
};
|
||||
|
||||
|
||||
cmGrPgH_t _pgH;
|
||||
cmGrPlH_t _plH;
|
||||
|
||||
cmGrPageFltk* _pg;
|
||||
Fl_Group* _ctl_grp;
|
||||
Fl_Group* _usr_grp;
|
||||
Fl_Output* _status; // status text output
|
||||
|
||||
Fl_Scrollbar* _hsb; // scroll bars
|
||||
Fl_Scrollbar* _vsb;
|
||||
|
||||
Fl_Output* _gx; // current global coord display
|
||||
Fl_Output* _gy;
|
||||
|
||||
Fl_Output* _lx; // current local coord display
|
||||
Fl_Output* _ly;
|
||||
|
||||
Fl_Output* _s0x; // seletion point
|
||||
Fl_Output* _s0y;
|
||||
Fl_Output* _s1x;
|
||||
Fl_Output* _s1y;
|
||||
Fl_Output* _sdx;
|
||||
Fl_Output* _sdy;
|
||||
|
||||
int _textSz;
|
||||
|
||||
void _layout();
|
||||
Fl_Group* _create_ctls();
|
||||
void _create_scroll_bars();
|
||||
void _showHideScrollBars();
|
||||
cmGrH_t _getFocusedView();
|
||||
|
||||
// controls callback
|
||||
static void _s_ctl_cb(Fl_Widget* w, long id );
|
||||
|
||||
// plot page callbacks
|
||||
static void _s_cmGrCallback( void* arg, cmGrH_t grH, cmGrCbId_t id, unsigned eventFlags, cmGrKeyCodeId_t keycode );
|
||||
|
||||
// plot object callbacks
|
||||
static bool _s_cmGrPlotObjCbFunc( cmGrPlotCbArg_t* arg );
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
865
src/libcmpp/fltk/cmUiDrvrFltk.cpp
Normal file
865
src/libcmpp/fltk/cmUiDrvrFltk.cpp
Normal file
@ -0,0 +1,865 @@
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Widget.H>
|
||||
#include <FL/Fl_Group.H>
|
||||
#include <FL/Fl_Tabs.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <FL/Fl_Check_Button.H>
|
||||
#include <FL/Fl_Box.H>
|
||||
#include <Fl/Fl_Input.H>
|
||||
#include <Fl/Fl_Value_Input.H>
|
||||
#include <Fl/Fl_Value_Slider.H>
|
||||
#include <Fl/Fl_Progress.H>
|
||||
#include <Fl/Fl_Menu_Button.H>
|
||||
#include <Fl/Fl_Select_Browser.H>
|
||||
#include <Fl/Fl_Text_Display.H>
|
||||
#include <FL/fl_draw.H>
|
||||
|
||||
#include "Fl_File_Btn.h"
|
||||
#include "Fl_Vert_Progress.h"
|
||||
|
||||
#include "cmGlobal.h"
|
||||
#include "cmRpt.h"
|
||||
#include "cmErr.h"
|
||||
#include "cmCtx.h"
|
||||
#include "cmMem.h"
|
||||
#include "cmMallocDebug.h"
|
||||
|
||||
#include "cmRtSysMsg.h"
|
||||
#include "cmUiDrvr.h"
|
||||
#include "cmUiDrvrFltk.h"
|
||||
|
||||
|
||||
cmUiDrvrFltk::cmUiDrvrFltk(cmCtx_t* ctx, Fl_Tabs* tabs, cmUiDriverFunc_t cbFunc, void* cbArg)
|
||||
: _tabs(NULL),_cbFunc(NULL),_cbArgs(NULL),_panels(NULL)
|
||||
{
|
||||
cmErrSetup(&_err,&ctx->rpt,"cmUiDrvrFltk");
|
||||
setBaseWindow(tabs);
|
||||
setCallback(cbFunc,cbArg);
|
||||
}
|
||||
|
||||
void cmUiDrvrFltk::setBaseWindow( Fl_Tabs* tabs )
|
||||
{
|
||||
_tabs = tabs;
|
||||
if( _tabs != NULL )
|
||||
_tabs->callback(_s_tab_cb,this);
|
||||
}
|
||||
|
||||
void cmUiDrvrFltk::setCallback( cmUiDriverFunc_t cbFunc, void* cbArg )
|
||||
{
|
||||
_cbFunc = cbFunc;
|
||||
_cbArgs = cbArg;
|
||||
}
|
||||
|
||||
cmUiDrvrFltk::~cmUiDrvrFltk()
|
||||
{
|
||||
_destroyAllPanels(false);
|
||||
}
|
||||
|
||||
cmUiRC_t cmUiDrvrFltk::cmUiDriverFunc( void* cbArg, const cmUiDriverArg_t* args )
|
||||
{
|
||||
cmUiDrvrFltk* p = (cmUiDrvrFltk*)cbArg;
|
||||
cmUiRC_t rc = kOkUiRC;
|
||||
switch(args->dId)
|
||||
{
|
||||
case kInvalidDId:
|
||||
break;
|
||||
|
||||
case kCreateCtlDId:
|
||||
rc = p->_createCtl(args);
|
||||
break;
|
||||
|
||||
case kDestroyCtlDId:
|
||||
rc = p->_destroyCtl(args->appId,args->panelId,args->usrId,true);
|
||||
break;
|
||||
|
||||
case kSetValDId:
|
||||
rc = p->_setValueCtl(args);
|
||||
break;
|
||||
|
||||
case kEnableDId:
|
||||
rc = p->_enableCtl(args);
|
||||
break;
|
||||
|
||||
//case kDestroyAllDId:
|
||||
//rc = p->_destroyAllPanels(true);
|
||||
//break;
|
||||
|
||||
case kMaxDId:
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
void cmUiDrvrFltk::_insertNewCtl( panel_t* pp, ctl_t* ctl, Fl_Widget* wp, unsigned flags )
|
||||
{
|
||||
ctl->wdgt = wp;
|
||||
|
||||
if( ctl->usrId != cmInvalidId )
|
||||
{
|
||||
ctl->link = pp->ctls;
|
||||
pp->ctls = ctl;
|
||||
wp->callback( _s_ctl_cb, ctl );
|
||||
}
|
||||
|
||||
pp->grp->add(wp);
|
||||
|
||||
|
||||
int align_flags = 0;
|
||||
if( cmIsFlag(flags,kLeftUiFl)) align_flags |= FL_ALIGN_LEFT;
|
||||
if( cmIsFlag(flags,kTopUiFl)) align_flags |= FL_ALIGN_TOP;
|
||||
if( cmIsFlag(flags,kRightUiFl)) align_flags |= FL_ALIGN_RIGHT;
|
||||
if( cmIsFlag(flags,kBottomUiFl)) align_flags |= FL_ALIGN_BOTTOM;
|
||||
if( cmIsFlag(flags,kHCtrUiFl)) align_flags |= FL_ALIGN_CENTER;
|
||||
if( cmIsFlag(flags,kInsideUiFl)) align_flags |= FL_ALIGN_INSIDE;
|
||||
if( cmIsFlag(flags,kVCtrUiFl)) align_flags = cmClrFlag(align_flags,FL_ALIGN_TOP | FL_ALIGN_BOTTOM);
|
||||
|
||||
|
||||
wp->align(align_flags);
|
||||
|
||||
|
||||
int when_flags = 0;
|
||||
if( cmIsFlag(flags,kSendChangeFl)) when_flags |= FL_WHEN_CHANGED;
|
||||
if( cmIsFlag(flags,kSendEnterFl)) when_flags |= FL_WHEN_ENTER_KEY;
|
||||
if( cmIsFlag(flags,kSendFocusFl)) when_flags |= FL_WHEN_RELEASE;
|
||||
if( cmIsFlag(flags,kSendNoChangeFl)) when_flags |= FL_WHEN_NOT_CHANGED;
|
||||
|
||||
if( when_flags != 0 )
|
||||
wp->when(when_flags);
|
||||
}
|
||||
|
||||
bool cmUiDrvrFltk::_hasNoAlignFlags( unsigned flags ) const
|
||||
{
|
||||
return !cmIsFlag(flags, kLeftUiFl | kTopUiFl | kRightUiFl | kBottomUiFl | kVCtrUiFl | kHCtrUiFl );
|
||||
}
|
||||
|
||||
cmUiRC_t cmUiDrvrFltk::_createCtl( const cmUiDriverArg_t* a )
|
||||
{
|
||||
cmUiRC_t rc;
|
||||
panel_t* pp;
|
||||
panel_t* prvPnl;
|
||||
|
||||
// if this is a panel create request
|
||||
if( a->cId == kPanelUiCId )
|
||||
return _createPanel(a);
|
||||
|
||||
// locate the new control's panel
|
||||
if((rc = _findPanel(a->appId,a->panelId,pp,prvPnl)) != kOkUiRC )
|
||||
return rc;
|
||||
|
||||
// allocate the control record
|
||||
ctl_t* ctl ;
|
||||
if( a->usrId == cmInvalidId )
|
||||
ctl = &_dummy;
|
||||
else
|
||||
ctl = cmMemAllocZ(ctl_t,1);
|
||||
|
||||
ctl->cId = a->cId;
|
||||
ctl->pnl = pp;
|
||||
ctl->usrId = a->usrId;
|
||||
ctl->flags = a->flags;
|
||||
|
||||
int x = a->x + pp->x_offs;
|
||||
int y = a->y + pp->y_offs;
|
||||
|
||||
// cache the event callback arg record so that it
|
||||
// does not have to be filled on every callback.
|
||||
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);
|
||||
|
||||
//printf("%i %i %i %i\n",x,y,a->w,a->h);
|
||||
|
||||
switch(a->cId)
|
||||
{
|
||||
case kInvalidUiCId:
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
case kPanelUiCId:
|
||||
break;
|
||||
|
||||
case kBtnUiCId:
|
||||
ctl->u.btn = new Fl_Button(x,y,a->w,a->h,a->sval);
|
||||
_insertNewCtl(pp,ctl,ctl->u.btn,a->flags);
|
||||
ctl->cbArg.flags |= kIvalUiFl;
|
||||
break;
|
||||
|
||||
case kCheckUiCId:
|
||||
ctl->u.chk = new Fl_Check_Button(x,y,a->w,a->h,a->sval);
|
||||
_insertNewCtl(pp,ctl,ctl->u.chk,a->flags);
|
||||
ctl->cbArg.flags |= kIvalUiFl;
|
||||
ctl->u.chk->value(a->ival);
|
||||
break;
|
||||
|
||||
case kMenuBtnUiCId:
|
||||
ctl->u.mbt = new Fl_Menu_Button(x,y,a->w,a->h,a->sval!=NULL ? a->sval : NULL);
|
||||
_insertNewCtl(pp,ctl,ctl->u.mbt,a->flags);
|
||||
ctl->cbArg.flags |= kIvalUiFl;
|
||||
ctl->u.mbt->value(0);
|
||||
break;
|
||||
|
||||
case kListUiCId:
|
||||
ctl->u.lst = new Fl_Select_Browser(x,y,a->w,a->h);
|
||||
_insertNewCtl(pp,ctl,ctl->u.lst,a->flags);
|
||||
ctl->cbArg.flags |= kIvalUiFl;
|
||||
break;
|
||||
|
||||
case kLabelUiCId:
|
||||
{
|
||||
unsigned flags = a->flags;
|
||||
ctl->u.lbl = new Fl_Box(x,y,a->w,a->h);
|
||||
ctl->u.lbl->copy_label(a->sval);
|
||||
if( _hasNoAlignFlags(flags) )
|
||||
flags |= kHCtrUiFl | kInsideUiFl;
|
||||
_insertNewCtl(pp,ctl,ctl->u.lbl,flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case kStringUiCId:
|
||||
{
|
||||
unsigned flags = a->flags;
|
||||
ctl->u.str = new Fl_Input(x,y,a->w/2,a->h);
|
||||
ctl->u.str->copy_label(a->sval);
|
||||
if( _hasNoAlignFlags(flags) )
|
||||
flags |= kRightUiFl;
|
||||
_insertNewCtl(pp,ctl,ctl->u.str,flags);
|
||||
ctl->cbArg.flags |= kSvalUiFl;
|
||||
}
|
||||
break;
|
||||
|
||||
case kConsoleUiCId:
|
||||
{
|
||||
unsigned flags = a->flags;
|
||||
ctl->u.con = new Fl_Text_Display(x,y,a->w,a->h);
|
||||
ctl->u.con->buffer(new Fl_Text_Buffer());
|
||||
ctl->u.con->textsize(12);
|
||||
ctl->u.con->textfont(FL_COURIER);
|
||||
ctl->u.con->copy_label(a->sval);
|
||||
if( _hasNoAlignFlags(flags) )
|
||||
flags |= kRightUiFl;
|
||||
_insertNewCtl(pp,ctl,ctl->u.con,flags);
|
||||
ctl->cbArg.flags |= kSvalUiFl;
|
||||
}
|
||||
break;
|
||||
|
||||
case kSliderUiCId:
|
||||
{
|
||||
unsigned flags = a->flags;
|
||||
int w = a->w;
|
||||
int h = a->h;
|
||||
|
||||
if( cmIsFlag(flags,kHorzUiFl) )
|
||||
{
|
||||
if( _hasNoAlignFlags(flags) )
|
||||
flags |= kRightUiFl;
|
||||
|
||||
w /= 2;
|
||||
|
||||
}
|
||||
|
||||
if( cmIsFlag(flags,kVertUiFl) )
|
||||
{
|
||||
if( _hasNoAlignFlags(flags) )
|
||||
flags |= kTopUiFl | kHCtrUiFl;
|
||||
|
||||
if( a->sval != NULL )
|
||||
{
|
||||
int hh,ww;
|
||||
fl_measure(a->sval,ww,hh);
|
||||
|
||||
if( flags & kTopUiFl )
|
||||
{
|
||||
y += hh;
|
||||
h -= hh;
|
||||
}
|
||||
|
||||
if( flags & kBottomUiFl)
|
||||
h -= hh;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ctl->u.sld = new Fl_Value_Slider(x,y,w,h);
|
||||
ctl->u.sld->copy_label(a->sval);
|
||||
|
||||
|
||||
if( cmIsFlag(flags,kHorzUiFl) )
|
||||
ctl->u.sld->type(FL_HOR_NICE_SLIDER);
|
||||
|
||||
if( cmIsFlag(flags,kVertUiFl) )
|
||||
ctl->u.sld->type(FL_VERT_NICE_SLIDER);
|
||||
|
||||
_insertNewCtl(pp,ctl,ctl->u.sld,flags);
|
||||
|
||||
ctl->cbArg.flags |= kFvalUiFl;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case kNumberUiCId:
|
||||
{
|
||||
unsigned flags = a->flags;
|
||||
ctl->u.num = new Fl_Value_Input(x,y,a->w/2,a->h);
|
||||
ctl->u.num->copy_label(a->sval);
|
||||
if( _hasNoAlignFlags(flags) )
|
||||
flags |= kRightUiFl;
|
||||
|
||||
_insertNewCtl(pp,ctl,ctl->u.num,flags);
|
||||
ctl->cbArg.flags |= kFvalUiFl;
|
||||
ctl->u.num->when(FL_WHEN_ENTER_KEY | FL_WHEN_NOT_CHANGED );
|
||||
}
|
||||
break;
|
||||
|
||||
case kProgressUiCId:
|
||||
{
|
||||
unsigned flags = a->flags;
|
||||
ctl->u.prg = new Fl_Progress(x,y,a->w/2,a->h);
|
||||
ctl->u.prg->copy_label(a->sval);
|
||||
if( _hasNoAlignFlags(flags) )
|
||||
flags |= kRightUiFl;
|
||||
_insertNewCtl(pp,ctl,ctl->u.prg,flags);
|
||||
ctl->u.prg->color( fl_rgb_color((unsigned char)256),fl_rgb_color((unsigned char)128));
|
||||
}
|
||||
break;
|
||||
|
||||
case kMeterUiCId:
|
||||
{
|
||||
unsigned flags = a->flags;
|
||||
if( cmIsFlag(flags,kVertUiFl) )
|
||||
{
|
||||
ctl->u.mtr = new Fl_Vert_Progress(x,y,a->w/2,a->h);
|
||||
ctl->u.mtr->color( fl_rgb_color((unsigned char)256),fl_rgb_color((unsigned char)128));
|
||||
}
|
||||
else
|
||||
{
|
||||
ctl->u.mtr = new Fl_Progress(x,y,a->w,a->h);
|
||||
ctl->u.mtr->color( fl_rgb_color((unsigned char)256),fl_rgb_color((unsigned char)128));
|
||||
}
|
||||
|
||||
ctl->u.mtr->copy_label(a->sval);
|
||||
|
||||
if( _hasNoAlignFlags(flags) )
|
||||
flags |= kRightUiFl;
|
||||
_insertNewCtl(pp,ctl,ctl->u.mtr,flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case kFilenameUiCId:
|
||||
case kDirUiCId:
|
||||
{
|
||||
unsigned flags = a->cId==kDirUiCId ? Fl_File_Btn::kDir_Type_Id : Fl_File_Btn::kFile_Type_Id;
|
||||
ctl->u.fnb = new Fl_File_Btn(flags,"",x,y,a->w,a->h,a->sval);
|
||||
flags = a->flags;
|
||||
if( _hasNoAlignFlags(flags) )
|
||||
flags |= kRightUiFl;
|
||||
_insertNewCtl(pp,ctl,ctl->u.fnb,flags);
|
||||
ctl->cbArg.flags |= kSvalUiFl;
|
||||
}
|
||||
break;
|
||||
|
||||
case kMaxUiCId:
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
pp->grp->redraw();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
cmUiRC_t cmUiDrvrFltk::_setValueCtl( const cmUiDriverArg_t* a )
|
||||
{
|
||||
cmUiRC_t rc;
|
||||
panel_t* pp = NULL;
|
||||
panel_t* prvPnl = NULL;
|
||||
ctl_t* ctl = NULL;
|
||||
ctl_t* prvCtl = NULL;
|
||||
|
||||
if((rc = _findPanel(a->appId,a->panelId,pp,prvPnl)) != kOkUiRC )
|
||||
return rc;
|
||||
|
||||
if((rc= _findCtl(pp, a->usrId, ctl, prvCtl )) != kOkUiRC )
|
||||
return rc;
|
||||
|
||||
|
||||
switch( a->cId )
|
||||
{
|
||||
case kInvalidUiCId:
|
||||
break;
|
||||
|
||||
case kPanelUiCId:
|
||||
break;
|
||||
|
||||
case kBtnUiCId:
|
||||
if( cmIsFlag(a->flags,kLblUiFl) )
|
||||
ctl->u.btn->copy_label(a->sval);
|
||||
break;
|
||||
|
||||
case kCheckUiCId:
|
||||
switch( a->flags & (kLblUiFl | kValUiFl) )
|
||||
{
|
||||
case kValUiFl: ctl->u.chk->value(a->ival); break;
|
||||
case kLblUiFl: ctl->u.chk->copy_label(a->sval); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case kMenuBtnUiCId:
|
||||
switch( a->flags & (kAppendUiFl | kClearUiFl | kValUiFl) )
|
||||
{
|
||||
case kValUiFl:
|
||||
if( a->ival < ctl->u.mbt->size() )
|
||||
{
|
||||
ctl->u.mbt->value(a->ival);
|
||||
if( ctl->u.mbt->mvalue() != NULL)
|
||||
ctl->u.mbt->copy_label( ctl->u.mbt->mvalue()->label());
|
||||
}
|
||||
break;
|
||||
|
||||
case kClearUiFl:
|
||||
ctl->u.mbt->clear();
|
||||
ctl->u.mbt->copy_label("");
|
||||
break;
|
||||
|
||||
case kAppendUiFl:
|
||||
{
|
||||
int n;
|
||||
ctl->u.mbt->add( a->sval,0,ctl->u.mbt->callback(),ctl->u.mbt->user_data(),0);
|
||||
n = ctl->u.mbt->size();
|
||||
if( (n) == 2 )
|
||||
{
|
||||
|
||||
ctl->u.mbt->value(0);
|
||||
if( ctl->u.mbt->mvalue() != NULL)
|
||||
{
|
||||
const char* s = ctl->u.mbt->mvalue()->label();
|
||||
ctl->u.mbt->copy_label( s);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case kListUiCId:
|
||||
switch( a->flags & (kAppendUiFl | kClearUiFl | kValUiFl) )
|
||||
{
|
||||
case kValUiFl: ctl->u.lst->value(a->ival); break;
|
||||
case kAppendUiFl: ctl->u.lst->add( a->sval ); break;
|
||||
case kClearUiFl: ctl->u.lst->clear(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case kLabelUiCId:
|
||||
ctl->u.str->value(a->sval);
|
||||
break;
|
||||
|
||||
case kStringUiCId:
|
||||
switch( a->flags & (kLblUiFl | kValUiFl) )
|
||||
{
|
||||
case kValUiFl: ctl->u.str->value(a->sval); break;
|
||||
case kLblUiFl: ctl->u.str->copy_label(a->sval); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case kConsoleUiCId:
|
||||
switch( a->flags & (kLblUiFl | kValUiFl) )
|
||||
{
|
||||
case kValUiFl: if(a->sval!=NULL) ctl->u.con->insert(a->sval); break;
|
||||
case kLblUiFl: ctl->u.str->copy_label(a->sval); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case kSliderUiCId:
|
||||
case kNumberUiCId:
|
||||
{
|
||||
Fl_Valuator* vp = static_cast<Fl_Valuator*>(ctl->wdgt);
|
||||
|
||||
// Correct for problem where the vertical slider values go up as the
|
||||
// slider knob is dragged down.
|
||||
bool invertFl = a->cId == kSliderUiCId && cmIsFlag(ctl->flags,kVertUiFl);
|
||||
|
||||
switch(a->flags & (kNumMask | kLblUiFl | kMinUiFl | kMaxUiFl))
|
||||
{
|
||||
case kLblUiFl: ctl->u.num->copy_label(a->sval); break;
|
||||
case kValUiFl: vp->value(a->fval); break;
|
||||
case kIncUiFl: vp->step(a->fval); break;
|
||||
case kMinUiFl: invertFl ? vp->maximum(a->fval) : vp->minimum(a->fval); break;
|
||||
case kMaxUiFl: invertFl ? vp->minimum(a->fval) : vp->maximum(a->fval); break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kProgressUiCId:
|
||||
switch( a->flags & (kLblUiFl | kValUiFl | kMinUiFl | kMaxUiFl) )
|
||||
{
|
||||
case kValUiFl: ctl->u.prg->value(a->ival); break;
|
||||
case kLblUiFl: ctl->u.prg->copy_label(a->sval); break;
|
||||
case kMinUiFl: ctl->u.prg->minimum(a->ival); break;
|
||||
case kMaxUiFl: ctl->u.prg->maximum(a->ival); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case kMeterUiCId:
|
||||
switch( a->flags & (kLblUiFl | kValUiFl | kMinUiFl | kMaxUiFl) )
|
||||
{
|
||||
case kValUiFl: ctl->u.mtr->value(a->ival); ctl->u.mtr->redraw(); break;
|
||||
case kLblUiFl: ctl->u.mtr->copy_label(a->sval); break;
|
||||
case kMinUiFl: ctl->u.prg->minimum(a->ival); break;
|
||||
case kMaxUiFl: ctl->u.prg->maximum(a->ival); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case kFilenameUiCId:
|
||||
case kDirUiCId:
|
||||
switch(a->flags & (kFnMask | kValUiFl | kFnPatUiFl | kFnDirUiFl) )
|
||||
{
|
||||
case kValUiFl:
|
||||
ctl->u.fnb->filename(a->sval);
|
||||
break;
|
||||
case kFnPatUiFl: ctl->u.fnb->pattern_string(a->sval); break;
|
||||
case kFnDirUiFl:
|
||||
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 );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case kMaxUiCId:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
// echo the result back to the UI
|
||||
//if( cmIsFlag(a->flags,kValUiFl|kAppendUiFl) )
|
||||
// _cbFunc(_cbArgs,a);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
cmUiRC_t cmUiDrvrFltk::_enableCtl( const cmUiDriverArg_t* a )
|
||||
{
|
||||
cmUiRC_t rc;
|
||||
panel_t* pp = NULL;
|
||||
panel_t* prvPnl = NULL;
|
||||
ctl_t* ctl = NULL;
|
||||
ctl_t* prvCtl = NULL;
|
||||
|
||||
if((rc = _findPanel(a->appId,a->panelId,pp,prvPnl)) != kOkUiRC )
|
||||
return rc;
|
||||
|
||||
if((rc= _findCtl(pp, a->usrId, ctl, prvCtl )) != kOkUiRC )
|
||||
return rc;
|
||||
|
||||
if( a->ival )
|
||||
ctl->wdgt->activate();
|
||||
else
|
||||
ctl->wdgt->deactivate();
|
||||
|
||||
_doCb(ctl,kEnableDId,0);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
cmUiRC_t cmUiDrvrFltk::_destroyCtl( unsigned appId, unsigned panelId, unsigned usrId, bool deleteWindowEleFlag )
|
||||
{
|
||||
cmUiRC_t rc = kOkUiRC;
|
||||
|
||||
panel_t* pp = NULL;
|
||||
panel_t* prvPnl = NULL;
|
||||
|
||||
// locate the panel assoc'd with the ctl
|
||||
if((rc = _findPanel(appId,panelId,pp,prvPnl,true)) != kOkUiRC )
|
||||
return rc;
|
||||
|
||||
// if the panel is the ctl to delete ...
|
||||
if( usrId == pp->usrId )
|
||||
{
|
||||
// ... unlink the panel
|
||||
if( prvPnl!=NULL)
|
||||
prvPnl->link = pp->link;
|
||||
else
|
||||
{
|
||||
assert(_panels == pp );
|
||||
_panels = pp->link;
|
||||
}
|
||||
}
|
||||
|
||||
return _destroyCtl(pp,usrId,deleteWindowEleFlag);
|
||||
}
|
||||
|
||||
cmUiRC_t cmUiDrvrFltk::_destroyCtl( panel_t* pp, unsigned usrId, bool deleteWindowEleFlag )
|
||||
{
|
||||
cmUiRC_t rc = kOkUiRC;
|
||||
ctl_t* ctl = NULL;
|
||||
ctl_t* prvCtl = NULL;
|
||||
|
||||
// if the panel is the ctl to delete
|
||||
if( usrId == pp->usrId )
|
||||
{
|
||||
return _destroyPanel(pp,deleteWindowEleFlag);
|
||||
}
|
||||
|
||||
// locate the control on the panel
|
||||
if((rc = _findCtl(pp,usrId,ctl,prvCtl,true)) != kOkUiRC )
|
||||
return rc;
|
||||
|
||||
// unlink the control
|
||||
if( prvCtl!=NULL)
|
||||
prvCtl->link = ctl->link;
|
||||
else
|
||||
{
|
||||
assert( pp->ctls == ctl );
|
||||
pp->ctls = ctl->link;
|
||||
}
|
||||
|
||||
// delete the window element
|
||||
if( deleteWindowEleFlag)
|
||||
delete ctl->wdgt;
|
||||
|
||||
// release the control recd
|
||||
cmMemFree(ctl);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
cmUiRC_t cmUiDrvrFltk::_createPanel( const cmUiDriverArg_t* a )
|
||||
{
|
||||
int tx,ty,tw,th;
|
||||
_tabs->client_area(tx,ty,tw,th);
|
||||
panel_t* pnl = cmMemAllocZ(panel_t,1);
|
||||
|
||||
pnl->drvr = this;
|
||||
pnl->grp = new Fl_Group(tx,ty,tw,th,a->sval);
|
||||
pnl->grp->user_data(pnl);
|
||||
pnl->appId = a->appId;
|
||||
pnl->usrId = a->usrId;
|
||||
pnl->x_offs = tx + 2;
|
||||
pnl->y_offs = ty + 2;
|
||||
pnl->link = _panels;
|
||||
_panels = pnl;
|
||||
|
||||
pnl->grp->end();
|
||||
|
||||
if( cmIsFlag(a->flags,kPrependUiFl) )
|
||||
_tabs->insert(*pnl->grp,0);
|
||||
else
|
||||
_tabs->add(pnl->grp);
|
||||
|
||||
// cache the event callback arg record so that it
|
||||
// does not have to be filled on every callback.
|
||||
cmUiDriverArgSetup(&pnl->cbArg,a->hdr.rtSubIdx,kUiDrvrSelRtId,kSetValDId,a->appId,a->usrId,a->usrId,kPanelUiCId,kIvalUiFl,0,0,NULL,tx,ty,tw,th);
|
||||
|
||||
|
||||
_tabs->redraw();
|
||||
|
||||
return kOkUiRC;
|
||||
}
|
||||
|
||||
cmUiRC_t cmUiDrvrFltk::_destroyAllPanels( bool deleteWindowEleFlag )
|
||||
{
|
||||
cmUiRC_t rc = kOkUiRC;
|
||||
|
||||
while( _panels != NULL )
|
||||
{
|
||||
cmUiRC_t rc0;
|
||||
if((rc0 = _destroyCtl(_panels->appId,_panels->usrId,_panels->usrId,deleteWindowEleFlag)) != kOkUiRC )
|
||||
rc = rc0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
cmUiRC_t cmUiDrvrFltk::_destroyPanel(panel_t* pp, bool deleteWindowEleFlag)
|
||||
{
|
||||
cmUiRC_t rc = kOkUiRC;
|
||||
|
||||
// delete the FLTK panel itself
|
||||
if( deleteWindowEleFlag )
|
||||
{
|
||||
delete pp->grp;
|
||||
deleteWindowEleFlag = false;
|
||||
}
|
||||
|
||||
while( pp->ctls != NULL )
|
||||
{
|
||||
cmUiRC_t rc0;
|
||||
|
||||
if((rc0 = _destroyCtl(pp,pp->ctls->usrId,deleteWindowEleFlag)) != kOkUiRC )
|
||||
rc = rc0;
|
||||
}
|
||||
|
||||
cmMemFree(pp);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
cmUiRC_t cmUiDrvrFltk::_findPanel( unsigned appId, unsigned usrId, panel_t*& ppRef, panel_t*& prvPnl, bool errFl )
|
||||
{
|
||||
ppRef = NULL;
|
||||
prvPnl = NULL;
|
||||
|
||||
panel_t* pp = _panels;
|
||||
for(; pp!=NULL; pp=pp->link)
|
||||
{
|
||||
if(pp->appId==appId && pp->usrId==usrId )
|
||||
{
|
||||
ppRef = pp;
|
||||
return kOkUiRC;
|
||||
}
|
||||
prvPnl = pp;
|
||||
}
|
||||
if( errFl )
|
||||
cmErrMsg(&_err,kPanelNotFoundUiRC,"Panel not found for id=%i.",usrId);
|
||||
|
||||
return kPanelNotFoundUiRC;
|
||||
}
|
||||
|
||||
cmUiRC_t cmUiDrvrFltk::_findCtl( panel_t* pp, unsigned usrId, ctl_t*& ctlRef, ctl_t*& prvCtlRef, bool errFl )
|
||||
{
|
||||
ctlRef = NULL;
|
||||
prvCtlRef = NULL;
|
||||
ctl_t* cp = pp->ctls;
|
||||
for(; cp!=NULL; cp=cp->link)
|
||||
{
|
||||
if( cp->usrId == usrId )
|
||||
{
|
||||
ctlRef = cp;
|
||||
return kOkUiRC;
|
||||
}
|
||||
|
||||
prvCtlRef = cp;
|
||||
}
|
||||
if( errFl )
|
||||
cmErrMsg(&_err,kCtlNotFoundUiRC,"Control %i not found in panel %i.",usrId,pp->usrId);
|
||||
|
||||
return kCtlNotFoundUiRC;
|
||||
}
|
||||
|
||||
void cmUiDrvrFltk::_doCb( ctl_t* ctl, cmUiDId_t dId, unsigned flags )
|
||||
{
|
||||
cmUiDriverArg_t* a = &ctl->cbArg;
|
||||
unsigned orgFlags = a->flags;
|
||||
a->flags |= flags;
|
||||
a->dId = dId;
|
||||
|
||||
_cbFunc(_cbArgs,&ctl->cbArg);
|
||||
|
||||
a->flags = orgFlags;
|
||||
a->dId = kInvalidDId;
|
||||
}
|
||||
|
||||
void cmUiDrvrFltk::_s_ctl_cb(Fl_Widget* wp, void* arg )
|
||||
{
|
||||
ctl_t* ctl = (ctl_t*)arg;
|
||||
cmUiDrvrFltk* p = ctl->pnl->drvr;
|
||||
cmUiDriverArg_t* a = &ctl->cbArg;
|
||||
bool callbackFl = true;
|
||||
unsigned flags = kValUiFl;
|
||||
|
||||
switch( ctl->cId )
|
||||
{
|
||||
case kInvalidUiCId:
|
||||
assert(0);
|
||||
callbackFl = false;
|
||||
break;
|
||||
|
||||
case kPanelUiCId:
|
||||
callbackFl = false;
|
||||
break;
|
||||
|
||||
case kBtnUiCId:
|
||||
break;
|
||||
|
||||
case kCheckUiCId:
|
||||
a->ival = ctl->u.chk->value();
|
||||
flags |= kIvalUiFl;
|
||||
break;
|
||||
|
||||
case kMenuBtnUiCId:
|
||||
if( ctl->u.mbt->mvalue() != NULL && ctl->u.mbt->mvalue()->label() != NULL )
|
||||
ctl->u.mbt->copy_label(ctl->u.mbt->mvalue()->label());
|
||||
a->ival = ctl->u.mbt->value();
|
||||
flags |= kIvalUiFl;
|
||||
break;
|
||||
|
||||
case kListUiCId:
|
||||
a->ival = ctl->u.lst->value() - 1;
|
||||
flags |= kIvalUiFl;
|
||||
break;
|
||||
|
||||
case kLabelUiCId:
|
||||
callbackFl = false;
|
||||
break;
|
||||
|
||||
case kStringUiCId:
|
||||
a->sval = ctl->u.str->value();
|
||||
flags |= kSvalUiFl;
|
||||
break;
|
||||
|
||||
case kConsoleUiCId:
|
||||
callbackFl = false;
|
||||
break;
|
||||
|
||||
case kSliderUiCId:
|
||||
a->fval = ctl->u.sld->value();
|
||||
flags |= kFvalUiFl;
|
||||
break;
|
||||
|
||||
case kNumberUiCId:
|
||||
a->fval = ctl->u.num->value();
|
||||
flags |= kFvalUiFl;
|
||||
break;
|
||||
|
||||
case kProgressUiCId:
|
||||
callbackFl = false;
|
||||
break;
|
||||
|
||||
case kMeterUiCId:
|
||||
callbackFl = false;
|
||||
break;
|
||||
|
||||
case kFilenameUiCId:
|
||||
a->sval = ctl->u.fnb->filename();
|
||||
flags |= kSvalUiFl;
|
||||
break;
|
||||
|
||||
case kDirUiCId:
|
||||
a->sval = ctl->u.fnb->filename();
|
||||
flags |= kSvalUiFl;
|
||||
break;
|
||||
|
||||
case kMaxUiCId:
|
||||
callbackFl = false;
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if( callbackFl )
|
||||
p->_doCb(ctl,kSetValDId,flags);
|
||||
|
||||
}
|
||||
|
||||
void cmUiDrvrFltk::_s_tab_cb(Fl_Widget* wp, void* arg )
|
||||
{
|
||||
cmUiDrvrFltk* p = (cmUiDrvrFltk*)arg;
|
||||
Fl_Widget* w = p->_tabs->value();
|
||||
|
||||
panel_t* pp = p->_panels;
|
||||
for(; pp!=NULL; pp=pp->link)
|
||||
{
|
||||
// if this is the panel being selected then send a 1 otherwise send a 0.
|
||||
pp->cbArg.flags = cmSetFlag(pp->cbArg.flags, kIvalUiFl );
|
||||
pp->cbArg.dId = kSetValDId;
|
||||
pp->cbArg.ival = w->user_data() == pp->grp->user_data();
|
||||
|
||||
p->_cbFunc(p->_cbArgs,&pp->cbArg);
|
||||
|
||||
pp->cbArg.flags = cmClrFlag(pp->cbArg.flags, kIvalUiFl );
|
||||
pp->cbArg.dId = kInvalidDId;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
99
src/libcmpp/fltk/cmUiDrvrFltk.h
Normal file
99
src/libcmpp/fltk/cmUiDrvrFltk.h
Normal file
@ -0,0 +1,99 @@
|
||||
#ifndef cmUiDrvrFltk_h
|
||||
#define cmUiDrvrFltk_h
|
||||
|
||||
class Fl_Tabs;
|
||||
class Fl_Widget;
|
||||
class Fl_Button;
|
||||
class Fl_Check_Button;
|
||||
class Fl_Menu_Button;
|
||||
class Fl_Select_Browser;
|
||||
class Fl_Box;
|
||||
class Fl_Input;
|
||||
class Fl_Value_Input;
|
||||
class Fl_Value_Slider;
|
||||
class Fl_Progress;
|
||||
class Fl_Vert_Progress;
|
||||
class Fl_File_Btn;
|
||||
class Fl_Text_Display;
|
||||
|
||||
class cmUiDrvrFltk
|
||||
{
|
||||
public:
|
||||
|
||||
cmUiDrvrFltk(cmCtx_t* ctx, Fl_Tabs* tabs, cmUiDriverFunc_t cbFunc, void* cbArg);
|
||||
virtual ~cmUiDrvrFltk();
|
||||
|
||||
void setBaseWindow( Fl_Tabs* tabs );
|
||||
void setCallback( cmUiDriverFunc_t cbFunc, void* cbArg );
|
||||
|
||||
static cmUiRC_t cmUiDriverFunc( void* arg, const cmUiDriverArg_t* a );
|
||||
|
||||
private:
|
||||
struct panel_str;
|
||||
|
||||
typedef struct ctl_str
|
||||
{
|
||||
cmUiCId_t cId; // control type id
|
||||
unsigned usrId; // user id
|
||||
unsigned flags; // flags from this controls create call.
|
||||
struct panel_str* pnl; // parent panel
|
||||
Fl_Widget* wdgt; // this controls FLTK wdgt ptr
|
||||
cmUiDriverArg_t cbArg; // cached callback arg. recd used by this ctl
|
||||
struct ctl_str* link; // panel.ctls list link
|
||||
|
||||
union
|
||||
{
|
||||
Fl_Button* btn;
|
||||
Fl_Check_Button* chk;
|
||||
Fl_Menu_Button* mbt;
|
||||
Fl_Select_Browser* lst;
|
||||
Fl_Box* lbl;
|
||||
Fl_Input* str;
|
||||
Fl_Text_Display* con;
|
||||
Fl_Value_Input* num;
|
||||
Fl_Value_Slider* sld;
|
||||
Fl_Progress* prg;
|
||||
Fl_Progress* mtr;
|
||||
Fl_File_Btn* fnb;
|
||||
} u;
|
||||
} ctl_t;
|
||||
|
||||
typedef struct panel_str
|
||||
{
|
||||
cmUiDrvrFltk* drvr; // parent driver object
|
||||
Fl_Group* grp; // panel Widget
|
||||
unsigned appId; // id of the app. this panel serves
|
||||
unsigned usrId; // panels id
|
||||
int x_offs; // left control border
|
||||
int y_offs; // top control border
|
||||
ctl_t* ctls; // this panels control list
|
||||
cmUiDriverArg_t cbArg; // cached callback arg recd used by this ctl
|
||||
struct panel_str* link; // links used by _panels
|
||||
} panel_t;
|
||||
|
||||
cmErr_t _err; //
|
||||
Fl_Tabs* _tabs; // Fl_Tabs Widget containing the panels
|
||||
cmUiDriverFunc_t _cbFunc; // application event callback function
|
||||
void* _cbArgs; //
|
||||
panel_t* _panels; // panel list
|
||||
ctl_t _dummy; //
|
||||
|
||||
void _insertNewCtl( panel_t* pp, ctl_t* ctl, Fl_Widget* wp, unsigned flags );
|
||||
bool _hasNoAlignFlags( unsigned flags ) const;
|
||||
cmUiRC_t _createCtl( const cmUiDriverArg_t* a );
|
||||
cmUiRC_t _destroyCtl( unsigned appId, unsigned panelId, unsigned usrId, bool deleteWindowEleFlag );
|
||||
cmUiRC_t _destroyCtl( panel_t* pp, unsigned usrId, bool deleteWindowEleFlag );
|
||||
cmUiRC_t _createPanel( const cmUiDriverArg_t* a );
|
||||
cmUiRC_t _setValueCtl( const cmUiDriverArg_t* a );
|
||||
cmUiRC_t _enableCtl( const cmUiDriverArg_t* a );
|
||||
cmUiRC_t _destroyAllPanels( bool deleteWindowEleFl );
|
||||
cmUiRC_t _destroyPanel(panel_t* pp, bool deleteWindowEleFl );
|
||||
cmUiRC_t _findPanel( unsigned appId, unsigned usrId, panel_t*& ppRef, panel_t*& prvPnlRef, bool errFl=true );
|
||||
cmUiRC_t _findCtl( panel_t* pp, unsigned usrId, ctl_t*& ctlRef, ctl_t*& prvCtlRef, bool errFl=true );
|
||||
void _doCb( ctl_t* ctl, cmUiDId_t dId, unsigned flags );
|
||||
|
||||
static void _s_ctl_cb(Fl_Widget* wp, void* data );
|
||||
static void _s_tab_cb(Fl_Widget* wp, void* data );
|
||||
};
|
||||
|
||||
#endif
|
11
src/tlCtl/Makefile.am
Normal file
11
src/tlCtl/Makefile.am
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
tlCtlSRC = src/tlCtl/cmdIf.h src/tlCtl/cmdIf.cpp
|
||||
tlCtlSRC += src/tlCtl/gvHashFunc.h src/tlCtl/gvHashFunc.cpp
|
||||
tlCtlSRC += src/tlCtl/cmGrTlFltk.h src/tlCtl/cmGrTlFltk.cpp
|
||||
tlCtlSRC += src/tlCtl/cmGrScFltk.h src/tlCtl/cmGrScFltk.cpp
|
||||
tlCtlSRC += src/tlCtl/cmGrTksbFltk.h src/tlCtl/cmGrTksbFltk.cpp
|
||||
tlCtlSRC += src/tlCtl/cmGrTksrFltk.h src/tlCtl/cmGrTksrFltk.cpp
|
||||
tlCtlSRC += src/tlCtl/cmGr2dFltk.h src/tlCtl/cmGr2dFltk.cpp
|
||||
|
||||
tlCtlSRC += src/tlCtl/tlCtl.h src/tlCtl/tlCtl.cpp
|
148
src/tlCtl/cmGr2dFltk.cpp
Normal file
148
src/tlCtl/cmGr2dFltk.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
#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 "cmGr.h"
|
||||
#include "cmGrDevCtx.h"
|
||||
#include "cmGrPlot.h"
|
||||
#include "cmGrPage.h"
|
||||
#include "cmGrFltk.h"
|
||||
#include "cmGr2dFltk.h"
|
||||
|
||||
|
||||
cmGr2dFltk::cmGr2dFltk(cmCtx_t* ctx, Fl_Menu_Bar* menuBar, int x, int y, int w, int h)
|
||||
: cmGrPlotFltk(ctx,x,y,w,h),
|
||||
_x(0),_y(0),_radius(0),_angle(0),
|
||||
_objId(0)
|
||||
{
|
||||
cmErrSetup(&_err,&ctx->rpt,"cmGr2dFltk");
|
||||
|
||||
if( cmGrPageIsValid(pageHandle()) == false )
|
||||
return;
|
||||
|
||||
initViews(1,1);
|
||||
|
||||
unsigned vwIdx = 0;
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx);
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
cmGrVExt_t limExt;
|
||||
|
||||
cmGrVExtSetD(&limExt,-kWidth,-kHeight,kWidth, kHeight);
|
||||
|
||||
cmGrObjSetWorldExt( cvH, cmGrRootObjH(cvH), &limExt );
|
||||
cmGrObjSetWorldLimitExt(cvH, cmGrRootObjH(cvH), &limExt, kLeftGrFl | kRightGrFl | kTopGrFl | kBottomGrFl );
|
||||
|
||||
_createObj();
|
||||
|
||||
cmGrSetViewExtentsE( cvH, &limExt );
|
||||
|
||||
}
|
||||
|
||||
cmGr2dFltk::~cmGr2dFltk()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool cmGr2dFltk::on_plot_object( cmGrPlotCbArg_t* arg )
|
||||
{
|
||||
if( arg->selId==kEventCbSelGrPlId && cmIsFlag(arg->eventFlags,kMsDragGrFl ) )
|
||||
{
|
||||
cmGrVExt_t vext;
|
||||
cmGrPlotObjVExt(arg->objH,&vext);
|
||||
//cmGrVExtPrint("",&vext);
|
||||
_x = cmGrVExtMinX(&vext);
|
||||
_y = cmGrVExtMinY(&vext);
|
||||
_radius = sqrtf(_x*_x + _y*_y)/kWidth;
|
||||
_angle = -( atan2f(_y,_x) - M_PI/2.0);
|
||||
|
||||
if( _angle < 0 )
|
||||
_angle += 2.0 * M_PI;
|
||||
|
||||
_angle = 360.0f * _angle / (2.0*M_PI);
|
||||
|
||||
setStatusText(cmTsPrintfS("r:%f angle:%f",_radius,_angle));
|
||||
|
||||
callback()(this,user_data());
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
double cmGr2dFltk::x() const
|
||||
{ return _x; }
|
||||
|
||||
double cmGr2dFltk::y() const
|
||||
{ return _y; }
|
||||
|
||||
double cmGr2dFltk::radius() const
|
||||
{ return _radius; }
|
||||
|
||||
double cmGr2dFltk::angle() const
|
||||
{ return _angle; }
|
||||
|
||||
void cmGr2dFltk::_createObj()
|
||||
{
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
unsigned vwIdx = 0;
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx );
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t objH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjTypeId_t objTypeId = kRectGrPlId;
|
||||
cmReal_t x = 0;
|
||||
cmReal_t y = 0;
|
||||
cmReal_t w = 0;
|
||||
cmReal_t h = 0;
|
||||
unsigned flags = 0; //kNoDragGrPlFl;
|
||||
cmGrVExt_t* wext = NULL;
|
||||
|
||||
if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags | kNoDragGrPlFl, x, y, w, h, NULL, wext ) != kOkGrPlRC )
|
||||
{
|
||||
cmErrMsg(&_err,kCreateObjRC,"Plot origin object create failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
cmGrPlotObjSetPhysExt(objH, -2, -2, 2, 2 );
|
||||
cmGrPlotObjSetFontSize(objH,8);
|
||||
}
|
||||
|
||||
objH = cmGrPlObjNullHandle;
|
||||
|
||||
if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, NULL, wext ) != kOkGrPlRC )
|
||||
{
|
||||
cmErrMsg(&_err,kCreateObjRC,"Plot object create failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
//unsigned f = 0 ? (kNorthJsGrFl | kTopJsGrFl) : (kSouthJsGrFl | kBottomJsGrFl);
|
||||
//cmGrPlotObjSetLabelAttr( objH, f | kWestJsGrFl | kTopJsGrFl | kRightJsGrFl, 0, kBlackGrId );
|
||||
cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kGreenGrId );
|
||||
cmGrPlotObjSetPhysExt(objH, -4, -4, 4, 4 );
|
||||
cmGrPlotObjSetFontSize(objH,8);
|
||||
}
|
||||
|
||||
}
|
||||
|
44
src/tlCtl/cmGr2dFltk.h
Normal file
44
src/tlCtl/cmGr2dFltk.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef cmGr2dFltk_h
|
||||
#define cmGr2dFltk_h
|
||||
|
||||
class Fl_Menu_Bar;
|
||||
|
||||
class cmGr2dFltk : public cmGrPlotFltk
|
||||
{
|
||||
public:
|
||||
cmGr2dFltk(cmCtx_t* ctx, Fl_Menu_Bar* menuBar, int x, int y, int w, int h);
|
||||
|
||||
virtual ~cmGr2dFltk();
|
||||
|
||||
virtual bool on_plot_object( cmGrPlotCbArg_t* arg );
|
||||
|
||||
double x() const;
|
||||
double y() const;
|
||||
double radius() const;
|
||||
double angle() const;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kWidth = 100,
|
||||
kHeight = 100
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kOkRC = 0,
|
||||
kCreateObjRC
|
||||
};
|
||||
|
||||
cmErr_t _err;
|
||||
double _x;
|
||||
double _y;
|
||||
double _radius;
|
||||
double _angle;
|
||||
unsigned _objId;
|
||||
|
||||
void _createObj();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
565
src/tlCtl/cmGrScFltk.cpp
Normal file
565
src/tlCtl/cmGrScFltk.cpp
Normal file
@ -0,0 +1,565 @@
|
||||
#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 "cmSymTbl.h"
|
||||
#include "cmTime.h"
|
||||
#include "cmMidi.h"
|
||||
#include "cmMidiFile.h"
|
||||
#include "cmAudioFile.h"
|
||||
#include "cmAudioFileMgr.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 "cmGrScFltk.h"
|
||||
#include "cmGrPlotAudio.h"
|
||||
#include "cmdIf.h"
|
||||
|
||||
cmGrScFltk::cmGrScFltk(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),
|
||||
_samplesMetricId(cmInvalidId),_secondsMetricId(cmInvalidId),
|
||||
_objSecs(0),_objId(0),
|
||||
_togFl(true),
|
||||
_lastBarPlotObjH(cmGrPlObjNullHandle)
|
||||
{
|
||||
cmErrSetup(&_err,&ctx->rpt,"cmGrScFltk");
|
||||
|
||||
_createMenu();
|
||||
|
||||
if( cmGrPageIsValid(pageHandle()) == false )
|
||||
return;
|
||||
|
||||
initViews(1,1);
|
||||
|
||||
unsigned vwIdx = 0;
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx);
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
cmGrAxH_t axH = cmGrAxNullHandle;
|
||||
cmGrVExt_t limExt;
|
||||
|
||||
_samplesMetricId = cmGrPageLabelFuncRegister( pgH, gvRoundHashValueFunc, this, "Round" );
|
||||
_secondsMetricId = cmGrPageLabelFuncRegister( pgH, gvMinSecMsHashValueFunc, this, "Min:Sec:Ms" );
|
||||
unsigned pitchLabelFuncId = cmGrPageLabelFuncRegister( pgH, gvMidiSciPitchValueFunc, this, "Pitch" );
|
||||
|
||||
cmGrVExtSetD(&limExt,0,0,0,127);
|
||||
cmGrObjSetWorldExt( cvH, cmGrRootObjH(cvH), &limExt );
|
||||
|
||||
cmGrObjSetWorldLimitExt(cvH, cmGrRootObjH(cvH), &limExt, kTopGrFl | kBottomGrFl );
|
||||
|
||||
axH = cmGrViewAxisHandle(vwH, kTopGrIdx);
|
||||
cmGrAxisSetCfg( axH, cmClrFlag(cmGrAxisCfg( axH ), kHashMarkGrFl | kHashLabelGrFl ));
|
||||
|
||||
axH = cmGrViewAxisHandle(vwH, kLeftGrIdx );
|
||||
cmGrAxisSetLabelFunc( axH, pitchLabelFuncId );
|
||||
cmGrViewSetLabelFunc( vwH, kLeftGrIdx, pitchLabelFuncId );
|
||||
|
||||
axH = cmGrViewAxisHandle(vwH, kRightGrIdx);
|
||||
cmGrAxisSetCfg( axH, cmClrFlag(cmGrAxisCfg( axH ), kHashLabelGrFl ));
|
||||
|
||||
cmGrViewSetCfg( vwH, cmSetFlag(cmGrViewCfg(vwH),kSelectHorzGrFl) );
|
||||
|
||||
}
|
||||
|
||||
cmGrScFltk::~cmGrScFltk()
|
||||
{
|
||||
}
|
||||
|
||||
cmScMsgTypeId_t cmGrScFltk::recvScoreMsg( const void* msg, unsigned msgByteCnt )
|
||||
{
|
||||
cmScMsg_t m;
|
||||
|
||||
cmScoreDecode(msg,msgByteCnt,&m);
|
||||
|
||||
switch( m.typeId )
|
||||
{
|
||||
case kBeginMsgScId:
|
||||
{
|
||||
_objId = 0;
|
||||
_objSecs = 0;
|
||||
// remove all objects from all views
|
||||
//cmGrPageClear(pageHandle());
|
||||
//_srate = m.srate;
|
||||
//_updateSeqMenu(m.seqCnt,m.seqId);
|
||||
}
|
||||
break;
|
||||
|
||||
case kEndMsgScId:
|
||||
//size(w(),h()+1);
|
||||
break;
|
||||
|
||||
case kEventMsgScId:
|
||||
_insertEvent(&m.u.evt);
|
||||
break;
|
||||
|
||||
case kSectionMsgScId:
|
||||
_insertSection(&m.u.sect);
|
||||
break;
|
||||
|
||||
case kVarMsgScId:
|
||||
break;
|
||||
|
||||
default:
|
||||
{ assert(0); }
|
||||
}
|
||||
|
||||
return m.typeId;
|
||||
}
|
||||
|
||||
void cmGrScFltk::setSampleRate( double srate )
|
||||
{ _srate = srate; }
|
||||
|
||||
double cmGrScFltk::sampleRate() const
|
||||
{ return _srate; }
|
||||
|
||||
bool cmGrScFltk::on_plot_object( cmGrPlotCbArg_t* arg )
|
||||
{
|
||||
if( arg->selId==kStateChangeGrPlId && cmIsFlag(arg->deltaFlags,kSelectGrPlFl) )
|
||||
{
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(arg->objH);
|
||||
|
||||
if( sop!=NULL && sop->id==kEventMsgScId && sop->u.ep != NULL /* && sep->type == kBarEvtScId */ )
|
||||
{
|
||||
_lastBarPlotObjH = arg->objH;
|
||||
|
||||
unsigned scoreIdx = scoreSelectedEleIndex();
|
||||
|
||||
// callback to: kcApp::_ctl_cb(ctl_t* cp)
|
||||
callback()(this,user_data());
|
||||
|
||||
_cmdIf->onScoreBarSelected(scoreIdx);
|
||||
|
||||
setStatusText(cmTsPrintfS("Score Index:%i",scoreIdx));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmGrScFltk::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);
|
||||
|
||||
if( cmGrPlotObjIsValid(poH) )
|
||||
{
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(poH);
|
||||
|
||||
if( sop->id==kEventMsgScId && sop->u.ep!=NULL && sop->u.ep->type==kBarEvtScId && sop->u.ep->barNumb==barNumb )
|
||||
{
|
||||
unsigned flags = cmGrPlotObjStateFlags(poH);
|
||||
|
||||
cmGrPlotObjSetStateFlags(poH,cmSetFlag(flags,kFocusGrPlFl | kSelectGrPlFl));
|
||||
redraw();
|
||||
|
||||
_lastBarPlotObjH = poH;
|
||||
|
||||
_cmdIf->onScoreBarSelected(sop->u.ep->locIdx);
|
||||
|
||||
setStatusText(cmTsPrintfS("Score Index:%i",sop->u.ep->locIdx));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned cmGrScFltk::scoreSelectedEleIndex() const
|
||||
{
|
||||
|
||||
if( cmGrPlotObjIsValid(_lastBarPlotObjH) )
|
||||
{
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(_lastBarPlotObjH);
|
||||
|
||||
if( sop!=NULL && sop->id==kEventMsgScId && sop->u.ep != NULL /* && sop->u.ep->type == kBarEvtScId */ )
|
||||
return sop->u.ep->locIdx;
|
||||
}
|
||||
return cmInvalidIdx;
|
||||
}
|
||||
|
||||
void cmGrScFltk::setScoreLocation( unsigned locIdx, unsigned vel, unsigned smpIdx )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void cmGrScFltk::_insertSection( const cmScoreSection_t* m )
|
||||
{
|
||||
// The argument is a serialzed copy of a cmScoreSection_t record.
|
||||
// Convert it to a pointer to an actual object in the local score mgr.
|
||||
if( cmGrPageIsValid(pageHandle()) == false )
|
||||
return;
|
||||
|
||||
m = _cmdIf->scoreSectionIdToPtr(m->index);
|
||||
assert(m!=NULL);
|
||||
|
||||
const cmScoreEvt_t* ep = _cmdIf->scoreEventIdToPtr(m->begEvtIndex);
|
||||
assert( ep != NULL );
|
||||
|
||||
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
unsigned vwIdx = 0;
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx );
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t objH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjTypeId_t objTypeId = kLineGrPlId;
|
||||
cmReal_t x = ep->secs;
|
||||
cmReal_t y = 120;
|
||||
cmReal_t w = 0;
|
||||
cmReal_t h = 7;
|
||||
const cmChar_t* label = m->label;
|
||||
unsigned flags = kNoDragGrPlFl;
|
||||
cmGrVExt_t wext;
|
||||
scObj_t scObj(m);
|
||||
|
||||
cmGrVExtSetNull(&wext);
|
||||
|
||||
if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, cmGrVExtIsNull(&wext)?NULL:&wext ) != kOkGrPlRC )
|
||||
{
|
||||
cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on a score section.", cmStringNullGuard(label));
|
||||
return;
|
||||
}
|
||||
|
||||
cmGrPlotObjAllocUser(objH,&scObj,sizeof(scObj));
|
||||
|
||||
unsigned f = 0 ? (kNorthJsGrFl | kTopJsGrFl) : (kSouthJsGrFl | kBottomJsGrFl);
|
||||
cmGrPlotObjSetLabelAttr( objH, f | kWestJsGrFl | kTopJsGrFl | kRightJsGrFl, 0, kBlackGrId );
|
||||
cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kGreenGrId );
|
||||
//cmGrPlotObjSetPhysExt(objH, 1, 0, 1, 0 );
|
||||
cmGrPlotObjSetFontSize(objH,8);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void cmGrScFltk::_insertEvent( const cmScoreEvt_t* m )
|
||||
{
|
||||
// The argument is a serialzed copy of a cmScoreEvt record.
|
||||
// Convert it to a pointer to an actual object in the local score mgr.
|
||||
if( cmGrPageIsValid(pageHandle()) == false )
|
||||
return;
|
||||
|
||||
m = _cmdIf->scoreEventIdToPtr(m->index);
|
||||
assert(m!=NULL);
|
||||
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
unsigned vwIdx = 0;
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx );
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t objH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjTypeId_t objTypeId = kVLineGrPlId;
|
||||
cmReal_t x = m->secs;
|
||||
cmReal_t y = 0;
|
||||
cmReal_t w = 0;
|
||||
cmReal_t h = 127;
|
||||
const cmChar_t* label = NULL;
|
||||
unsigned flags = kNoDragGrPlFl;
|
||||
int bufN = 7;
|
||||
cmChar_t buf[bufN+1];
|
||||
cmGrVExt_t wext;
|
||||
scObj_t scObj(m);
|
||||
|
||||
cmGrVExtSetNull(&wext);
|
||||
|
||||
switch( m->type )
|
||||
{
|
||||
case kNonEvtScId:
|
||||
objTypeId = kRectGrPlId;
|
||||
y = m->pitch;
|
||||
h = 1;
|
||||
w = m->durSecs;
|
||||
label = cmMidiToSciPitch(m->pitch,NULL,0);
|
||||
break;
|
||||
|
||||
case kBarEvtScId:
|
||||
{
|
||||
buf[bufN] = 0;
|
||||
snprintf(buf,bufN,"%i",m->barNumb);
|
||||
objTypeId = kVLineGrPlId;
|
||||
label = buf;
|
||||
}
|
||||
break;
|
||||
|
||||
case kPedalEvtScId:
|
||||
if( cmIsFlag(m->flags, kPedalDnScFl ) == false )
|
||||
return;
|
||||
|
||||
objTypeId = kRectGrPlId;
|
||||
y = m->pitch; // pedal type (damper=64, sostenuto=66) is held in pitch
|
||||
h = 1;
|
||||
w = m->durSecs;
|
||||
flags += kNoFillGrPlFl;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, cmGrVExtIsNull(&wext)?NULL:&wext ) != kOkGrPlRC )
|
||||
{
|
||||
cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on a score event.", cmStringNullGuard(label));
|
||||
return;
|
||||
}
|
||||
|
||||
cmGrPlotObjAllocUser(objH,&scObj,sizeof(scObj));
|
||||
|
||||
|
||||
switch( m->type )
|
||||
{
|
||||
case kBarEvtScId:
|
||||
{
|
||||
unsigned f = _togFl ? (kNorthJsGrFl | kTopJsGrFl) : (kSouthJsGrFl | kBottomJsGrFl);
|
||||
cmGrPlotObjSetLabelAttr( objH, f | kWestJsGrFl | kTopJsGrFl | kRightJsGrFl, 0, kBlueGrId );
|
||||
cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kYellowGrId );
|
||||
cmGrPlotObjSetPhysExt(objH, 1, 0, 1, 0 );
|
||||
_togFl = !_togFl;
|
||||
}
|
||||
break;
|
||||
|
||||
case kNonEvtScId:
|
||||
cmGrPlotObjSetLineColor( objH, kEnablePlGrId, cmGrPlotObjFillColor(objH,kEnablePlGrId) );
|
||||
cmGrPlotObjSetFontSize(objH,8);
|
||||
break;
|
||||
|
||||
case kPedalEvtScId:
|
||||
cmGrPlotObjSetLineColor( objH, kEnablePlGrId, y==64 ? kDarkGreenGrId : kLightGreenGrId );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( cmIsFlag(m->flags,kInvalidScFl) )
|
||||
{
|
||||
cmGrPlotObjSetFillColor(objH, kEnablePlGrId, kRedGrId );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cmGrScFltk::_createMenu( )
|
||||
{
|
||||
int idx = _menuBar->add("Score",0,NULL,0,FL_SUBMENU);
|
||||
const char* titleArray[] = { "Pitch", "Attributes", "Dynamics", "Location", "Fraction", "Section Even", "Section Dyn", "Section Tempo" };
|
||||
bool onFl[] = { true, false, false, false, false, false, false, false };
|
||||
int i;
|
||||
for(i=0; i<kMenuItemCnt; ++i)
|
||||
{
|
||||
_menuArray[i].id = i;
|
||||
_menuArray[i].p = this;
|
||||
_menuBar->insert(idx+1+i,titleArray[i],0,_s_menuCallback, _menuArray + i, FL_MENU_TOGGLE );
|
||||
|
||||
if( onFl[i] )
|
||||
{
|
||||
Fl_Menu_Item* mip = (Fl_Menu_Item*)_menuBar->menu() + idx + i + 1;
|
||||
mip->set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cmGrScFltk::_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("Score")) == -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;
|
||||
}
|
||||
|
||||
void cmGrScFltk::_setEventLabels()
|
||||
{
|
||||
enum { kPitchFl=0x01, kAttrFl=0x02, kDynFl=0x04, kLocFl=0x08, kFracFl=0x10 };
|
||||
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
unsigned flags = 0;
|
||||
flags |= _isMenuChecked(kPitchMId) ? kPitchFl : 0;
|
||||
flags |= _isMenuChecked(kAttrMId) ? kAttrFl : 0;
|
||||
flags |= _isMenuChecked(kDynMId) ? kDynFl : 0;
|
||||
flags |= _isMenuChecked(kLocIdxMId) ? kLocFl : 0;
|
||||
flags |= _isMenuChecked(kFracMId) ? kFracFl : 0;
|
||||
|
||||
unsigned n = cmGrPlotObjectCount(plH);
|
||||
unsigned i;
|
||||
for(i=0; i<n; ++i)
|
||||
{
|
||||
cmGrPlObjH_t poH = cmGrPlotObjectIndexToHandle(plH,i);
|
||||
|
||||
if( cmGrPlotObjIsValid(poH) )
|
||||
{
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(poH);
|
||||
|
||||
if( sop!=NULL && sop->id==kEventMsgScId && sop->u.ep!=NULL && sop->u.ep->type==kNonEvtScId )
|
||||
{
|
||||
const cmScoreEvt_t* ep = sop->u.ep;
|
||||
int bufN = 255;
|
||||
cmChar_t buf[ bufN+1 ];
|
||||
|
||||
buf[bufN] = 0;
|
||||
buf[0] = 0;
|
||||
|
||||
if( cmIsFlag(flags,kPitchFl) )
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"%s ",cmMidiToSciPitch(ep->pitch,NULL,0));
|
||||
|
||||
if( cmIsFlag(flags,kAttrFl) )
|
||||
{
|
||||
cmChar_t s[4];
|
||||
int j=0;
|
||||
if( cmIsFlag(ep->flags,kEvenScFl) )
|
||||
s[j++] = 'e';
|
||||
if( cmIsFlag(ep->flags,kDynScFl) )
|
||||
s[j++] = 'd';
|
||||
if( cmIsFlag(ep->flags,kTempoScFl) )
|
||||
s[j++] = 't';
|
||||
s[j] = 0;
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"%s ",s);
|
||||
}
|
||||
|
||||
|
||||
if( cmIsFlag(flags,kDynFl) && cmIsFlag(ep->flags,kDynScFl) )
|
||||
{
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"d:%i",ep->dynVal);
|
||||
|
||||
if( ep->perfDynLvl != 0 )
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"|%i ",ep->perfDynLvl);
|
||||
else
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf)," ");
|
||||
}
|
||||
|
||||
if( cmIsFlag(flags,kLocFl) )
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"loc:%i ",ep->locIdx);
|
||||
|
||||
if( cmIsFlag(flags,kFracFl) && ep->frac != 0)
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"%5.3f ",ep->frac);
|
||||
|
||||
cmGrPlotObjSetLabel(poH, buf );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmGrScFltk::_setSectionLabels()
|
||||
{
|
||||
enum { kEvenFl=0x01, kDynFl=0x02, kTempoFl=0x04 };
|
||||
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
unsigned flags = 0;
|
||||
flags |= _isMenuChecked(kSectEvenMId) ? kEvenFl : 0;
|
||||
flags |= _isMenuChecked(kSectDynMId) ? kDynFl : 0;
|
||||
flags |= _isMenuChecked(kSectTempoMId) ? kTempoFl : 0;
|
||||
|
||||
unsigned n = cmGrPlotObjectCount(plH);
|
||||
unsigned i;
|
||||
for(i=0; i<n; ++i)
|
||||
{
|
||||
cmGrPlObjH_t poH = cmGrPlotObjectIndexToHandle(plH,i);
|
||||
|
||||
if( cmGrPlotObjIsValid(poH) )
|
||||
{
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(poH);
|
||||
|
||||
if( sop!=NULL && sop->id==kSectionMsgScId && sop->u.sp!=NULL )
|
||||
{
|
||||
const cmScoreSection_t* sp = sop->u.sp;
|
||||
int bufN = 255;
|
||||
cmChar_t buf[ bufN+1 ];
|
||||
|
||||
buf[bufN] = 0;
|
||||
buf[0] = 0;
|
||||
|
||||
snprintf(buf,bufN,"%s ",sp->label);
|
||||
|
||||
if( cmIsFlag(flags,kEvenFl) && sp->vars[kEvenVarScId] != DBL_MAX)
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"e:%f ",sp->vars[kEvenVarScId]);
|
||||
|
||||
if( cmIsFlag(flags,kDynFl) && sp->vars[kDynVarScId] != DBL_MAX)
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"d:%f ",sp->vars[kDynVarScId]);
|
||||
|
||||
if( cmIsFlag(flags,kTempoFl) && sp->vars[kTempoVarScId] != DBL_MAX)
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"t:%f ",sp->vars[kTempoVarScId]);
|
||||
|
||||
cmGrPlotObjSetLabel(poH, buf );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cmGrScFltk::_s_menuCallback(Fl_Widget* w, void* arg )
|
||||
{
|
||||
item_t* ip = (item_t*)arg;
|
||||
cmGrScFltk* p = ip->p;
|
||||
unsigned long id = ip->id;
|
||||
|
||||
switch( id )
|
||||
{
|
||||
case kPitchMId:
|
||||
case kAttrMId:
|
||||
case kDynMId:
|
||||
case kLocIdxMId:
|
||||
case kFracMId:
|
||||
{
|
||||
p->_setEventLabels();
|
||||
p->redraw();
|
||||
}
|
||||
break;
|
||||
|
||||
case kSectEvenMId:
|
||||
case kSectDynMId:
|
||||
case kSectTempoMId:
|
||||
{
|
||||
p->_setSectionLabels();
|
||||
p->redraw();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
89
src/tlCtl/cmGrScFltk.h
Normal file
89
src/tlCtl/cmGrScFltk.h
Normal file
@ -0,0 +1,89 @@
|
||||
#ifndef cmGrScFltk_h
|
||||
#define cmGrScFltk_h
|
||||
|
||||
class Fl_Menu_Bar;
|
||||
class cmdIf;
|
||||
|
||||
class cmGrScFltk : public cmGrPlotFltk, public gvHashFuncArg
|
||||
{
|
||||
public:
|
||||
cmGrScFltk(cmCtx_t* ctx, cmdIf* cp, Fl_Menu_Bar* menuBar, int x, int y, int w, int h);
|
||||
virtual ~cmGrScFltk();
|
||||
|
||||
virtual cmScMsgTypeId_t recvScoreMsg( const void* msg, unsigned msgByteCnt );
|
||||
|
||||
void setSampleRate( double srate );
|
||||
virtual double sampleRate() const;
|
||||
|
||||
virtual bool on_plot_object( cmGrPlotCbArg_t* arg );
|
||||
|
||||
virtual void selectBar( unsigned barNumb );
|
||||
|
||||
virtual unsigned scoreSelectedEleIndex() const;
|
||||
|
||||
virtual void setScoreLocation( unsigned locIdx, unsigned vel, unsigned smpIdx );
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kOkRC,
|
||||
kInsertObjFailRC
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kPitchMId,
|
||||
kAttrMId,
|
||||
kDynMId,
|
||||
kLocIdxMId,
|
||||
kFracMId,
|
||||
kSectEvenMId,
|
||||
kSectDynMId,
|
||||
kSectTempoMId,
|
||||
kMenuItemCnt
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cmGrScFltk* p;
|
||||
int id;
|
||||
} item_t;
|
||||
|
||||
typedef struct scObj_str
|
||||
{
|
||||
cmScMsgTypeId_t id; // kEventMsgScId | kSectionMsgScId
|
||||
union
|
||||
{
|
||||
const cmScoreEvt_t* ep;
|
||||
const cmScoreSection_t* sp;
|
||||
} u;
|
||||
|
||||
scObj_str( const cmScoreEvt_t* e) : id(kEventMsgScId) {u.ep=e;}
|
||||
scObj_str( const cmScoreSection_t* s) : id(kSectionMsgScId) {u.sp=s;}
|
||||
} scObj_t;
|
||||
|
||||
double _srate;
|
||||
cmErr_t _err;
|
||||
cmdIf* _cmdIf;
|
||||
Fl_Menu_Bar* _menuBar;
|
||||
unsigned _samplesMetricId;
|
||||
unsigned _secondsMetricId;
|
||||
double _objSecs;
|
||||
unsigned _objId;
|
||||
bool _togFl;
|
||||
cmGrPlObjH_t _lastBarPlotObjH;
|
||||
item_t _menuArray[ kMenuItemCnt ];
|
||||
|
||||
void _insertSection( const cmScoreSection_t* s );
|
||||
void _insertEvent( const cmScoreEvt_t* m );
|
||||
void _createMenu();
|
||||
bool _isMenuChecked( int id );
|
||||
void _setEventLabels();
|
||||
void _setSectionLabels();
|
||||
|
||||
static void _s_menuCallback(Fl_Widget* w, void* arg);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
695
src/tlCtl/cmGrTksbFltk.cpp
Normal file
695
src/tlCtl/cmGrTksbFltk.cpp
Normal file
@ -0,0 +1,695 @@
|
||||
#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 "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 "cmGrTksbFltk.h"
|
||||
#include "cmGrPlotAudio.h"
|
||||
#include "cmdIf.h"
|
||||
|
||||
cmGrTksbFltk::cmGrTksbFltk(cmCtx_t* ctx, cmdIf* cp, Fl_Menu_Bar* menu, int x, int y, int w, int h)
|
||||
: cmGrPlotFltk(ctx,x,y,w,h),
|
||||
//_cmdIf(cp),
|
||||
_tksbH(cmTakeSeqBldrNullHandle),
|
||||
_menuBar(menu),
|
||||
_samplesMetricId(cmInvalidId),_secondsMetricId(cmInvalidId),
|
||||
//_objSecs(0),
|
||||
_objId(0),
|
||||
//_togFl(true),
|
||||
_lastBarPlotObjH(cmGrPlObjNullHandle),
|
||||
_nextTakeY(5),
|
||||
_curCbTId(kInvalidTId)
|
||||
{
|
||||
cmErrSetup(&_err,&ctx->rpt,"cmGrTksbFltk");
|
||||
|
||||
_createMenu();
|
||||
|
||||
if( cmGrPageIsValid(pageHandle()) == false )
|
||||
return;
|
||||
|
||||
initViews(1,1);
|
||||
|
||||
unsigned vwIdx = 0;
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx);
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
cmGrAxH_t axH = cmGrAxNullHandle;
|
||||
cmGrVExt_t limExt;
|
||||
|
||||
_samplesMetricId = cmGrPageLabelFuncRegister( pgH, gvRoundHashValueFunc, this, "Round" );
|
||||
_secondsMetricId = cmGrPageLabelFuncRegister( pgH, gvMinSecMsHashValueFunc, this, "Min:Sec:Ms" );
|
||||
unsigned pitchLabelFuncId = cmGrPageLabelFuncRegister( pgH, gvMidiSciPitchValueFunc, this, "Pitch" );
|
||||
|
||||
cmGrVExtSetD(&limExt,0,0,0,127);
|
||||
cmGrObjSetWorldExt( cvH, cmGrRootObjH(cvH), &limExt );
|
||||
|
||||
cmGrObjSetWorldLimitExt(cvH, cmGrRootObjH(cvH), &limExt, kTopGrFl | kBottomGrFl );
|
||||
|
||||
axH = cmGrViewAxisHandle(vwH, kTopGrIdx);
|
||||
cmGrAxisSetCfg( axH, cmClrFlag(cmGrAxisCfg( axH ), kHashMarkGrFl | kHashLabelGrFl ));
|
||||
|
||||
axH = cmGrViewAxisHandle(vwH, kLeftGrIdx );
|
||||
cmGrAxisSetLabelFunc( axH, pitchLabelFuncId );
|
||||
cmGrViewSetLabelFunc( vwH, kLeftGrIdx, pitchLabelFuncId );
|
||||
|
||||
axH = cmGrViewAxisHandle(vwH, kRightGrIdx);
|
||||
cmGrAxisSetCfg( axH, cmClrFlag(cmGrAxisCfg( axH ), kHashLabelGrFl ));
|
||||
|
||||
cmGrViewSetCfg( vwH, cmSetFlag(cmGrViewCfg(vwH),kSelectHorzGrFl) );
|
||||
|
||||
}
|
||||
|
||||
cmGrTksbFltk::~cmGrTksbFltk()
|
||||
{
|
||||
}
|
||||
|
||||
void _cmGrTksbRecvScoreMsg( void* cbArg, const void* msg, unsigned msgByteCnt )
|
||||
{
|
||||
cmGrTksbFltk* thisPtr = (cmGrTksbFltk*)cbArg;
|
||||
thisPtr->recvScoreMsg(msg,msgByteCnt);
|
||||
}
|
||||
|
||||
void cmGrTksbFltk::setTksbHandle( void* v )
|
||||
{
|
||||
_tksbH.h = v;
|
||||
|
||||
|
||||
if( cmTakeSeqBldrIsValid(_tksbH) == false )
|
||||
return;
|
||||
|
||||
// load the score plot objects
|
||||
cmScoreSeqNotifyCb(cmTakeSeqBldrScoreHandle(_tksbH),_cmGrTksbRecvScoreMsg, this );
|
||||
|
||||
// get the count of score-track takes
|
||||
unsigned n = cmTakeSeqBldrScTrkTakeCount(_tksbH);
|
||||
|
||||
// for each score-track take
|
||||
for(unsigned i=0; i<n; ++i)
|
||||
{
|
||||
cmTksbScTrkTake_t r;
|
||||
|
||||
// get the ith take
|
||||
if( cmTakeSeqBldrScTrkTake(_tksbH,i,&r) != kOkTsbRC )
|
||||
continue;
|
||||
|
||||
// create the take plot-object
|
||||
_insertTake(&r);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cmScMsgTypeId_t cmGrTksbFltk::recvScoreMsg( const void* msg, unsigned msgByteCnt )
|
||||
{
|
||||
cmScMsg_t m;
|
||||
|
||||
cmScoreDecode(msg,msgByteCnt,&m);
|
||||
|
||||
switch( m.typeId )
|
||||
{
|
||||
case kBeginMsgScId:
|
||||
{
|
||||
_objId = 0;
|
||||
_objSecs = 0;
|
||||
// remove all objects from all views
|
||||
//cmGrPageClear(pageHandle());
|
||||
//_srate = m.srate;
|
||||
//_updateSeqMenu(m.seqCnt,m.seqId);
|
||||
}
|
||||
break;
|
||||
|
||||
case kEndMsgScId:
|
||||
//size(w(),h()+1);
|
||||
break;
|
||||
|
||||
case kEventMsgScId:
|
||||
_insertEvent(&m.u.evt);
|
||||
break;
|
||||
|
||||
case kSectionMsgScId:
|
||||
_insertSection(&m.u.sect);
|
||||
break;
|
||||
|
||||
case kVarMsgScId:
|
||||
break;
|
||||
|
||||
default:
|
||||
{ assert(0); }
|
||||
}
|
||||
|
||||
return m.typeId;
|
||||
}
|
||||
|
||||
|
||||
double cmGrTksbFltk::sampleRate() const
|
||||
{
|
||||
if( cmTakeSeqBldrIsValid(_tksbH) )
|
||||
return cmTakeSeqBldrSampleRate(_tksbH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool cmGrTksbFltk::on_plot_object( cmGrPlotCbArg_t* arg )
|
||||
{
|
||||
if( arg->selId!=kStateChangeGrPlId || cmIsNotFlag(arg->deltaFlags,kSelectGrPlFl) )
|
||||
return true;
|
||||
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(arg->objH);
|
||||
unsigned state = cmGrPlotObjStateFlags(arg->objH);
|
||||
bool isSelectedFl = cmIsFlag( state, kSelectGrPlFl);
|
||||
|
||||
if( sop == NULL )
|
||||
return true;
|
||||
|
||||
//printf("SELECT:%i %i 0x%x\n",cmGrPlotObjId(arg->objH),isSelectedFl,state);
|
||||
|
||||
if( sop->id==kTakeTksbId && sop->u.tlMarkerUid!=cmInvalidId )
|
||||
{
|
||||
if( isSelectedFl )
|
||||
cmTakeSeqBldrLoadTake(_tksbH,sop->u.tlMarkerUid,true);
|
||||
else
|
||||
cmTakeSeqBldrUnloadTake(_tksbH,sop->u.tlMarkerUid);
|
||||
|
||||
setStatusText(cmTsPrintfS("%s", cmStringNullGuard(cmTakeSeqBldrScTrkTakeText(_tksbH,sop->u.tlMarkerUid))));
|
||||
|
||||
_curCbTId = kRefreshTId;
|
||||
|
||||
// callback to: kcApp::_ctl_cb(ctl_t* cp)
|
||||
callback()(this,user_data());
|
||||
|
||||
}
|
||||
|
||||
if( sop->id==kEventTksbId && sop->u.ep!=NULL && sop->u.ep->type==kBarEvtScId )
|
||||
{
|
||||
_lastBarPlotObjH = arg->objH;
|
||||
|
||||
_curCbTId = kSelectTId;
|
||||
|
||||
// callback to: kcApp::_ctl_cb(ctl_t* cp)
|
||||
callback()(this,user_data());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
cmGrTksbFltk::cbTId_t cmGrTksbFltk::cbTypeId() const
|
||||
{ return _curCbTId; }
|
||||
|
||||
unsigned cmGrTksbFltk::scoreSelectedEleIndex() const
|
||||
{
|
||||
|
||||
if( cmGrPlotObjIsValid(_lastBarPlotObjH) )
|
||||
{
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(_lastBarPlotObjH);
|
||||
|
||||
if( sop!=NULL && sop->id==kEventTksbId && sop->u.ep != NULL && sop->u.ep->type == kBarEvtScId )
|
||||
{
|
||||
return sop->u.ep->locIdx;
|
||||
}
|
||||
}
|
||||
return cmInvalidIdx;
|
||||
}
|
||||
|
||||
void cmGrTksbFltk::setScoreLocation( unsigned locIdx, unsigned vel, unsigned smpIdx )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void cmGrTksbFltk::_insertSection( const cmScoreSection_t* m )
|
||||
{
|
||||
// The argument is a serialzed copy of a cmScoreSection_t record.
|
||||
// Convert it to a pointer to an actual object in the local score mgr.
|
||||
if( cmGrPageIsValid(pageHandle()) == false )
|
||||
return;
|
||||
|
||||
m = cmScoreSection(cmTakeSeqBldrScoreHandle(_tksbH),m->index);
|
||||
assert(m!=NULL);
|
||||
|
||||
const cmScoreEvt_t* ep = cmScoreEvt( cmTakeSeqBldrScoreHandle(_tksbH), m->begEvtIndex);
|
||||
assert( ep != NULL );
|
||||
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
unsigned vwIdx = 0;
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx );
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t objH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjTypeId_t objTypeId = kLineGrPlId;
|
||||
cmReal_t x = ep->secs;
|
||||
cmReal_t y = 120;
|
||||
cmReal_t w = 0;
|
||||
cmReal_t h = 7;
|
||||
const cmChar_t* label = m->label;
|
||||
unsigned flags = kNoDragGrPlFl;
|
||||
cmGrVExt_t wext;
|
||||
scObj_t scObj(m);
|
||||
|
||||
cmGrVExtSetNull(&wext);
|
||||
|
||||
if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, cmGrVExtIsNull(&wext)?NULL:&wext ) != kOkGrPlRC )
|
||||
{
|
||||
cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on a score section.", cmStringNullGuard(label));
|
||||
return;
|
||||
}
|
||||
|
||||
cmGrPlotObjAllocUser(objH,&scObj,sizeof(scObj));
|
||||
|
||||
unsigned f = 0 ? (kNorthJsGrFl | kTopJsGrFl) : (kSouthJsGrFl | kBottomJsGrFl);
|
||||
cmGrPlotObjSetLabelAttr( objH, f | kWestJsGrFl | kTopJsGrFl | kRightJsGrFl, 0, kBlackGrId );
|
||||
cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kGreenGrId );
|
||||
//cmGrPlotObjSetPhysExt(objH, 1, 0, 1, 0 );
|
||||
cmGrPlotObjSetFontSize(objH,8);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void cmGrTksbFltk::_insertEvent( const cmScoreEvt_t* m )
|
||||
{
|
||||
// The argument is a serialzed copy of a cmScoreEvt record.
|
||||
// Convert it to a pointer to an actual object in the local score mgr.
|
||||
if( cmGrPageIsValid(pageHandle()) == false )
|
||||
return;
|
||||
|
||||
// Get a pointer to the score event
|
||||
m = cmScoreEvt( cmTakeSeqBldrScoreHandle(_tksbH), m->index );
|
||||
assert(m!=NULL);
|
||||
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
unsigned vwIdx = 0;
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx );
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t objH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjTypeId_t objTypeId = kVLineGrPlId;
|
||||
cmReal_t x = m->secs;
|
||||
cmReal_t y = 0;
|
||||
cmReal_t w = 0;
|
||||
cmReal_t h = 127;
|
||||
const cmChar_t* label = NULL;
|
||||
unsigned flags = kNoDragGrPlFl;
|
||||
int bufN = 7;
|
||||
cmChar_t buf[bufN+1];
|
||||
cmGrVExt_t wext;
|
||||
scObj_t scObj(m);
|
||||
|
||||
cmGrVExtSetNull(&wext);
|
||||
|
||||
switch( m->type )
|
||||
{
|
||||
case kNonEvtScId:
|
||||
objTypeId = kRectGrPlId;
|
||||
y = m->pitch;
|
||||
h = 1;
|
||||
w = m->durSecs;
|
||||
label = cmMidiToSciPitch(m->pitch,NULL,0);
|
||||
break;
|
||||
|
||||
case kPedalEvtScId:
|
||||
objTypeId = kRectGrPlId;
|
||||
y = 108;
|
||||
h = 2;
|
||||
w = m->durSecs;
|
||||
label = "pedal";
|
||||
break;
|
||||
|
||||
case kBarEvtScId:
|
||||
{
|
||||
buf[bufN] = 0;
|
||||
snprintf(buf,bufN,"%i",m->barNumb);
|
||||
objTypeId = kVLineGrPlId;
|
||||
label = buf;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// create the plot object to represent this event
|
||||
if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, cmGrVExtIsNull(&wext)?NULL:&wext ) != kOkGrPlRC )
|
||||
{
|
||||
cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on a score event.", cmStringNullGuard(label));
|
||||
return;
|
||||
}
|
||||
|
||||
// store the score event reference as custom data inside the plot object
|
||||
cmGrPlotObjAllocUser(objH,&scObj,sizeof(scObj));
|
||||
|
||||
|
||||
switch( m->type )
|
||||
{
|
||||
case kBarEvtScId:
|
||||
{
|
||||
unsigned f = _togFl ? (kNorthJsGrFl | kTopJsGrFl) : (kSouthJsGrFl | kBottomJsGrFl);
|
||||
cmGrPlotObjSetLabelAttr( objH, f | kWestJsGrFl | kTopJsGrFl | kRightJsGrFl, 0, kBlueGrId );
|
||||
cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kYellowGrId );
|
||||
cmGrPlotObjSetPhysExt(objH, 1, 0, 1, 0 );
|
||||
_togFl = !_togFl;
|
||||
}
|
||||
break;
|
||||
|
||||
case kNonEvtScId:
|
||||
cmGrPlotObjSetLineColor( objH, kEnablePlGrId, cmGrPlotObjFillColor(objH,kEnablePlGrId) );
|
||||
cmGrPlotObjSetFontSize(objH,8);
|
||||
break;
|
||||
|
||||
case kPedalEvtScId:
|
||||
cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kDeepPinkGrId );
|
||||
cmGrPlotObjSetFillColor(objH, kEnablePlGrId, kDeepPinkGrId );
|
||||
cmGrPlotObjSetFontSize(objH,8);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( cmIsFlag(m->flags,kInvalidScFl) )
|
||||
{
|
||||
cmGrPlotObjSetFillColor(objH, kEnablePlGrId, kRedGrId );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cmGrTksbFltk::_insertTake( const cmTksbScTrkTake_t* take )
|
||||
{
|
||||
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
unsigned vwIdx = 0;
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx );
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t objH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjTypeId_t objTypeId = kRectGrPlId;
|
||||
cmReal_t x = 0;
|
||||
cmReal_t y = 0;
|
||||
cmReal_t w = 0;
|
||||
cmReal_t h = 127;
|
||||
const cmChar_t* label = NULL;
|
||||
unsigned flags = kNoDragGrPlFl | kNoFillGrPlFl;
|
||||
int bufN = 7;
|
||||
cmChar_t buf[bufN+1];
|
||||
cmGrVExt_t wext;
|
||||
cmGrVExt_t vext;
|
||||
scObj_t scObj(take->tlMarkerUid);
|
||||
|
||||
cmGrVExtSetNull(&wext);
|
||||
|
||||
if( cmGrPlotObjIsValid(objH = _scEvtIdxToPlotObj( take->minScEvtIdx ))==false )
|
||||
return;
|
||||
|
||||
cmGrPlotObjVExt( objH, &vext);
|
||||
|
||||
x = cmGrVExtMinX(&vext);
|
||||
|
||||
if( cmGrPlotObjIsValid(objH = _scEvtIdxToPlotObj( take->maxScEvtIdx )) == false )
|
||||
return;
|
||||
|
||||
cmGrPlotObjVExt( objH, &vext);
|
||||
|
||||
w = cmGrVExtMaxX(&vext) - x;
|
||||
h = 1;
|
||||
y = _nextTakeY;
|
||||
|
||||
|
||||
buf[bufN] = 0;
|
||||
snprintf(buf,bufN,"%i",(_nextTakeY-5)/2);
|
||||
label = buf;
|
||||
|
||||
_nextTakeY += 2;
|
||||
if( _nextTakeY > 120 )
|
||||
_nextTakeY = 5;
|
||||
|
||||
// create the plot object to represent this event
|
||||
if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, cmGrVExtIsNull(&wext)?NULL:&wext ) != kOkGrPlRC )
|
||||
{
|
||||
cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on score-track take.", cmStringNullGuard(label));
|
||||
return;
|
||||
}
|
||||
|
||||
// store the score event reference as custom data inside the plot object
|
||||
cmGrPlotObjAllocUser(objH,&scObj,sizeof(scObj));
|
||||
|
||||
|
||||
cmGrPlotObjSetLineColor( objH, kFocusPlGrId, kRedGrId );
|
||||
cmGrPlotObjSetLineColor( objH, kSelectPlGrId, kDeepPinkGrId );
|
||||
cmGrPlotObjSetFontSize(objH,8);
|
||||
|
||||
}
|
||||
|
||||
#define cmMENU_TITLE "Bldr"
|
||||
void cmGrTksbFltk::_createMenu( )
|
||||
{
|
||||
int idx = _menuBar->add(cmMENU_TITLE,0,NULL,0,FL_SUBMENU);
|
||||
const char* titleArray[] = { "Pitch", "Attributes", "Dynamics", "Location", "Fraction", "Section Even", "Section Dyn", "Section Tempo" };
|
||||
bool onFl[] = { true, false, false, false, false, false, false, false };
|
||||
int i;
|
||||
for(i=0; i<kMenuItemCnt; ++i)
|
||||
{
|
||||
_menuArray[i].id = i;
|
||||
_menuArray[i].p = this;
|
||||
_menuBar->insert(idx+1+i,titleArray[i],0,_s_menuCallback, _menuArray + i, FL_MENU_TOGGLE );
|
||||
|
||||
if( onFl[i] )
|
||||
{
|
||||
Fl_Menu_Item* mip = (Fl_Menu_Item*)_menuBar->menu() + idx + i + 1;
|
||||
mip->set();
|
||||
}
|
||||
}
|
||||
|
||||
_menuBar->redraw();
|
||||
|
||||
}
|
||||
|
||||
bool cmGrTksbFltk::_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(cmMENU_TITLE)) == -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;
|
||||
}
|
||||
|
||||
void cmGrTksbFltk::_setEventLabels()
|
||||
{
|
||||
enum { kPitchFl=0x01, kAttrFl=0x02, kDynFl=0x04, kLocFl=0x08, kFracFl };
|
||||
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
unsigned flags = 0;
|
||||
flags |= _isMenuChecked(kPitchMId) ? kPitchFl : 0;
|
||||
flags |= _isMenuChecked(kAttrMId) ? kAttrFl : 0;
|
||||
flags |= _isMenuChecked(kDynMId) ? kDynFl : 0;
|
||||
flags |= _isMenuChecked(kLocIdxMId) ? kLocFl : 0;
|
||||
flags |= _isMenuChecked(kFracMId) ? kFracFl : 0;
|
||||
|
||||
unsigned n = cmGrPlotObjectCount(plH);
|
||||
unsigned i;
|
||||
for(i=0; i<n; ++i)
|
||||
{
|
||||
cmGrPlObjH_t poH = cmGrPlotObjectIndexToHandle(plH,i);
|
||||
|
||||
if( cmGrPlotObjIsValid(poH) )
|
||||
{
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(poH);
|
||||
|
||||
if( sop!=NULL && sop->id==kEventTksbId && sop->u.ep!=NULL && sop->u.ep->type==kNonEvtScId )
|
||||
{
|
||||
const cmScoreEvt_t* ep = sop->u.ep;
|
||||
int bufN = 255;
|
||||
cmChar_t buf[ bufN+1 ];
|
||||
|
||||
buf[bufN] = 0;
|
||||
buf[0] = 0;
|
||||
|
||||
if( cmIsFlag(flags,kPitchFl) )
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"%s ",cmMidiToSciPitch(ep->pitch,NULL,0));
|
||||
|
||||
if( cmIsFlag(flags,kAttrFl) )
|
||||
{
|
||||
cmChar_t s[4];
|
||||
int j=0;
|
||||
if( cmIsFlag(ep->flags,kEvenScFl) )
|
||||
s[j++] = 'e';
|
||||
if( cmIsFlag(ep->flags,kDynScFl) )
|
||||
s[j++] = 'd';
|
||||
if( cmIsFlag(ep->flags,kTempoScFl) )
|
||||
s[j++] = 't';
|
||||
s[j] = 0;
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"%s ",s);
|
||||
}
|
||||
|
||||
|
||||
if( cmIsFlag(flags,kDynFl) && cmIsFlag(ep->flags,kDynScFl) )
|
||||
{
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"d:%i",ep->dynVal);
|
||||
|
||||
if( ep->perfDynLvl != 0 )
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"|%i ",ep->perfDynLvl);
|
||||
else
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf)," ");
|
||||
}
|
||||
|
||||
if( cmIsFlag(flags,kLocFl) )
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"loc:%i ",ep->locIdx);
|
||||
|
||||
if( cmIsFlag(flags,kFracFl) && ep->frac != 0)
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"%5.3f ",ep->frac);
|
||||
|
||||
cmGrPlotObjSetLabel(poH, buf );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmGrTksbFltk::_setSectionLabels()
|
||||
{
|
||||
enum { kEvenFl=0x01, kDynFl=0x02, kTempoFl=0x04 };
|
||||
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
unsigned flags = 0;
|
||||
flags |= _isMenuChecked(kSectEvenMId) ? kEvenFl : 0;
|
||||
flags |= _isMenuChecked(kSectDynMId) ? kDynFl : 0;
|
||||
flags |= _isMenuChecked(kSectTempoMId) ? kTempoFl : 0;
|
||||
|
||||
unsigned n = cmGrPlotObjectCount(plH);
|
||||
unsigned i;
|
||||
for(i=0; i<n; ++i)
|
||||
{
|
||||
cmGrPlObjH_t poH = cmGrPlotObjectIndexToHandle(plH,i);
|
||||
|
||||
if( cmGrPlotObjIsValid(poH) )
|
||||
{
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(poH);
|
||||
|
||||
if( sop!=NULL && sop->id==kSectionTksbId && sop->u.sp!=NULL )
|
||||
{
|
||||
const cmScoreSection_t* sp = sop->u.sp;
|
||||
int bufN = 255;
|
||||
cmChar_t buf[ bufN+1 ];
|
||||
|
||||
buf[bufN] = 0;
|
||||
buf[0] = 0;
|
||||
|
||||
snprintf(buf,bufN,"%s ",sp->label);
|
||||
|
||||
if( cmIsFlag(flags,kEvenFl) && sp->vars[kEvenVarScId] != DBL_MAX)
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"e:%f ",sp->vars[kEvenVarScId]);
|
||||
|
||||
if( cmIsFlag(flags,kDynFl) && sp->vars[kDynVarScId] != DBL_MAX)
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"d:%f ",sp->vars[kDynVarScId]);
|
||||
|
||||
if( cmIsFlag(flags,kTempoFl) && sp->vars[kTempoVarScId] != DBL_MAX)
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"t:%f ",sp->vars[kTempoVarScId]);
|
||||
|
||||
cmGrPlotObjSetLabel(poH, buf );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void cmGrTksbFltk::_s_menuCallback(Fl_Widget* w, void* arg )
|
||||
{
|
||||
item_t* ip = (item_t*)arg;
|
||||
cmGrTksbFltk* p = ip->p;
|
||||
unsigned long id = ip->id;
|
||||
|
||||
switch( id )
|
||||
{
|
||||
case kPitchMId:
|
||||
case kAttrMId:
|
||||
case kDynMId:
|
||||
case kLocIdxMId:
|
||||
case kFracMId:
|
||||
{
|
||||
p->_setEventLabels();
|
||||
p->redraw();
|
||||
}
|
||||
break;
|
||||
|
||||
case kSectEvenMId:
|
||||
case kSectDynMId:
|
||||
case kSectTempoMId:
|
||||
{
|
||||
p->_setSectionLabels();
|
||||
p->redraw();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cmGrPlObjH_t cmGrTksbFltk::_scEvtIdxToPlotObj( unsigned scEvtIdx )
|
||||
{
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
unsigned n = cmGrPlotObjectCount(plH);
|
||||
unsigned i;
|
||||
cmGrPlObjH_t poH;
|
||||
scObj_t* sop;
|
||||
|
||||
for(i=0; i<n; ++i)
|
||||
if(cmGrPlotObjIsValid(poH = cmGrPlotObjectIndexToHandle(plH,i))
|
||||
&& (sop = (scObj_t*)cmGrPlotObjUserPtr(poH)) != NULL
|
||||
&& sop->id == kEventTksbId
|
||||
&& sop->u.ep->index == scEvtIdx )
|
||||
{
|
||||
return poH;
|
||||
}
|
||||
|
||||
|
||||
return cmGrPlObjNullHandle;
|
||||
}
|
||||
|
110
src/tlCtl/cmGrTksbFltk.h
Normal file
110
src/tlCtl/cmGrTksbFltk.h
Normal file
@ -0,0 +1,110 @@
|
||||
#ifndef cmGrTksbFltk_h
|
||||
#define cmGrTksbFltk_h
|
||||
|
||||
class Fl_Menu_Bar;
|
||||
class cmdIf;
|
||||
|
||||
class cmGrTksbFltk : public cmGrPlotFltk, public gvHashFuncArg
|
||||
{
|
||||
public:
|
||||
cmGrTksbFltk(cmCtx_t* ctx, cmdIf* cp, Fl_Menu_Bar* menuBar, int x, int y, int w, int h);
|
||||
virtual ~cmGrTksbFltk();
|
||||
|
||||
void setTksbHandle( void* vp );
|
||||
|
||||
virtual cmScMsgTypeId_t recvScoreMsg( const void* msg, unsigned msgByteCnt );
|
||||
|
||||
virtual double sampleRate() const;
|
||||
|
||||
virtual bool on_plot_object( cmGrPlotCbArg_t* arg );
|
||||
|
||||
typedef enum
|
||||
{
|
||||
kInvalidTId,
|
||||
kSelectTId,
|
||||
kRefreshTId,
|
||||
} cbTId_t;
|
||||
|
||||
cbTId_t cbTypeId() const;
|
||||
|
||||
virtual unsigned scoreSelectedEleIndex() const;
|
||||
|
||||
virtual void setScoreLocation( unsigned locIdx, unsigned vel, unsigned smpIdx );
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kOkRC,
|
||||
kInsertObjFailRC
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kPitchMId,
|
||||
kAttrMId,
|
||||
kDynMId,
|
||||
kLocIdxMId,
|
||||
kFracMId,
|
||||
kSectEvenMId,
|
||||
kSectDynMId,
|
||||
kSectTempoMId,
|
||||
kMenuItemCnt
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cmGrTksbFltk* p;
|
||||
int id;
|
||||
} item_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
kEventTksbId,
|
||||
kSectionTksbId,
|
||||
kTakeTksbId
|
||||
} tksbId_t;
|
||||
|
||||
typedef struct scObj_str
|
||||
{
|
||||
tksbId_t id;
|
||||
union
|
||||
{
|
||||
const cmScoreEvt_t* ep;
|
||||
const cmScoreSection_t* sp;
|
||||
unsigned tlMarkerUid;
|
||||
} u;
|
||||
|
||||
scObj_str( const cmScoreEvt_t* e) : id(kEventTksbId) { u.ep=e;}
|
||||
scObj_str( const cmScoreSection_t* s) : id(kSectionTksbId) { u.sp=s;}
|
||||
scObj_str( unsigned i ) : id(kTakeTksbId) { u.tlMarkerUid=i;}
|
||||
} scObj_t;
|
||||
|
||||
cmErr_t _err;
|
||||
//cmdIf* _cmdIf;
|
||||
cmTakeSeqBldrH_t _tksbH;
|
||||
Fl_Menu_Bar* _menuBar;
|
||||
unsigned _samplesMetricId;
|
||||
unsigned _secondsMetricId;
|
||||
double _objSecs;
|
||||
unsigned _objId;
|
||||
bool _togFl;
|
||||
cmGrPlObjH_t _lastBarPlotObjH;
|
||||
item_t _menuArray[ kMenuItemCnt ];
|
||||
unsigned _nextTakeY;
|
||||
cbTId_t _curCbTId;
|
||||
|
||||
void _insertSection( const cmScoreSection_t* s );
|
||||
void _insertEvent( const cmScoreEvt_t* m );
|
||||
void _insertTake( const cmTksbScTrkTake_t* take );
|
||||
void _createMenu();
|
||||
bool _isMenuChecked( int id );
|
||||
void _setEventLabels();
|
||||
void _setSectionLabels();
|
||||
cmGrPlObjH_t _scEvtIdxToPlotObj( unsigned scEvtIdx );
|
||||
|
||||
static void _s_menuCallback(Fl_Widget* w, void* arg);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
461
src/tlCtl/cmGrTksrFltk.cpp
Normal file
461
src/tlCtl/cmGrTksrFltk.cpp
Normal file
@ -0,0 +1,461 @@
|
||||
#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 "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 "cmGrTksrFltk.h"
|
||||
#include "cmGrPlotAudio.h"
|
||||
#include "cmdIf.h"
|
||||
|
||||
cmGrTksrFltk::cmGrTksrFltk(cmCtx_t* ctx, cmdIf* cp, Fl_Menu_Bar* menu, int x, int y, int w, int h)
|
||||
: cmGrPlotFltk(ctx,x,y,w,h),
|
||||
//_cmdIf(cp),
|
||||
_tksbH(cmTakeSeqBldrNullHandle),
|
||||
_menuBar(menu),
|
||||
_samplesMetricId(cmInvalidId),_secondsMetricId(cmInvalidId),
|
||||
//_objSecs(0),
|
||||
_objId(0)
|
||||
//_togFl(true)
|
||||
{
|
||||
cmErrSetup(&_err,&ctx->rpt,"cmGrTksrFltk");
|
||||
|
||||
_createMenu();
|
||||
|
||||
if( cmGrPageIsValid(pageHandle()) == false )
|
||||
return;
|
||||
|
||||
initViews(1,1);
|
||||
|
||||
unsigned vwIdx = 0;
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx);
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
cmGrAxH_t axH = cmGrAxNullHandle;
|
||||
cmGrVExt_t limExt;
|
||||
|
||||
_samplesMetricId = cmGrPageLabelFuncRegister( pgH, gvRoundHashValueFunc, this, "Round" );
|
||||
_secondsMetricId = cmGrPageLabelFuncRegister( pgH, gvMinSecMsHashValueFunc, this, "Min:Sec:Ms" );
|
||||
unsigned pitchLabelFuncId = cmGrPageLabelFuncRegister( pgH, gvMidiSciPitchValueFunc, this, "Pitch" );
|
||||
|
||||
cmGrVExtSetD(&limExt,0,0,0,127);
|
||||
cmGrObjSetWorldExt( cvH, cmGrRootObjH(cvH), &limExt );
|
||||
|
||||
cmGrObjSetWorldLimitExt(cvH, cmGrRootObjH(cvH), &limExt, kTopGrFl | kBottomGrFl );
|
||||
|
||||
axH = cmGrViewAxisHandle(vwH, kTopGrIdx);
|
||||
cmGrAxisSetCfg( axH, cmClrFlag(cmGrAxisCfg( axH ), kHashMarkGrFl | kHashLabelGrFl ));
|
||||
|
||||
axH = cmGrViewAxisHandle(vwH, kLeftGrIdx );
|
||||
cmGrAxisSetLabelFunc( axH, pitchLabelFuncId );
|
||||
cmGrViewSetLabelFunc( vwH, kLeftGrIdx, pitchLabelFuncId );
|
||||
|
||||
axH = cmGrViewAxisHandle(vwH, kRightGrIdx);
|
||||
cmGrAxisSetCfg( axH, cmClrFlag(cmGrAxisCfg( axH ), kHashLabelGrFl ));
|
||||
|
||||
cmGrViewSetCfg( vwH, cmSetFlag(cmGrViewCfg(vwH),kSelectHorzGrFl) );
|
||||
|
||||
}
|
||||
|
||||
cmGrTksrFltk::~cmGrTksrFltk()
|
||||
{}
|
||||
|
||||
|
||||
void cmGrTksrFltk::setTksbHandle( void* v )
|
||||
{
|
||||
_tksbH.h = v;
|
||||
}
|
||||
|
||||
void cmGrTksrFltk::refresh()
|
||||
{
|
||||
if( cmGrPlotClear( plotHandle() ) != kOkGrPlRC )
|
||||
{
|
||||
cmErrMsg(&_err,kClearPlotFailRC,"Plot clear failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if( cmTakeSeqBldrIsValid(_tksbH) == false )
|
||||
return;
|
||||
|
||||
// insert tksb events here
|
||||
cmTakeSeqBldrRendReset(_tksbH);
|
||||
|
||||
cmTksbRend_t m;
|
||||
unsigned absSmpIdx = 0;
|
||||
double srate = cmTakeSeqBldrSampleRate(_tksbH);
|
||||
while( cmTakeSeqBldrRendNext(_tksbH,&m) )
|
||||
{
|
||||
m.evt.smpIdx = absSmpIdx;
|
||||
_insertEvent(&m,srate);
|
||||
absSmpIdx += m.offsetSmp;
|
||||
}
|
||||
}
|
||||
|
||||
double cmGrTksrFltk::sampleRate() const
|
||||
{
|
||||
if( cmTakeSeqBldrIsValid(_tksbH) )
|
||||
return cmTakeSeqBldrSampleRate(_tksbH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool cmGrTksrFltk::on_plot_object( cmGrPlotCbArg_t* arg )
|
||||
{
|
||||
/*
|
||||
if( arg->selId==kStateChangeGrPlId && cmIsFlag(arg->deltaFlags,kSelectGrPlFl) )
|
||||
{
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(arg->objH);
|
||||
unsigned state = cmGrPlotObjStateFlags(arg->objH);
|
||||
bool isSelectedFl = cmIsFlag( state, kSelectGrPlFl);
|
||||
|
||||
if( sop != NULL )
|
||||
{
|
||||
|
||||
//printf("SELECT:%i %i 0x%x\n",cmGrPlotObjId(arg->objH),isSelectedFl,state);
|
||||
|
||||
if( sop->id==kTakeTksrId && sop->u.tlMarkerUid!=cmInvalidId )
|
||||
{
|
||||
if( isSelectedFl )
|
||||
cmTakeSeqBldrLoadTake(_tksbH,sop->u.tlMarkerUid,true);
|
||||
else
|
||||
cmTakeSeqBldrUnloadTake(_tksbH,sop->u.tlMarkerUid);
|
||||
|
||||
setStatusText(cmTsPrintfS("%s", cmStringNullGuard(cmTakeSeqBldrScTrkTakeText(_tksbH,sop->u.tlMarkerUid))));
|
||||
}
|
||||
|
||||
if( sop->id==kEventTksrId && sop->u.ep!=NULL && sop->u.ep->type==kBarEvtScId )
|
||||
{
|
||||
_lastBarPlotObjH = arg->objH;
|
||||
|
||||
// callback to: kcApp::_ctl_cb(ctl_t* cp)
|
||||
callback()(this,user_data());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void cmGrTksrFltk::_insertEvent( const cmTksbRend_t* m, double srate )
|
||||
{
|
||||
if( cmGrPageIsValid(pageHandle()) == false )
|
||||
return;
|
||||
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
unsigned vwIdx = 0;
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx );
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjH_t objH = cmGrPlObjNullHandle;
|
||||
cmGrPlObjTypeId_t objTypeId = kRectGrPlId;
|
||||
cmReal_t x = m->evt.smpIdx / srate;
|
||||
cmReal_t y = 0;
|
||||
cmReal_t h = 1;
|
||||
cmReal_t w = m->durSmp / srate;
|
||||
const cmChar_t* label = NULL;
|
||||
unsigned flags = kNoDragGrPlFl;
|
||||
tksrId_t tid = kInvalidTksrId;
|
||||
|
||||
|
||||
if( cmMidiIsNoteOn(m->evt.status) )
|
||||
{
|
||||
tid = kNoteTksrId;
|
||||
y = m->evt.d0;
|
||||
label = cmMidiToSciPitch(m->evt.d0,NULL,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( cmMidiIsPedalDown(m->evt.status,m->evt.d0,m->evt.d1) )
|
||||
{
|
||||
tid = kPedalTksrId;
|
||||
y = 120;
|
||||
label = cmMidiPedalLabel(m->evt.d0);
|
||||
flags |= kNoFillGrPlFl;
|
||||
}
|
||||
}
|
||||
|
||||
if( tid == kInvalidTksrId )
|
||||
return;
|
||||
|
||||
//printf("absSmpIdx:%f %f\n",x,w);
|
||||
|
||||
|
||||
// create the plot object to represent this event
|
||||
if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, NULL ) != kOkGrPlRC )
|
||||
{
|
||||
cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on a score event.", cmStringNullGuard(label));
|
||||
return;
|
||||
}
|
||||
|
||||
// store the score event reference as custom data inside the plot object
|
||||
scObj_t scObj(tid,m->rid);
|
||||
cmGrPlotObjAllocUser(objH,&scObj,sizeof(scObj));
|
||||
|
||||
|
||||
switch( tid )
|
||||
{
|
||||
case kNoteTksrId:
|
||||
cmGrPlotObjSetLineColor( objH, kEnablePlGrId, cmGrPlotObjFillColor(objH,kEnablePlGrId) );
|
||||
cmGrPlotObjSetFontSize(objH,8);
|
||||
break;
|
||||
|
||||
case kPedalTksrId:
|
||||
cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kDeepPinkGrId );
|
||||
cmGrPlotObjSetFontSize(objH,8);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#define cmMENU_TITLE "Rndr"
|
||||
void cmGrTksrFltk::_createMenu( )
|
||||
{
|
||||
int idx = _menuBar->add(cmMENU_TITLE,0,NULL,0,FL_SUBMENU);
|
||||
const char* titleArray[] = { "Pitch", "ScEvtIdx", "Delete", "Sustain", "Sostenuto", "Write", "Read" };
|
||||
bool onFl[] = { true, false, false, false, false, false, false };
|
||||
bool checkFl[] = { true, true, false, false, false, false, false };
|
||||
int i;
|
||||
for(i=0; i<kMenuItemCnt; ++i)
|
||||
{
|
||||
_menuArray[i].id = i;
|
||||
_menuArray[i].p = this;
|
||||
_menuBar->insert(idx+1+i,titleArray[i],0,_s_menuCallback, _menuArray + i, checkFl[i] ? FL_MENU_TOGGLE : 0 );
|
||||
|
||||
if( onFl[i] )
|
||||
{
|
||||
Fl_Menu_Item* mip = (Fl_Menu_Item*)_menuBar->menu() + idx + i + 1;
|
||||
mip->set();
|
||||
}
|
||||
}
|
||||
|
||||
_menuBar->redraw();
|
||||
|
||||
}
|
||||
|
||||
bool cmGrTksrFltk::_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(cmMENU_TITLE)) == -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;
|
||||
}
|
||||
|
||||
void cmGrTksrFltk::_setEventLabels()
|
||||
{
|
||||
enum { kPitchFl=0x01, kScEvtFl=0x02 };
|
||||
|
||||
if( cmTakeSeqBldrIsValid( _tksbH ) == false )
|
||||
return;
|
||||
|
||||
cmGrPlH_t plH = plotHandle();
|
||||
unsigned flags = 0;
|
||||
flags |= _isMenuChecked(kPitchMId) ? kPitchFl : 0;
|
||||
flags |= _isMenuChecked(kScEvtMId) ? kScEvtFl : 0;
|
||||
|
||||
unsigned n = cmGrPlotObjectCount(plH);
|
||||
unsigned i;
|
||||
for(i=0; i<n; ++i)
|
||||
{
|
||||
cmGrPlObjH_t poH = cmGrPlotObjectIndexToHandle(plH,i);
|
||||
|
||||
if( cmGrPlotObjIsValid(poH) )
|
||||
{
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(poH);
|
||||
|
||||
if( sop!=NULL && sop->id==kNoteTksrId && sop->u.rid!=cmInvalidId )
|
||||
{
|
||||
cmTksbRend_t r;
|
||||
|
||||
if( cmTakeSeqBldrRendInfo( _tksbH, sop->u.rid, &r ) == kOkTsbRC )
|
||||
{
|
||||
|
||||
int bufN = 255;
|
||||
cmChar_t buf[ bufN+1 ];
|
||||
|
||||
buf[bufN] = 0;
|
||||
buf[0] = 0;
|
||||
|
||||
if( cmIsFlag(flags,kPitchFl) && r.evt.status == kNoteOnMdId )
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"%s ",cmMidiToSciPitch(r.evt.d0,NULL,0));
|
||||
|
||||
if( cmIsFlag(flags,kScEvtFl) && r.scEvtIdx != cmInvalidIdx )
|
||||
snprintf(buf+strlen(buf),bufN-strlen(buf),"sei:%i ",r.scEvtIdx);
|
||||
|
||||
cmGrPlotObjSetLabel(poH, buf );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void cmGrTksrFltk::_s_deleteSelectedEle( void* arg, cmGrPlObjH_t oh )
|
||||
{
|
||||
if( cmIsFlag(cmGrPlotObjStateFlags(oh), kSelectGrPlFl) )
|
||||
{
|
||||
cmGrTksrFltk* p = (cmGrTksrFltk*)arg;
|
||||
scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(oh);
|
||||
cmTakeSeqBldrRendDelete( p->_tksbH, sop->u.rid );
|
||||
}
|
||||
}
|
||||
|
||||
void cmGrTksrFltk::_write()
|
||||
{
|
||||
const cmChar_t* fn = "/home/kevin/temp/kr/tksb/tksb0.js";
|
||||
|
||||
if( cmTakeSeqBldrIsValid(_tksbH) == false )
|
||||
return;
|
||||
|
||||
if( cmTakeSeqBldrWrite( _tksbH, fn ) != kOkTsbRC )
|
||||
cmErrMsg(&_err,kTksbFailRC,"Render write failed for '%s'.",cmStringNullGuard(fn));
|
||||
|
||||
}
|
||||
|
||||
void cmGrTksrFltk::_read()
|
||||
{
|
||||
const cmChar_t* fn = "/home/kevin/temp/kr/tksb/tksb0.js";
|
||||
|
||||
if( cmTakeSeqBldrIsValid(_tksbH) == false )
|
||||
return;
|
||||
|
||||
if( cmTakeSeqBldrRead( _tksbH, fn ) != kOkTsbRC )
|
||||
cmErrMsg(&_err,kTksbFailRC,"Render write failed for '%s'.",cmStringNullGuard(fn));
|
||||
}
|
||||
|
||||
void cmGrTksrFltk::_insertPedal( unsigned long pedalMId )
|
||||
{
|
||||
if( cmTakeSeqBldrIsValid(_tksbH) == false )
|
||||
return;
|
||||
|
||||
unsigned vwIdx = 0;
|
||||
cmGrPgH_t pgH = pageHandle();
|
||||
cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx);
|
||||
cmGrH_t cvH = cmGrViewGrHandle( vwH );
|
||||
double srate = cmTakeSeqBldrSampleRate(_tksbH);
|
||||
cmGrVPt_t pt0,pt1;
|
||||
unsigned rid;
|
||||
cmTksbEvent_t e;
|
||||
memset(&e,0,sizeof(e));
|
||||
|
||||
cmGrSelectPoints( cvH, &pt0, &pt1 );
|
||||
|
||||
unsigned durSmp = (pt1.x - pt0.x) * srate;
|
||||
|
||||
e.status = kCtlMdId;
|
||||
switch( pedalMId )
|
||||
{
|
||||
case kSustainMId:
|
||||
e.d0 = kSustainCtlMdId;
|
||||
break;
|
||||
|
||||
case kSostenutoMId:
|
||||
e.d0 = kSostenutoCtlMdId;
|
||||
break;
|
||||
}
|
||||
|
||||
//printf("x0:%f x1:%f %i\n",pt0.x,pt1.x,durSmp);
|
||||
|
||||
e.smpIdx = pt0.x * srate;
|
||||
e.d1 = 127;
|
||||
cmTakeSeqBldrRendInsert( _tksbH, &e, durSmp, &rid );
|
||||
|
||||
e.smpIdx = pt1.x * srate;
|
||||
e.d1 = 0;
|
||||
cmTakeSeqBldrRendInsert( _tksbH, &e, 0, &rid );
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
void cmGrTksrFltk::_s_menuCallback(Fl_Widget* w, void* arg )
|
||||
{
|
||||
item_t* ip = (item_t*)arg;
|
||||
cmGrTksrFltk* p = ip->p;
|
||||
unsigned long id = ip->id;
|
||||
|
||||
switch( id )
|
||||
{
|
||||
case kPitchMId:
|
||||
case kScEvtMId:
|
||||
p->_setEventLabels();
|
||||
p->redraw();
|
||||
break;
|
||||
|
||||
case kDeleteMId:
|
||||
cmGrPlotObjCb(p->plotHandle(),_s_deleteSelectedEle,p);
|
||||
p->refresh();
|
||||
p->redraw();
|
||||
break;
|
||||
|
||||
case kSustainMId:
|
||||
case kSostenutoMId:
|
||||
p->_insertPedal(id);
|
||||
p->refresh();
|
||||
p->redraw();
|
||||
break;
|
||||
|
||||
case kWriteMId:
|
||||
p->_write();
|
||||
break;
|
||||
|
||||
case kReadMId:
|
||||
p->_read();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
91
src/tlCtl/cmGrTksrFltk.h
Normal file
91
src/tlCtl/cmGrTksrFltk.h
Normal file
@ -0,0 +1,91 @@
|
||||
#ifndef cmGrTksrFltk_h
|
||||
#define cmGrTksrFltk_h
|
||||
|
||||
class Fl_Menu_Bar;
|
||||
class cmdIf;
|
||||
|
||||
class cmGrTksrFltk : public cmGrPlotFltk, public gvHashFuncArg
|
||||
{
|
||||
public:
|
||||
cmGrTksrFltk(cmCtx_t* ctx, cmdIf* cp, Fl_Menu_Bar* menuBar, int x, int y, int w, int h);
|
||||
virtual ~cmGrTksrFltk();
|
||||
|
||||
void setTksbHandle( void* vp );
|
||||
|
||||
void refresh();
|
||||
|
||||
virtual double sampleRate() const;
|
||||
|
||||
virtual bool on_plot_object( cmGrPlotCbArg_t* arg );
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kOkRC,
|
||||
kInsertObjFailRC,
|
||||
kClearPlotFailRC,
|
||||
kTksbFailRC
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kPitchMId,
|
||||
kScEvtMId,
|
||||
kDeleteMId,
|
||||
kSustainMId,
|
||||
kSostenutoMId,
|
||||
kWriteMId,
|
||||
kReadMId,
|
||||
kMenuItemCnt
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cmGrTksrFltk* p;
|
||||
int id;
|
||||
} item_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
kInvalidTksrId,
|
||||
kNoteTksrId,
|
||||
kPedalTksrId,
|
||||
} tksrId_t;
|
||||
|
||||
typedef struct scObj_str
|
||||
{
|
||||
tksrId_t id;
|
||||
union
|
||||
{
|
||||
unsigned rid;
|
||||
} u;
|
||||
|
||||
scObj_str( tksrId_t i, unsigned rid ) : id(i) { u.rid=rid; }
|
||||
} scObj_t;
|
||||
|
||||
cmErr_t _err;
|
||||
//cmdIf* _cmdIf;
|
||||
cmTakeSeqBldrH_t _tksbH;
|
||||
Fl_Menu_Bar* _menuBar;
|
||||
unsigned _samplesMetricId;
|
||||
unsigned _secondsMetricId;
|
||||
//double _objSecs;
|
||||
unsigned _objId;
|
||||
//bool _togFl;
|
||||
item_t _menuArray[ kMenuItemCnt ];
|
||||
|
||||
void _insertEvent( const cmTksbRend_t* m, double srate );
|
||||
void _createMenu();
|
||||
bool _isMenuChecked( int id );
|
||||
void _setEventLabels();
|
||||
void _write();
|
||||
void _read();
|
||||
void _insertPedal( unsigned long pedalMId );
|
||||
|
||||
static void _s_deleteSelectedEle( void* arg, cmGrPlObjH_t oh );
|
||||
static void _s_menuCallback(Fl_Widget* w, void* arg);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
835
src/tlCtl/cmGrTlFltk.cpp
Normal file
835
src/tlCtl/cmGrTlFltk.cpp
Normal file
@ -0,0 +1,835 @@
|
||||
#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;
|
||||
}
|
||||
}
|
108
src/tlCtl/cmGrTlFltk.h
Normal file
108
src/tlCtl/cmGrTlFltk.h
Normal file
@ -0,0 +1,108 @@
|
||||
#ifndef cmGrTlFltk_h
|
||||
#define cmGrTlFltk_h
|
||||
|
||||
class Fl_Menu_Bar;
|
||||
class cmdIf;
|
||||
|
||||
|
||||
class cmGrTlFltk : public cmGrPlotFltk, public gvHashFuncArg
|
||||
{
|
||||
public:
|
||||
cmGrTlFltk(cmCtx_t* ctx, cmdIf* cp, Fl_Menu_Bar* menuBar, int x, int y, int w, int h);
|
||||
virtual ~cmGrTlFltk();
|
||||
|
||||
virtual cmTlUiMsgTypeId_t recvTimeLineMsg( const void* msg, unsigned msgByteCnt );
|
||||
virtual void recvAudioFileLoad( unsigned fileId );
|
||||
|
||||
virtual double sampleRate() const { return _srate; }
|
||||
|
||||
// Call these functions to notify the UI of changes of state that
|
||||
// occurred programmatically. These notifications are bubbling up
|
||||
// from the engine.
|
||||
typedef enum { kSamplesMetricId, kSecondsMetricId } timeAxisMetricId_t;
|
||||
virtual void setTimeAxisMetric( timeAxisMetricId_t metricId );
|
||||
virtual void toggleMarkerText();
|
||||
virtual unsigned timeLineSelectedMarkerId() const;
|
||||
virtual void setAudioFileCursor( unsigned smpIdx );
|
||||
virtual void selectBar( unsigned barNumb );
|
||||
|
||||
// This function is called to notify the timeline UI that that state of one of it's
|
||||
// UI elements has been changed/manipulated by the user. This is the first
|
||||
// point of contact with a requested change from the user which is being
|
||||
// directed down to the engine.
|
||||
virtual bool on_plot_object( cmGrPlotCbArg_t* arg );
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
kOkRC,
|
||||
kParentObjNotFoundRC,
|
||||
kInsertObjFailRC,
|
||||
kAudioObjFailRC,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kAudioVwIdx,
|
||||
kMidiVwIdx,
|
||||
kViewCnt
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kViewSamplesMId,
|
||||
kViewSecondsMId,
|
||||
kViewMarkTextMId,
|
||||
kViewPitchMId,
|
||||
kViewVelocityMId,
|
||||
kViewIdMId,
|
||||
kGenOnsetMarksMId,
|
||||
kDelOnsetMarksMId,
|
||||
kMenuItemCnt
|
||||
};
|
||||
|
||||
// Flags returned by _getMenuCheckFlags();
|
||||
enum { kPitchChkFl=0x01, kVelChkFl=0x02, kIdChkFl=0x04 };
|
||||
|
||||
|
||||
typedef struct item_str
|
||||
{
|
||||
cmGrTlFltk* p;
|
||||
int id;
|
||||
} item_t;
|
||||
|
||||
|
||||
cmErr_t _err;
|
||||
double _srate;
|
||||
cmdIf* _cmdIf;
|
||||
Fl_Menu_Bar* _menuBar;
|
||||
int _seqMenuIdx;
|
||||
int _seqCnt;
|
||||
item_t* _seqItemArray;
|
||||
int _markCnt;
|
||||
unsigned _samplesMetricId;
|
||||
unsigned _secondsMetricId;
|
||||
cmGrPlObjH_t _selMarkPlotObjH;
|
||||
unsigned _curSeqId;
|
||||
item_t _menuArray[ kMenuItemCnt ];
|
||||
|
||||
|
||||
void _insertTimeLineObj( const cmTlUiMsg_t* m );
|
||||
void _updateSeqMenu(int newSeqCnt, unsigned seqId);
|
||||
void _createMenu();
|
||||
bool _isMenuChecked(int id);
|
||||
unsigned _getMenuCheckFlags();
|
||||
void _setLabels();
|
||||
void _setMidiEventLabels( cmGrPlObjH_t poH, unsigned flags);
|
||||
|
||||
static void _s_seqMenuCallback( Fl_Widget* w, void* vp );
|
||||
|
||||
static void _s_midiSciPitchValueFunc( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value );
|
||||
static void _s_roundHashValueFunc( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value );
|
||||
static void _s_minSecMsHashValueFunc( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value );
|
||||
static void _s_menuCallback( Fl_Widget* w, void* arg );
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
650
src/tlCtl/cmdIf.cpp
Normal file
650
src/tlCtl/cmdIf.cpp
Normal file
@ -0,0 +1,650 @@
|
||||
#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 "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 "cmThread.h"
|
||||
#include "cmText.h"
|
||||
#include "cmFileSys.h"
|
||||
#include "cmJson.h"
|
||||
#include "cmPrefs.h"
|
||||
#include "cmSymTbl.h"
|
||||
#include "cmTime.h"
|
||||
#include "cmMidi.h"
|
||||
#include "cmMidiFile.h"
|
||||
#include "cmAudioFile.h"
|
||||
#include "cmTimeLine.h"
|
||||
|
||||
#include "cmScore.h"
|
||||
|
||||
#include "cmProcObj.h"
|
||||
#include "cmProc4.h"
|
||||
|
||||
#include "cmAudioFileMgr.h"
|
||||
#include "cmdIf.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
cmdIf::cmdIf( cmCtx_t* ctx, cmdIfRspdr* rspdr, const cmChar_t* audioPath )
|
||||
: _ctx(ctx),_thH(cmThreadNullHandle),
|
||||
_cmdQueH(cmTs1p1cNullHandle),_outQueH(cmTs1p1cNullHandle),
|
||||
_tlH(cmTimeLineNullHandle),_afmH(cmAfmNullHandle),_scH(cmScNullHandle),
|
||||
_afPath(NULL),_rspdr(rspdr),_curSeqId(cmInvalidId)
|
||||
{
|
||||
cmErrSetup(&_err,&ctx->rpt,"cmdIf");
|
||||
|
||||
cmAfmCreate(ctx,&_afmH);
|
||||
|
||||
cmThreadCreate( &_thH, _thFunc, this, &ctx->rpt );
|
||||
cmTs1p1cCreate( &_cmdQueH, 4*64536, NULL, NULL, &_ctx->rpt );
|
||||
cmTs1p1cCreate( &_outQueH, 4*64536, NULL, NULL, &_ctx->rpt );
|
||||
|
||||
if( audioPath != NULL )
|
||||
setAudioFilePath(audioPath);
|
||||
}
|
||||
|
||||
cmdIf::~cmdIf()
|
||||
{
|
||||
cmThreadDestroy( &_thH ); // stop the thread to prevent interfering with que release
|
||||
_releaseQue(&_cmdQueH);
|
||||
_releaseQue(&_outQueH);
|
||||
cmTimeLineFinalize(&_tlH);
|
||||
cmAfmDestroy(&_afmH);
|
||||
cmScoreFinalize(&_scH);
|
||||
cmMemFree(_afPath);
|
||||
}
|
||||
|
||||
cmdIf::rc_t cmdIf::open( const cmChar_t* fn )
|
||||
{ return _sendCmd(kOpenCmdId,0,fn); }
|
||||
|
||||
cmdIf::rc_t cmdIf::close( )
|
||||
{ return _sendCmd(kCloseCmdId); }
|
||||
|
||||
const cmChar_t* cmdIf::tlFileName() const
|
||||
{
|
||||
if( cmTimeLineIsValid(_tlH) == false )
|
||||
return NULL;
|
||||
|
||||
return cmTimeLineFileName(_tlH);
|
||||
}
|
||||
|
||||
const cmTlMidiFile_t* cmdIf::tlMidiFileObjPtr( const cmTlObj_t* op ) const
|
||||
{ return cmTimeLineMidiFileObjPtr(_tlH,const_cast<cmTlObj_t*>(op)); }
|
||||
|
||||
const cmTlAudioFile_t* cmdIf::tlAudioFileObjPtr( const cmTlObj_t* op ) const
|
||||
{ return cmTimeLineAudioFileObjPtr(_tlH,const_cast<cmTlObj_t*>(op)); }
|
||||
|
||||
const cmTlMidiEvt_t* cmdIf::tlMidiEvtObjPtr( const cmTlObj_t* op ) const
|
||||
|
||||
{ return cmTimeLineMidiEvtObjPtr(_tlH,const_cast<cmTlObj_t*>(op)); }
|
||||
|
||||
const cmTlAudioEvt_t* cmdIf::tlAudioEvtObjPtr( const cmTlObj_t* op ) const
|
||||
{ return cmTimeLineAudioEvtObjPtr(_tlH,const_cast<cmTlObj_t*>(op)); }
|
||||
|
||||
const cmTlMarker_t* cmdIf::tlMarkerObjPtr( const cmTlObj_t* op ) const
|
||||
{ return cmTimeLineMarkerObjPtr(_tlH,const_cast<cmTlObj_t*>(op)); }
|
||||
|
||||
|
||||
const cmChar_t* cmdIf::scoreFileName() const
|
||||
{
|
||||
if( cmScoreIsValid(_scH) == false )
|
||||
return NULL;
|
||||
return cmScoreFileName(_scH);
|
||||
}
|
||||
|
||||
const cmScoreEvt_t* cmdIf::scoreEventIdToPtr( unsigned scEvtId ) const
|
||||
{
|
||||
if( cmScoreIsValid(_scH)==false )
|
||||
return NULL;
|
||||
return cmScoreEvt(_scH,scEvtId);
|
||||
}
|
||||
|
||||
const cmScoreSection_t* cmdIf::scoreSectionIdToPtr( unsigned scSectId ) const
|
||||
{
|
||||
if( cmScoreIsValid(_scH)==false)
|
||||
return NULL;
|
||||
return cmScoreSection(_scH,scSectId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const cmTlObj_t* cmdIf::tlObjIdToPtr( unsigned tlObjId ) const
|
||||
{ return cmTlIdToObjPtr( _tlH, tlObjId ); }
|
||||
|
||||
|
||||
cmdIf::rc_t cmdIf::selectSequence( unsigned id )
|
||||
{ return _sendCmd(kSelectSeqCmdId,id); }
|
||||
|
||||
|
||||
cmdIf::rc_t cmdIf::audioFileLoad( const cmChar_t* fn, unsigned appFileId )
|
||||
{
|
||||
const cmChar_t* afFn = fn;
|
||||
//cmFileSysPathPart_t* pp = NULL ;
|
||||
|
||||
/*
|
||||
if( _afPath != NULL )
|
||||
{
|
||||
pp = cmFsPathParts(fn);
|
||||
afFn = cmFsMakeFn(_afPath,pp->fnStr,pp->extStr,NULL);
|
||||
}
|
||||
*/
|
||||
|
||||
rc_t rc = _sendCmd(kAfLoadCmdId,appFileId,afFn);
|
||||
|
||||
/*
|
||||
if( _afPath != NULL )
|
||||
{
|
||||
cmFsFreeFn(afFn);
|
||||
cmFsFreePathParts(pp);
|
||||
}
|
||||
*/
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
cmAfmFileH_t cmdIf::audioFileHandle( unsigned appFileId )
|
||||
{ return cmAfmIdToHandle(_afmH,appFileId); }
|
||||
|
||||
void cmdIf::setAudioFilePath( const cmChar_t* path )
|
||||
{ _afPath = cmMemResizeStr(_afPath,path); }
|
||||
|
||||
cmdIf::rc_t cmdIf::setScore( const cmChar_t* scoreFn )
|
||||
{ return _sendCmd(kScoreCmdId,0,scoreFn); }
|
||||
|
||||
void cmdIf::setScoreLocation( unsigned locIdx, unsigned smpIdx, unsigned pitch, unsigned vel )
|
||||
{
|
||||
cmScoreSetPerfEvent(_scH,locIdx,smpIdx,pitch,vel);
|
||||
}
|
||||
|
||||
void cmdIf::setScoreVarValue( unsigned locIdx, unsigned varId, double value )
|
||||
{
|
||||
cmScoreSetPerfValue(_scH,locIdx,varId,value);
|
||||
}
|
||||
|
||||
void cmdIf::setScoreDynLevel( unsigned evtIdx, unsigned dynLvl )
|
||||
{
|
||||
cmScoreSetPerfDynLevel(_scH,evtIdx,dynLvl);
|
||||
}
|
||||
|
||||
|
||||
void cmdIf::onTimeLineMarkerSelected( unsigned markerTlId )
|
||||
{
|
||||
if( _rspdr != NULL )
|
||||
_rspdr->cmdIfOnTimeLineMarkerSelect(markerTlId);
|
||||
|
||||
_onTimeLineObjSelected(markerTlId);
|
||||
|
||||
}
|
||||
|
||||
void cmdIf::onTimeLineMidiEvtSelected( unsigned midiEvtTlId )
|
||||
{
|
||||
if( _rspdr != NULL )
|
||||
_rspdr->cmdIfOnTimeLineMidiEvtSelect(midiEvtTlId);
|
||||
|
||||
_onTimeLineObjSelected(midiEvtTlId);
|
||||
}
|
||||
|
||||
void cmdIf::onScoreBarSelected( unsigned scoreIdx )
|
||||
{
|
||||
if( cmScoreIsValid(_scH) )
|
||||
cmScoreClearPerfInfo(_scH);
|
||||
|
||||
if( _rspdr != NULL )
|
||||
_rspdr->cmdIfOnScoreBarSelect(scoreIdx);
|
||||
|
||||
}
|
||||
|
||||
cmdIf::rc_t cmdIf::generateOnsetMarks()
|
||||
{ return _sendCmd( kGenOnsetMarksCmdId); }
|
||||
|
||||
cmdIf::rc_t cmdIf::deleteOnsetMarks()
|
||||
{ return _sendCmd( kDelOnsetMarksCmdId); }
|
||||
|
||||
|
||||
bool cmdIf::isBusy() const
|
||||
{ return cmThreadIsValid(_thH) && cmThreadState(_thH)==kRunningThId; }
|
||||
|
||||
void cmdIf::onIdle()
|
||||
{
|
||||
if( !cmTs1p1cIsValid(_outQueH) )
|
||||
return;
|
||||
|
||||
// pick up msg's sent from the worker thread
|
||||
while( cmTs1p1cMsgWaiting(_outQueH) )
|
||||
{
|
||||
cmd_t c;
|
||||
cmThRC_t thRC;
|
||||
|
||||
if((thRC = cmTs1p1cDequeueMsg(_outQueH,&c,sizeof(c))) != kOkThRC )
|
||||
{
|
||||
_thErrorMsg("Deque response failed.");
|
||||
continue;
|
||||
}
|
||||
|
||||
//printf("deq th->app id:%i val:%i n:%i msg:%p\n",c.id,c.value,c.byteCnt,c.u.msg);
|
||||
|
||||
switch( c.id )
|
||||
{
|
||||
// the worker thread is busy - show a modal progress window
|
||||
case kShowStatusCmdId:
|
||||
_rspdr->cmdIfShowStatusMsg(c.u.string);
|
||||
break;
|
||||
|
||||
// the worker thread is idle - remove the modal progress window
|
||||
case kHideStatusCmdId:
|
||||
_rspdr->cmdIfHideStatus();
|
||||
break;
|
||||
|
||||
// report an error which occured during a worker thread operation
|
||||
case kErrMsgCmdId:
|
||||
_rspdr->cmdIfErrorMsg(c.u.string);
|
||||
break;
|
||||
|
||||
// send a msg to the time-line UI
|
||||
case kTimeLineMsgCmdId:
|
||||
_rspdr->cmdIfTimeLineMsg(c.u.msg,c.byteCnt);
|
||||
break;
|
||||
|
||||
case kAfLoadCmdId:
|
||||
_rspdr->cmdIfAudioFileLoad(c.value);
|
||||
break;
|
||||
|
||||
case kScoreMsgCmdId:
|
||||
_rspdr->cmdIfScoreMsg(c.u.msg,c.byteCnt);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( c.byteCnt )
|
||||
{
|
||||
cmMemFree(c.u.msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
// App Thread Functions
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
cmdIf::rc_t cmdIf::_sendCmd( cmdId_t id, unsigned value, const char* str )
|
||||
{
|
||||
rc_t rc;
|
||||
if((rc = _enqueue( _cmdQueH, id, value, str, str==NULL ? 0 : strlen(str)+1 )) == kOkRC )
|
||||
cmThreadPause(_thH, 0 );
|
||||
else
|
||||
{
|
||||
cmErrMsg(&_err,kCmdEnqueueFailRC,"Command enque failed.");
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void cmdIf::_releaseQue( cmTs1p1cH_t* queHPtr )
|
||||
{
|
||||
|
||||
while( cmTs1p1cMsgWaiting(*queHPtr) )
|
||||
{
|
||||
cmd_t c;
|
||||
cmThRC_t thRC;
|
||||
|
||||
if((thRC = cmTs1p1cDequeueMsg(*queHPtr,&c,sizeof(c))) != kOkThRC )
|
||||
{
|
||||
// TODO: PRINT ERROR MSG HERE USING APP THREAD ERROR HANDLER
|
||||
//_thErrorMsg("Deque command failed during queue draining.");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if( c.byteCnt )
|
||||
cmMemFree(c.u.msg);
|
||||
|
||||
}
|
||||
|
||||
cmTs1p1cDestroy(queHPtr);
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Worker Thread Functions
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool cmdIf::_thFunc( void* arg )
|
||||
{
|
||||
cmdIf* p = (cmdIf*)arg;
|
||||
|
||||
while( cmTs1p1cMsgWaiting(p->_cmdQueH) )
|
||||
{
|
||||
cmd_t c;
|
||||
cmThRC_t thRC;
|
||||
|
||||
if((thRC = cmTs1p1cDequeueMsg(p->_cmdQueH,&c,sizeof(c))) != kOkThRC )
|
||||
{
|
||||
p->_thErrorMsg("Deque command failed.");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(c.id )
|
||||
{
|
||||
case kOpenCmdId:
|
||||
p->_thDoOpen(&c);
|
||||
break;
|
||||
|
||||
case kCloseCmdId:
|
||||
p->_thDoClose(&c);
|
||||
break;
|
||||
|
||||
case kSelectSeqCmdId:
|
||||
p->_thDoSelectSeq(&c);
|
||||
break;
|
||||
|
||||
case kAfLoadCmdId:
|
||||
p->_thDoAfLoad(&c);
|
||||
break;
|
||||
|
||||
case kScoreCmdId:
|
||||
p->_thDoScore(&c);
|
||||
break;
|
||||
|
||||
case kGenOnsetMarksCmdId:
|
||||
p->_thDoGenOnsetMarks(&c);
|
||||
break;
|
||||
|
||||
case kDelOnsetMarksCmdId:
|
||||
p->_thDoDelOnsetMarks(&c);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( c.byteCnt )
|
||||
cmMemFree(c.u.msg);
|
||||
|
||||
}
|
||||
|
||||
|
||||
cmThreadPause( p->_thH, kPauseThFl );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//void cmdIfRptFunc( void* user, const cmChar_t* text )
|
||||
//{ printf("%s",text); }
|
||||
|
||||
void cmdIf::_thDoOpen( const cmd_t* cmd )
|
||||
{
|
||||
_thStatusMsg("Loading: '%s'",cmd->u.string);
|
||||
|
||||
if( cmTimeLineInitializeFromFile(_ctx,&_tlH,_thSendTimeLineMsg,this,cmd->u.string,_afPath) != kOkTlRC )
|
||||
_thErrorMsg("Load failed on '%s'.",cmd->u.string);
|
||||
else
|
||||
{
|
||||
_curSeqId = 0;
|
||||
|
||||
// Make notification callbacks for all time line records to _thSendTimeLineMsg()
|
||||
// _thSendTimeLineMsg() then enqueues msg's into _outQueH which are picked
|
||||
// up by the idle handler
|
||||
cmTimeLineSeqNotify(_tlH,_curSeqId);
|
||||
}
|
||||
_thSendResponse(kHideStatusCmdId);
|
||||
}
|
||||
|
||||
void cmdIf::_thDoClose( const cmd_t* cmd )
|
||||
{
|
||||
_thStatusMsg("Closing ... ");
|
||||
|
||||
if( cmTimeLineFinalize(&_tlH) != kOkTlRC )
|
||||
{
|
||||
_thErrorMsg("Time line finalize failed.");
|
||||
}
|
||||
|
||||
_thSendResponse(kHideStatusCmdId);
|
||||
}
|
||||
|
||||
void cmdIf::_thDoSelectSeq( const cmd_t* cmd )
|
||||
{
|
||||
_thStatusMsg("Selecting Sequence:%i ",cmd->value);
|
||||
|
||||
_curSeqId = cmInvalidId;
|
||||
if( cmTimeLineSeqNotify(_tlH,cmd->value) != kOkTlRC )
|
||||
_thErrorMsg("Sequence selection failed.");
|
||||
else
|
||||
_curSeqId = cmd->value;
|
||||
|
||||
_thSendResponse(kHideStatusCmdId);
|
||||
}
|
||||
|
||||
void cmdIf::_thDoAfLoad( const cmd_t* cmd )
|
||||
{
|
||||
_thStatusMsg("Loading Audio File: '%s'",cmd->u.string);
|
||||
|
||||
cmAfmFileH_t afH = cmAfmFileNullHandle;
|
||||
|
||||
if( cmAfmFileOpen(_afmH,&afH,cmd->u.string, cmd->value, NULL ) != kOkAfmRC )
|
||||
_thErrorMsg("Audio file load failed on '%s'.",cmd->u.string);
|
||||
else
|
||||
{
|
||||
double msPerSummaryPt = 50.0;
|
||||
unsigned samplesPerSummaryPt = (unsigned)floor(cmAfmFileInfo(afH)->srate * msPerSummaryPt / 1000.0);
|
||||
|
||||
if( cmAfmFileSummarize(afH,samplesPerSummaryPt) != kOkAfmRC )
|
||||
_thErrorMsg("Audio file summarization failed on '%s'.",cmd->u.string);
|
||||
else
|
||||
_thSendResponse(kAfLoadCmdId,cmd->u.string,cmd->value);
|
||||
}
|
||||
|
||||
_thSendResponse(kHideStatusCmdId);
|
||||
}
|
||||
|
||||
void cmdIf::_thDoScore( const cmd_t* cmd )
|
||||
{
|
||||
_thStatusMsg("Loading Score File: '%s'",cmd->u.string);
|
||||
|
||||
if( cmScoreInitialize(_ctx,&_scH,cmd->u.string,0,NULL,0,_thSendScoreMsg,this,cmSymTblNullHandle) != kOkScRC )
|
||||
_thErrorMsg("Score open failed on '%s'.",cmStringNullGuard(cmd->u.string));
|
||||
else
|
||||
{
|
||||
// Make notification callbacks for all score records to _thSendScoreMsg()
|
||||
// _thSendScoreMsg() then enqueues msg's into _outQueH which are picked
|
||||
// up by the idle handler
|
||||
cmScoreSeqNotify(_scH);
|
||||
}
|
||||
_thSendResponse(kHideStatusCmdId);
|
||||
}
|
||||
|
||||
void cmdIf::_thDoGenOnsetMarks( const cmd_t* cmd )
|
||||
{
|
||||
if( !cmTimeLineIsValid(_tlH) )
|
||||
return;
|
||||
|
||||
_thStatusMsg("Generating Onset Markers.");
|
||||
|
||||
// makes notification callbacks to _thSendTimeLineMsg()
|
||||
if( cmTimeLineGenOnsetMarks(_tlH,_curSeqId) != kOkTlRC )
|
||||
_thErrorMsg("Onset marker generation failed.");
|
||||
else
|
||||
cmTimeLineSeqNotify(_tlH,_curSeqId);
|
||||
|
||||
_thSendResponse(kHideStatusCmdId);
|
||||
}
|
||||
|
||||
void cmdIf::_thDoDelOnsetMarks( const cmd_t* cmd )
|
||||
{
|
||||
if( !cmTimeLineIsValid(_tlH) )
|
||||
return;
|
||||
|
||||
_thStatusMsg("Deleting Onset Markers.");
|
||||
|
||||
// makes notification callbacks to _thSendTimeLineMsg()
|
||||
if( cmTimeLineDeleteOnsetMarks(_tlH,_curSeqId) != kOkTlRC )
|
||||
_thErrorMsg("Onset marker deletion failed.");
|
||||
|
||||
_thSendResponse(kHideStatusCmdId);
|
||||
}
|
||||
|
||||
/*
|
||||
void cmdIf::_thErrorMsg( const char* fmt, va_list vl )
|
||||
{
|
||||
const cmChar_t* s = cmTsVPrintf(fmt,vl);
|
||||
_thSendResponse(kErrMsgCmdId,s);
|
||||
cmTsFreeStr(s);
|
||||
}
|
||||
*/
|
||||
void cmdIf::_thErrorMsg( const char* fmt, ... )
|
||||
{
|
||||
va_list vl,vl1;
|
||||
va_start(vl,fmt);
|
||||
va_copy(vl1,vl);
|
||||
|
||||
int n = vsnprintf(NULL,0,fmt,vl);
|
||||
char b[n+1];
|
||||
vsnprintf(b,n+1,fmt,vl1);
|
||||
_thSendResponse(kErrMsgCmdId,b);
|
||||
|
||||
va_end(vl1);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
/*
|
||||
void cmdIf::_thStatusMsg( const char* fmt, va_list vl )
|
||||
{
|
||||
const cmChar_t* s = cmTsVPrintf(fmt,vl);
|
||||
_thSendResponse(kShowStatusCmdId,s);
|
||||
cmTsFreeStr(s);
|
||||
}
|
||||
*/
|
||||
|
||||
void cmdIf::_thStatusMsg( const char* fmt, ... )
|
||||
{
|
||||
va_list vl,vl1;
|
||||
va_start(vl,fmt);
|
||||
va_copy(vl1,vl);
|
||||
|
||||
int n = vsnprintf(NULL,0,fmt,vl);
|
||||
char b[n+1];
|
||||
vsnprintf(b,n+1,fmt,vl1);
|
||||
_thSendResponse(kShowStatusCmdId,b);
|
||||
va_end(vl1);
|
||||
va_end(vl);
|
||||
}
|
||||
|
||||
|
||||
void cmdIf::_thSendResponse( cmdId_t id, const char* str, unsigned value )
|
||||
{
|
||||
if( _enqueue( _outQueH, id, value, str, str==NULL ? 0 : strlen(str)+1 ) != kOkRC )
|
||||
{
|
||||
_thErrorMsg("Response send failed.");
|
||||
}
|
||||
}
|
||||
|
||||
void cmdIf::_thSendTimeLineMsg( void* arg, const void* msg, unsigned byteCnt )
|
||||
{
|
||||
cmdIf* p = (cmdIf*)arg;
|
||||
if( cmTs1p1cIsValid( p->_outQueH ) )
|
||||
if( p->_enqueue( p->_outQueH, kTimeLineMsgCmdId, 0, msg, byteCnt ) != kOkRC )
|
||||
p->_thErrorMsg("Time Line enqueue failed on response queue.");
|
||||
}
|
||||
|
||||
void cmdIf::_thSendScoreMsg( void* arg, const void* msg, unsigned byteCnt )
|
||||
{
|
||||
cmdIf* p = (cmdIf*)arg;
|
||||
if( cmTs1p1cIsValid( p->_outQueH ) )
|
||||
if( p->_enqueue( p->_outQueH, kScoreMsgCmdId, 0, msg, byteCnt ) != kOkRC )
|
||||
p->_thErrorMsg("Score msg enqueue failed on response queue.");
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Thread Independent Functions
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
cmdIf::rc_t cmdIf::_enqueue( cmTs1p1cH_t qH, cmdId_t id, unsigned value, const void* data, unsigned byteCnt )
|
||||
{
|
||||
cmThRC_t thRC;
|
||||
rc_t rc = kOkRC;
|
||||
cmd_t c;
|
||||
|
||||
assert( (byteCnt==0 && data==NULL) || (byteCnt!=0 && data!=NULL) );
|
||||
|
||||
c.id = id;
|
||||
c.byteCnt = byteCnt;
|
||||
c.value = value;
|
||||
c.u.msg = NULL;
|
||||
|
||||
if( byteCnt )
|
||||
{
|
||||
// memory allocated here must be deleted after the record is dequeued
|
||||
c.u.string = cmMemAlloc(char,byteCnt);
|
||||
memcpy(c.u.msg,data,byteCnt);
|
||||
}
|
||||
|
||||
//printf("enq %s id:%i n:%i msg:%p\n", cmHandlesAreEqual(qH,_outQueH) ? "thr->app" : "app->thr", c.id,c.byteCnt,c.u.string);
|
||||
|
||||
if((thRC = cmTs1p1cEnqueueMsg(qH,&c,sizeof(c))) != kOkThRC )
|
||||
{
|
||||
if( byteCnt )
|
||||
cmMemFree(c.u.string);
|
||||
|
||||
rc = kCmdFailRC;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void cmdIf::_onTimeLineObjSelected( unsigned tlObjId )
|
||||
{
|
||||
const cmTlObj_t* mop;
|
||||
if((mop = cmTimeLineIdToObj(_tlH,cmInvalidId,tlObjId)) == NULL )
|
||||
{
|
||||
cmErrMsg(&_err,kCmdFailRC,"Unexpected invalid time line marker id '%i'.",tlObjId);
|
||||
return;
|
||||
}
|
||||
|
||||
const cmTlAudioFile_t* afp = cmTimeLineAudioFileAtTime(_tlH, mop->seqId, mop->seqSmpIdx );
|
||||
const cmTlMidiFile_t* mfp = cmTimeLineMidiFileAtTime( _tlH, mop->seqId, mop->seqSmpIdx );
|
||||
const cmTlMidiEvt_t* mep = cmTimeLineMidiEvtAtTime( _tlH, mop->seqId, mop->seqSmpIdx );
|
||||
|
||||
if( afp != NULL )
|
||||
printf("%s\n",afp->fn);
|
||||
|
||||
if( mfp != NULL )
|
||||
printf("%s : %i\n",mfp->fn,mop->seqSmpIdx);
|
||||
|
||||
if( mep != NULL )
|
||||
{
|
||||
if( mep->msg->status == kNoteOnMdId )
|
||||
printf("%s : %i\n",cmMidiToSciPitch(mep->msg->u.chMsgPtr->d0,NULL,0),mep->obj.seqSmpIdx);
|
||||
else
|
||||
printf("midi:%i\n",mep->msg->status);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void cmdIf::testStub()
|
||||
{
|
||||
//ed_main();
|
||||
//cmScAlignScanMarkers(_err.rpt, _tlH, _scH );
|
||||
//sc_main(_scH,_tlH);
|
||||
cmScorePrintLoc(_scH);
|
||||
}
|
||||
|
||||
|
211
src/tlCtl/cmdIf.h
Normal file
211
src/tlCtl/cmdIf.h
Normal file
@ -0,0 +1,211 @@
|
||||
#ifndef cmdIf_h
|
||||
#define cmdIf_h
|
||||
|
||||
class Fl_Output;
|
||||
|
||||
|
||||
// This class allows the 'model' to run independently
|
||||
// from the user interface. This eliminates problems with
|
||||
// application unresponsiveness which would arise from
|
||||
// executing compute intensive operations from UI control or
|
||||
// menu callback functions. It also allows a progress
|
||||
// or status bar to be shown while the model operation
|
||||
// is in progress.
|
||||
|
||||
// The class works by enqueueing all incoming commands
|
||||
// into a thread-safe queue. An internal worker thread
|
||||
// executes the commands in the order they are received
|
||||
// and thereby changes the state of the model.
|
||||
|
||||
// The results of model changes are posted to a second
|
||||
// thread-safe queue. These responses are picked
|
||||
// up by the onIdle() member and dispatched to an
|
||||
// object with a cmIfRspdr interface. Note that because
|
||||
// the onIdle() function is called from the applications
|
||||
// idle handler the callbacks to the cmIfRspdr are
|
||||
// always in the application thread and can therefore
|
||||
// safely interact with any application data constructs.
|
||||
|
||||
// All calls to this object and all callbacks from it,
|
||||
// therefore occur in the application thread.
|
||||
|
||||
|
||||
class cmdIfRspdr
|
||||
{
|
||||
public:
|
||||
virtual ~cmdIfRspdr(){}
|
||||
virtual void cmdIfShowStatusMsg( const char* msg ) = 0;
|
||||
virtual void cmdIfHideStatus() = 0;
|
||||
virtual void cmdIfErrorMsg( const char* msg ) = 0;
|
||||
virtual void cmdIfTimeLineMsg( const void* msg, unsigned msgByteCnt ) = 0;
|
||||
virtual void cmdIfAudioFileLoad( unsigned fileId ) = 0;
|
||||
virtual void cmdIfScoreMsg( const void* msg, unsigned msgByteCnt ) = 0;
|
||||
|
||||
virtual void cmdIfOnTimeLineMarkerSelect( unsigned markerId ) = 0;
|
||||
virtual void cmdIfOnTimeLineMidiEvtSelect(unsigned midiEvtId ) = 0;
|
||||
virtual void cmdIfOnScoreBarSelect( unsigned scoreIndex ) = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class cmdIf
|
||||
{
|
||||
public:
|
||||
|
||||
typedef enum
|
||||
{
|
||||
kOkRC,
|
||||
kCmdFailRC,
|
||||
kCmdEnqueueFailRC
|
||||
} rc_t;
|
||||
|
||||
cmdIf( cmCtx_t* ctx, cmdIfRspdr* rspdr, const cmChar_t* audioPath=NULL );
|
||||
virtual ~cmdIf();
|
||||
|
||||
// Open a time line.
|
||||
rc_t open( const cmChar_t* fn );
|
||||
|
||||
// Close the time line.
|
||||
rc_t close();
|
||||
|
||||
// Time line interface
|
||||
const cmChar_t* tlFileName() const;
|
||||
const cmTlObj_t* tlObjIdToPtr( unsigned tlObjId ) const;
|
||||
const cmTlMidiFile_t* tlMidiFileObjPtr( const cmTlObj_t* op ) const;
|
||||
const cmTlAudioFile_t* tlAudioFileObjPtr( const cmTlObj_t* op ) const;
|
||||
const cmTlMidiEvt_t* tlMidiEvtObjPtr( const cmTlObj_t* op ) const;
|
||||
const cmTlAudioEvt_t* tlAudioEvtObjPtr( const cmTlObj_t* op ) const;
|
||||
const cmTlMarker_t* tlMarkerObjPtr( const cmTlObj_t* op ) const;
|
||||
|
||||
const cmChar_t* scoreFileName() const;
|
||||
const cmScoreEvt_t* scoreEventIdToPtr( unsigned scEvtId ) const;
|
||||
const cmScoreSection_t* scoreSectionIdToPtr( unsigned scSectId ) const;
|
||||
|
||||
// Make a time line sequence active.
|
||||
rc_t selectSequence( unsigned id );
|
||||
|
||||
// Load an audio file into the audio file mgr.
|
||||
// If an audio file path was set via setAudioFilePath() then
|
||||
// the directories referenced by 'fn' will be replaced by
|
||||
// the previously set audio file path.
|
||||
rc_t audioFileLoad( const cmChar_t* fn, unsigned appFileId );
|
||||
|
||||
// Return the audio file handle assigned to appFileId.
|
||||
cmAfmFileH_t audioFileHandle( unsigned appFileId );
|
||||
|
||||
// Set the audio file location.
|
||||
void setAudioFilePath( const cmChar_t* path );
|
||||
|
||||
// Assign a score file
|
||||
rc_t setScore( const cmChar_t* scoreFn );
|
||||
|
||||
// Set the current score location
|
||||
void setScoreLocation( unsigned locIdx, unsigned smpIdx, unsigned pitch, unsigned vel );
|
||||
|
||||
// Set the value of a score variable
|
||||
void setScoreVarValue( unsigned locIdx, unsigned varId, double value );
|
||||
|
||||
// Set the performed dynamic level of a score event.
|
||||
void setScoreDynLevel( unsigned evtIdx, unsigned dynLvl );
|
||||
|
||||
void onTimeLineMarkerSelected( unsigned markerTlId );
|
||||
void onTimeLineMidiEvtSelected( unsigned midiEvtTlId );
|
||||
void onScoreBarSelected( unsigned scoreIndex );
|
||||
|
||||
// Generate or delete Audio/MIDI onset markers.
|
||||
rc_t generateOnsetMarks();
|
||||
rc_t deleteOnsetMarks();
|
||||
|
||||
// True if the worker thread is running.
|
||||
bool isBusy() const;
|
||||
|
||||
// Called by the application to dequeue messages via callbacks to
|
||||
// the cmdIfRspdr.
|
||||
void onIdle();
|
||||
|
||||
void testStub();
|
||||
|
||||
private:
|
||||
|
||||
// Id's used by cmd_t
|
||||
typedef enum
|
||||
{
|
||||
kInvalidCmdId, // 0
|
||||
kOpenCmdId, // 1 app->thread
|
||||
kCloseCmdId, // 2 app->thread
|
||||
kSelectSeqCmdId, // 3 app->thread
|
||||
kAfLoadCmdId, // 4 app->thread and thread->app
|
||||
kScoreCmdId, // 5 app->thread
|
||||
kShowStatusCmdId, // 6 thread->app
|
||||
kHideStatusCmdId, // 7 thread->app
|
||||
kErrMsgCmdId, // 8 thread->app
|
||||
kTimeLineMsgCmdId, // 9 thread->app
|
||||
kScoreMsgCmdId, //10 thread->app
|
||||
kGenOnsetMarksCmdId,
|
||||
kDelOnsetMarksCmdId
|
||||
|
||||
} cmdId_t;
|
||||
|
||||
// Messages are passed between the app and the worker thread
|
||||
// and v.v. using this record format. Note that the u.msg
|
||||
// field is always dynamically allocated by _enqueue()
|
||||
// and must be released following the dequeue operation.
|
||||
typedef struct cmd_str
|
||||
{
|
||||
cmdId_t id; // cmdId
|
||||
unsigned byteCnt; // length of msg
|
||||
unsigned value; // msg value
|
||||
|
||||
union
|
||||
{
|
||||
void* msg; // msg[byteCnt]
|
||||
char* string; // string[byteCnt]
|
||||
} u;
|
||||
} cmd_t;
|
||||
|
||||
cmCtx_t* _ctx; //
|
||||
cmErr_t _err; //
|
||||
cmThreadH_t _thH; // worker thread
|
||||
cmTs1p1cH_t _cmdQueH; // app->model
|
||||
cmTs1p1cH_t _outQueH; // model->appl
|
||||
cmTlH_t _tlH; // time line handle
|
||||
cmAfmH_t _afmH; // audio file manager
|
||||
cmScH_t _scH; // score handle
|
||||
cmChar_t* _afPath; //
|
||||
cmdIfRspdr* _rspdr; //
|
||||
unsigned _curSeqId; // seqId of last selected sequence
|
||||
|
||||
|
||||
// Functions called from the app thread.
|
||||
rc_t _sendCmd( cmdId_t id, unsigned value=0, const char* str=NULL );
|
||||
void _releaseQue( cmTs1p1cH_t* queHPtr );
|
||||
|
||||
// Functions called from the worker thread
|
||||
static bool _thFunc( void* arg );
|
||||
void _thDoOpen( const cmd_t* cmd );
|
||||
void _thDoClose( const cmd_t* cmd );
|
||||
void _thDoSelectSeq( const cmd_t* cmd );
|
||||
void _thDoAfLoad( const cmd_t* cmd );
|
||||
void _thDoScore( const cmd_t* cmd );
|
||||
void _thDoGenOnsetMarks( const cmd_t* cmd );
|
||||
void _thDoDelOnsetMarks( const cmd_t* cmd );
|
||||
|
||||
//void _thErrorMsg( const char* fmt, va_list vl );
|
||||
void _thErrorMsg( const char* fmt, ... );
|
||||
//void _thStatusMsg( const char* fmt, va_list vl );
|
||||
void _thStatusMsg( const char* fmt, ... );
|
||||
void _thSendResponse( cmdId_t id, const char* str = NULL, unsigned value=0 );
|
||||
static void _thSendTimeLineMsg( void* arg, const void* msg, unsigned byteCnt );
|
||||
static void _thSendScoreMsg( void* arg, const void* msg, unsigned byteCnt );
|
||||
|
||||
// Thread independent functions
|
||||
rc_t _enqueue( cmTs1p1cH_t qH, cmdId_t id, unsigned value, const void* msg, unsigned msgByteCnt );
|
||||
|
||||
|
||||
// Print context information for selected time line objects
|
||||
void _onTimeLineObjSelected( unsigned tlObjId );
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
62
src/tlCtl/gvHashFunc.cpp
Normal file
62
src/tlCtl/gvHashFunc.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
#include "cmPrefix.h"
|
||||
#include "cmGlobal.h"
|
||||
#include "cmFloatTypes.h"
|
||||
#include "cmRpt.h"
|
||||
#include "cmErr.h"
|
||||
#include "cmCtx.h"
|
||||
#include "cmTime.h"
|
||||
#include "cmMidi.h"
|
||||
#include "cmGr.h"
|
||||
#include "gvHashFunc.h"
|
||||
|
||||
void gvRoundHashValueFunc( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value )
|
||||
{
|
||||
snprintf(label,labelCharCnt,"%i",(int)round(value));
|
||||
}
|
||||
|
||||
void gvMidiSciPitchValueFunc( 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 gvMinSecMsHashValueFunc( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value )
|
||||
{
|
||||
gvHashFuncArg* p = (gvHashFuncArg*)arg;
|
||||
|
||||
int min=0,sec=0,ms=0;
|
||||
|
||||
double smpPerMin = p->sampleRate() * 60.0;
|
||||
double smpPerMs = p->sampleRate() / 1000.0;
|
||||
|
||||
if( value > smpPerMin )
|
||||
{
|
||||
min = (int)floor( value / smpPerMin );
|
||||
value -= min * smpPerMin;
|
||||
}
|
||||
|
||||
if( value > p->sampleRate() )
|
||||
{
|
||||
sec = (int)floor( value / p->sampleRate() );
|
||||
value -= sec * p->sampleRate();
|
||||
}
|
||||
|
||||
|
||||
if( value > smpPerMs )
|
||||
{
|
||||
ms = (int)floor( value / smpPerMs );
|
||||
value -= ms * smpPerMs;
|
||||
}
|
||||
|
||||
snprintf(label,labelCharCnt,"%i:%2i:%2i",min,sec,ms);
|
||||
}
|
||||
|
18
src/tlCtl/gvHashFunc.h
Normal file
18
src/tlCtl/gvHashFunc.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef gvHashFunc_h
|
||||
#define gvHashFunc_h
|
||||
|
||||
class gvHashFuncArg
|
||||
{
|
||||
public:
|
||||
virtual ~gvHashFuncArg(){}
|
||||
virtual double sampleRate() const = 0;
|
||||
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
void gvRoundHashValueFunc( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value );
|
||||
void gvMinSecMsHashValueFunc( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value );
|
||||
void gvMidiSciPitchValueFunc( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value );
|
||||
}
|
||||
|
||||
#endif
|
388
src/tlCtl/tlCtl.cpp
Normal file
388
src/tlCtl/tlCtl.cpp
Normal file
@ -0,0 +1,388 @@
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Widget.H>
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <FL/Fl_Menu_Bar.H>
|
||||
#include <FL/Fl_Group.H>
|
||||
#include <FL/fl_draw.H>
|
||||
|
||||
#include <vector>
|
||||
#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();
|
||||
}
|
99
src/tlCtl/tlCtl.h
Normal file
99
src/tlCtl/tlCtl.h
Normal file
@ -0,0 +1,99 @@
|
||||
#ifndef tlCtl_h
|
||||
#define tlCtl_h
|
||||
|
||||
class Fl_Menu_Bar;
|
||||
class cmGrTlFltk;
|
||||
class cmGrScFltk;
|
||||
class cmGrTksbFltk;
|
||||
class cmGrTksrFltk;
|
||||
class cmGr2dFltk;
|
||||
class tlStatusWnd;
|
||||
class tlCtl;
|
||||
|
||||
class tlCtlRspdr
|
||||
{
|
||||
public:
|
||||
virtual ~tlCtlRspdr(){}
|
||||
virtual void tlCtlNewTimeLineFile( tlCtl* tlCtl, const cmChar_t* fn ) = 0;
|
||||
virtual void tlCtlNewScoreFile( tlCtl* tlCtl, const cmChar_t* fn ) = 0;
|
||||
|
||||
};
|
||||
|
||||
class tlCtl : public cmdIfRspdr
|
||||
{
|
||||
public:
|
||||
tlCtl( cmCtx_t* ctx, Fl_Window* app, Fl_Menu_Bar* menuBar, tlCtlRspdr* rspdr );
|
||||
virtual ~tlCtl();
|
||||
|
||||
//
|
||||
// This group of functions represent commands from the application (kcApp) to the
|
||||
// time-line control.
|
||||
//
|
||||
|
||||
Fl_Widget* initTimeLineCtlr( int x, int y, int w, int h );
|
||||
Fl_Widget* initScoreCtlr( int x, int y, int w, int h );
|
||||
Fl_Widget* initTakeSeqBldrCtlr( int x, int y, int w, int h );
|
||||
Fl_Widget* initTakeSeqRendCtlr( int x, int y, int w, int h );
|
||||
Fl_Widget* init2dCtlr( int x, int y, int w, int h );
|
||||
|
||||
void openTlFile( const cmChar_t* fn );
|
||||
void openScoreFile( const cmChar_t* fn );
|
||||
void openTakeSeqBldr( void* v );
|
||||
void openTakeSeqRend( void* v );
|
||||
void setAudioFilePath( const cmChar_t* path );
|
||||
void setAudioFileCursor( unsigned smpIdx );
|
||||
void setTimeLineSelectBar( unsigned barNumb );
|
||||
void setScoreSelectBar( unsigned barNumb );
|
||||
|
||||
// Set the currrent score location
|
||||
void setScoreLocation( unsigned locIdx, unsigned smpIdx, unsigned pitch, unsigned vel );
|
||||
|
||||
// Set the value of a score variable.
|
||||
void setScoreVarValue( unsigned locIdx, unsigned varId, double value );
|
||||
|
||||
// Set the performed dynamic level of a score event.
|
||||
void setScoreDynLevel( unsigned evtIdx, unsigned dynLvl );
|
||||
|
||||
void refreshTakeSeqRend();
|
||||
|
||||
void onIdle();
|
||||
|
||||
|
||||
//
|
||||
// cmdIfRspdr Interface
|
||||
//
|
||||
// These functions are callbacks from cmdIf to communicate
|
||||
// from cmdIf processes to the UI or back to the engine.
|
||||
|
||||
virtual void cmdIfShowStatusMsg( const char* msg );
|
||||
virtual void cmdIfHideStatus();
|
||||
virtual void cmdIfErrorMsg( const char* msg );
|
||||
virtual void cmdIfTimeLineMsg( const void* msg, unsigned msgByteCnt );
|
||||
virtual void cmdIfAudioFileLoad( unsigned fileId );
|
||||
virtual void cmdIfScoreMsg( const void* msg, unsigned msgByteCnt );
|
||||
virtual void cmdIfOnTimeLineMarkerSelect( unsigned markerId );
|
||||
virtual void cmdIfOnTimeLineMidiEvtSelect(unsigned midiEvtId );
|
||||
virtual void cmdIfOnScoreBarSelect( unsigned scoreIndex );
|
||||
|
||||
unsigned timeLineSelectedMarkerId() const;
|
||||
unsigned scoreSelectedEleIndex() const;
|
||||
unsigned tksbSelectedEleIndex() const;
|
||||
|
||||
void testStub();
|
||||
|
||||
private:
|
||||
cmErr_t _err;
|
||||
cmCtx_t* _ctx;
|
||||
tlCtlRspdr* _rspdr;
|
||||
cmdIf* _cmdIf;
|
||||
cmGrTlFltk* _tlCtlr;
|
||||
cmGrScFltk* _scCtlr;
|
||||
cmGrTksbFltk* _tksbCtlr;
|
||||
cmGrTksrFltk* _tksrCtlr;
|
||||
cmGr2dFltk* _2dCtlr;
|
||||
tlStatusWnd* _statusWnd;
|
||||
Fl_Menu_Bar* _menu;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user