| @@ -346,7 +346,7 @@ Timeline::draw ( void ) | |||
| draw_child( *hscroll ); | |||
| draw_child( *vscroll ); | |||
| // redraw_overlay(); | |||
| redraw_overlay(); | |||
| return; | |||
| } | |||
| @@ -392,23 +392,34 @@ Timeline::draw ( void ) | |||
| void | |||
| Timeline::draw_overlay ( void ) | |||
| { | |||
| fl_color( FL_BLUE ); | |||
| fl_line_style( FL_DOT, 4 ); | |||
| // TODO: draw selection rectangle here! | |||
| fl_rect( _selection.x, _selection.y, _selection.w, _selection.h ); | |||
| fl_line_style( FL_SOLID, 0 ); | |||
| /* fl_color( FL_BLUE ); */ | |||
| /* fl_line_style( FL_DOT, 4 ); */ | |||
| } | |||
| /* fl_rect( 300, 400, 200, 300 ); */ | |||
| // #include "Track_Widget.H" | |||
| /* fl_line_style( FL_SOLID, 0 ); */ | |||
| /** select all widgets in inside rectangle /r/ */ | |||
| void | |||
| Timeline::select( const Rectangle &r ) | |||
| { | |||
| for ( int i = tracks->children(); i-- ; ) | |||
| { | |||
| Track_Header *t = (Track_Header*)tracks->child( i ); | |||
| if ( t->y() >= r.y && t->y() + t->h() <= r.y + r.h ) | |||
| t->track()->select_range( r.x, r.w ); | |||
| } | |||
| } | |||
| int | |||
| Timeline::handle ( int m ) | |||
| { | |||
| static Drag *drag = NULL; | |||
| switch ( m ) | |||
| { | |||
| @@ -418,43 +429,57 @@ Timeline::handle ( int m ) | |||
| { | |||
| case FL_Delete: | |||
| { | |||
| /* for ( int i = tracks->children(); i--; ) */ | |||
| /* { */ | |||
| /* Track_Header *t = (Track_Header*)tracks->child( i ); */ | |||
| /* t->track()->remove_selected(); */ | |||
| /* } */ | |||
| Track_Widget::delete_selected(); | |||
| return 1; | |||
| } | |||
| } | |||
| } | |||
| /* case FL_MOUSEWHEEL: */ | |||
| /* { */ | |||
| /* // vscroll->deactivate(); */ | |||
| return 0; | |||
| } | |||
| default: | |||
| { | |||
| int r = Fl_Overlay_Window::handle( m ); | |||
| /* int r = Fl_Overlay_Window::handle( m ); */ | |||
| if ( r ) | |||
| return r; | |||
| /* /\* vscroll->activate(); *\/ */ | |||
| const int X = Fl::event_x(); | |||
| const int Y = Fl::event_y(); | |||
| /* if ( r ) */ | |||
| /* return r; */ | |||
| switch ( m ) | |||
| { | |||
| case FL_PUSH: | |||
| { | |||
| drag = new Drag( X - x(), Y - y() ); | |||
| _selection.x = drag->x; | |||
| _selection.y = drag->y; | |||
| break; | |||
| } | |||
| case FL_DRAG: | |||
| { | |||
| _selection.w = X - drag->x; | |||
| _selection.h = Y - drag->y; | |||
| break; | |||
| } | |||
| case FL_RELEASE: | |||
| { | |||
| delete drag; | |||
| drag = NULL; | |||
| /* /\* if ( hscroll->handle( m ) ) *\/ */ | |||
| /* /\* return 1; *\/ */ | |||
| select( _selection ); | |||
| /* /\* return vscroll->handle( m ); *\/ */ | |||
| _selection.w = _selection.h = 0; | |||
| break; | |||
| } | |||
| default: | |||
| return 0; | |||
| break; | |||
| } | |||
| /* } */ | |||
| default: | |||
| return Fl_Overlay_Window::handle( m ); | |||
| redraw_overlay(); | |||
| return 1; | |||
| } | |||
| } | |||
| } | |||
| @@ -49,6 +49,18 @@ class Time_Track; | |||
| #include <list> | |||
| using std::list; | |||
| struct Rectangle | |||
| { | |||
| int x; | |||
| int y; | |||
| int w; | |||
| int h; | |||
| Rectangle ( ) : x( 0 ), y( 0 ), w( 0 ), h( 0 ) {} | |||
| Rectangle ( int X, int Y, int W, int H ) : x( X ), y( Y ), w( W ), h( H ) {} | |||
| }; | |||
| struct Timeline : public Fl_Overlay_Window | |||
| { | |||
| @@ -57,6 +69,8 @@ struct Timeline : public Fl_Overlay_Window | |||
| int _old_xposition; | |||
| int _old_yposition; | |||
| Rectangle _selection; | |||
| bool _enable_measure_lines; | |||
| enum snap_flags_e { | |||
| @@ -117,4 +131,6 @@ struct Timeline : public Fl_Overlay_Window | |||
| void draw_overlay ( void ); | |||
| int handle ( int m ); | |||
| void select( const Rectangle &r ); | |||
| }; | |||
| @@ -102,7 +102,7 @@ Track::remove_selected ( void ) | |||
| Track_Widget * | |||
| Track::event_widget ( void ) | |||
| { | |||
| int ets = timeline->xoffset + timeline->x_to_ts( Fl::event_x() - x() ); | |||
| 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); | |||
| @@ -110,6 +110,17 @@ Track::event_widget ( void ) | |||
| return NULL; | |||
| } | |||
| void | |||
| Track::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 <Track_Widget *>::const_reverse_iterator r = _widgets.rbegin(); r != _widgets.rend(); r++ ) | |||
| if ( ! ( (*r)->offset() > ets || (*r)->offset() + (*r)->length() < sts ) ) | |||
| (*r)->select(); | |||
| } | |||
| void | |||
| Track::add ( Track_Widget *r ) | |||
| { | |||
| @@ -113,6 +113,8 @@ public: | |||
| void remove ( Track_Widget *r ); | |||
| void add ( Track_Widget *r ); | |||
| void select_range ( int X, int W ); | |||
| void remove_selected ( void ); | |||
| const list <Track_Widget *> widgets ( void ) const { return _widgets; } | |||
| @@ -27,6 +27,16 @@ | |||
| #include <algorithm> | |||
| using namespace std; | |||
| struct Drag | |||
| { | |||
| /* mouse coords at start of drag */ | |||
| int x; | |||
| int y; | |||
| int state; | |||
| Drag( int X, int Y ) : x( X ), y( Y ) { state = 0; } | |||
| }; | |||
| /* Base class for virtual widget on a track */ | |||
| class Track_Widget : public Loggable | |||
| { | |||
| @@ -45,15 +55,6 @@ protected: | |||
| Fl_Color _color; /* color of waveform */ | |||
| Fl_Color _box_color; /* color of background (box) */ | |||
| struct Drag | |||
| { | |||
| /* mouse coords at start of drag */ | |||
| int x; | |||
| int y; | |||
| int state; | |||
| Drag( int X, int Y ) : x( X ), y( Y ) { state = 0; } | |||
| }; | |||
| Drag *_drag; | |||
| @@ -84,12 +85,18 @@ public: | |||
| void select ( void ) | |||
| { | |||
| if ( selected() ) | |||
| return; | |||
| _selection.push_back( this ); | |||
| redraw(); | |||
| } | |||
| void deselect ( void ) | |||
| { | |||
| _selection.remove( this ); | |||
| redraw(); | |||
| } | |||