| @@ -17,7 +17,7 @@ | |||||
| /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||||
| /*******************************************************************************/ | /*******************************************************************************/ | ||||
| #include "Audio_Track.H" | |||||
| #include "Audio_Sequence.H" | |||||
| #include "dsp.h" | #include "dsp.h" | ||||
| @@ -54,13 +54,13 @@ deurlify ( char *url ) | |||||
| /** event handler that supports DND of audio clips */ | /** event handler that supports DND of audio clips */ | ||||
| int | int | ||||
| Audio_Track::handle ( int m ) | |||||
| Audio_Sequence::handle ( int m ) | |||||
| { | { | ||||
| switch ( m ) | switch ( m ) | ||||
| { | { | ||||
| case FL_DND_DRAG: | case FL_DND_DRAG: | ||||
| return Track::handle( m ) | 1; | |||||
| return Sequence::handle( m ) | 1; | |||||
| /* case FL_DND_ENTER: */ | /* case FL_DND_ENTER: */ | ||||
| /* case FL_DND_LEAVE: */ | /* case FL_DND_LEAVE: */ | ||||
| @@ -110,7 +110,7 @@ Audio_Track::handle ( int m ) | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| default: | default: | ||||
| return Track::handle( m ); | |||||
| return Sequence::handle( m ); | |||||
| } | } | ||||
| } | } | ||||
| @@ -123,14 +123,14 @@ Audio_Track::handle ( int m ) | |||||
| /** determine region coverage and fill /buf/ with interleaved samples | /** determine region coverage and fill /buf/ with interleaved samples | ||||
| * from /frame/ to /nframes/ for exactly /channels/ channels. */ | * from /frame/ to /nframes/ for exactly /channels/ channels. */ | ||||
| nframes_t | nframes_t | ||||
| Audio_Track::play ( sample_t *buf, nframes_t frame, nframes_t nframes, int channels ) | |||||
| Audio_Sequence::play ( sample_t *buf, nframes_t frame, nframes_t nframes, int channels ) | |||||
| { | { | ||||
| sample_t *cbuf = new sample_t[ nframes ]; | sample_t *cbuf = new sample_t[ nframes ]; | ||||
| memset( cbuf, 0, nframes * sizeof( sample_t ) ); | memset( cbuf, 0, nframes * sizeof( sample_t ) ); | ||||
| /* quick and dirty--let the regions figure out coverage for themselves */ | /* quick and dirty--let the regions figure out coverage for themselves */ | ||||
| for ( list <Track_Widget *>::const_iterator i = _widgets.begin(); | |||||
| for ( list <Sequence_Widget *>::const_iterator i = _widgets.begin(); | |||||
| i != _widgets.end(); i++ ) | i != _widgets.end(); i++ ) | ||||
| { | { | ||||
| const Region *r = (Region*)(*i); | const Region *r = (Region*)(*i); | ||||
| @@ -158,7 +158,7 @@ Audio_Track::play ( sample_t *buf, nframes_t frame, nframes_t nframes, int chann | |||||
| /* /\* THREAD: RT *\/ */ | /* /\* THREAD: RT *\/ */ | ||||
| /* nframes_t */ | /* nframes_t */ | ||||
| /* Audio_Track::process ( nframes_t nframes ) */ | |||||
| /* Audio_Sequence::process ( nframes_t nframes ) */ | |||||
| /* { */ | /* { */ | ||||
| /* return disktream->process( nframes ); */ | /* return disktream->process( nframes ); */ | ||||
| /* } */ | /* } */ | ||||
| @@ -19,36 +19,36 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Track.H" | |||||
| #include "Sequence.H" | |||||
| #include "Region.H" | #include "Region.H" | ||||
| #include <FL/Fl_Input.H> | #include <FL/Fl_Input.H> | ||||
| class Audio_Track : public Track | |||||
| class Audio_Sequence : public Sequence | |||||
| { | { | ||||
| public: | public: | ||||
| Audio_Track ( int X, int Y, int W, int H ) : Track( X, Y, W, H ) | |||||
| Audio_Sequence ( int X, int Y, int W, int H ) : Sequence( X, Y, W, H ) | |||||
| { | { | ||||
| log_create(); | log_create(); | ||||
| } | } | ||||
| ~Audio_Track ( ) | |||||
| ~Audio_Sequence ( ) | |||||
| { | { | ||||
| log_destroy(); | log_destroy(); | ||||
| } | } | ||||
| Track * clone_empty ( void ) | |||||
| Sequence * clone_empty ( void ) | |||||
| { | { | ||||
| Audio_Track *t = new Audio_Track( x(), y(), w(), h() ); | |||||
| Audio_Sequence *t = new Audio_Sequence( x(), y(), w(), h() ); | |||||
| return t; | return t; | ||||
| } | } | ||||
| const char *class_name ( void ) { return "Audio_Track"; } | |||||
| const char *class_name ( void ) { return "Audio_Sequence"; } | |||||
| int handle ( int m ); | int handle ( int m ); | ||||
| void dump ( void ); | void dump ( void ); | ||||
| @@ -19,9 +19,9 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Track_Point.H" | |||||
| #include "Sequence_Point.H" | |||||
| class Control_Point : public Track_Point | |||||
| class Control_Point : public Sequence_Point | |||||
| { | { | ||||
| float _y; | float _y; | ||||
| @@ -74,7 +74,7 @@ protected: | |||||
| { | { | ||||
| int i; | int i; | ||||
| sscanf( v, "%X", &i ); | sscanf( v, "%X", &i ); | ||||
| Track *t = (Track*)Loggable::find( i ); | |||||
| Sequence *t = (Sequence*)Loggable::find( i ); | |||||
| assert( t ); | assert( t ); | ||||
| @@ -113,7 +113,7 @@ public: | |||||
| } | } | ||||
| Control_Point ( Track *t, nframes_t when, float y ) | |||||
| Control_Point ( Sequence *t, nframes_t when, float y ) | |||||
| { | { | ||||
| _track = t; | _track = t; | ||||
| _y = y; | _y = y; | ||||
| @@ -130,7 +130,7 @@ public: | |||||
| _y = rhs._y; | _y = rhs._y; | ||||
| } | } | ||||
| Track_Widget *clone ( const Track_Widget *r ) | |||||
| Sequence_Widget *clone ( const Sequence_Widget *r ) | |||||
| { | { | ||||
| return new Control_Point( *(Control_Point*)r ); | return new Control_Point( *(Control_Point*)r ); | ||||
| } | } | ||||
| @@ -147,7 +147,7 @@ public: | |||||
| int | int | ||||
| handle ( int m ) | handle ( int m ) | ||||
| { | { | ||||
| int r = Track_Widget::handle( m ); | |||||
| int r = Sequence_Widget::handle( m ); | |||||
| switch ( m ) | switch ( m ) | ||||
| { | { | ||||
| @@ -19,28 +19,28 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Track.H" | |||||
| #include "Sequence.H" | |||||
| #include "Control_Point.H" | #include "Control_Point.H" | ||||
| class Control_Track : public Track | |||||
| class Control_Sequence : public Sequence | |||||
| { | { | ||||
| public: | public: | ||||
| Control_Track ( int X, int Y, int W, int H ) : Track( X, Y, W, H ) | |||||
| Control_Sequence ( int X, int Y, int W, int H ) : Sequence( X, Y, W, H ) | |||||
| { | { | ||||
| color( fl_darker( FL_GREEN ) ); | color( fl_darker( FL_GREEN ) ); | ||||
| log_create(); | log_create(); | ||||
| } | } | ||||
| ~Control_Track ( ) | |||||
| ~Control_Sequence ( ) | |||||
| { | { | ||||
| log_destroy(); | log_destroy(); | ||||
| } | } | ||||
| const char *class_name ( void ) { return "Control_Track"; } | |||||
| const char *class_name ( void ) { return "Control_Sequence"; } | |||||
| void | void | ||||
| draw ( void ) | draw ( void ) | ||||
| @@ -63,11 +63,11 @@ public: | |||||
| fl_begin_complex_polygon(); | fl_begin_complex_polygon(); | ||||
| list <Track_Widget *>::const_iterator e = _widgets.end(); | |||||
| list <Sequence_Widget *>::const_iterator e = _widgets.end(); | |||||
| e--; | e--; | ||||
| if ( _widgets.size() ) | if ( _widgets.size() ) | ||||
| for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); ; r++ ) | |||||
| for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); ; r++ ) | |||||
| { | { | ||||
| if ( r == _widgets.begin() ) | if ( r == _widgets.begin() ) | ||||
| { | { | ||||
| @@ -92,7 +92,7 @@ public: | |||||
| timeline->draw_measure_lines( x(), y(), w(), h(), color() ); | timeline->draw_measure_lines( x(), y(), w(), h(), color() ); | ||||
| for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | |||||
| for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | |||||
| (*r)->draw_box(); | (*r)->draw_box(); | ||||
| fl_pop_clip(); | fl_pop_clip(); | ||||
| @@ -101,7 +101,7 @@ public: | |||||
| int | int | ||||
| handle ( int m ) | handle ( int m ) | ||||
| { | { | ||||
| int r = Track::handle( m ); | |||||
| int r = Sequence::handle( m ); | |||||
| if ( r ) | if ( r ) | ||||
| return r; | return r; | ||||
| @@ -18,8 +18,8 @@ | |||||
| /*******************************************************************************/ | /*******************************************************************************/ | ||||
| #include "Disk_Stream.H" | #include "Disk_Stream.H" | ||||
| #include "Track_Header.H" | |||||
| #include "Audio_Track.H" | |||||
| #include "Track.H" | |||||
| #include "Audio_Sequence.H" | |||||
| #include "Port.H" | #include "Port.H" | ||||
| #include "Engine.H" // for locking. | #include "Engine.H" // for locking. | ||||
| @@ -53,7 +53,7 @@ | |||||
| float Disk_Stream::seconds_to_buffer = 5.0f; | float Disk_Stream::seconds_to_buffer = 5.0f; | ||||
| // size_t Disk_Stream::disk_block_frames = 2048; | // size_t Disk_Stream::disk_block_frames = 2048; | ||||
| Disk_Stream::Disk_Stream ( Track_Header *th, float frame_rate, nframes_t nframes, int channels ) : _th( th ) | |||||
| Disk_Stream::Disk_Stream ( Track *th, float frame_rate, nframes_t nframes, int channels ) : _th( th ) | |||||
| { | { | ||||
| _frame = 0; | _frame = 0; | ||||
| _thread = 0; | _thread = 0; | ||||
| @@ -99,10 +99,10 @@ Disk_Stream::shutdown ( void ) | |||||
| pthread_join( _thread, NULL ); | pthread_join( _thread, NULL ); | ||||
| } | } | ||||
| Audio_Track * | |||||
| Audio_Sequence * | |||||
| Disk_Stream::track ( void ) | Disk_Stream::track ( void ) | ||||
| { | { | ||||
| return (Audio_Track*)_th->track(); | |||||
| return (Audio_Sequence*)_th->track(); | |||||
| } | } | ||||
| /** start Disk_Stream thread */ | /** start Disk_Stream thread */ | ||||
| @@ -32,8 +32,8 @@ | |||||
| #include <vector> | #include <vector> | ||||
| using std::vector; | using std::vector; | ||||
| class Track_Header; | |||||
| class Audio_Track; | |||||
| class Track; | |||||
| class Audio_Sequence; | |||||
| class Disk_Stream : public Mutex | class Disk_Stream : public Mutex | ||||
| { | { | ||||
| @@ -42,7 +42,7 @@ protected: | |||||
| pthread_t _thread; /* io thread */ | pthread_t _thread; /* io thread */ | ||||
| Track_Header *_th; /* Track_Header we belong to */ | |||||
| Track *_th; /* Track we belong to */ | |||||
| nframes_t _nframes; /* buffer size */ | nframes_t _nframes; /* buffer size */ | ||||
| @@ -59,7 +59,7 @@ protected: | |||||
| int channels ( void ) const { return _rb.size(); } | int channels ( void ) const { return _rb.size(); } | ||||
| Audio_Track * track ( void ); | |||||
| Audio_Sequence * track ( void ); | |||||
| static void *disk_thread ( void *arg ); | static void *disk_thread ( void *arg ); | ||||
| @@ -84,7 +84,7 @@ public: | |||||
| /* must be set before any Disk_Streams are created */ | /* must be set before any Disk_Streams are created */ | ||||
| static float seconds_to_buffer; | static float seconds_to_buffer; | ||||
| Disk_Stream ( Track_Header *th, float frame_rate, nframes_t nframes, int channels ); | |||||
| Disk_Stream ( Track *th, float frame_rate, nframes_t nframes, int channels ); | |||||
| virtual ~Disk_Stream ( ); | virtual ~Disk_Stream ( ); | ||||
| @@ -3,11 +3,11 @@ SRCS= \ | |||||
| Waveform.C \ | Waveform.C \ | ||||
| Region.C \ | Region.C \ | ||||
| main.C \ | main.C \ | ||||
| Track.C \ | |||||
| Audio_Track.C \ | |||||
| Sequence.C \ | |||||
| Audio_Sequence.C \ | |||||
| Timeline.C \ | Timeline.C \ | ||||
| Track_Header.C \ | |||||
| Track_Widget.C \ | |||||
| Track.C \ | |||||
| Sequence_Widget.C \ | |||||
| Tempo_Point.C \ | Tempo_Point.C \ | ||||
| Time_Point.C \ | Time_Point.C \ | ||||
| Peaks.C \ | Peaks.C \ | ||||
| @@ -23,8 +23,8 @@ | |||||
| /* FIXME: we shouldn't depend on these */ | /* FIXME: we shouldn't depend on these */ | ||||
| #include "Timeline.H" | #include "Timeline.H" | ||||
| #include "Engine.H" | #include "Engine.H" | ||||
| #include "Audio_Track.H" | |||||
| #include "Track_Header.H" | |||||
| #include "Audio_Sequence.H" | |||||
| #include "Track.H" | |||||
| #include "Port.H" | #include "Port.H" | ||||
| #include "Playback_DS.H" | #include "Playback_DS.H" | ||||
| @@ -27,7 +27,7 @@ class Playback_DS : public Disk_Stream | |||||
| public: | public: | ||||
| Playback_DS ( Track_Header *th, float frame_rate, nframes_t nframes, int channels ) : | |||||
| Playback_DS ( Track *th, float frame_rate, nframes_t nframes, int channels ) : | |||||
| Disk_Stream( th, frame_rate, nframes, channels ) | Disk_Stream( th, frame_rate, nframes, channels ) | ||||
| { | { | ||||
| run(); | run(); | ||||
| @@ -22,8 +22,8 @@ | |||||
| /* FIXME: we shouldn't depend on these */ | /* FIXME: we shouldn't depend on these */ | ||||
| #include "Timeline.H" | #include "Timeline.H" | ||||
| #include "Engine.H" | #include "Engine.H" | ||||
| #include "Audio_Track.H" | |||||
| #include "Track_Header.H" | |||||
| #include "Audio_Sequence.H" | |||||
| #include "Track.H" | |||||
| #include "Port.H" | #include "Port.H" | ||||
| #include "Record_DS.H" | #include "Record_DS.H" | ||||
| @@ -37,7 +37,7 @@ class Record_DS : public Disk_Stream | |||||
| public: | public: | ||||
| Record_DS ( Track_Header *th, float frame_rate, nframes_t nframes, int channels ) : | |||||
| Record_DS ( Track *th, float frame_rate, nframes_t nframes, int channels ) : | |||||
| Disk_Stream( th, frame_rate, nframes, channels ) | Disk_Stream( th, frame_rate, nframes, channels ) | ||||
| { | { | ||||
| sem_destroy( &_blocks ); | sem_destroy( &_blocks ); | ||||
| @@ -17,7 +17,7 @@ | |||||
| /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||||
| /*******************************************************************************/ | /*******************************************************************************/ | ||||
| #include "Track.H" | |||||
| #include "Sequence.H" | |||||
| #include "Region.H" | #include "Region.H" | ||||
| #include "Timeline.H" | #include "Timeline.H" | ||||
| #include "Waveform.H" | #include "Waveform.H" | ||||
| @@ -103,7 +103,7 @@ Region::init ( void ) | |||||
| /* copy constructor */ | /* copy constructor */ | ||||
| Region::Region ( const Region & rhs ) | Region::Region ( const Region & rhs ) | ||||
| { | { | ||||
| *((Track_Widget*)this) = (Track_Widget &)rhs; | |||||
| *((Sequence_Widget*)this) = (Sequence_Widget &)rhs; | |||||
| _clip = rhs._clip; | _clip = rhs._clip; | ||||
| _scale = rhs._scale; | _scale = rhs._scale; | ||||
| @@ -114,8 +114,8 @@ Region::Region ( const Region & rhs ) | |||||
| log_create(); | log_create(); | ||||
| } | } | ||||
| Track_Widget * | |||||
| Region::clone ( const Track_Widget *r ) | |||||
| Sequence_Widget * | |||||
| Region::clone ( const Sequence_Widget *r ) | |||||
| { | { | ||||
| return new Region( *(Region*)r ); | return new Region( *(Region*)r ); | ||||
| } | } | ||||
| @@ -132,7 +132,7 @@ Region::Region ( Audio_File *c ) | |||||
| /* used when DND importing */ | /* used when DND importing */ | ||||
| Region::Region ( Audio_File *c, Track *t, nframes_t o ) | |||||
| Region::Region ( Audio_File *c, Sequence *t, nframes_t o ) | |||||
| { | { | ||||
| init(); | init(); | ||||
| _clip = c; | _clip = c; | ||||
| @@ -242,11 +242,11 @@ Region::handle ( int m ) | |||||
| switch ( m ) | switch ( m ) | ||||
| { | { | ||||
| case FL_ENTER: | case FL_ENTER: | ||||
| Track_Widget::handle( m ); | |||||
| Sequence_Widget::handle( m ); | |||||
| redraw(); | redraw(); | ||||
| break; | break; | ||||
| case FL_LEAVE: | case FL_LEAVE: | ||||
| Track_Widget::handle( m ); | |||||
| Sequence_Widget::handle( m ); | |||||
| redraw(); | redraw(); | ||||
| break; | break; | ||||
| case FL_KEYBOARD: | case FL_KEYBOARD: | ||||
| @@ -335,7 +335,7 @@ Region::handle ( int m ) | |||||
| normalize(); | normalize(); | ||||
| else | else | ||||
| { | { | ||||
| if ( Track_Widget::current() == this ) | |||||
| if ( Sequence_Widget::current() == this ) | |||||
| { | { | ||||
| if ( selected() ) | if ( selected() ) | ||||
| deselect(); | deselect(); | ||||
| @@ -390,14 +390,14 @@ Region::handle ( int m ) | |||||
| } | } | ||||
| else | else | ||||
| return Track_Widget::handle( m ); | |||||
| return Sequence_Widget::handle( m ); | |||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case FL_RELEASE: | case FL_RELEASE: | ||||
| { | { | ||||
| Track_Widget::handle( m ); | |||||
| Sequence_Widget::handle( m ); | |||||
| copied = false; | copied = false; | ||||
| if ( trimming != NO ) | if ( trimming != NO ) | ||||
| @@ -470,10 +470,10 @@ Region::handle ( int m ) | |||||
| } | } | ||||
| } | } | ||||
| ret = Track_Widget::handle( m ); | |||||
| ret = Sequence_Widget::handle( m ); | |||||
| return ret | 1; | return ret | 1; | ||||
| default: | default: | ||||
| return Track_Widget::handle( m ); | |||||
| return Sequence_Widget::handle( m ); | |||||
| break; | break; | ||||
| } | } | ||||
| @@ -19,18 +19,18 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Audio_File.H" | #include "Audio_File.H" | ||||
| #include "Track.H" | |||||
| #include "Sequence.H" | |||||
| #include "Timeline.H" | #include "Timeline.H" | ||||
| /* Regions are "virtual" FLTK widgets; this is necessary because the | /* Regions are "virtual" FLTK widgets; this is necessary because the | ||||
| * dimensions of real FLTK widgets are limited to 16-bits, which is | * dimensions of real FLTK widgets are limited to 16-bits, which is | ||||
| * far too little for our purposes */ | * far too little for our purposes */ | ||||
| #include "Track_Widget.H" | |||||
| #include "Sequence_Widget.H" | |||||
| #include "Loggable.H" | #include "Loggable.H" | ||||
| class Region : public Track_Widget | |||||
| class Region : public Sequence_Widget | |||||
| { | { | ||||
| public: | public: | ||||
| @@ -98,7 +98,7 @@ private: | |||||
| Fade _fade_in; | Fade _fade_in; | ||||
| Fade _fade_out; | Fade _fade_out; | ||||
| friend class Track_Header; /* for _clip */ | |||||
| friend class Track; /* for _clip */ | |||||
| protected: | protected: | ||||
| const char *class_name ( void ) { return "Region"; } | const char *class_name ( void ) { return "Region"; } | ||||
| @@ -166,7 +166,7 @@ protected: | |||||
| { | { | ||||
| int i; | int i; | ||||
| sscanf( v, "%X", &i ); | sscanf( v, "%X", &i ); | ||||
| Track *t = (Track*)Loggable::find( i ); | |||||
| Sequence *t = (Sequence*)Loggable::find( i ); | |||||
| assert( t ); | assert( t ); | ||||
| @@ -200,7 +200,7 @@ public: | |||||
| bool current ( void ) const { return this == belowmouse(); } | bool current ( void ) const { return this == belowmouse(); } | ||||
| friend class Track_Header; /* for _clip in Track_Header::write() */ | |||||
| friend class Track; /* for _clip in Track::write() */ | |||||
| public: | public: | ||||
| @@ -216,7 +216,7 @@ public: | |||||
| } | } | ||||
| Track_Widget *clone ( const Track_Widget *r ); | |||||
| Sequence_Widget *clone ( const Sequence_Widget *r ); | |||||
| ~Region ( ) | ~Region ( ) | ||||
| { | { | ||||
| @@ -228,7 +228,7 @@ public: | |||||
| Region ( const Region & rhs ); | Region ( const Region & rhs ); | ||||
| Region ( Audio_File *c ); | Region ( Audio_File *c ); | ||||
| Region ( Audio_File *c, Track *t, nframes_t o ); | |||||
| Region ( Audio_File *c, Sequence *t, nframes_t o ); | |||||
| int handle ( int m ); | int handle ( int m ); | ||||
| void draw_fade ( const Fade &fade, Fade::fade_dir_e dir, bool filled, int X, int W ); | void draw_fade ( const Fade &fade, Fade::fade_dir_e dir, bool filled, int X, int W ); | ||||
| @@ -20,9 +20,9 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Loggable.H" | #include "Loggable.H" | ||||
| #include "Track_Point.H" | |||||
| #include "Sequence_Point.H" | |||||
| class Ruler_Point : public Track_Point | |||||
| class Ruler_Point : public Sequence_Point | |||||
| { | { | ||||
| public: | public: | ||||
| @@ -73,7 +73,7 @@ protected: | |||||
| { | { | ||||
| int i; | int i; | ||||
| sscanf( v, "%X", &i ); | sscanf( v, "%X", &i ); | ||||
| Track *t = (Track*)Loggable::find( i ); | |||||
| Sequence *t = (Sequence*)Loggable::find( i ); | |||||
| assert( t ); | assert( t ); | ||||
| @@ -123,7 +123,7 @@ public: | |||||
| _label = strdup( rhs._label ); | _label = strdup( rhs._label ); | ||||
| } | } | ||||
| Track_Widget *clone ( const Track_Widget *r ) | |||||
| Sequence_Widget *clone ( const Sequence_Widget *r ) | |||||
| { | { | ||||
| return new Ruler_Point( *(Ruler_Point*)r ); | return new Ruler_Point( *(Ruler_Point*)r ); | ||||
| } | } | ||||
| @@ -138,7 +138,7 @@ public: | |||||
| int | int | ||||
| handle ( int m ) | handle ( int m ) | ||||
| { | { | ||||
| int r = Track_Widget::handle( m ); | |||||
| int r = Sequence_Widget::handle( m ); | |||||
| if ( m == FL_RELEASE ) | if ( m == FL_RELEASE ) | ||||
| { | { | ||||
| @@ -19,16 +19,16 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Track.H" | |||||
| #include "Sequence.H" | |||||
| #include "Ruler_Point.H" | #include "Ruler_Point.H" | ||||
| #include "Timeline.H" | #include "Timeline.H" | ||||
| class Ruler_Track : public Track | |||||
| class Ruler_Sequence : public Sequence | |||||
| { | { | ||||
| public: | public: | ||||
| Ruler_Track ( int X, int Y, int W, int H ) : Track ( X, Y, W, H ) | |||||
| Ruler_Sequence ( int X, int Y, int W, int H ) : Sequence ( X, Y, W, H ) | |||||
| { | { | ||||
| box( FL_UP_BOX ); | box( FL_UP_BOX ); | ||||
| } | } | ||||
| @@ -36,7 +36,7 @@ public: | |||||
| void | void | ||||
| draw ( void ) | draw ( void ) | ||||
| { | { | ||||
| Track::draw(); | |||||
| Sequence::draw(); | |||||
| timeline->draw_measure_BBT( x(), y(), w(), h(), FL_WHITE ); | timeline->draw_measure_BBT( x(), y(), w(), h(), FL_WHITE ); | ||||
| } | } | ||||
| @@ -0,0 +1,417 @@ | |||||
| /*******************************************************************************/ | |||||
| /* Copyright (C) 2008 Jonathan Moore Liles */ | |||||
| /* */ | |||||
| /* This program is free software; you can redistribute it and/or modify it */ | |||||
| /* under the terms of the GNU General Public License as published by the */ | |||||
| /* Free Software Foundation; either version 2 of the License, or (at your */ | |||||
| /* option) any later version. */ | |||||
| /* */ | |||||
| /* This program is distributed in the hope that it will be useful, but WITHOUT */ | |||||
| /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ | |||||
| /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */ | |||||
| /* more details. */ | |||||
| /* */ | |||||
| /* You should have received a copy of the GNU General Public License along */ | |||||
| /* with This program; see the file COPYING. If not,write to the Free Software */ | |||||
| /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |||||
| /*******************************************************************************/ | |||||
| #include "Sequence.H" | |||||
| #include "Timeline.H" | |||||
| #include "Region.H" | |||||
| #include <FL/fl_draw.H> | |||||
| queue <Sequence_Widget *> Sequence::_delete_queue; | |||||
| Sequence::Sequence ( int X, int Y, int W, int H ) : Fl_Widget( X, Y, W, H ) | |||||
| { | |||||
| _name = NULL; | |||||
| box( FL_DOWN_BOX ); | |||||
| color( fl_darker( FL_GRAY ) ); | |||||
| align( FL_ALIGN_LEFT ); | |||||
| // log_create(); | |||||
| } | |||||
| Sequence::~Sequence ( ) | |||||
| { | |||||
| /* FIXME: what to do with regions? */ | |||||
| parent()->redraw(); | |||||
| parent()->remove( this ); | |||||
| // log_destroy(); | |||||
| } | |||||
| void | |||||
| Sequence::sort ( void ) | |||||
| { | |||||
| _widgets.sort( Sequence_Widget::sort_func ); | |||||
| } | |||||
| /** return a pointer to the widget that /r/ overlaps, or NULL if none. */ | |||||
| Sequence_Widget * | |||||
| Sequence::overlaps ( Sequence_Widget *r ) | |||||
| { | |||||
| for ( list <Sequence_Widget *>::const_iterator i = _widgets.begin(); i != _widgets.end(); i++ ) | |||||
| { | |||||
| if ( *i == r ) continue; | |||||
| if ( ! ( (*i)->offset() > r->offset() + r->length() || (*i)->offset() + (*i)->length() < r->offset() ) ) | |||||
| return *i; | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| #include "Waveform.H" | |||||
| void | |||||
| Sequence::draw ( void ) | |||||
| { | |||||
| if ( ! fl_not_clipped( x(), y(), w(), h() ) ) | |||||
| return; | |||||
| fl_push_clip( x(), y(), w(), h() ); | |||||
| draw_box(); | |||||
| int X, Y, W, H; | |||||
| fl_clip_box( x(), y(), w(), h(), X, Y, W, H ); | |||||
| if ( Sequence_Widget::pushed() && Sequence_Widget::pushed()->track() == this ) | |||||
| { | |||||
| /* make sure the Sequence_Widget::pushed widget is above all others */ | |||||
| remove( Sequence_Widget::pushed() ); | |||||
| add( Sequence_Widget::pushed() ); | |||||
| } | |||||
| int xfades = 0; | |||||
| // printf( "track::draw %d,%d %dx%d\n", X,Y,W,H ); | |||||
| timeline->draw_measure_lines( x(), y(), w(), h(), color() ); | |||||
| for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | |||||
| (*r)->draw_box(); | |||||
| for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | |||||
| (*r)->draw(); | |||||
| /* draw crossfades */ | |||||
| for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | |||||
| { | |||||
| Sequence_Widget *o = overlaps( *r ); | |||||
| if ( o ) | |||||
| { | |||||
| if ( *o <= **r ) | |||||
| { | |||||
| /* if ( o->x() == (*r)->x() && o->w() == (*r)->w() ) */ | |||||
| /* printf( "complete superposition\n" ); */ | |||||
| if ( (*r)->x() >= o->x() && (*r)->x() + (*r)->w() <= o->x() + o->w() ) | |||||
| /* completely inside */ | |||||
| continue; | |||||
| ++xfades; | |||||
| Rectangle b( (*r)->x(), | |||||
| o->y(), | |||||
| (o->x() + o->w()) - (*r)->x(), | |||||
| o->h() ); | |||||
| Fl_Color c = fl_color_average( o->box_color(), (*r)->box_color(), 0.50f ); | |||||
| c = fl_color_average( c, FL_YELLOW, 0.30f ); | |||||
| fl_push_clip( b.x, b.y, b.w, b.h ); | |||||
| draw_box( FL_FLAT_BOX, b.x - 100, b.y, b.w + 200, b.h, c ); | |||||
| draw_box( FL_UP_FRAME, b.x - 100, b.y, b.w + 200, b.h, c ); | |||||
| fl_pop_clip(); | |||||
| } | |||||
| } | |||||
| } | |||||
| // printf( "There are %d xfades\n", xfades ); | |||||
| for ( list <Sequence_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | |||||
| { | |||||
| Sequence_Widget *o = overlaps( *r ); | |||||
| if ( o ) | |||||
| { | |||||
| if ( *o <= **r ) | |||||
| { | |||||
| if ( (*r)->x() >= o->x() && (*r)->x() + (*r)->w() <= o->x() + o->w() ) | |||||
| /* completely inside */ | |||||
| continue; | |||||
| Rectangle b( (*r)->x(), o->y(), (o->x() + o->w()) - (*r)->x(), o->h() ); | |||||
| /* draw overlapping waveforms in X-ray style. */ | |||||
| Waveform::fill = false; | |||||
| /* Fl_Color oc = o->color(); */ | |||||
| /* Fl_Color rc = (*r)->color(); */ | |||||
| /* /\* give each region a different color *\/ */ | |||||
| /* o->color( FL_RED ); */ | |||||
| /* (*r)->color( FL_GREEN ); */ | |||||
| fl_push_clip( b.x, b.y, b.w, b.h ); | |||||
| o->draw(); | |||||
| (*r)->draw(); | |||||
| fl_pop_clip(); | |||||
| Waveform::fill = true; | |||||
| /* o->color( oc ); */ | |||||
| /* (*r)->color( rc ); */ | |||||
| /* fl_color( FL_BLACK ); */ | |||||
| /* fl_line_style( FL_DOT, 4 ); */ | |||||
| /* b.x = (*r)->line_x(); */ | |||||
| /* b.w = min( 32767, (*r)->abs_w() ); */ | |||||
| /* fl_line( b.x, b.y, b.x + b.w, b.y + b.h ); */ | |||||
| /* fl_line( b.x, b.y + b.h, b.x + b.w, b.y ); */ | |||||
| /* fl_line_style( FL_SOLID, 0 ); */ | |||||
| // fl_pop_clip(); | |||||
| } | |||||
| } | |||||
| } | |||||
| fl_pop_clip(); | |||||
| } | |||||
| void | |||||
| Sequence::remove ( Sequence_Widget *r ) | |||||
| { | |||||
| // Logger _log( this ); | |||||
| _widgets.remove( r ); | |||||
| } | |||||
| void | |||||
| Sequence::remove_selected ( void ) | |||||
| { | |||||
| Loggable::block_start(); | |||||
| for ( list <Sequence_Widget *>::iterator r = _widgets.begin(); r != _widgets.end(); ) | |||||
| if ( (*r)->selected() ) | |||||
| { | |||||
| Sequence_Widget *t = *r; | |||||
| _widgets.erase( r++ ); | |||||
| delete t; | |||||
| } | |||||
| else | |||||
| ++r; | |||||
| Loggable::block_end(); | |||||
| } | |||||
| Sequence_Widget * | |||||
| Sequence::event_widget ( void ) | |||||
| { | |||||
| nframes_t ets = timeline->xoffset + timeline->x_to_ts( Fl::event_x() - x() ); | |||||
| for ( list <Sequence_Widget *>::const_reverse_iterator r = _widgets.rbegin(); r != _widgets.rend(); r++ ) | |||||
| if ( ets > (*r)->offset() && ets < (*r)->offset() + (*r)->length() ) | |||||
| return (*r); | |||||
| return NULL; | |||||
| } | |||||
| void | |||||
| Sequence::select_range ( int X, int W ) | |||||
| { | |||||
| nframes_t sts = timeline->xoffset + timeline->x_to_ts( X - x() ); | |||||
| nframes_t ets = sts + timeline->x_to_ts( W ); | |||||
| for ( list <Sequence_Widget *>::const_reverse_iterator r = _widgets.rbegin(); r != _widgets.rend(); r++ ) | |||||
| if ( ! ( (*r)->offset() > ets || (*r)->offset() + (*r)->length() < sts ) ) | |||||
| (*r)->select(); | |||||
| } | |||||
| void | |||||
| Sequence::add ( Sequence_Widget *r ) | |||||
| { | |||||
| // Logger _log( this ); | |||||
| if ( r->track() ) | |||||
| { | |||||
| r->redraw(); | |||||
| r->track()->remove( r ); | |||||
| // r->track()->redraw(); | |||||
| } | |||||
| r->track( this ); | |||||
| _widgets.push_back( r ); | |||||
| sort(); | |||||
| } | |||||
| /* snap /r/ to nearest edge */ | |||||
| void | |||||
| Sequence::snap ( Sequence_Widget *r ) | |||||
| { | |||||
| const int snap_pixels = 10; | |||||
| const int rx1 = r->x(); | |||||
| const int rx2 = r->x() + r->w(); | |||||
| for ( list <Sequence_Widget*>::iterator i = _widgets.begin(); i != _widgets.end(); i++ ) | |||||
| { | |||||
| const Sequence_Widget *w = (*i); | |||||
| if ( w == r ) | |||||
| continue; | |||||
| const int wx1 = w->x(); | |||||
| const int wx2 = w->x() + w->w(); | |||||
| if ( abs( rx1 - wx2 ) < snap_pixels ) | |||||
| { | |||||
| r->offset( w->offset() + w->length() + 1 ); | |||||
| // printf( "snap: %lu | %lu\n", w->offset() + w->length(), r->offset() ); | |||||
| goto done; | |||||
| } | |||||
| if ( abs( rx2 - wx1 ) < snap_pixels ) | |||||
| { | |||||
| r->offset( ( w->offset() - r->length() ) - 1 ); | |||||
| // printf( "snap: %lu | %lu\n", r->offset() + r->length(), w->offset() ); | |||||
| goto done; | |||||
| } | |||||
| } | |||||
| { | |||||
| int nx = timeline->nearest_line( r->abs_x() ); | |||||
| if ( nx >= 0 ) | |||||
| { | |||||
| r->offset( timeline->x_to_ts( nx ) ); | |||||
| return; | |||||
| } | |||||
| } | |||||
| // r->offset( timeline->x_to_ts( r->x() ) ); | |||||
| done: | |||||
| return; | |||||
| // r->resize(); | |||||
| // r->position( rx1, y() ); | |||||
| } | |||||
| int | |||||
| Sequence::handle ( int m ) | |||||
| { | |||||
| switch ( m ) | |||||
| { | |||||
| case FL_FOCUS: | |||||
| return 1; | |||||
| case FL_UNFOCUS: | |||||
| return 1; | |||||
| case FL_DND_ENTER: | |||||
| printf( "enter\n" ); | |||||
| if ( Sequence_Widget::pushed() && Sequence_Widget::pushed()->track()->class_name() == class_name() ) | |||||
| { | |||||
| add( Sequence_Widget::pushed() ); | |||||
| redraw(); | |||||
| } | |||||
| case FL_DND_LEAVE: | |||||
| return 1; | |||||
| case FL_MOVE: | |||||
| { | |||||
| Sequence_Widget *r = event_widget(); | |||||
| if ( r != Sequence_Widget::belowmouse() ) | |||||
| { | |||||
| if ( Sequence_Widget::belowmouse() ) | |||||
| Sequence_Widget::belowmouse()->handle( FL_LEAVE ); | |||||
| Sequence_Widget::belowmouse( r ); | |||||
| if ( r ) | |||||
| r->handle( FL_ENTER ); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| default: | |||||
| { | |||||
| Sequence_Widget *r = Sequence_Widget::pushed() ? Sequence_Widget::pushed() : event_widget(); | |||||
| if ( r ) | |||||
| { | |||||
| int retval = r->dispatch( m ); | |||||
| if ( retval && m == FL_PUSH ) | |||||
| { | |||||
| take_focus(); | |||||
| Sequence_Widget::pushed( r ); | |||||
| } | |||||
| if ( retval && m == FL_RELEASE ) | |||||
| Sequence_Widget::pushed( NULL ); | |||||
| Loggable::block_start(); | |||||
| while ( _delete_queue.size() ) | |||||
| { | |||||
| Sequence_Widget *t = _delete_queue.front(); | |||||
| _delete_queue.pop(); | |||||
| if ( Sequence_Widget::pushed() == t ) | |||||
| Sequence_Widget::pushed( NULL ); | |||||
| if ( Sequence_Widget::belowmouse() == t ) | |||||
| { | |||||
| Sequence_Widget::belowmouse()->handle( FL_LEAVE ); | |||||
| Sequence_Widget::belowmouse( NULL ); | |||||
| } | |||||
| delete t; | |||||
| } | |||||
| Loggable::block_end(); | |||||
| return retval; | |||||
| } | |||||
| else | |||||
| return Fl_Widget::handle( m ); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,131 @@ | |||||
| /*******************************************************************************/ | |||||
| /* Copyright (C) 2008 Jonathan Moore Liles */ | |||||
| /* */ | |||||
| /* This program is free software; you can redistribute it and/or modify it */ | |||||
| /* under the terms of the GNU General Public License as published by the */ | |||||
| /* Free Software Foundation; either version 2 of the License, or (at your */ | |||||
| /* option) any later version. */ | |||||
| /* */ | |||||
| /* This program is distributed in the hope that it will be useful, but WITHOUT */ | |||||
| /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ | |||||
| /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */ | |||||
| /* more details. */ | |||||
| /* */ | |||||
| /* You should have received a copy of the GNU General Public License along */ | |||||
| /* with This program; see the file COPYING. If not,write to the Free Software */ | |||||
| /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |||||
| /*******************************************************************************/ | |||||
| #pragma once | |||||
| #include <FL/Fl_Widget.H> | |||||
| #include <FL/Fl_Group.H> | |||||
| #include <FL/Fl.H> | |||||
| // #include "Region.H" | |||||
| #include <stdio.h> | |||||
| #include "Loggable.H" | |||||
| #include <assert.h> | |||||
| #include <list> | |||||
| // using namespace std; | |||||
| class Region; | |||||
| class Sequence_Widget; | |||||
| #include "types.h" | |||||
| /* This is the base class for all track types. */ | |||||
| class Sequence : public Fl_Widget, public Loggable | |||||
| { | |||||
| char *_name; | |||||
| static queue <Sequence_Widget *> _delete_queue; | |||||
| protected: | |||||
| std::list <Sequence_Widget *> _widgets; | |||||
| Sequence_Widget *event_widget ( void ); | |||||
| virtual const char *class_name ( void ) { return "Sequence"; } | |||||
| void set ( char ** ) { return; } | |||||
| char ** get ( void ) | |||||
| { | |||||
| // char *r; | |||||
| char **sa = (char**)malloc( sizeof( char* ) * 2); | |||||
| sa[0] = (char*)malloc( (_widgets.size() * ((sizeof( int ) * 2) + 3)) + 1 ); | |||||
| sa[1] = NULL; | |||||
| sa[0][0] = '\0'; | |||||
| /* char *s = sa[0]; */ | |||||
| /* s += sprintf( s, ":items " ); */ | |||||
| /* for ( list <Sequence_Widget *>::const_iterator i = _widgets.begin(); i != _widgets.end(); i++ ) */ | |||||
| /* { */ | |||||
| /* s += sprintf( s, "0x%X", ((Loggable*)(*i))->id() ); */ | |||||
| /* list <Sequence_Widget *>::const_iterator e = i; */ | |||||
| /* if ( ++e != _widgets.end() ) */ | |||||
| /* s += sprintf( s, "," ); */ | |||||
| /* } */ | |||||
| return sa; | |||||
| } | |||||
| public: | |||||
| Sequence ( int X, int Y, int W, int H ); | |||||
| virtual ~Sequence ( ); | |||||
| const char * name ( void ) const { return _name; } | |||||
| void name ( char *s ) { if ( _name ) free( _name ); _name = s; label( _name ); } | |||||
| void sort ( void ); | |||||
| void remove ( Sequence_Widget *r ); | |||||
| void add ( Sequence_Widget *r ); | |||||
| void select_range ( int X, int W ); | |||||
| void remove_selected ( void ); | |||||
| const std::list <Sequence_Widget *> widgets ( void ) const { return _widgets; } | |||||
| void queue_delete ( Sequence_Widget *r ) | |||||
| { | |||||
| _delete_queue.push( r ); | |||||
| } | |||||
| Sequence_Widget * overlaps ( Sequence_Widget *r ); | |||||
| virtual Sequence * clone ( void ) | |||||
| { | |||||
| assert( 0 ); | |||||
| } | |||||
| virtual Sequence * clone_empty ( void ) | |||||
| { | |||||
| return NULL; | |||||
| } | |||||
| virtual void snap ( Sequence_Widget *r ); | |||||
| virtual int handle ( int m ); | |||||
| virtual void draw ( void ); | |||||
| virtual nframes_t process ( nframes_t nframes ) { return 0; } | |||||
| }; | |||||
| @@ -19,9 +19,9 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Track_Widget.H" | |||||
| #include "Sequence_Widget.H" | |||||
| class Track_Point : public Track_Widget | |||||
| class Sequence_Point : public Sequence_Widget | |||||
| { | { | ||||
| protected: | protected: | ||||
| @@ -38,20 +38,20 @@ public: | |||||
| int abs_w ( void ) const { return 10; } | int abs_w ( void ) const { return 10; } | ||||
| nframes_t length ( void ) const { return timeline->x_to_ts( abs_w() ); } | nframes_t length ( void ) const { return timeline->x_to_ts( abs_w() ); } | ||||
| Track_Point ( ) | |||||
| Sequence_Point ( ) | |||||
| { | { | ||||
| _label = NULL; | _label = NULL; | ||||
| } | } | ||||
| virtual ~Track_Point ( ) | |||||
| virtual ~Sequence_Point ( ) | |||||
| { | { | ||||
| } | } | ||||
| virtual void | virtual void | ||||
| draw ( void ) | draw ( void ) | ||||
| { | { | ||||
| Track_Widget::draw(); | |||||
| Sequence_Widget::draw(); | |||||
| draw_label( _label, align() ); | draw_label( _label, align() ); | ||||
| } | } | ||||
| @@ -25,15 +25,15 @@ | |||||
| the original? | the original? | ||||
| */ | */ | ||||
| #include "Track_Widget.H" | |||||
| #include "Sequence_Widget.H" | |||||
| list <Track_Widget *> Track_Widget::_selection; | |||||
| Track_Widget * Track_Widget::_current = NULL; | |||||
| Track_Widget * Track_Widget::_pushed = NULL; | |||||
| Track_Widget * Track_Widget::_belowmouse = NULL; | |||||
| list <Sequence_Widget *> Sequence_Widget::_selection; | |||||
| Sequence_Widget * Sequence_Widget::_current = NULL; | |||||
| Sequence_Widget * Sequence_Widget::_pushed = NULL; | |||||
| Sequence_Widget * Sequence_Widget::_belowmouse = NULL; | |||||
| void | void | ||||
| Track_Widget::draw_label ( const char *label, Fl_Align align, Fl_Color color ) | |||||
| Sequence_Widget::draw_label ( const char *label, Fl_Align align, Fl_Color color ) | |||||
| { | { | ||||
| int X, Y; | int X, Y; | ||||
| @@ -109,9 +109,9 @@ Track_Widget::draw_label ( const char *label, Fl_Align align, Fl_Color color ) | |||||
| } | } | ||||
| int | int | ||||
| Track_Widget::dispatch ( int m ) | |||||
| Sequence_Widget::dispatch ( int m ) | |||||
| { | { | ||||
| Track_Widget::_current = this; | |||||
| Sequence_Widget::_current = this; | |||||
| if ( selected() ) | if ( selected() ) | ||||
| { | { | ||||
| @@ -120,7 +120,7 @@ Track_Widget::dispatch ( int m ) | |||||
| int r = 0; | int r = 0; | ||||
| for ( list <Track_Widget *>::iterator i = _selection.begin(); i != _selection.end(); i++ ) | |||||
| for ( list <Sequence_Widget *>::iterator i = _selection.begin(); i != _selection.end(); i++ ) | |||||
| if ( *i != this ) | if ( *i != this ) | ||||
| r |= (*i)->handle( m ); | r |= (*i)->handle( m ); | ||||
| @@ -136,7 +136,7 @@ Track_Widget::dispatch ( int m ) | |||||
| /* base hanlde just does basic dragging */ | /* base hanlde just does basic dragging */ | ||||
| int | int | ||||
| Track_Widget::handle ( int m ) | |||||
| Sequence_Widget::handle ( int m ) | |||||
| { | { | ||||
| int X = Fl::event_x(); | int X = Fl::event_x(); | ||||
| int Y = Fl::event_y(); | int Y = Fl::event_y(); | ||||
| @@ -199,7 +199,7 @@ Track_Widget::handle ( int m ) | |||||
| // _r->offset = timeline->x_to_ts( nx ) + timeline->xoffset; | // _r->offset = timeline->x_to_ts( nx ) + timeline->xoffset; | ||||
| offset( timeline->x_to_ts( nx ) + timeline->xoffset ); | offset( timeline->x_to_ts( nx ) + timeline->xoffset ); | ||||
| if ( Track_Widget::_current == this ) | |||||
| if ( Sequence_Widget::_current == this ) | |||||
| _track->snap( this ); | _track->snap( this ); | ||||
| } | } | ||||
| @@ -19,14 +19,14 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Track.H" | |||||
| #include "Sequence.H" | |||||
| #include "Loggable.H" | #include "Loggable.H" | ||||
| #include "Timeline.H" | #include "Timeline.H" | ||||
| #include <list> | #include <list> | ||||
| #include <algorithm> | #include <algorithm> | ||||
| using namespace std; | using namespace std; | ||||
| class Track_Widget; | |||||
| class Sequence_Widget; | |||||
| struct Drag | struct Drag | ||||
| { | { | ||||
| @@ -35,7 +35,7 @@ struct Drag | |||||
| int y; | int y; | ||||
| int state; | int state; | ||||
| Track_Widget *original; | |||||
| Sequence_Widget *original; | |||||
| Drag( int X, int Y ) : x( X ), y( Y ) { state = 0; } | Drag( int X, int Y ) : x( X ), y( Y ) { state = 0; } | ||||
| }; | }; | ||||
| @@ -48,25 +48,25 @@ struct Range | |||||
| }; | }; | ||||
| /* Base class for virtual widget on a track */ | /* Base class for virtual widget on a track */ | ||||
| class Track_Widget : public Loggable | |||||
| class Sequence_Widget : public Loggable | |||||
| { | { | ||||
| static list <Track_Widget *> _selection; /* all the widgets making up the selection */ | |||||
| static list <Sequence_Widget *> _selection; /* all the widgets making up the selection */ | |||||
| /* FIXME: is this not the same as /pushed/? */ | /* FIXME: is this not the same as /pushed/? */ | ||||
| static Track_Widget * _current; /* the widget initiating events that affect the selection */ | |||||
| static Sequence_Widget * _current; /* the widget initiating events that affect the selection */ | |||||
| /* these are actually managed in the Track classes */ | |||||
| static Track_Widget * _pushed; /* the widget receiving drag events (a copy) */ | |||||
| static Track_Widget * _original; /* the original of the /pushed/ widget */ | |||||
| static Track_Widget * _belowmouse; /* the widget below the mouse cursor */ | |||||
| /* these are actually managed in the Sequence classes */ | |||||
| static Sequence_Widget * _pushed; /* the widget receiving drag events (a copy) */ | |||||
| static Sequence_Widget * _original; /* the original of the /pushed/ widget */ | |||||
| static Sequence_Widget * _belowmouse; /* the widget below the mouse cursor */ | |||||
| /* can't have this */ | /* can't have this */ | ||||
| Track_Widget ( const Track_Widget &rhs ); | |||||
| Sequence_Widget ( const Sequence_Widget &rhs ); | |||||
| protected: | protected: | ||||
| Track *_track; /* track this region belongs to */ | |||||
| Sequence *_track; /* track this region belongs to */ | |||||
| Range _range; /* range for playback */ | Range _range; /* range for playback */ | ||||
| Range *_r; /* range for editing / display (points to the same thing as above, except for when dragging etc) */ | Range *_r; /* range for editing / display (points to the same thing as above, except for when dragging etc) */ | ||||
| @@ -78,7 +78,7 @@ protected: | |||||
| public: | public: | ||||
| Track_Widget ( ) | |||||
| Sequence_Widget ( ) | |||||
| { | { | ||||
| _track = NULL; | _track = NULL; | ||||
| @@ -89,7 +89,7 @@ public: | |||||
| _drag = NULL; | _drag = NULL; | ||||
| } | } | ||||
| virtual ~Track_Widget ( ) | |||||
| virtual ~Sequence_Widget ( ) | |||||
| { | { | ||||
| redraw(); | redraw(); | ||||
| @@ -98,8 +98,8 @@ public: | |||||
| _selection.remove( this ); | _selection.remove( this ); | ||||
| } | } | ||||
| const Track_Widget & | |||||
| operator= ( const Track_Widget &rhs ) | |||||
| const Sequence_Widget & | |||||
| operator= ( const Sequence_Widget &rhs ) | |||||
| { | { | ||||
| if ( this == &rhs ) | if ( this == &rhs ) | ||||
| return *this; | return *this; | ||||
| @@ -114,12 +114,12 @@ public: | |||||
| } | } | ||||
| /* Track_Widget ( const Track_Widget &rhs ) */ | |||||
| /* Sequence_Widget ( const Sequence_Widget &rhs ) */ | |||||
| /* { */ | /* { */ | ||||
| /* *this = rhs; */ | /* *this = rhs; */ | ||||
| /* } */ | /* } */ | ||||
| virtual Track_Widget *clone ( const Track_Widget *r ) = 0; | |||||
| virtual Sequence_Widget *clone ( const Sequence_Widget *r ) = 0; | |||||
| bool selected ( void ) | bool selected ( void ) | ||||
| { | { | ||||
| @@ -151,15 +151,15 @@ public: | |||||
| delete _selection.front(); | delete _selection.front(); | ||||
| } | } | ||||
| static Track_Widget *current ( void ) { return Track_Widget::_current; } | |||||
| static Sequence_Widget *current ( void ) { return Sequence_Widget::_current; } | |||||
| static Track_Widget *pushed ( void ) { return Track_Widget::_pushed; } | |||||
| static Track_Widget *belowmouse ( void ) { return Track_Widget::_belowmouse; } | |||||
| static Sequence_Widget *pushed ( void ) { return Sequence_Widget::_pushed; } | |||||
| static Sequence_Widget *belowmouse ( void ) { return Sequence_Widget::_belowmouse; } | |||||
| static void pushed ( Track_Widget *w ) { Track_Widget::_pushed = w; } | |||||
| static void belowmouse ( Track_Widget *w ) { Track_Widget::_belowmouse = w; } | |||||
| static void pushed ( Sequence_Widget *w ) { Sequence_Widget::_pushed = w; } | |||||
| static void belowmouse ( Sequence_Widget *w ) { Sequence_Widget::_belowmouse = w; } | |||||
| // static void pushed ( Track_Widget *w ) { Track_Widget::_pushed = w; } | |||||
| // static void pushed ( Sequence_Widget *w ) { Sequence_Widget::_pushed = w; } | |||||
| void begin_drag ( const Drag &d ) | void begin_drag ( const Drag &d ) | ||||
| { | { | ||||
| @@ -190,7 +190,7 @@ public: | |||||
| { | { | ||||
| long d = where - _r->offset; | long d = where - _r->offset; | ||||
| for ( list <Track_Widget *>::iterator i = _selection.begin(); i != _selection.end(); i++ ) | |||||
| for ( list <Sequence_Widget *>::iterator i = _selection.begin(); i != _selection.end(); i++ ) | |||||
| { | { | ||||
| (*i)->redraw(); | (*i)->redraw(); | ||||
| @@ -243,8 +243,8 @@ public: | |||||
| void color ( Fl_Color v ) { _color = v; } | void color ( Fl_Color v ) { _color = v; } | ||||
| Fl_Color box_color ( void ) { return _box_color; } | Fl_Color box_color ( void ) { return _box_color; } | ||||
| Track * track ( void ) const { return _track; } | |||||
| void track ( Track *t ) { _track = t; } | |||||
| Sequence * track ( void ) const { return _track; } | |||||
| void track ( Sequence *t ) { _track = t; } | |||||
| nframes_t offset ( void ) const { return _r->offset; } | nframes_t offset ( void ) const { return _r->offset; } | ||||
| // void offset ( nframes_t o ) { _r->offset = o; } | // void offset ( nframes_t o ) { _r->offset = o; } | ||||
| @@ -285,13 +285,13 @@ public: | |||||
| } | } | ||||
| bool | bool | ||||
| operator< ( const Track_Widget & rhs ) | |||||
| operator< ( const Sequence_Widget & rhs ) | |||||
| { | { | ||||
| return _r->offset < rhs._r->offset; | return _r->offset < rhs._r->offset; | ||||
| } | } | ||||
| bool | bool | ||||
| operator<=( const Track_Widget & rhs ) | |||||
| operator<=( const Sequence_Widget & rhs ) | |||||
| { | { | ||||
| return _r->offset <= rhs._r->offset; | return _r->offset <= rhs._r->offset; | ||||
| } | } | ||||
| @@ -300,7 +300,7 @@ public: | |||||
| virtual int handle ( int m ); | virtual int handle ( int m ); | ||||
| static bool | static bool | ||||
| sort_func ( Track_Widget *lhs, Track_Widget *rhs ) | |||||
| sort_func ( Sequence_Widget *lhs, Sequence_Widget *rhs ) | |||||
| { | { | ||||
| return *lhs < *rhs; | return *lhs < *rhs; | ||||
| } | } | ||||
| @@ -19,7 +19,7 @@ | |||||
| #include "Tempo_Point.H" | #include "Tempo_Point.H" | ||||
| #include "Tempo_Track.H" | |||||
| #include "Tempo_Sequence.H" | |||||
| #include "Timeline.H" // for timeline->tempo_track | #include "Timeline.H" // for timeline->tempo_track | ||||
| char ** | char ** | ||||
| @@ -101,7 +101,7 @@ Tempo_Point::~Tempo_Point ( ) | |||||
| int | int | ||||
| Tempo_Point::handle ( int m ) | Tempo_Point::handle ( int m ) | ||||
| { | { | ||||
| int r = Track_Widget::handle( m ); | |||||
| int r = Sequence_Widget::handle( m ); | |||||
| if ( m == FL_RELEASE ) | if ( m == FL_RELEASE ) | ||||
| { | { | ||||
| @@ -19,10 +19,10 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Track_Point.H" | |||||
| // #include "Tempo_Track.H" | |||||
| #include "Sequence_Point.H" | |||||
| // #include "Tempo_Sequence.H" | |||||
| class Tempo_Point : public Track_Point | |||||
| class Tempo_Point : public Sequence_Point | |||||
| { | { | ||||
| float _tempo; | float _tempo; | ||||
| @@ -60,7 +60,7 @@ public: | |||||
| _tempo = rhs._tempo; | _tempo = rhs._tempo; | ||||
| } | } | ||||
| Track_Widget *clone ( const Track_Widget *r ) | |||||
| Sequence_Widget *clone ( const Sequence_Widget *r ) | |||||
| { | { | ||||
| return new Tempo_Point( *(Tempo_Point*)r ); | return new Tempo_Point( *(Tempo_Point*)r ); | ||||
| } | } | ||||
| @@ -19,17 +19,17 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Track.H" | |||||
| #include "Sequence.H" | |||||
| #include "Tempo_Point.H" | #include "Tempo_Point.H" | ||||
| #include <list> | #include <list> | ||||
| class Tempo_Track : public Track | |||||
| class Tempo_Sequence : public Sequence | |||||
| { | { | ||||
| public: | public: | ||||
| Tempo_Track ( int X, int Y, int W, int H ) : Track ( X, Y, W, H ) | |||||
| Tempo_Sequence ( int X, int Y, int W, int H ) : Sequence ( X, Y, W, H ) | |||||
| { | { | ||||
| box( FL_UP_BOX ); | box( FL_UP_BOX ); | ||||
| } | } | ||||
| @@ -39,7 +39,7 @@ public: | |||||
| { | { | ||||
| // sort(); | // sort(); | ||||
| for ( std::list <Track_Widget *>::const_reverse_iterator i = _widgets.rbegin(); | |||||
| for ( std::list <Sequence_Widget *>::const_reverse_iterator i = _widgets.rbegin(); | |||||
| i != _widgets.rend(); i++ ) | i != _widgets.rend(); i++ ) | ||||
| { | { | ||||
| if ( (*i)->offset() < when ) | if ( (*i)->offset() < when ) | ||||
| @@ -18,7 +18,7 @@ | |||||
| /*******************************************************************************/ | /*******************************************************************************/ | ||||
| #include "Time_Point.H" | #include "Time_Point.H" | ||||
| #include "Time_Track.H" | |||||
| #include "Time_Sequence.H" | |||||
| #include "Timeline.H" // for timeline->time_track | #include "Timeline.H" // for timeline->time_track | ||||
| char ** | char ** | ||||
| @@ -19,7 +19,7 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Track_Point.H" | |||||
| #include "Sequence_Point.H" | |||||
| #include "Loggable.H" | #include "Loggable.H" | ||||
| struct time_sig | struct time_sig | ||||
| @@ -43,7 +43,7 @@ struct time_sig | |||||
| #define __CLASS__ "Time_Point" | #define __CLASS__ "Time_Point" | ||||
| class Time_Point : public Track_Point | |||||
| class Time_Point : public Sequence_Point | |||||
| { | { | ||||
| time_sig _time; | time_sig _time; | ||||
| @@ -96,7 +96,7 @@ public: | |||||
| _time = rhs._time; | _time = rhs._time; | ||||
| } | } | ||||
| Track_Widget *clone ( const Track_Widget *r ) | |||||
| Sequence_Widget *clone ( const Sequence_Widget *r ) | |||||
| { | { | ||||
| return new Time_Point( *(Time_Point*)r ); | return new Time_Point( *(Time_Point*)r ); | ||||
| } | } | ||||
| @@ -116,7 +116,7 @@ public: | |||||
| int | int | ||||
| handle ( int m ) | handle ( int m ) | ||||
| { | { | ||||
| int r = Track_Widget::handle( m ); | |||||
| int r = Sequence_Widget::handle( m ); | |||||
| if ( m == FL_RELEASE ) | if ( m == FL_RELEASE ) | ||||
| { | { | ||||
| @@ -19,18 +19,18 @@ | |||||
| #pragma once | #pragma once | ||||
| #include "Track.H" | |||||
| #include "Sequence.H" | |||||
| #include "Time_Point.H" | #include "Time_Point.H" | ||||
| #include <list> | #include <list> | ||||
| using std::list; | using std::list; | ||||
| class Time_Track : public Track | |||||
| class Time_Sequence : public Sequence | |||||
| { | { | ||||
| public: | public: | ||||
| Time_Track ( int X, int Y, int W, int H ) : Track ( X, Y, W, H ) | |||||
| Time_Sequence ( int X, int Y, int W, int H ) : Sequence ( X, Y, W, H ) | |||||
| { | { | ||||
| box( FL_UP_BOX ); | box( FL_UP_BOX ); | ||||
| } | } | ||||
| @@ -38,7 +38,7 @@ public: | |||||
| time_sig | time_sig | ||||
| time ( nframes_t when ) | time ( nframes_t when ) | ||||
| { | { | ||||
| for ( list <Track_Widget *>::const_reverse_iterator i = _widgets.rbegin(); | |||||
| for ( list <Sequence_Widget *>::const_reverse_iterator i = _widgets.rbegin(); | |||||
| i != _widgets.rend(); i++ ) | i != _widgets.rend(); i++ ) | ||||
| { | { | ||||
| if ( (*i)->offset() < when ) | if ( (*i)->offset() < when ) | ||||
| @@ -18,18 +18,18 @@ | |||||
| /*******************************************************************************/ | /*******************************************************************************/ | ||||
| #include "Timeline.H" | #include "Timeline.H" | ||||
| #include "Tempo_Track.H" | |||||
| #include "Time_Track.H" | |||||
| #include "Audio_Track.H" | |||||
| #include "Control_Track.H" | |||||
| #include "Tempo_Sequence.H" | |||||
| #include "Time_Sequence.H" | |||||
| #include "Audio_Sequence.H" | |||||
| #include "Control_Sequence.H" | |||||
| #include <FL/Fl_Scrollbar.H> | #include <FL/Fl_Scrollbar.H> | ||||
| #include "Ruler_Track.H" | |||||
| #include "Ruler_Sequence.H" | |||||
| // #include <FL/Fl_Image.H> | // #include <FL/Fl_Image.H> | ||||
| // #include <FL/Fl_RGB_Image.H> // needed for alpha blending | // #include <FL/Fl_RGB_Image.H> // needed for alpha blending | ||||
| #include "Track_Header.H" | |||||
| #include "Track.H" | |||||
| const float UPDATE_FREQ = 0.02f; | const float UPDATE_FREQ = 0.02f; | ||||
| @@ -107,11 +107,11 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi | |||||
| } | } | ||||
| { | { | ||||
| Fl_Pack *o = new Fl_Pack( X + Track_Header::width(), Y, (W - Track_Header::width()) - vscroll->w(), H - hscroll->h(), "rulers" ); | |||||
| Fl_Pack *o = new Fl_Pack( X + Track::width(), Y, (W - Track::width()) - vscroll->w(), H - hscroll->h(), "rulers" ); | |||||
| o->type( Fl_Pack::VERTICAL ); | o->type( Fl_Pack::VERTICAL ); | ||||
| { | { | ||||
| Tempo_Track *o = new Tempo_Track( 0, 0, 800, 24 ); | |||||
| Tempo_Sequence *o = new Tempo_Sequence( 0, 0, 800, 24 ); | |||||
| o->color( FL_RED ); | o->color( FL_RED ); | ||||
| @@ -127,7 +127,7 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi | |||||
| } | } | ||||
| { | { | ||||
| Time_Track *o = new Time_Track( 0, 24, 800, 24 ); | |||||
| Time_Sequence *o = new Time_Sequence( 0, 24, 800, 24 ); | |||||
| o->color( fl_color_average( FL_RED, FL_WHITE, 0.50f ) ); | o->color( fl_color_average( FL_RED, FL_WHITE, 0.50f ) ); | ||||
| @@ -143,7 +143,7 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi | |||||
| } | } | ||||
| { | { | ||||
| Ruler_Track *o = new Ruler_Track( 0, 24, 800, 24 ); | |||||
| Ruler_Sequence *o = new Ruler_Sequence( 0, 24, 800, 24 ); | |||||
| o->color( FL_GREEN ); | o->color( FL_GREEN ); | ||||
| @@ -180,14 +180,14 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi | |||||
| /* for ( int i = 1; i--; ) */ | /* for ( int i = 1; i--; ) */ | ||||
| /* { */ | /* { */ | ||||
| /* // Track_Header *t = new Track_Header( 0, 0, W, 75 ); */ | |||||
| /* Track_Header *t = new Track_Header( 0, 0, W, 30 ); */ | |||||
| /* Track *o = new Audio_Track( 0, 0, 1, 100 ); */ | |||||
| /* // Track *t = new Track( 0, 0, W, 75 ); */ | |||||
| /* Track *t = new Track( 0, 0, W, 30 ); */ | |||||
| /* Sequence *o = new Audio_Sequence( 0, 0, 1, 100 ); */ | |||||
| /* t->track( o ); */ | /* t->track( o ); */ | ||||
| /* t->add( new Audio_Track( 0, 0, 1, 100 ) ); */ | |||||
| /* t->add( new Audio_Track( 0, 0, 1, 100 ) ); */ | |||||
| /* t->add_control( new Control_Track( 0, 0, 1, 100 ) ); */ | |||||
| /* t->add( new Audio_Sequence( 0, 0, 1, 100 ) ); */ | |||||
| /* t->add( new Audio_Sequence( 0, 0, 1, 100 ) ); */ | |||||
| /* t->add_control( new Control_Sequence( 0, 0, 1, 100 ) ); */ | |||||
| /* t->color( (Fl_Color)rand() ); */ | /* t->color( (Fl_Color)rand() ); */ | ||||
| /* } */ | /* } */ | ||||
| @@ -250,11 +250,11 @@ struct BBT | |||||
| BBT | BBT | ||||
| Timeline::bbt ( nframes_t when ) | Timeline::bbt ( nframes_t when ) | ||||
| { | { | ||||
| Tempo_Track *tempo = (Tempo_Track*)rulers->child( 0 ); | |||||
| Tempo_Sequence *tempo = (Tempo_Sequence*)rulers->child( 0 ); | |||||
| BBT bbt; | BBT bbt; | ||||
| for ( list <Track_Widget *>::const_iterator i = tempo.widgets.begin(); | |||||
| for ( list <Sequence_Widget *>::const_iterator i = tempo.widgets.begin(); | |||||
| i != tempo.widgets.end(); ++i ) | i != tempo.widgets.end(); ++i ) | ||||
| { | { | ||||
| Tempo_Point *p = *i; | Tempo_Point *p = *i; | ||||
| @@ -272,7 +272,7 @@ Timeline::nearest_line ( int ix ) | |||||
| { | { | ||||
| for ( int x = ix - 10; x < ix + 10; ++x ) | for ( int x = ix - 10; x < ix + 10; ++x ) | ||||
| { | { | ||||
| const int measure = ts_to_x( (double)(_sample_rate * 60) / beats_per_minute( x_to_ts( x - Track_Header::width() ) + xoffset )); | |||||
| const int measure = ts_to_x( (double)(_sample_rate * 60) / beats_per_minute( x_to_ts( x - Track::width() ) + xoffset )); | |||||
| // const int abs_x = ts_to_x( xoffset ) + x; | // const int abs_x = ts_to_x( xoffset ) + x; | ||||
| @@ -304,13 +304,13 @@ Timeline::draw_measure ( int X, int Y, int W, int H, Fl_Color color, bool BBT ) | |||||
| for ( int x = X; x < X + W; ++x ) | for ( int x = X; x < X + W; ++x ) | ||||
| { | { | ||||
| measure = ts_to_x( (double)(_sample_rate * 60) / beats_per_minute( x_to_ts( x - Track_Header::width() ) + xoffset ) ); | |||||
| measure = ts_to_x( (double)(_sample_rate * 60) / beats_per_minute( x_to_ts( x - Track::width() ) + xoffset ) ); | |||||
| const int abs_x = ts_to_x( xoffset ) + x - Track_Header::width(); | |||||
| const int abs_x = ts_to_x( xoffset ) + x - Track::width(); | |||||
| if ( 0 == abs_x % measure ) | if ( 0 == abs_x % measure ) | ||||
| { | { | ||||
| int bpb = beats_per_bar( x_to_ts( x -Track_Header::width() ) + xoffset ); | |||||
| int bpb = beats_per_bar( x_to_ts( x -Track::width() ) + xoffset ); | |||||
| if ( 0 == (abs_x / measure) % bpb ) | if ( 0 == (abs_x / measure) % bpb ) | ||||
| { | { | ||||
| @@ -419,12 +419,12 @@ Timeline::draw_clip ( void * v, int X, int Y, int W, int H ) | |||||
| tl->draw_child( *tl->rulers ); | tl->draw_child( *tl->rulers ); | ||||
| /* headers */ | /* headers */ | ||||
| fl_push_clip( tl->tracks->x(), tl->rulers->y() + tl->rulers->h(), Track_Header::width(), tl->h() - tl->rulers->h() - tl->hscroll->h() ); | |||||
| fl_push_clip( tl->tracks->x(), tl->rulers->y() + tl->rulers->h(), Track::width(), tl->h() - tl->rulers->h() - tl->hscroll->h() ); | |||||
| tl->draw_child( *tl->tracks ); | tl->draw_child( *tl->tracks ); | ||||
| fl_pop_clip(); | fl_pop_clip(); | ||||
| /* track bodies */ | /* track bodies */ | ||||
| fl_push_clip( tl->tracks->x() + Track_Header::width(), tl->rulers->y() + tl->rulers->h(), tl->tracks->w() - Track_Header::width(), tl->h() - tl->rulers->h() - tl->hscroll->h() ); | |||||
| fl_push_clip( tl->tracks->x() + Track::width(), tl->rulers->y() + tl->rulers->h(), tl->tracks->w() - Track::width(), tl->h() - tl->rulers->h() - tl->hscroll->h() ); | |||||
| tl->draw_child( *tl->tracks ); | tl->draw_child( *tl->tracks ); | ||||
| fl_pop_clip(); | fl_pop_clip(); | ||||
| @@ -541,13 +541,13 @@ Timeline::draw ( void ) | |||||
| int dy = _old_yposition - _yposition; | int dy = _old_yposition - _yposition; | ||||
| if ( ! dy ) | if ( ! dy ) | ||||
| fl_scroll( X + Track_Header::width(), rulers->y(), rulers->w() - Fl::box_dw( rulers->child(0)->box() ), rulers->h(), dx, 0, draw_clip, this ); | |||||
| fl_scroll( X + Track::width(), rulers->y(), rulers->w() - Fl::box_dw( rulers->child(0)->box() ), rulers->h(), dx, 0, draw_clip, this ); | |||||
| Y = rulers->y() + rulers->h(); | Y = rulers->y() + rulers->h(); | ||||
| H = h() - rulers->h() - hscroll->h(); | H = h() - rulers->h() - hscroll->h(); | ||||
| if ( dy == 0 ) | if ( dy == 0 ) | ||||
| fl_scroll( X + Track_Header::width(), Y, W - Track_Header::width(), H, dx, dy, draw_clip, this ); | |||||
| fl_scroll( X + Track::width(), Y, W - Track::width(), H, dx, dy, draw_clip, this ); | |||||
| else | else | ||||
| fl_scroll( X, Y, W, H, dx, dy, draw_clip, this ); | fl_scroll( X, Y, W, H, dx, dy, draw_clip, this ); | ||||
| @@ -561,9 +561,9 @@ Timeline::draw ( void ) | |||||
| void | void | ||||
| Timeline::draw_playhead ( void ) | Timeline::draw_playhead ( void ) | ||||
| { | { | ||||
| int x = ( ts_to_x( transport.frame ) - ts_to_x( xoffset ) ) + tracks->x() + Track_Header::width(); | |||||
| int x = ( ts_to_x( transport.frame ) - ts_to_x( xoffset ) ) + tracks->x() + Track::width(); | |||||
| if ( x < tracks->x() + Track_Header::width() || x > tracks->x() + tracks->w() ) | |||||
| if ( x < tracks->x() + Track::width() || x > tracks->x() + tracks->w() ) | |||||
| return; | return; | ||||
| fl_color( FL_RED ); | fl_color( FL_RED ); | ||||
| @@ -609,7 +609,7 @@ Timeline::draw_overlay ( void ) | |||||
| if ( ! ( _selection.w && _selection.h ) ) | if ( ! ( _selection.w && _selection.h ) ) | ||||
| return; | return; | ||||
| fl_push_clip( tracks->x() + Track_Header::width(), rulers->y() + rulers->h(), tracks->w() - Track_Header::width(), h() - rulers->h() - hscroll->h() ); | |||||
| fl_push_clip( tracks->x() + Track::width(), rulers->y() + rulers->h(), tracks->w() - Track::width(), h() - rulers->h() - hscroll->h() ); | |||||
| const Rectangle &r = _selection; | const Rectangle &r = _selection; | ||||
| @@ -659,7 +659,7 @@ Timeline::draw_overlay ( void ) | |||||
| } | } | ||||
| // #include "Track_Widget.H" | |||||
| // #include "Sequence_Widget.H" | |||||
| /** select all widgets in inside rectangle /r/ */ | /** select all widgets in inside rectangle /r/ */ | ||||
| void | void | ||||
| @@ -669,7 +669,7 @@ Timeline::select( const Rectangle &r ) | |||||
| for ( int i = tracks->children(); i-- ; ) | for ( int i = tracks->children(); i-- ; ) | ||||
| { | { | ||||
| Track_Header *t = (Track_Header*)tracks->child( i ); | |||||
| Track *t = (Track*)tracks->child( i ); | |||||
| if ( ! ( t->y() > Y + r.h || t->y() + t->h() < Y ) ) | if ( ! ( t->y() > Y + r.h || t->y() + t->h() < Y ) ) | ||||
| t->track()->select_range( r.x, r.w ); | t->track()->select_range( r.x, r.w ); | ||||
| @@ -689,7 +689,7 @@ Timeline::handle ( int m ) | |||||
| { | { | ||||
| case FL_Delete: | case FL_Delete: | ||||
| { | { | ||||
| Track_Widget::delete_selected(); | |||||
| Sequence_Widget::delete_selected(); | |||||
| return 1; | return 1; | ||||
| } | } | ||||
| @@ -740,16 +740,16 @@ Timeline::handle ( int m ) | |||||
| /* FIXME: prompt for I/O config? */ | /* FIXME: prompt for I/O config? */ | ||||
| /* add audio track */ | /* add audio track */ | ||||
| Track_Header *t = new Track_Header( 0, 0, tracks->w(), 30 ); | |||||
| Track *t = new Track( 0, 0, tracks->w(), 30 ); | |||||
| add_track( t ); | add_track( t ); | ||||
| Track *o = new Audio_Track( 0, 0, 1, 100 ); | |||||
| Sequence *o = new Audio_Sequence( 0, 0, 1, 100 ); | |||||
| t->track( o ); | t->track( o ); | ||||
| // t->add( new Audio_Track( 0, 0, 1, 100 ) ); | |||||
| // t->add( new Audio_Track( 0, 0, 1, 100 ) ); | |||||
| t->add_control( new Control_Track( 0, 0, 1, 100 ) ); | |||||
| // t->add( new Audio_Sequence( 0, 0, 1, 100 ) ); | |||||
| // t->add( new Audio_Sequence( 0, 0, 1, 100 ) ); | |||||
| t->add_control( new Control_Sequence( 0, 0, 1, 100 ) ); | |||||
| t->color( (Fl_Color)rand() ); | t->color( (Fl_Color)rand() ); | ||||
| } | } | ||||
| @@ -798,7 +798,7 @@ Timeline::handle ( int m ) | |||||
| void | void | ||||
| Timeline::add_track ( Track_Header *track ) | |||||
| Timeline::add_track ( Track *track ) | |||||
| { | { | ||||
| printf( "added new track to the timeline\n" ); | printf( "added new track to the timeline\n" ); | ||||
| /* FIXME: do locking */ | /* FIXME: do locking */ | ||||
| @@ -810,7 +810,7 @@ Timeline::add_track ( Track_Header *track ) | |||||
| } | } | ||||
| void | void | ||||
| Timeline::remove_track ( Track_Header *track ) | |||||
| Timeline::remove_track ( Track *track ) | |||||
| { | { | ||||
| printf( "removed track from the timeline\n" ); | printf( "removed track from the timeline\n" ); | ||||
| @@ -833,7 +833,7 @@ Timeline::process ( nframes_t nframes ) | |||||
| { | { | ||||
| for ( int i = tracks->children(); i-- ; ) | for ( int i = tracks->children(); i-- ; ) | ||||
| { | { | ||||
| Track_Header *t = (Track_Header*)tracks->child( i ); | |||||
| Track *t = (Track*)tracks->child( i ); | |||||
| t->process( nframes ); | t->process( nframes ); | ||||
| } | } | ||||
| @@ -848,7 +848,7 @@ Timeline::seek ( nframes_t frame ) | |||||
| { | { | ||||
| for ( int i = tracks->children(); i-- ; ) | for ( int i = tracks->children(); i-- ; ) | ||||
| { | { | ||||
| Track_Header *t = (Track_Header*)tracks->child( i ); | |||||
| Track *t = (Track*)tracks->child( i ); | |||||
| t->seek( frame ); | t->seek( frame ); | ||||
| } | } | ||||
| @@ -862,7 +862,7 @@ Timeline::seek_pending ( void ) | |||||
| for ( int i = tracks->children(); i-- ; ) | for ( int i = tracks->children(); i-- ; ) | ||||
| { | { | ||||
| Track_Header *t = (Track_Header*)tracks->child( i ); | |||||
| Track *t = (Track*)tracks->child( i ); | |||||
| if ( t->playback_ds ) | if ( t->playback_ds ) | ||||
| r += t->playback_ds->buffer_percent() < 50; | r += t->playback_ds->buffer_percent() < 50; | ||||
| @@ -40,12 +40,12 @@ | |||||
| class Timeline; | class Timeline; | ||||
| extern Timeline *timeline; | extern Timeline *timeline; | ||||
| #include "Track.H" | |||||
| #include "Sequence.H" | |||||
| class Tempo_Track; | |||||
| class Time_Track; | |||||
| class Ruler_Track; | |||||
| class Track_Header; | |||||
| class Tempo_Sequence; | |||||
| class Time_Sequence; | |||||
| class Ruler_Sequence; | |||||
| class Track; | |||||
| // disables double-buffering to make unnecessary redrawing more apparent | // disables double-buffering to make unnecessary redrawing more apparent | ||||
| // #define DEBUG_TIMELINE_DRAWING | // #define DEBUG_TIMELINE_DRAWING | ||||
| @@ -113,9 +113,9 @@ class Timeline : public Fl_Overlay_Window, public RWLock | |||||
| public: | public: | ||||
| Tempo_Track *tempo_track; | |||||
| Time_Track *time_track; | |||||
| Ruler_Track *ruler_track; | |||||
| Tempo_Sequence *tempo_track; | |||||
| Time_Sequence *time_track; | |||||
| Ruler_Sequence *ruler_track; | |||||
| nframes_t xoffset; | nframes_t xoffset; | ||||
| @@ -150,8 +150,8 @@ public: | |||||
| void select( const Rectangle &r ); | void select( const Rectangle &r ); | ||||
| void add_track ( Track_Header *track ); | |||||
| void remove_track ( Track_Header *track ); | |||||
| void add_track ( Track *track ); | |||||
| void remove_track ( Track *track ); | |||||
| private: | private: | ||||
| @@ -18,400 +18,356 @@ | |||||
| /*******************************************************************************/ | /*******************************************************************************/ | ||||
| #include "Track.H" | #include "Track.H" | ||||
| #include "Timeline.H" | |||||
| #include "Region.H" | |||||
| #include <FL/fl_draw.H> | |||||
| queue <Track_Widget *> Track::_delete_queue; | |||||
| Track::Track ( int X, int Y, int W, int H ) : Fl_Widget( X, Y, W, H ) | |||||
| { | |||||
| _name = NULL; | |||||
| #include "Transport.H" | |||||
| #include "Playback_DS.H" | |||||
| #include "Record_DS.H" | |||||
| box( FL_DOWN_BOX ); | |||||
| color( fl_darker( FL_GRAY ) ); | |||||
| align( FL_ALIGN_LEFT ); | |||||
| #include "Engine.H" | |||||
| // log_create(); | |||||
| } | |||||
| Track::~Track ( ) | |||||
| { | |||||
| /* FIXME: what to do with regions? */ | |||||
| parent()->redraw(); | |||||
| parent()->remove( this ); | |||||
| // log_destroy(); | |||||
| } | |||||
| #include "Port.H" | |||||
| void | void | ||||
| Track::sort ( void ) | |||||
| Track::cb_input_field ( Fl_Widget *w, void *v ) | |||||
| { | { | ||||
| _widgets.sort( Track_Widget::sort_func ); | |||||
| ((Track*)v)->cb_input_field(); | |||||
| } | } | ||||
| /** return a pointer to the widget that /r/ overlaps, or NULL if none. */ | |||||
| Track_Widget * | |||||
| Track::overlaps ( Track_Widget *r ) | |||||
| void | |||||
| Track::cb_button ( Fl_Widget *w, void *v ) | |||||
| { | { | ||||
| for ( list <Track_Widget *>::const_iterator i = _widgets.begin(); i != _widgets.end(); i++ ) | |||||
| { | |||||
| if ( *i == r ) continue; | |||||
| if ( ! ( (*i)->offset() > r->offset() + r->length() || (*i)->offset() + (*i)->length() < r->offset() ) ) | |||||
| return *i; | |||||
| } | |||||
| return NULL; | |||||
| ((Track*)v)->cb_button( w ); | |||||
| } | } | ||||
| #include "Waveform.H" | |||||
| void | void | ||||
| Track::draw ( void ) | |||||
| Track::cb_input_field ( void ) | |||||
| { | { | ||||
| log_start(); | |||||
| if ( ! fl_not_clipped( x(), y(), w(), h() ) ) | |||||
| return; | |||||
| fl_push_clip( x(), y(), w(), h() ); | |||||
| if ( _name ) | |||||
| free( _name ); | |||||
| draw_box(); | |||||
| _name = strdup( name_field->value() ); | |||||
| int X, Y, W, H; | |||||
| fl_clip_box( x(), y(), w(), h(), X, Y, W, H ); | |||||
| log_end(); | |||||
| } | |||||
| void | |||||
| Track::cb_button ( Fl_Widget *w ) | |||||
| { | |||||
| if ( Track_Widget::pushed() && Track_Widget::pushed()->track() == this ) | |||||
| printf( "FIXME: inform mixer here\n" ); | |||||
| if ( w == record_button ) | |||||
| { | { | ||||
| /* make sure the Track_Widget::pushed widget is above all others */ | |||||
| remove( Track_Widget::pushed() ); | |||||
| add( Track_Widget::pushed() ); | |||||
| /* FIXME: wrong place for this! */ | |||||
| if ( record_button->value() ) | |||||
| record_ds->start( transport.frame ); | |||||
| else | |||||
| record_ds->stop( transport.frame ); | |||||
| } | } | ||||
| int xfades = 0; | |||||
| // printf( "track::draw %d,%d %dx%d\n", X,Y,W,H ); | |||||
| timeline->draw_measure_lines( x(), y(), w(), h(), color() ); | |||||
| for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | |||||
| (*r)->draw_box(); | |||||
| for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | |||||
| (*r)->draw(); | |||||
| /* draw crossfades */ | |||||
| for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | |||||
| { | |||||
| Track_Widget *o = overlaps( *r ); | |||||
| if ( o ) | |||||
| else | |||||
| if ( w == take_menu ) | |||||
| { | { | ||||
| if ( *o <= **r ) | |||||
| { | |||||
| /* if ( o->x() == (*r)->x() && o->w() == (*r)->w() ) */ | |||||
| /* printf( "complete superposition\n" ); */ | |||||
| if ( (*r)->x() >= o->x() && (*r)->x() + (*r)->w() <= o->x() + o->w() ) | |||||
| /* completely inside */ | |||||
| continue; | |||||
| ++xfades; | |||||
| Rectangle b( (*r)->x(), | |||||
| o->y(), | |||||
| (o->x() + o->w()) - (*r)->x(), | |||||
| o->h() ); | |||||
| Fl_Color c = fl_color_average( o->box_color(), (*r)->box_color(), 0.50f ); | |||||
| c = fl_color_average( c, FL_YELLOW, 0.30f ); | |||||
| fl_push_clip( b.x, b.y, b.w, b.h ); | |||||
| draw_box( FL_FLAT_BOX, b.x - 100, b.y, b.w + 200, b.h, c ); | |||||
| draw_box( FL_UP_FRAME, b.x - 100, b.y, b.w + 200, b.h, c ); | |||||
| int v = take_menu->value(); | |||||
| switch ( v ) | |||||
| { | |||||
| case 0: /* show all takes */ | |||||
| show_all_takes( take_menu->menu()[ v ].value() ); | |||||
| return; | |||||
| case 1: /* new */ | |||||
| track( track()->clone_empty() ); | |||||
| return; | |||||
| } | |||||
| fl_pop_clip(); | |||||
| const char *s = take_menu->menu()[ v ].text; | |||||
| for ( int i = takes->children(); i--; ) | |||||
| { | |||||
| Sequence *t = (Sequence*)takes->child( i ); | |||||
| if ( ! strcmp( s, t->name() ) ) | |||||
| { | |||||
| track( t ); | |||||
| redraw(); | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | |||||
| } | |||||
| Track::Track ( int X, int Y, int W, int H, const char *L ) : | |||||
| Fl_Group ( X, Y, W, H, L ) | |||||
| { | |||||
| // printf( "There are %d xfades\n", xfades ); | |||||
| _track = NULL; | |||||
| _name = NULL; | |||||
| _selected = false; | |||||
| _show_all_takes = false; | |||||
| _size = 1; | |||||
| for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | |||||
| { | { | ||||
| Track_Widget *o = overlaps( *r ); | |||||
| if ( o ) | |||||
| { | |||||
| if ( *o <= **r ) | |||||
| { | |||||
| if ( (*r)->x() >= o->x() && (*r)->x() + (*r)->w() <= o->x() + o->w() ) | |||||
| /* completely inside */ | |||||
| continue; | |||||
| Rectangle b( (*r)->x(), o->y(), (o->x() + o->w()) - (*r)->x(), o->h() ); | |||||
| /* draw overlapping waveforms in X-ray style. */ | |||||
| Waveform::fill = false; | |||||
| char pname[40]; | |||||
| static int no = 0, ni = 0; | |||||
| /* Fl_Color oc = o->color(); */ | |||||
| /* Fl_Color rc = (*r)->color(); */ | |||||
| snprintf( pname, sizeof( pname ), "out-%d", no++ ); | |||||
| /* /\* give each region a different color *\/ */ | |||||
| /* o->color( FL_RED ); */ | |||||
| /* (*r)->color( FL_GREEN ); */ | |||||
| output.push_back( Port( strdup( pname ), Port::Output ) ); | |||||
| fl_push_clip( b.x, b.y, b.w, b.h ); | |||||
| snprintf( pname, sizeof( pname ), "in-%d", ni++ ); | |||||
| o->draw(); | |||||
| (*r)->draw(); | |||||
| input.push_back( Port( strdup( pname ), Port::Input ) ); | |||||
| fl_pop_clip(); | |||||
| snprintf( pname, sizeof( pname ), "in-%d", ni++ ); | |||||
| Waveform::fill = true; | |||||
| input.push_back( Port( strdup( pname ), Port::Input ) ); | |||||
| } | |||||
| /* o->color( oc ); */ | |||||
| /* (*r)->color( rc ); */ | |||||
| playback_ds = new Playback_DS( this, engine->frame_rate(), engine->nframes(), 1 ); | |||||
| record_ds = new Record_DS( this, engine->frame_rate(), engine->nframes(), 2 ); | |||||
| /* fl_color( FL_BLACK ); */ | |||||
| /* fl_line_style( FL_DOT, 4 ); */ | |||||
| Fl_Group::size( w(), height() ); | |||||
| /* b.x = (*r)->line_x(); */ | |||||
| /* b.w = min( 32767, (*r)->abs_w() ); */ | |||||
| Track *o = this; | |||||
| o->box( FL_THIN_UP_BOX ); | |||||
| { | |||||
| Fl_Group *o = new Fl_Group( 2, 2, 149, 70 ); | |||||
| o->color( ( Fl_Color ) 53 ); | |||||
| { | |||||
| Fl_Input *o = name_field = new Fl_Input( 2, 2, 144, 24 ); | |||||
| o->color( ( Fl_Color ) 33 ); | |||||
| o->labeltype( FL_NO_LABEL ); | |||||
| o->labelcolor( FL_GRAY0 ); | |||||
| o->textcolor( 32 ); | |||||
| /* fl_line( b.x, b.y, b.x + b.w, b.y + b.h ); */ | |||||
| o->callback( cb_input_field, (void*)this ); | |||||
| } | |||||
| /* fl_line( b.x, b.y + b.h, b.x + b.w, b.y ); */ | |||||
| { | |||||
| Fl_Group *o = controls = new Fl_Group( 2, 28, 149, 24 ); | |||||
| /* fl_line_style( FL_SOLID, 0 ); */ | |||||
| { | |||||
| Fl_Button *o = record_button = | |||||
| new Fl_Button( 6, 28, 26, 24, "@circle" ); | |||||
| o->type( 1 ); | |||||
| o->box( FL_THIN_UP_BOX ); | |||||
| o->color( FL_LIGHT1 ); | |||||
| o->selection_color( FL_RED ); | |||||
| o->labelsize( 8 ); | |||||
| o->callback( cb_button, this ); | |||||
| } | |||||
| { | |||||
| Fl_Button *o = mute_button = | |||||
| new Fl_Button( 35, 28, 26, 24, "m" ); | |||||
| o->type( 1 ); | |||||
| o->box( FL_THIN_UP_BOX ); | |||||
| o->color( FL_LIGHT1 ); | |||||
| o->labelsize( 11 ); | |||||
| o->callback( cb_button, this ); | |||||
| } | |||||
| { | |||||
| Fl_Button *o = solo_button = | |||||
| new Fl_Button( 66, 28, 26, 24, "s" ); | |||||
| o->type( 1 ); | |||||
| o->box( FL_THIN_UP_BOX ); | |||||
| o->color( FL_LIGHT1 ); | |||||
| o->labelsize( 11 ); | |||||
| o->callback( cb_button, this ); | |||||
| } | |||||
| { | |||||
| Fl_Menu_Button *o = take_menu = | |||||
| new Fl_Menu_Button( 97, 28, 47, 24, "T" ); | |||||
| o->box( FL_THIN_UP_BOX ); | |||||
| o->color( FL_LIGHT1 ); | |||||
| o->align( FL_ALIGN_LEFT | FL_ALIGN_INSIDE ); | |||||
| o->callback( cb_button, this ); | |||||
| // fl_pop_clip(); | |||||
| o->add( "Show all takes", 0, 0, 0, FL_MENU_TOGGLE ); | |||||
| o->add( "New", 0, 0, 0, FL_MENU_DIVIDER ); | |||||
| } | } | ||||
| o->end(); | |||||
| } | } | ||||
| } | |||||
| fl_pop_clip(); | |||||
| } | |||||
| void | |||||
| Track::remove ( Track_Widget *r ) | |||||
| { | |||||
| // Logger _log( this ); | |||||
| _widgets.remove( r ); | |||||
| } | |||||
| { | |||||
| Fl_Box *o = new Fl_Box( 0, 76, 149, 38 ); | |||||
| o->box( FL_FLAT_BOX ); | |||||
| Fl_Group::current()->resizable( o ); | |||||
| } | |||||
| o->size( Track::width(), h() ); | |||||
| o->end(); | |||||
| } | |||||
| { | |||||
| Fl_Pack *o = pack = new Fl_Pack( width(), 0, 1006, 115 ); | |||||
| o->labeltype( FL_NO_LABEL ); | |||||
| o->resize( x() + width(), y(), w() - width(), h() ); | |||||
| Fl_Group::current()->resizable( o ); | |||||
| void | |||||
| Track::remove_selected ( void ) | |||||
| { | |||||
| Loggable::block_start(); | |||||
| { | |||||
| Fl_Pack *o = control = new Fl_Pack( width(), 0, pack->w(), 115 ); | |||||
| o->end(); | |||||
| } | |||||
| for ( list <Track_Widget *>::iterator r = _widgets.begin(); r != _widgets.end(); ) | |||||
| if ( (*r)->selected() ) | |||||
| { | { | ||||
| Track_Widget *t = *r; | |||||
| _widgets.erase( r++ ); | |||||
| delete t; | |||||
| Fl_Pack *o = takes = new Fl_Pack( width(), 0, pack->w(), 115 ); | |||||
| o->end(); | |||||
| o->hide(); | |||||
| } | } | ||||
| else | |||||
| ++r; | |||||
| Loggable::block_end(); | |||||
| } | |||||
| o->end(); | |||||
| } | |||||
| end(); | |||||
| log_create(); | |||||
| } | |||||
| Track_Widget * | |||||
| Track::event_widget ( void ) | |||||
| Track::~Track ( ) | |||||
| { | { | ||||
| nframes_t ets = timeline->xoffset + timeline->x_to_ts( Fl::event_x() - x() ); | |||||
| for ( list <Track_Widget *>::const_reverse_iterator r = _widgets.rbegin(); r != _widgets.rend(); r++ ) | |||||
| if ( ets > (*r)->offset() && ets < (*r)->offset() + (*r)->length() ) | |||||
| return (*r); | |||||
| return NULL; | |||||
| log_destroy(); | |||||
| } | } | ||||
| void | |||||
| Track::select_range ( int X, int W ) | |||||
| static int pack_visible( Fl_Pack *p ) | |||||
| { | { | ||||
| nframes_t sts = timeline->xoffset + timeline->x_to_ts( X - x() ); | |||||
| nframes_t ets = sts + timeline->x_to_ts( W ); | |||||
| int v = 0; | |||||
| for ( int i = p->children(); i--; ) | |||||
| if ( p->child( i )->visible() ) | |||||
| v++; | |||||
| for ( list <Track_Widget *>::const_reverse_iterator r = _widgets.rbegin(); r != _widgets.rend(); r++ ) | |||||
| if ( ! ( (*r)->offset() > ets || (*r)->offset() + (*r)->length() < sts ) ) | |||||
| (*r)->select(); | |||||
| return v; | |||||
| } | } | ||||
| /* adjust size of widget and children */ | |||||
| void | void | ||||
| Track::add ( Track_Widget *r ) | |||||
| Track::resize ( void ) | |||||
| { | { | ||||
| // Logger _log( this ); | |||||
| for ( int i = takes->children(); i--; ) | |||||
| takes->child( i )->size( w(), height() ); | |||||
| for ( int i = control->children(); i--; ) | |||||
| control->child( i )->size( w(), height() ); | |||||
| if ( r->track() ) | |||||
| if ( _show_all_takes ) | |||||
| { | |||||
| takes->show(); | |||||
| Fl_Group::size( w(), height() * ( 1 + takes->children() + pack_visible( control ) ) ); | |||||
| } | |||||
| else | |||||
| { | { | ||||
| r->redraw(); | |||||
| r->track()->remove( r ); | |||||
| // r->track()->redraw(); | |||||
| takes->hide(); | |||||
| Fl_Group::size( w(), height() * ( 1 + pack_visible( control ) ) ); | |||||
| } | } | ||||
| r->track( this ); | |||||
| _widgets.push_back( r ); | |||||
| if ( track() ) | |||||
| track()->size( w(), height() ); | |||||
| sort(); | |||||
| if ( controls->y() + controls->h() > y() + h() ) | |||||
| controls->hide(); | |||||
| else | |||||
| controls->show(); | |||||
| parent()->redraw(); | |||||
| } | } | ||||
| /* snap /r/ to nearest edge */ | |||||
| void | void | ||||
| Track::snap ( Track_Widget *r ) | |||||
| Track::size ( int v ) | |||||
| { | { | ||||
| const int snap_pixels = 10; | |||||
| if ( v < 0 || v > 3 ) | |||||
| return; | |||||
| const int rx1 = r->x(); | |||||
| const int rx2 = r->x() + r->w(); | |||||
| _size = v; | |||||
| resize(); | |||||
| } | |||||
| for ( list <Track_Widget*>::iterator i = _widgets.begin(); i != _widgets.end(); i++ ) | |||||
| { | |||||
| const Track_Widget *w = (*i); | |||||
| if ( w == r ) | |||||
| continue; | |||||
| const int wx1 = w->x(); | |||||
| const int wx2 = w->x() + w->w(); | |||||
| void | |||||
| Track::track( Sequence * t ) | |||||
| { | |||||
| // t->size( 1, h() ); | |||||
| if ( track() ) | |||||
| add( track() ); | |||||
| if ( abs( rx1 - wx2 ) < snap_pixels ) | |||||
| { | |||||
| r->offset( w->offset() + w->length() + 1 ); | |||||
| // takes->insert( *track(), 0 ); | |||||
| // printf( "snap: %lu | %lu\n", w->offset() + w->length(), r->offset() ); | |||||
| _track = t; | |||||
| pack->insert( *t, 0 ); | |||||
| goto done; | |||||
| } | |||||
| resize(); | |||||
| } | |||||
| if ( abs( rx2 - wx1 ) < snap_pixels ) | |||||
| { | |||||
| r->offset( ( w->offset() - r->length() ) - 1 ); | |||||
| void | |||||
| Track::add_control( Sequence *t ) | |||||
| { | |||||
| control->add( t ); | |||||
| // printf( "snap: %lu | %lu\n", r->offset() + r->length(), w->offset() ); | |||||
| resize(); | |||||
| } | |||||
| goto done; | |||||
| } | |||||
| } | |||||
| { | |||||
| int nx = timeline->nearest_line( r->abs_x() ); | |||||
| /**********/ | |||||
| /* Engine */ | |||||
| /**********/ | |||||
| if ( nx >= 0 ) | |||||
| { | |||||
| r->offset( timeline->x_to_ts( nx ) ); | |||||
| return; | |||||
| } | |||||
| /* THREAD: RT */ | |||||
| nframes_t | |||||
| Track::process ( nframes_t nframes ) | |||||
| { | |||||
| if ( playback_ds ) | |||||
| { | |||||
| record_ds->process( nframes ); | |||||
| return playback_ds->process( nframes ); | |||||
| } | } | ||||
| // r->offset( timeline->x_to_ts( r->x() ) ); | |||||
| done: | |||||
| return; | |||||
| // r->resize(); | |||||
| // r->position( rx1, y() ); | |||||
| else | |||||
| return 0; | |||||
| } | } | ||||
| int | |||||
| Track::handle ( int m ) | |||||
| /* THREAD: RT */ | |||||
| void | |||||
| Track::seek ( nframes_t frame ) | |||||
| { | { | ||||
| if ( playback_ds ) | |||||
| return playback_ds->seek( frame ); | |||||
| } | |||||
| switch ( m ) | |||||
| { | |||||
| case FL_FOCUS: | |||||
| return 1; | |||||
| case FL_UNFOCUS: | |||||
| return 1; | |||||
| case FL_DND_ENTER: | |||||
| printf( "enter\n" ); | |||||
| if ( Track_Widget::pushed() && Track_Widget::pushed()->track()->class_name() == class_name() ) | |||||
| { | |||||
| add( Track_Widget::pushed() ); | |||||
| redraw(); | |||||
| } | |||||
| case FL_DND_LEAVE: | |||||
| return 1; | |||||
| case FL_MOVE: | |||||
| { | |||||
| Track_Widget *r = event_widget(); | |||||
| if ( r != Track_Widget::belowmouse() ) | |||||
| { | |||||
| if ( Track_Widget::belowmouse() ) | |||||
| Track_Widget::belowmouse()->handle( FL_LEAVE ); | |||||
| Track_Widget::belowmouse( r ); | |||||
| if ( r ) | |||||
| r->handle( FL_ENTER ); | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| default: | |||||
| { | |||||
| Track_Widget *r = Track_Widget::pushed() ? Track_Widget::pushed() : event_widget(); | |||||
| if ( r ) | |||||
| { | |||||
| int retval = r->dispatch( m ); | |||||
| if ( retval && m == FL_PUSH ) | |||||
| { | |||||
| take_focus(); | |||||
| Track_Widget::pushed( r ); | |||||
| } | |||||
| if ( retval && m == FL_RELEASE ) | |||||
| Track_Widget::pushed( NULL ); | |||||
| Loggable::block_start(); | |||||
| /* FIXME: what about theading issues with this region/audiofile being | |||||
| accessible from the UI thread? Need locking? */ | |||||
| while ( _delete_queue.size() ) | |||||
| { | |||||
| #include "Region.H" | |||||
| Track_Widget *t = _delete_queue.front(); | |||||
| _delete_queue.pop(); | |||||
| /* THREAD: IO */ | |||||
| /** create capture region and prepare to record */ | |||||
| void | |||||
| Track::record ( nframes_t frame ) | |||||
| { | |||||
| assert( _capture == NULL ); | |||||
| /* FIXME: hack */ | |||||
| Audio_File *af = Audio_File_SF::create( "testing.wav", 48000, input.size(), "Wav/24" ); | |||||
| if ( Track_Widget::pushed() == t ) | |||||
| Track_Widget::pushed( NULL ); | |||||
| if ( Track_Widget::belowmouse() == t ) | |||||
| { | |||||
| Track_Widget::belowmouse()->handle( FL_LEAVE ); | |||||
| Track_Widget::belowmouse( NULL ); | |||||
| } | |||||
| _capture = new Region( af, track(), frame ); | |||||
| delete t; | |||||
| } | |||||
| /* FIXME: wrong place for this */ | |||||
| _capture->_r->end = 0; | |||||
| } | |||||
| Loggable::block_end(); | |||||
| /* THREAD: IO */ | |||||
| /** write a block to the (already opened) capture file */ | |||||
| void | |||||
| Track::write ( sample_t *buf, nframes_t nframes ) | |||||
| { | |||||
| _capture->write( buf, nframes ); | |||||
| } | |||||
| return retval; | |||||
| } | |||||
| else | |||||
| return Fl_Widget::handle( m ); | |||||
| } | |||||
| } | |||||
| /* THREAD: IO */ | |||||
| void | |||||
| Track::stop ( nframes_t nframes ) | |||||
| { | |||||
| _capture = NULL; | |||||
| } | } | ||||
| @@ -17,115 +17,269 @@ | |||||
| /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||||
| /*******************************************************************************/ | /*******************************************************************************/ | ||||
| #pragma once | |||||
| #include <FL/Fl_Widget.H> | |||||
| #include <FL/Fl_Group.H> | |||||
| #ifndef Track_H | |||||
| #define Track_H | |||||
| #include <FL/Fl.H> | #include <FL/Fl.H> | ||||
| // #include "Region.H" | |||||
| #include <stdio.h> | |||||
| #include "Sequence.H" | |||||
| #include <FL/Fl_Group.H> | |||||
| #include <FL/Fl_Input.H> | |||||
| #include <FL/Fl_Button.H> | |||||
| #include <FL/Fl_Menu_Button.H> | |||||
| #include <FL/Fl_Pack.H> | |||||
| #include <FL/Fl_Box.H> | |||||
| #include "Loggable.H" | #include "Loggable.H" | ||||
| #include <assert.h> | |||||
| // #include "Port.H" | |||||
| #include <list> | |||||
| /* TODO: rename this to Audio_Sequence_Header or something since it's clearly audio specific. */ | |||||
| // using namespace std; | |||||
| #include <vector> | |||||
| using std::vector; | |||||
| class Region; | |||||
| class Track_Widget; | |||||
| class Playback_DS; | |||||
| class Record_DS; | |||||
| class Port; | |||||
| #include "types.h" | |||||
| class Track : public Fl_Group, public Loggable | |||||
| { | |||||
| public: | |||||
| /* This is the base class for all track types. */ | |||||
| Track ( int X, int Y, int W, int H, const char *L = 0 ); | |||||
| ~Track ( ); | |||||
| class Track : public Fl_Widget, public Loggable | |||||
| { | |||||
| private: | |||||
| // Sequence * _track; | |||||
| char *_name; | char *_name; | ||||
| static queue <Track_Widget *> _delete_queue; | |||||
| bool _selected; | |||||
| protected: | |||||
| bool _show_all_takes; | |||||
| std::list <Track_Widget *> _widgets; | |||||
| Track_Widget *event_widget ( void ); | |||||
| int _size; | |||||
| virtual const char *class_name ( void ) { return "Track"; } | |||||
| enum { AUDIO } _type; | |||||
| Sequence *_track; | |||||
| void set ( char ** ) { return; } | |||||
| Region *_capture; /* capture region */ | |||||
| char ** get ( void ) | |||||
| public: | |||||
| Fl_Input * name_field; | |||||
| Fl_Button *record_button; | |||||
| Fl_Button *mute_button; | |||||
| Fl_Button *solo_button; | |||||
| Fl_Menu_Button *take_menu; | |||||
| Fl_Group *controls; | |||||
| Fl_Pack *pack; | |||||
| Fl_Pack *control; | |||||
| Fl_Pack *takes; | |||||
| vector <Port> input; | |||||
| vector <Port> output; /* output ports... */ | |||||
| Playback_DS *playback_ds; | |||||
| Record_DS *record_ds; | |||||
| const char *class_name ( void ) { return "Track"; } | |||||
| void set ( char **sa ) | |||||
| { | { | ||||
| // char *r; | |||||
| for ( int i = 0; sa[i]; ++i ) | |||||
| { | |||||
| char *s = sa[i]; | |||||
| strtok( s, " " ); | |||||
| char *v = s + strlen( s ) + 1; | |||||
| if ( *v == '"' ) | |||||
| { | |||||
| v++; | |||||
| v[ strlen( v ) - 2 ] = '\0'; | |||||
| } | |||||
| if ( ! strcmp( s, ":h" ) ) | |||||
| { | |||||
| size( atoi( v ) ); | |||||
| Fl_Widget::size( w(), height() ); | |||||
| } | |||||
| else if ( ! strcmp( s, ":selected" ) ) | |||||
| _selected = atoi( v ); | |||||
| // else if ( ! strcmp( s, ":armed" | |||||
| else if ( ! strcmp( s, ":name" ) ) | |||||
| { | |||||
| _name = strdup( v ); | |||||
| name_field->value( _name ); | |||||
| } | |||||
| else if ( ! strcmp( s, ":track" ) ) | |||||
| { | |||||
| int i; | |||||
| sscanf( v, "%X", &i ); | |||||
| Sequence *t = (Sequence*)Loggable::find( i ); | |||||
| assert( t ); | |||||
| char **sa = (char**)malloc( sizeof( char* ) * 2); | |||||
| sa[0] = (char*)malloc( (_widgets.size() * ((sizeof( int ) * 2) + 3)) + 1 ); | |||||
| sa[1] = NULL; | |||||
| track( t ); | |||||
| } | |||||
| sa[0][0] = '\0'; | |||||
| /* char *s = sa[0]; */ | |||||
| free( s ); | |||||
| } | |||||
| free( sa ); | |||||
| } | |||||
| char ** get ( void ) | |||||
| { | |||||
| char **sa = (char**)malloc( sizeof( char* ) * (1 + 5) ); | |||||
| int i = 0; | |||||
| /* s += sprintf( s, ":items " ); */ | |||||
| /* for ( list <Track_Widget *>::const_iterator i = _widgets.begin(); i != _widgets.end(); i++ ) */ | |||||
| /* { */ | |||||
| /* s += sprintf( s, "0x%X", ((Loggable*)(*i))->id() ); */ | |||||
| asprintf( &sa[ i++ ], ":name \"%s\"", _name ? _name : "" ); | |||||
| asprintf( &sa[ i++ ], ":track 0x%X", track() ? track()->id() : 0 ); | |||||
| asprintf( &sa[ i++ ], ":selected %d", _selected ); | |||||
| // asprintf( &sa[ i++ ], ":record %d", record_button->value() ); | |||||
| /* list <Track_Widget *>::const_iterator e = i; */ | |||||
| /* if ( ++e != _widgets.end() ) */ | |||||
| /* s += sprintf( s, "," ); */ | |||||
| /* } */ | |||||
| /* asprintf( &sa[ i++ ], ":solo %d", solo_button->value() ); */ | |||||
| /* asprintf( &sa[ i++ ], ":mute %d", mute_button->value() ); */ | |||||
| asprintf( &sa[ i++ ], ":h %d", size() ); | |||||
| // asprintf( &sa[ i++ ], ":gain %f", _scale ); | |||||
| sa[ i ] = NULL; | |||||
| return sa; | return sa; | ||||
| } | } | ||||
| public: | |||||
| Track ( int X, int Y, int W, int H ); | |||||
| virtual ~Track ( ); | |||||
| /* for loggable */ | |||||
| static Loggable * | |||||
| create ( char **sa ) | |||||
| { | |||||
| Track *r = new Track( 0, 0, 1, 1 ); | |||||
| const char * name ( void ) const { return _name; } | |||||
| void name ( char *s ) { if ( _name ) free( _name ); _name = s; label( _name ); } | |||||
| r->set( sa ); | |||||
| void sort ( void ); | |||||
| return (Loggable *)r; | |||||
| } | |||||
| void | |||||
| draw ( void ) | |||||
| { | |||||
| if ( _selected ) | |||||
| { | |||||
| Fl_Color c = color(); | |||||
| void remove ( Track_Widget *r ); | |||||
| void add ( Track_Widget *r ); | |||||
| color( FL_RED ); | |||||
| void select_range ( int X, int W ); | |||||
| Fl_Group::draw(); | |||||
| void remove_selected ( void ); | |||||
| color( c ); | |||||
| } | |||||
| else | |||||
| Fl_Group::draw(); | |||||
| } | |||||
| const std::list <Track_Widget *> widgets ( void ) const { return _widgets; } | |||||
| void add_control( Sequence *t ); | |||||
| void queue_delete ( Track_Widget *r ) | |||||
| int size ( void ) const { return _size; } | |||||
| void resize ( void ); | |||||
| void size ( int v ); | |||||
| int height ( void ) const | |||||
| { | { | ||||
| _delete_queue.push( r ); | |||||
| static int table[] = { 30, 80, 150, 300 }; | |||||
| return table[ _size ]; | |||||
| } | } | ||||
| Track_Widget * overlaps ( Track_Widget *r ); | |||||
| void show_all_takes ( bool b ) | |||||
| { | |||||
| _show_all_takes = b; | |||||
| resize(); | |||||
| } | |||||
| const char * name ( void ) const { return _name; } | |||||
| bool mute ( void ) const { return mute_button->value(); } | |||||
| bool solo ( void ) const { return solo_button->value(); } | |||||
| bool armed ( void ) const { return record_button->value(); } | |||||
| bool selected ( void ) const { return _selected; } | |||||
| virtual Track * clone ( void ) | |||||
| static void cb_input_field ( Fl_Widget *w, void *v ); | |||||
| void cb_input_field ( void ); | |||||
| static void cb_button ( Fl_Widget *w, void *v ); | |||||
| void cb_button ( Fl_Widget *w ); | |||||
| static int width ( void ) { return 150; } | |||||
| void track( Sequence * t ); | |||||
| Sequence * track ( void ) { return _track; } | |||||
| void add ( Sequence * t ) | |||||
| { | |||||
| takes->insert( *t, 0 ); | |||||
| if ( ! t->name() ) | |||||
| { | |||||
| char pat[20]; | |||||
| snprintf( pat, sizeof( pat ), "%d", takes->children() ); | |||||
| t->name( strdup( pat ) ); | |||||
| take_menu->add( t->name() ); | |||||
| } | |||||
| } | |||||
| void remote ( Sequence *t ) | |||||
| { | { | ||||
| assert( 0 ); | |||||
| takes->remove( t ); | |||||
| // take_menu->remove( t->name() ); | |||||
| } | } | ||||
| virtual Track * clone_empty ( void ) | |||||
| int handle ( int m ) | |||||
| { | { | ||||
| return NULL; | |||||
| switch ( m ) | |||||
| { | |||||
| case FL_MOUSEWHEEL: | |||||
| { | |||||
| if ( ! Fl::event_shift() ) | |||||
| return 0; | |||||
| int d = Fl::event_dy(); | |||||
| printf( "%d\n", d ); | |||||
| if ( d < 0 ) | |||||
| size( size() - 1 ); | |||||
| else | |||||
| size( size() + 1 ); | |||||
| return 1; | |||||
| } | |||||
| default: | |||||
| return Fl_Group::handle( m ); | |||||
| } | |||||
| } | } | ||||
| virtual void snap ( Track_Widget *r ); | |||||
| virtual int handle ( int m ); | |||||
| virtual void draw ( void ); | |||||
| virtual nframes_t process ( nframes_t nframes ) { return 0; } | |||||
| /* Engine */ | |||||
| nframes_t process ( nframes_t nframes ); | |||||
| void seek ( nframes_t frame ); | |||||
| void record ( nframes_t nframes ); | |||||
| void write ( sample_t *buf, nframes_t nframes ); | |||||
| void stop ( nframes_t nframes ); | |||||
| }; | }; | ||||
| #endif | |||||
| @@ -1,373 +0,0 @@ | |||||
| /*******************************************************************************/ | |||||
| /* Copyright (C) 2008 Jonathan Moore Liles */ | |||||
| /* */ | |||||
| /* This program is free software; you can redistribute it and/or modify it */ | |||||
| /* under the terms of the GNU General Public License as published by the */ | |||||
| /* Free Software Foundation; either version 2 of the License, or (at your */ | |||||
| /* option) any later version. */ | |||||
| /* */ | |||||
| /* This program is distributed in the hope that it will be useful, but WITHOUT */ | |||||
| /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ | |||||
| /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */ | |||||
| /* more details. */ | |||||
| /* */ | |||||
| /* You should have received a copy of the GNU General Public License along */ | |||||
| /* with This program; see the file COPYING. If not,write to the Free Software */ | |||||
| /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |||||
| /*******************************************************************************/ | |||||
| #include "Track_Header.H" | |||||
| #include "Transport.H" | |||||
| #include "Playback_DS.H" | |||||
| #include "Record_DS.H" | |||||
| #include "Engine.H" | |||||
| #include "Port.H" | |||||
| void | |||||
| Track_Header::cb_input_field ( Fl_Widget *w, void *v ) | |||||
| { | |||||
| ((Track_Header*)v)->cb_input_field(); | |||||
| } | |||||
| void | |||||
| Track_Header::cb_button ( Fl_Widget *w, void *v ) | |||||
| { | |||||
| ((Track_Header*)v)->cb_button( w ); | |||||
| } | |||||
| void | |||||
| Track_Header::cb_input_field ( void ) | |||||
| { | |||||
| log_start(); | |||||
| if ( _name ) | |||||
| free( _name ); | |||||
| _name = strdup( name_field->value() ); | |||||
| log_end(); | |||||
| } | |||||
| void | |||||
| Track_Header::cb_button ( Fl_Widget *w ) | |||||
| { | |||||
| printf( "FIXME: inform mixer here\n" ); | |||||
| if ( w == record_button ) | |||||
| { | |||||
| /* FIXME: wrong place for this! */ | |||||
| if ( record_button->value() ) | |||||
| record_ds->start( transport.frame ); | |||||
| else | |||||
| record_ds->stop( transport.frame ); | |||||
| } | |||||
| else | |||||
| if ( w == take_menu ) | |||||
| { | |||||
| int v = take_menu->value(); | |||||
| switch ( v ) | |||||
| { | |||||
| case 0: /* show all takes */ | |||||
| show_all_takes( take_menu->menu()[ v ].value() ); | |||||
| return; | |||||
| case 1: /* new */ | |||||
| track( track()->clone_empty() ); | |||||
| return; | |||||
| } | |||||
| const char *s = take_menu->menu()[ v ].text; | |||||
| for ( int i = takes->children(); i--; ) | |||||
| { | |||||
| Track *t = (Track*)takes->child( i ); | |||||
| if ( ! strcmp( s, t->name() ) ) | |||||
| { | |||||
| track( t ); | |||||
| redraw(); | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| Track_Header::Track_Header ( int X, int Y, int W, int H, const char *L ) : | |||||
| Fl_Group ( X, Y, W, H, L ) | |||||
| { | |||||
| _track = NULL; | |||||
| _name = NULL; | |||||
| _selected = false; | |||||
| _show_all_takes = false; | |||||
| _size = 1; | |||||
| { | |||||
| char pname[40]; | |||||
| static int no = 0, ni = 0; | |||||
| snprintf( pname, sizeof( pname ), "out-%d", no++ ); | |||||
| output.push_back( Port( strdup( pname ), Port::Output ) ); | |||||
| snprintf( pname, sizeof( pname ), "in-%d", ni++ ); | |||||
| input.push_back( Port( strdup( pname ), Port::Input ) ); | |||||
| snprintf( pname, sizeof( pname ), "in-%d", ni++ ); | |||||
| input.push_back( Port( strdup( pname ), Port::Input ) ); | |||||
| } | |||||
| playback_ds = new Playback_DS( this, engine->frame_rate(), engine->nframes(), 1 ); | |||||
| record_ds = new Record_DS( this, engine->frame_rate(), engine->nframes(), 2 ); | |||||
| Fl_Group::size( w(), height() ); | |||||
| Track_Header *o = this; | |||||
| o->box( FL_THIN_UP_BOX ); | |||||
| { | |||||
| Fl_Group *o = new Fl_Group( 2, 2, 149, 70 ); | |||||
| o->color( ( Fl_Color ) 53 ); | |||||
| { | |||||
| Fl_Input *o = name_field = new Fl_Input( 2, 2, 144, 24 ); | |||||
| o->color( ( Fl_Color ) 33 ); | |||||
| o->labeltype( FL_NO_LABEL ); | |||||
| o->labelcolor( FL_GRAY0 ); | |||||
| o->textcolor( 32 ); | |||||
| o->callback( cb_input_field, (void*)this ); | |||||
| } | |||||
| { | |||||
| Fl_Group *o = controls = new Fl_Group( 2, 28, 149, 24 ); | |||||
| { | |||||
| Fl_Button *o = record_button = | |||||
| new Fl_Button( 6, 28, 26, 24, "@circle" ); | |||||
| o->type( 1 ); | |||||
| o->box( FL_THIN_UP_BOX ); | |||||
| o->color( FL_LIGHT1 ); | |||||
| o->selection_color( FL_RED ); | |||||
| o->labelsize( 8 ); | |||||
| o->callback( cb_button, this ); | |||||
| } | |||||
| { | |||||
| Fl_Button *o = mute_button = | |||||
| new Fl_Button( 35, 28, 26, 24, "m" ); | |||||
| o->type( 1 ); | |||||
| o->box( FL_THIN_UP_BOX ); | |||||
| o->color( FL_LIGHT1 ); | |||||
| o->labelsize( 11 ); | |||||
| o->callback( cb_button, this ); | |||||
| } | |||||
| { | |||||
| Fl_Button *o = solo_button = | |||||
| new Fl_Button( 66, 28, 26, 24, "s" ); | |||||
| o->type( 1 ); | |||||
| o->box( FL_THIN_UP_BOX ); | |||||
| o->color( FL_LIGHT1 ); | |||||
| o->labelsize( 11 ); | |||||
| o->callback( cb_button, this ); | |||||
| } | |||||
| { | |||||
| Fl_Menu_Button *o = take_menu = | |||||
| new Fl_Menu_Button( 97, 28, 47, 24, "T" ); | |||||
| o->box( FL_THIN_UP_BOX ); | |||||
| o->color( FL_LIGHT1 ); | |||||
| o->align( FL_ALIGN_LEFT | FL_ALIGN_INSIDE ); | |||||
| o->callback( cb_button, this ); | |||||
| o->add( "Show all takes", 0, 0, 0, FL_MENU_TOGGLE ); | |||||
| o->add( "New", 0, 0, 0, FL_MENU_DIVIDER ); | |||||
| } | |||||
| o->end(); | |||||
| } | |||||
| { | |||||
| Fl_Box *o = new Fl_Box( 0, 76, 149, 38 ); | |||||
| o->box( FL_FLAT_BOX ); | |||||
| Fl_Group::current()->resizable( o ); | |||||
| } | |||||
| o->size( Track_Header::width(), h() ); | |||||
| o->end(); | |||||
| } | |||||
| { | |||||
| Fl_Pack *o = pack = new Fl_Pack( width(), 0, 1006, 115 ); | |||||
| o->labeltype( FL_NO_LABEL ); | |||||
| o->resize( x() + width(), y(), w() - width(), h() ); | |||||
| Fl_Group::current()->resizable( o ); | |||||
| { | |||||
| Fl_Pack *o = control = new Fl_Pack( width(), 0, pack->w(), 115 ); | |||||
| o->end(); | |||||
| } | |||||
| { | |||||
| Fl_Pack *o = takes = new Fl_Pack( width(), 0, pack->w(), 115 ); | |||||
| o->end(); | |||||
| o->hide(); | |||||
| } | |||||
| o->end(); | |||||
| } | |||||
| end(); | |||||
| log_create(); | |||||
| } | |||||
| Track_Header::~Track_Header ( ) | |||||
| { | |||||
| log_destroy(); | |||||
| } | |||||
| static int pack_visible( Fl_Pack *p ) | |||||
| { | |||||
| int v = 0; | |||||
| for ( int i = p->children(); i--; ) | |||||
| if ( p->child( i )->visible() ) | |||||
| v++; | |||||
| return v; | |||||
| } | |||||
| /* adjust size of widget and children */ | |||||
| void | |||||
| Track_Header::resize ( void ) | |||||
| { | |||||
| for ( int i = takes->children(); i--; ) | |||||
| takes->child( i )->size( w(), height() ); | |||||
| for ( int i = control->children(); i--; ) | |||||
| control->child( i )->size( w(), height() ); | |||||
| if ( _show_all_takes ) | |||||
| { | |||||
| takes->show(); | |||||
| Fl_Group::size( w(), height() * ( 1 + takes->children() + pack_visible( control ) ) ); | |||||
| } | |||||
| else | |||||
| { | |||||
| takes->hide(); | |||||
| Fl_Group::size( w(), height() * ( 1 + pack_visible( control ) ) ); | |||||
| } | |||||
| if ( track() ) | |||||
| track()->size( w(), height() ); | |||||
| if ( controls->y() + controls->h() > y() + h() ) | |||||
| controls->hide(); | |||||
| else | |||||
| controls->show(); | |||||
| parent()->redraw(); | |||||
| } | |||||
| void | |||||
| Track_Header::size ( int v ) | |||||
| { | |||||
| if ( v < 0 || v > 3 ) | |||||
| return; | |||||
| _size = v; | |||||
| resize(); | |||||
| } | |||||
| void | |||||
| Track_Header::track( Track * t ) | |||||
| { | |||||
| // t->size( 1, h() ); | |||||
| if ( track() ) | |||||
| add( track() ); | |||||
| // takes->insert( *track(), 0 ); | |||||
| _track = t; | |||||
| pack->insert( *t, 0 ); | |||||
| resize(); | |||||
| } | |||||
| void | |||||
| Track_Header::add_control( Track *t ) | |||||
| { | |||||
| control->add( t ); | |||||
| resize(); | |||||
| } | |||||
| /**********/ | |||||
| /* Engine */ | |||||
| /**********/ | |||||
| /* THREAD: RT */ | |||||
| nframes_t | |||||
| Track_Header::process ( nframes_t nframes ) | |||||
| { | |||||
| if ( playback_ds ) | |||||
| { | |||||
| record_ds->process( nframes ); | |||||
| return playback_ds->process( nframes ); | |||||
| } | |||||
| else | |||||
| return 0; | |||||
| } | |||||
| /* THREAD: RT */ | |||||
| void | |||||
| Track_Header::seek ( nframes_t frame ) | |||||
| { | |||||
| if ( playback_ds ) | |||||
| return playback_ds->seek( frame ); | |||||
| } | |||||
| /* FIXME: what about theading issues with this region/audiofile being | |||||
| accessible from the UI thread? Need locking? */ | |||||
| #include "Region.H" | |||||
| /* THREAD: IO */ | |||||
| /** create capture region and prepare to record */ | |||||
| void | |||||
| Track_Header::record ( nframes_t frame ) | |||||
| { | |||||
| assert( _capture == NULL ); | |||||
| /* FIXME: hack */ | |||||
| Audio_File *af = Audio_File_SF::create( "testing.wav", 48000, input.size(), "Wav/24" ); | |||||
| _capture = new Region( af, track(), frame ); | |||||
| /* FIXME: wrong place for this */ | |||||
| _capture->_r->end = 0; | |||||
| } | |||||
| /* THREAD: IO */ | |||||
| /** write a block to the (already opened) capture file */ | |||||
| void | |||||
| Track_Header::write ( sample_t *buf, nframes_t nframes ) | |||||
| { | |||||
| _capture->write( buf, nframes ); | |||||
| } | |||||
| /* THREAD: IO */ | |||||
| void | |||||
| Track_Header::stop ( nframes_t nframes ) | |||||
| { | |||||
| _capture = NULL; | |||||
| } | |||||
| @@ -1,285 +0,0 @@ | |||||
| /*******************************************************************************/ | |||||
| /* Copyright (C) 2008 Jonathan Moore Liles */ | |||||
| /* */ | |||||
| /* This program is free software; you can redistribute it and/or modify it */ | |||||
| /* under the terms of the GNU General Public License as published by the */ | |||||
| /* Free Software Foundation; either version 2 of the License, or (at your */ | |||||
| /* option) any later version. */ | |||||
| /* */ | |||||
| /* This program is distributed in the hope that it will be useful, but WITHOUT */ | |||||
| /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ | |||||
| /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */ | |||||
| /* more details. */ | |||||
| /* */ | |||||
| /* You should have received a copy of the GNU General Public License along */ | |||||
| /* with This program; see the file COPYING. If not,write to the Free Software */ | |||||
| /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |||||
| /*******************************************************************************/ | |||||
| #ifndef Track_Header_H | |||||
| #define Track_Header_H | |||||
| #include <FL/Fl.H> | |||||
| #include "Track.H" | |||||
| #include <FL/Fl_Group.H> | |||||
| #include <FL/Fl_Input.H> | |||||
| #include <FL/Fl_Button.H> | |||||
| #include <FL/Fl_Menu_Button.H> | |||||
| #include <FL/Fl_Pack.H> | |||||
| #include <FL/Fl_Box.H> | |||||
| #include "Loggable.H" | |||||
| // #include "Port.H" | |||||
| /* TODO: rename this to Audio_Track_Header or something since it's audio specific. */ | |||||
| #include <vector> | |||||
| using std::vector; | |||||
| class Playback_DS; | |||||
| class Record_DS; | |||||
| class Port; | |||||
| class Track_Header : public Fl_Group, public Loggable | |||||
| { | |||||
| public: | |||||
| Track_Header ( int X, int Y, int W, int H, const char *L = 0 ); | |||||
| ~Track_Header ( ); | |||||
| private: | |||||
| // Track * _track; | |||||
| char *_name; | |||||
| bool _selected; | |||||
| bool _show_all_takes; | |||||
| int _size; | |||||
| enum { AUDIO } _type; | |||||
| Track *_track; | |||||
| Region *_capture; /* capture region */ | |||||
| public: | |||||
| Fl_Input * name_field; | |||||
| Fl_Button *record_button; | |||||
| Fl_Button *mute_button; | |||||
| Fl_Button *solo_button; | |||||
| Fl_Menu_Button *take_menu; | |||||
| Fl_Group *controls; | |||||
| Fl_Pack *pack; | |||||
| Fl_Pack *control; | |||||
| Fl_Pack *takes; | |||||
| vector <Port> input; | |||||
| vector <Port> output; /* output ports... */ | |||||
| Playback_DS *playback_ds; | |||||
| Record_DS *record_ds; | |||||
| const char *class_name ( void ) { return "Track_Header"; } | |||||
| void set ( char **sa ) | |||||
| { | |||||
| for ( int i = 0; sa[i]; ++i ) | |||||
| { | |||||
| char *s = sa[i]; | |||||
| strtok( s, " " ); | |||||
| char *v = s + strlen( s ) + 1; | |||||
| if ( *v == '"' ) | |||||
| { | |||||
| v++; | |||||
| v[ strlen( v ) - 2 ] = '\0'; | |||||
| } | |||||
| if ( ! strcmp( s, ":h" ) ) | |||||
| { | |||||
| size( atoi( v ) ); | |||||
| Fl_Widget::size( w(), height() ); | |||||
| } | |||||
| else if ( ! strcmp( s, ":selected" ) ) | |||||
| _selected = atoi( v ); | |||||
| // else if ( ! strcmp( s, ":armed" | |||||
| else if ( ! strcmp( s, ":name" ) ) | |||||
| { | |||||
| _name = strdup( v ); | |||||
| name_field->value( _name ); | |||||
| } | |||||
| else if ( ! strcmp( s, ":track" ) ) | |||||
| { | |||||
| int i; | |||||
| sscanf( v, "%X", &i ); | |||||
| Track *t = (Track*)Loggable::find( i ); | |||||
| assert( t ); | |||||
| track( t ); | |||||
| } | |||||
| free( s ); | |||||
| } | |||||
| free( sa ); | |||||
| } | |||||
| char ** get ( void ) | |||||
| { | |||||
| char **sa = (char**)malloc( sizeof( char* ) * (1 + 5) ); | |||||
| int i = 0; | |||||
| asprintf( &sa[ i++ ], ":name \"%s\"", _name ? _name : "" ); | |||||
| asprintf( &sa[ i++ ], ":track 0x%X", track() ? track()->id() : 0 ); | |||||
| asprintf( &sa[ i++ ], ":selected %d", _selected ); | |||||
| // asprintf( &sa[ i++ ], ":record %d", record_button->value() ); | |||||
| /* asprintf( &sa[ i++ ], ":solo %d", solo_button->value() ); */ | |||||
| /* asprintf( &sa[ i++ ], ":mute %d", mute_button->value() ); */ | |||||
| asprintf( &sa[ i++ ], ":h %d", size() ); | |||||
| // asprintf( &sa[ i++ ], ":gain %f", _scale ); | |||||
| sa[ i ] = NULL; | |||||
| return sa; | |||||
| } | |||||
| /* for loggable */ | |||||
| static Loggable * | |||||
| create ( char **sa ) | |||||
| { | |||||
| Track_Header *r = new Track_Header( 0, 0, 1, 1 ); | |||||
| r->set( sa ); | |||||
| return (Loggable *)r; | |||||
| } | |||||
| void | |||||
| draw ( void ) | |||||
| { | |||||
| if ( _selected ) | |||||
| { | |||||
| Fl_Color c = color(); | |||||
| color( FL_RED ); | |||||
| Fl_Group::draw(); | |||||
| color( c ); | |||||
| } | |||||
| else | |||||
| Fl_Group::draw(); | |||||
| } | |||||
| void add_control( Track *t ); | |||||
| int size ( void ) const { return _size; } | |||||
| void resize ( void ); | |||||
| void size ( int v ); | |||||
| int height ( void ) const | |||||
| { | |||||
| static int table[] = { 30, 80, 150, 300 }; | |||||
| return table[ _size ]; | |||||
| } | |||||
| void show_all_takes ( bool b ) | |||||
| { | |||||
| _show_all_takes = b; | |||||
| resize(); | |||||
| } | |||||
| const char * name ( void ) const { return _name; } | |||||
| bool mute ( void ) const { return mute_button->value(); } | |||||
| bool solo ( void ) const { return solo_button->value(); } | |||||
| bool armed ( void ) const { return record_button->value(); } | |||||
| bool selected ( void ) const { return _selected; } | |||||
| static void cb_input_field ( Fl_Widget *w, void *v ); | |||||
| void cb_input_field ( void ); | |||||
| static void cb_button ( Fl_Widget *w, void *v ); | |||||
| void cb_button ( Fl_Widget *w ); | |||||
| static int width ( void ) { return 150; } | |||||
| void track( Track * t ); | |||||
| Track * track ( void ) { return _track; } | |||||
| void add ( Track * t ) | |||||
| { | |||||
| takes->insert( *t, 0 ); | |||||
| if ( ! t->name() ) | |||||
| { | |||||
| char pat[20]; | |||||
| snprintf( pat, sizeof( pat ), "%d", takes->children() ); | |||||
| t->name( strdup( pat ) ); | |||||
| take_menu->add( t->name() ); | |||||
| } | |||||
| } | |||||
| void remote ( Track *t ) | |||||
| { | |||||
| takes->remove( t ); | |||||
| // take_menu->remove( t->name() ); | |||||
| } | |||||
| int handle ( int m ) | |||||
| { | |||||
| switch ( m ) | |||||
| { | |||||
| case FL_MOUSEWHEEL: | |||||
| { | |||||
| if ( ! Fl::event_shift() ) | |||||
| return 0; | |||||
| int d = Fl::event_dy(); | |||||
| printf( "%d\n", d ); | |||||
| if ( d < 0 ) | |||||
| size( size() - 1 ); | |||||
| else | |||||
| size( size() + 1 ); | |||||
| return 1; | |||||
| } | |||||
| default: | |||||
| return Fl_Group::handle( m ); | |||||
| } | |||||
| } | |||||
| /* Engine */ | |||||
| nframes_t process ( nframes_t nframes ); | |||||
| void seek ( nframes_t frame ); | |||||
| void record ( nframes_t nframes ); | |||||
| void write ( sample_t *buf, nframes_t nframes ); | |||||
| void stop ( nframes_t nframes ); | |||||
| }; | |||||
| #endif | |||||
| @@ -40,15 +40,15 @@ | |||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| #include "Track.H" | |||||
| #include "Audio_Track.H" | |||||
| #include "Sequence.H" | |||||
| #include "Audio_Sequence.H" | |||||
| #include "Timeline.H" | #include "Timeline.H" | ||||
| #include "Tempo_Track.H" | |||||
| #include "Time_Track.H" | |||||
| #include "Control_Track.H" | |||||
| #include "Tempo_Sequence.H" | |||||
| #include "Time_Sequence.H" | |||||
| #include "Control_Sequence.H" | |||||
| #include "Loggable.H" | #include "Loggable.H" | ||||
| #include "Track_Header.H" | |||||
| #include "Track.H" | |||||
| // #include "const.h" | // #include "const.h" | ||||
| #include "Engine.H" | #include "Engine.H" | ||||
| @@ -77,7 +77,7 @@ main ( int argc, char **argv ) | |||||
| Loggable::register_create( "Tempo_Point", &Tempo_Point::create ); | Loggable::register_create( "Tempo_Point", &Tempo_Point::create ); | ||||
| Loggable::register_create( "Time_Point", &Time_Point::create ); | Loggable::register_create( "Time_Point", &Time_Point::create ); | ||||
| Loggable::register_create( "Control_Point", &Control_Point::create ); | Loggable::register_create( "Control_Point", &Control_Point::create ); | ||||
| Loggable::register_create( "Track_Header", &Track_Header::create ); | |||||
| Loggable::register_create( "Track", &Track::create ); | |||||
| /* TODO: change to seesion dir */ | /* TODO: change to seesion dir */ | ||||