diff --git a/Region.H b/Region.H index dc86f47..0fb8f08 100644 --- a/Region.H +++ b/Region.H @@ -33,297 +33,7 @@ using namespace std; * dimensions of real FLTK widgets are limited to 16-bits, which is * far too little for our purposes */ - -/* Base class for virtual widget on a track */ -class Track_Widget -{ - -protected: - - Track *_track; /* track this region belongs to */ - - nframes_t _offset; /* where on the timeline */ - 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) */ - -public: - - Track_Widget ( ) - { - _track = NULL; - - _offset = _start = _end = 0; - - _selected = false; - } - - Fl_Group * parent ( void ) const { return _track; } - - int scroll_x ( void ) const { return timeline.ts_to_x( timeline.xoffset ); } - nframes_t scroll_ts ( void ) const { return timeline.xoffset; } - - int y ( void ) const { return _track->y(); } - int h ( void ) const { return _track->h(); } - - int x ( void ) const { return _offset < timeline.xoffset ? -1 : min( 32767, _track->x() + timeline.ts_to_x( _offset - timeline.xoffset ) ); } - virtual int w ( void ) const - { - int tx = timeline.ts_to_x( _offset ); - - int rw; - if ( tx < scroll_x() ) - rw = abs_w() - (scroll_x() - tx); - else - rw = abs_w(); - - return min( rw, _track->w() ); - } - - int abs_x ( void ) const { return timeline.ts_to_x( timeline.xoffset ); } - virtual int abs_w ( void ) const { return timeline.ts_to_x( _end - _start ); } - - - Fl_Color color ( void ) { return _color; } - Fl_Color box_color ( void ) { return _box_color; } - - Track * track ( void ) const { return _track; } - void track ( Track *t ) { _track = t; } - - nframes_t offset ( void ) const { return _offset; } - void offset ( nframes_t o ) { _offset = o; } - - void end ( nframes_t v ) { _end = v; } - nframes_t end ( void ) const { return _end; } - void start ( nframes_t v ) { _start = v; } - nframes_t start ( void ) const { return _start; } - - virtual nframes_t length ( void ) const { return _end - _start; } - - virtual Fl_Boxtype box ( void ) const { return FL_UP_BOX; } - - /* just draw a simple box */ - - virtual void - draw_box ( int X, int Y, int W, int H ) - { - fl_draw_box( box(), x(), y(), w(), y(), _box_color ); - } - - virtual void - draw ( int X, int Y, int W, int H ) - { - draw_box( X, Y, W, H ); - } - - - 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_font( FL_HELVETICA, 14 ); */ -/* fl_color( FL_BLACK ); */ -/* fl_draw( label, X + 2, Y + 2, w(), h(), align ); */ -/* fl_color( FL_WHITE ); */ -/* fl_draw( label, X, Y, w(), h(), align ); */ - - /* for some reasone FL_SHADOW_LABLE doesn't always use - * black for the shadow color...so we can't rely on it. */ - - Fl_Label lab; - - lab.color = FL_WHITE; - 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; - int tx = timeline.ts_to_x( _offset ); - - if ( tx < scroll_x() ) - dx = min( 32767, scroll_x() - tx ); - - 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; - - int X = Fl::event_x(); - int Y = Fl::event_y(); - - switch ( m ) - { - case FL_PUSH: - { - ox = x() - X; - oy = y() - Y; - - if ( Fl::event_state() & FL_CTRL && - Fl::event_button() == 3 ) - { - _track->queue_delete( this ); - return 0; - } - - return 1; - } - case FL_RELEASE: - fl_cursor( FL_CURSOR_DEFAULT ); - return 1; - case FL_DRAG: - { - if ( ox + X >= _track->x() ) - { - int nx = ox + 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.xoffset = pos; - - timeline.tracks->redraw(); - } - - - return 1; - } - default: - return 0; - } - } - - bool - operator< ( const Track_Widget & rhs ) - { - return _offset < rhs._offset; - } -}; - - -class Track_Point : public Track_Widget -{ - -protected: - - char *_label; - -public: - - int abs_w ( void ) const { return 10; } - nframes_t length ( void ) const { return timeline.x_to_ts( abs_w() ); } - - Track_Point ( ) - { - _label = NULL; - } - - void - draw ( int X, int Y, int W, int H ) - { - Track_Widget::draw( x(), Y, w(), H ); - - draw_label( _label, FL_ALIGN_RIGHT ); - } -}; - -class Tempo_Point : public Track_Point -{ - float _tempo; - - void - _make_label ( void ) - { - if ( ! _label ) - _label = new char[40]; - - snprintf( _label, 40, "%.1f", _tempo ); - } -public: - - Tempo_Point ( nframes_t when, float bpm ) - { - _tempo = bpm; - _offset = when; - - _make_label(); - } - - ~Tempo_Point ( ) - { if ( _label ) delete[] _label; } - -}; +#include "Track_Widget.H" class Region : public Track_Widget { diff --git a/Tempo_Point.H b/Tempo_Point.H new file mode 100644 index 0000000..5e82d24 --- /dev/null +++ b/Tempo_Point.H @@ -0,0 +1,49 @@ + +/*******************************************************************************/ +/* 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 "Track_Point.H" + +class Tempo_Point : public Track_Point +{ + float _tempo; + + void + _make_label ( void ) + { + if ( ! _label ) + _label = new char[40]; + + snprintf( _label, 40, "%.1f", _tempo ); + } +public: + + Tempo_Point ( nframes_t when, float bpm ) + { + _tempo = bpm; + _offset = when; + + _make_label(); + } + + ~Tempo_Point ( ) + { if ( _label ) delete[] _label; } + +}; diff --git a/Timeline.H b/Timeline.H index 1898136..e892dae 100644 --- a/Timeline.H +++ b/Timeline.H @@ -30,6 +30,13 @@ #include +class Timeline; +extern Timeline timeline; + +#include "Track.H" +// #include "Tempo_Point.H" +// #include "Region.H" + #include using std::list; @@ -69,6 +76,8 @@ struct Timeline { Fl_Pack *tracks; Fl_Scrollbar *scrollbar; + Track *tempo_track; + float fpp; /* frames per pixel */ // nframes_t fpp; @@ -119,12 +128,7 @@ struct Timeline { void beats_per_minute ( nframes_t when, float bpm ) { - tempo_event t; - - t.timestamp = when; - t.beats_per_minute = bpm; - - tempo_points.push_back( t ); +// tempo_track->add( new Tempo_Point( when, bpm ) ); } /* /\* return the offset of the closest measure line to /t/ *\/ */ @@ -159,5 +163,3 @@ struct Timeline { fl_line_style( FL_SOLID, 0 ); } }; - -extern Timeline timeline; diff --git a/Track.H b/Track.H index f4c6d78..cc2307c 100644 --- a/Track.H +++ b/Track.H @@ -69,6 +69,8 @@ public: void remove ( Track_Widget *r ); void add ( Track_Widget *r ); + const list widgets ( void ) const { return _widgets; } + void queue_delete ( Track_Widget *r ) { assert( ! _queued_widget ); diff --git a/Track_Point.H b/Track_Point.H new file mode 100644 index 0000000..c97bd17 --- /dev/null +++ b/Track_Point.H @@ -0,0 +1,48 @@ + +/*******************************************************************************/ +/* 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 "Track_Widget.H" + +class Track_Point : public Track_Widget +{ + +protected: + + char *_label; + +public: + + int abs_w ( void ) const { return 10; } + nframes_t length ( void ) const { return timeline.x_to_ts( abs_w() ); } + + Track_Point ( ) + { + _label = NULL; + } + + void + draw ( int X, int Y, int W, int H ) + { + Track_Widget::draw( x(), Y, w(), H ); + + draw_label( _label, FL_ALIGN_RIGHT ); + } +}; diff --git a/Track_Widget.H b/Track_Widget.H new file mode 100644 index 0000000..217b0a7 --- /dev/null +++ b/Track_Widget.H @@ -0,0 +1,259 @@ + +/*******************************************************************************/ +/* 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 "Track.H" + +/* Base class for virtual widget on a track */ +class Track_Widget +{ + +protected: + + Track *_track; /* track this region belongs to */ + + nframes_t _offset; /* where on the timeline */ + 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) */ + +public: + + Track_Widget ( ) + { + _track = NULL; + + _offset = _start = _end = 0; + + _selected = false; + } + + Fl_Group * parent ( void ) const { return _track; } + + int scroll_x ( void ) const { return timeline.ts_to_x( timeline.xoffset ); } + nframes_t scroll_ts ( void ) const { return timeline.xoffset; } + + int y ( void ) const { return _track->y(); } + int h ( void ) const { return _track->h(); } + + int x ( void ) const { return _offset < timeline.xoffset ? -1 : min( 32767, _track->x() + timeline.ts_to_x( _offset - timeline.xoffset ) ); } + virtual int w ( void ) const + { + int tx = timeline.ts_to_x( _offset ); + + int rw; + if ( tx < scroll_x() ) + rw = abs_w() - (scroll_x() - tx); + else + rw = abs_w(); + + return min( rw, _track->w() ); + } + + int abs_x ( void ) const { return timeline.ts_to_x( timeline.xoffset ); } + virtual int abs_w ( void ) const { return timeline.ts_to_x( _end - _start ); } + + + Fl_Color color ( void ) { return _color; } + Fl_Color box_color ( void ) { return _box_color; } + + Track * track ( void ) const { return _track; } + void track ( Track *t ) { _track = t; } + + nframes_t offset ( void ) const { return _offset; } + void offset ( nframes_t o ) { _offset = o; } + + void end ( nframes_t v ) { _end = v; } + nframes_t end ( void ) const { return _end; } + void start ( nframes_t v ) { _start = v; } + nframes_t start ( void ) const { return _start; } + + virtual nframes_t length ( void ) const { return _end - _start; } + + virtual Fl_Boxtype box ( void ) const { return FL_UP_BOX; } + + /* just draw a simple box */ + + virtual void + draw_box ( int X, int Y, int W, int H ) + { + fl_draw_box( box(), x(), y(), w(), y(), _box_color ); + } + + virtual void + draw ( int X, int Y, int W, int H ) + { + draw_box( X, Y, W, H ); + } + + + 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_font( FL_HELVETICA, 14 ); */ +/* fl_color( FL_BLACK ); */ +/* fl_draw( label, X + 2, Y + 2, w(), h(), align ); */ +/* fl_color( FL_WHITE ); */ +/* fl_draw( label, X, Y, w(), h(), align ); */ + + /* for some reasone FL_SHADOW_LABLE doesn't always use + * black for the shadow color...so we can't rely on it. */ + + Fl_Label lab; + + lab.color = FL_WHITE; + 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; + int tx = timeline.ts_to_x( _offset ); + + if ( tx < scroll_x() ) + dx = min( 32767, scroll_x() - tx ); + + 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; + + int X = Fl::event_x(); + int Y = Fl::event_y(); + + switch ( m ) + { + case FL_PUSH: + { + ox = x() - X; + oy = y() - Y; + + if ( Fl::event_state() & FL_CTRL && + Fl::event_button() == 3 ) + { + _track->queue_delete( this ); + return 0; + } + + return 1; + } + case FL_RELEASE: + fl_cursor( FL_CURSOR_DEFAULT ); + return 1; + case FL_DRAG: + { + if ( ox + X >= _track->x() ) + { + int nx = ox + 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.xoffset = pos; + + timeline.tracks->redraw(); + } + + + return 1; + } + default: + return 0; + } + } + + bool + operator< ( const Track_Widget & rhs ) + { + return _offset < rhs._offset; + } +}; diff --git a/main.C b/main.C index 24e4e5d..9b666f3 100644 --- a/main.C +++ b/main.C @@ -42,6 +42,7 @@ #include "Track.H" #include "Audio_Track.H" #include "Timeline.H" +#include "Tempo_Point.H" #include "const.h"