From 0b3c107192f4f2fc380563395ba60dd262e66517 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Mon, 3 Mar 2008 15:00:38 -0600 Subject: [PATCH] Change the way selection works. --- Makefile | 2 +- Region.C | 11 ++- Region.H | 9 ++- Timeline.C | 15 ++-- Track_Widget.C | 177 +++++++++++++++++++++++++++++++++++++++++ Track_Widget.H | 208 ++++++++++--------------------------------------- 6 files changed, 244 insertions(+), 178 deletions(-) create mode 100644 Track_Widget.C diff --git a/Makefile b/Makefile index f9e4107..304ed9d 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CXXFLAGS=-ggdb -Wall -O0 LIBS=-lsndfile `fltk-config --ldflags` # CXXFLAGS=`fltk-config -cxxflags` -SRCS= Waveform.C Region.C Peaks.C main.C Track.C Audio_Track.C Timeline.C Audio_File.C Audio_File_SF.C Loggable.C Track_Header.C +SRCS= Waveform.C Region.C Peaks.C main.C Track.C Audio_Track.C Timeline.C Audio_File.C Audio_File_SF.C Loggable.C Track_Header.C Track_Widget.C OBJS=$(SRCS:.C=.o) diff --git a/Region.C b/Region.C index c2a2cc9..c4becf6 100644 --- a/Region.C +++ b/Region.C @@ -282,7 +282,12 @@ Region::handle ( int m ) if ( Fl::event_state() & FL_CTRL ) normalize(); else - _selected = ! _selected; + { + if ( selected() ) + deselect(); + else + select(); + } redraw(); goto changed; @@ -392,7 +397,7 @@ Region::draw_box( int X, int Y, int W, int H ) fl_push_clip( x(), Y, w(), H ); - if ( _selected ) + if ( selected() ) fl_draw_box( fl_down( box() ), x() - 10, y(), w() + 50, h(), _selection_color ); // fl_draw_box( fl_down( box() ), x() - 10, Y, w() + 50, H, fl_invert_color( _box_color ) ); else @@ -449,7 +454,7 @@ Region::draw ( int X, int Y, int W, int H ) // _scale, _selected ? _color : fl_invert_color( _color ) ); draw_waveform( rx, X, (y() + Fl::box_dy( box() )) + (i * ch), W, ch, _clip, i, _start + offset, min( (_end - _start) - offset, _end), - _scale, _selected ? fl_invert_color( _color ) : _color ); + _scale, selected() ? fl_invert_color( _color ) : _color ); timeline->draw_measure_lines( rx, Y, rw, H, _box_color ); diff --git a/Region.H b/Region.H index 2dbf6f2..dafe629 100644 --- a/Region.H +++ b/Region.H @@ -72,7 +72,7 @@ protected: asprintf( &sa[ i++ ], ":x %lu", _offset ); asprintf( &sa[ i++ ], ":l %lu", _start ); asprintf( &sa[ i++ ], ":r %lu", _end ); - asprintf( &sa[ i++ ], ":selected %d", _selected ); + asprintf( &sa[ i++ ], ":selected %d", selected() ); asprintf( &sa[ i++ ], ":gain %f", _scale ); sa[ i ] = NULL; @@ -107,7 +107,12 @@ protected: _end = atol( v ); else if ( ! strcmp( s, ":selected" ) ) - _selected = atoi( v ); + { + if ( atoi( v ) ) + select(); + else + deselect(); + } else if ( ! strcmp( s, ":gain" ) ) _scale = atof( v ); diff --git a/Timeline.C b/Timeline.C index c1421f6..b144333 100644 --- a/Timeline.C +++ b/Timeline.C @@ -418,13 +418,18 @@ 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(); - } +/* for ( int i = tracks->children(); i--; ) */ +/* { */ +/* Track_Header *t = (Track_Header*)tracks->child( i ); */ + +/* t->track()->remove_selected(); */ +/* } */ + + Track_Widget::delete_selected(); + return 1; + } } diff --git a/Track_Widget.C b/Track_Widget.C new file mode 100644 index 0000000..cd497be --- /dev/null +++ b/Track_Widget.C @@ -0,0 +1,177 @@ + +/*******************************************************************************/ +/* 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_Widget.H" + +list Track_Widget::_selection; + +void +Track_Widget::draw_label ( const char *label, Fl_Align align ) +{ + int X, Y; + + X = x(); + Y = y(); + + /* FIXME: why do we have to to this here? why doesn't Fl_Lable::draw take care of this stuff? */ + if ( ! (align & FL_ALIGN_INSIDE) ) + { + if ( align & FL_ALIGN_RIGHT ) + { + X += w(); + align = (Fl_Align)((align & ~FL_ALIGN_RIGHT) | FL_ALIGN_LEFT); + } + if ( align & FL_ALIGN_BOTTOM ) + { + Y += h(); + align = (Fl_Align)((align & ~FL_ALIGN_BOTTOM) | FL_ALIGN_TOP); + } + } + + Fl_Label lab; + + lab.color = 0; + lab.type = FL_SHADOW_LABEL; + lab.value = label; + lab.font = FL_HELVETICA; + lab.size = 14; + + int W = w(); + int H = h(); + + if ( align & FL_ALIGN_INSIDE ) + { + X += Fl::box_dx( box() ); + Y += Fl::box_dy( box() ); + W -= Fl::box_dw( box() ); + H -= Fl::box_dh( box() ); + } + + if ( align & FL_ALIGN_CLIP ) fl_push_clip( X, Y, W, H ); + + int dx = 0; + + if ( abs_x() < scroll_x() ) + dx = min( 32767, scroll_x() - abs_x() ); + + lab.draw( X - dx, Y, W, H, align ); + + if ( align & FL_ALIGN_CLIP ) fl_pop_clip(); + +} + + +/* base hanlde just does basic dragging */ +int +Track_Widget::handle ( int m ) +{ + static int ox, oy; + static bool dragging = false; + + int X = Fl::event_x(); + int Y = Fl::event_y(); + + Logger _log( this ); + + switch ( m ) + { + case FL_ENTER: + fl_cursor( FL_CURSOR_HAND ); + return 1; + case FL_LEAVE: + fl_cursor( FL_CURSOR_DEFAULT ); + return 1; + case FL_PUSH: + { + ox = x() - X; + oy = y() - Y; + + if ( Fl::event_state() & FL_CTRL && + Fl::event_button() == 3 ) + { +// log_destroy(); + + redraw(); + _track->queue_delete( this ); + return 0; + } + + return 1; + } + case FL_RELEASE: + if ( dragging ) + _log.release(); + dragging = false; + fl_cursor( FL_CURSOR_DEFAULT ); + return 1; + case FL_DRAG: + { + if ( ! dragging ) + { + dragging = true; + _log.hold(); + } + + redraw(); + + if ( timeline->ts_to_x( timeline->xoffset ) + ox + X > _track->x() ) + { + int nx = (ox + X) - _track->x(); + + _offset = timeline->x_to_ts( nx ) + timeline->xoffset; + + _track->snap( this ); + } + + // _track->redraw(); + fl_cursor( FL_CURSOR_MOVE ); + + + if ( X >= _track->x() + _track->w() || + X <= _track->x() ) + { + /* this drag needs to scroll */ + + nframes_t pos = timeline->xoffset; + + nframes_t d = timeline->x_to_ts( 100 ); + + if ( X <= _track->x() ) + { + + if ( pos > d ) + pos -= d; + else + pos = 0; + } + else + pos += d; + + timeline->position( timeline->ts_to_x( pos ) ); + _track->redraw(); +// timeline->redraw(); + } + + + return 1; + } + default: + return 0; + } +} diff --git a/Track_Widget.H b/Track_Widget.H index d41de29..86c2160 100644 --- a/Track_Widget.H +++ b/Track_Widget.H @@ -21,7 +21,9 @@ #include "Track.H" #include "Loggable.H" - +#include "Audio_File.H" +#include "Timeline.H" +#include #include using namespace std; @@ -29,6 +31,8 @@ using namespace std; class Track_Widget : public Loggable { + static list _selection; + protected: Track *_track; /* track this region belongs to */ @@ -37,8 +41,6 @@ protected: nframes_t _start; /* first sample from clip */ nframes_t _end; /* last sample from clip */ - bool _selected; - Fl_Color _color; /* color of waveform */ Fl_Color _box_color; /* color of background (box) */ @@ -49,17 +51,46 @@ public: _track = NULL; _offset = _start = _end = 0; - - _selected = false; } virtual ~Track_Widget ( ) { redraw(); + _track->remove( this ); + + _selection.remove( this ); } - bool selected ( void ) { return _selected; } + bool selected ( void ) + { + return ::find( _selection.begin(), _selection.end(), this ) != _selection.end(); + } + + void select ( void ) + { + _selection.push_back( this ); + } + + void deselect ( void ) + { + _selection.remove( this ); + } + + + static void + delete_selected ( void ) + { + while ( _selection.size() ) + delete _selection.front(); + } + + static void + move_selected ( long d ) + { + for ( list ::iterator i = _selection.begin(); i != _selection.end(); i++ ) + i->_offset += d; + } Fl_Group * parent ( void ) const { return _track; } @@ -130,170 +161,13 @@ public: draw_box( X, Y, W, H ); } - -/* virtual void */ -/* dump ( void ) */ -/* { */ -/* printf( "Unknown %p %lu %lu %lu\n", this, _offset, _start, _end ); */ -/* } */ - - virtual void - draw_label ( const char *label, Fl_Align align ) - { - int X, Y; - - X = x(); - Y = y(); - - /* FIXME: why do we have to to this here? why doesn't Fl_Lable::draw take care of this stuff? */ - if ( ! (align & FL_ALIGN_INSIDE) ) - { - if ( align & FL_ALIGN_RIGHT ) - { - X += w(); - align = (Fl_Align)((align & ~FL_ALIGN_RIGHT) | FL_ALIGN_LEFT); - } - if ( align & FL_ALIGN_BOTTOM ) - { - Y += h(); - align = (Fl_Align)((align & ~FL_ALIGN_BOTTOM) | FL_ALIGN_TOP); - } - } - - Fl_Label lab; - - lab.color = 0; - lab.type = FL_SHADOW_LABEL; - lab.value = label; - lab.font = FL_HELVETICA; - lab.size = 14; - - int W = w(); - int H = h(); - - if ( align & FL_ALIGN_INSIDE ) - { - X += Fl::box_dx( box() ); - Y += Fl::box_dy( box() ); - W -= Fl::box_dw( box() ); - H -= Fl::box_dh( box() ); - } - - if ( align & FL_ALIGN_CLIP ) fl_push_clip( X, Y, W, H ); - - int dx = 0; - - if ( abs_x() < scroll_x() ) - dx = min( 32767, scroll_x() - abs_x() ); - - lab.draw( X - dx, Y, W, H, align ); - - if ( align & FL_ALIGN_CLIP ) fl_pop_clip(); - - } - - /* base hanlde just does basic dragging */ - virtual int - handle ( int m ) - { - static int ox, oy; - static bool dragging = false; - - int X = Fl::event_x(); - int Y = Fl::event_y(); - - Logger _log( this ); - - switch ( m ) - { - case FL_ENTER: - fl_cursor( FL_CURSOR_HAND ); - return 1; - case FL_LEAVE: - fl_cursor( FL_CURSOR_DEFAULT ); - return 1; - case FL_PUSH: - { - ox = x() - X; - oy = y() - Y; - - if ( Fl::event_state() & FL_CTRL && - Fl::event_button() == 3 ) - { -// log_destroy(); - - redraw(); - _track->queue_delete( this ); - return 0; - } - - return 1; - } - case FL_RELEASE: - if ( dragging ) - _log.release(); - dragging = false; - fl_cursor( FL_CURSOR_DEFAULT ); - return 1; - case FL_DRAG: - { - if ( ! dragging ) - { - dragging = true; - _log.hold(); - } - - redraw(); - - if ( timeline->ts_to_x( timeline->xoffset ) + ox + X > _track->x() ) - { - int nx = (ox + X) - _track->x(); - - _offset = timeline->x_to_ts( nx ) + timeline->xoffset; - - _track->snap( this ); - } - - // _track->redraw(); - fl_cursor( FL_CURSOR_MOVE ); - - - if ( X >= _track->x() + _track->w() || - X <= _track->x() ) - { - /* this drag needs to scroll */ - - nframes_t pos = timeline->xoffset; - - nframes_t d = timeline->x_to_ts( 100 ); - - if ( X <= _track->x() ) - { - - if ( pos > d ) - pos -= d; - else - pos = 0; - } - else - pos += d; - - timeline->position( timeline->ts_to_x( pos ) ); - _track->redraw(); -// timeline->redraw(); - } - - - return 1; - } - default: - return 0; - } - } - bool operator< ( const Track_Widget & rhs ) { return _offset < rhs._offset; } + + virtual void draw_label ( const char *label, Fl_Align align ); + virtual int handle ( int m ); + };