From b50766b7dac1c1a8249d0b54ab33939a93043df4 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Thu, 1 Nov 2012 03:35:04 -0700 Subject: [PATCH] Timeline: Replace the scrollbars with a new Pan/zoom widget. --- lib/ntk | 2 +- timeline/src/Audio_Region.C | 8 +- timeline/src/Audio_Region.H | 1 + timeline/src/Scalebar.H | 107 ---------------- timeline/src/Sequence_Widget.H | 2 + timeline/src/Timeline.C | 227 ++++++++++++++++++--------------- timeline/src/Timeline.H | 14 +- 7 files changed, 142 insertions(+), 219 deletions(-) delete mode 100644 timeline/src/Scalebar.H diff --git a/lib/ntk b/lib/ntk index f24b363..ff7f8bd 160000 --- a/lib/ntk +++ b/lib/ntk @@ -1 +1 @@ -Subproject commit f24b36393548f176a197a8a4aa05a79620b77ada +Subproject commit ff7f8bdc4dfcbf6c34f5165a97f9a4368f69f6c8 diff --git a/timeline/src/Audio_Region.C b/timeline/src/Audio_Region.C index c119126..befd05b 100644 --- a/timeline/src/Audio_Region.C +++ b/timeline/src/Audio_Region.C @@ -430,6 +430,12 @@ Audio_Region::draw_fade ( const Fade &fade, Fade::fade_dir_e dir, bool line, int fl_end_polygon(); } +Fl_Color +Audio_Region::actual_box_color ( void ) const +{ + return Audio_Region::inherit_track_color ? sequence()->track()->color() : _box_color; +} + void Audio_Region::draw_box( void ) { @@ -437,7 +443,7 @@ Audio_Region::draw_box( void ) Fl_Color selection_color = _selection_color; - Fl_Color color = Audio_Region::inherit_track_color ? sequence()->track()->color() : _box_color; + Fl_Color color = actual_box_color(); color = fl_color_average( color, sequence()->color(), 0.75f ); diff --git a/timeline/src/Audio_Region.H b/timeline/src/Audio_Region.H index 6920fc1..07ac34b 100644 --- a/timeline/src/Audio_Region.H +++ b/timeline/src/Audio_Region.H @@ -164,6 +164,7 @@ public: void split ( nframes_t where ); bool recording ( void ) const; + virtual Fl_Color actual_box_color ( void ) const; /* Engine */ nframes_t read ( sample_t *buf, nframes_t pos, nframes_t nframes, int channel ) const; nframes_t write ( nframes_t nframes ); diff --git a/timeline/src/Scalebar.H b/timeline/src/Scalebar.H deleted file mode 100644 index f41244a..0000000 --- a/timeline/src/Scalebar.H +++ /dev/null @@ -1,107 +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. */ -/*******************************************************************************/ - - -#pragma once - -#include -#include -#include - -#include - -class Scalebar : public Fl_Scrollbar -{ - int _zoom; - - bool _zoom_changed; - - int _zoom_min; - int _zoom_max; - - void constrain ( void ) - { - if ( _zoom > _zoom_max ) - _zoom = _zoom_max; - else - if ( _zoom < _zoom_min ) - _zoom = _zoom_min; - } - - void maybe_do_callback ( int z ) - { - if ( z != _zoom ) - { - _zoom_changed = true; - do_callback(); - _zoom_changed = false; - - slider_size( w() / maximum() ); - } - - } - -public: - - Scalebar ( int X, int Y, int W, int H ) : Fl_Scrollbar ( X, Y, W, H ) - { - _zoom = 1; - _zoom_min = 0; - _zoom_max = 4; - _zoom_changed = false; - - step( 1 ); - } - - bool zoom_changed ( void ) const { return _zoom_changed; } - double zoom ( void ) const { return _zoom; } - void zoom ( int v ) { int z = _zoom ; _zoom = v; constrain(); maybe_do_callback( z ); } -// double value ( void ) const { return Fl_Slider::value(); } - void zoom_range ( int zmin, int zmax ) { _zoom_min = zmin; _zoom_max = zmax; } - - void zoom_out ( void ) { int z = _zoom; ++_zoom; constrain(); maybe_do_callback( z ); } - void zoom_in ( void ) {int z = _zoom; --_zoom; constrain(); maybe_do_callback( z ); } - - int - handle ( int m ) - { - switch ( m ) - { - case FL_MOUSEWHEEL: - { - if ( ! Fl::event_ctrl() ) - return 0; - - int d = Fl::event_dy(); - - double z = _zoom; - - _zoom += d; - - constrain(); - - maybe_do_callback( z ); - - return 1; - } - default: - return Fl_Scrollbar::handle( m ); - } - } -}; diff --git a/timeline/src/Sequence_Widget.H b/timeline/src/Sequence_Widget.H index dc5d511..ff4e335 100644 --- a/timeline/src/Sequence_Widget.H +++ b/timeline/src/Sequence_Widget.H @@ -160,6 +160,7 @@ protected: public: + virtual ~Sequence_Widget ( ); virtual Sequence_Widget *clone ( void ) const = 0; @@ -235,6 +236,7 @@ public: virtual void box_color ( Fl_Color v ) { _box_color = v; } virtual Fl_Color selection_color ( void ) const { return _selection_color; } virtual void selection_color ( Fl_Color v ) { _selection_color = v; } + virtual Fl_Color actual_box_color ( void ) const { return box_color(); } Sequence * sequence ( void ) const { return _sequence; } void sequence ( Sequence *t ) { _sequence = t; } diff --git a/timeline/src/Timeline.C b/timeline/src/Timeline.C index b488c10..3d103fe 100644 --- a/timeline/src/Timeline.C +++ b/timeline/src/Timeline.C @@ -28,6 +28,7 @@ #include #include #include +#include #include "Timeline.H" #include "Tempo_Sequence.H" @@ -35,12 +36,10 @@ #include "Cursor_Sequence.H" #include "Audio_Sequence.H" #include "Control_Sequence.H" -#include "Scalebar.H" #include "Sequence.H" #include "Annotation_Sequence.H" #include "Track.H" #include "Transport.H" - #include "Engine/Engine.H" // for lock() #include "FL/menu_popup.H" @@ -227,18 +226,13 @@ Timeline::snapshot ( void ) } } -/** recalculate the size of vertical scrolling area and inform scrollbar */ -void -Timeline::adjust_vscroll ( void ) -{ - vscroll->value( _yposition, h() - rulers->h() - hscroll->h(), 0, pack_visible_height( tracks ) ); -} /** recalculate the size of horizontal scrolling area and inform scrollbar */ void Timeline::adjust_hscroll ( void ) { - hscroll->value( ts_to_x( xoffset ), tracks->w() - Track::width(), 0, ts_to_x( length() ) ); + hscroll->y_value( hscroll->y_value(), h() - rulers->h() - hscroll->h(), 0, pack_visible_height( tracks )); + hscroll->x_value( ts_to_x( xoffset ), tracks->w() - Track::width(), 0, ts_to_x( length() ) ); } void @@ -250,33 +244,31 @@ Timeline::cb_scroll ( Fl_Widget *w, void *v ) void Timeline::cb_scroll ( Fl_Widget *w ) { - if ( w == vscroll ) + //adjust_hscroll(); + + if ( hscroll->zoom_changed() ) { - tracks->position( tracks->x(), (rulers->y() + rulers->h()) - vscroll->value() ); + nframes_t under_mouse = x_to_offset( Fl::event_x() ); - yposition( vscroll->value() ); + _fpp = hscroll->zoom(); - adjust_vscroll(); + const int tw = tracks->w() - Track::width(); + + hscroll->x_value( ts_to_x( under_mouse ) ); + + redraw(); } - else + + if ( _old_yposition != hscroll->y_value() ) { - if ( hscroll->zoom_changed() ) - { + tracks->position( tracks->x(), (rulers->y() + rulers->h()) - hscroll->y_value() ); + damage( FL_DAMAGE_SCROLL ); + } - nframes_t under_mouse = x_to_offset( Fl::event_x() ); - - _fpp = hscroll->zoom(); - - const int tw = tracks->w() - Track::width(); -// hscroll->value( ts_to_x( xoffset ), tw, 0, ts_to_x( length() ) ); - - hscroll->value( max( 0, ts_to_x( under_mouse ) - ( Fl::event_x() - tracks->x() - Track::width() ) ), - tw, 0, ts_to_x( length() ) ); - - redraw(); - } - - xposition( hscroll->value() ); + if ( _old_xposition != x_to_ts( hscroll->x_value() )) + { + damage( FL_DAMAGE_SCROLL ); + xposition( hscroll->x_value() ); } } @@ -550,7 +542,6 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : BASE( X, Y, W box( FL_FLAT_BOX ); xoffset = 0; - _yposition = 0; _old_yposition = 0; _old_xposition = 0; @@ -585,31 +576,26 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : BASE( X, Y, W menu_set_callback( const_cast(menu->menu()), &Timeline::menu_cb, (void*)this ); { - Scalebar *o = new Scalebar( X, Y + H - 18, W - 18, 18 ); + Fl_Panzoomer *o = new Fl_Panzoomer( X, Y + H - 100, W, 100 ); - o->range( 0, 48000 * 300 ); +// o->range( 0, 48000 * 300 ); // o->zoom_range( 1, 16384 ); // o->zoom_range( 1, 65536 << 4 ); o->zoom_range( 1, 20 ); - o->zoom( 8 ); + o->box( FL_FLAT_BOX ); + o->color( FL_BACKGROUND_COLOR ); o->type( FL_HORIZONTAL ); o->callback( cb_scroll, this ); + o->draw_thumbnail_view_callback( &Timeline::draw_thumbnail_view, this ); + hscroll = o; } { - Fl_Scrollbar *o = new Fl_Scrollbar( X + W - 18, Y, 18, H - 18 ); - - o->type( FL_VERTICAL ); - o->callback( cb_scroll, this ); - vscroll = o; - } - - { - Fl_Pack *o = new Fl_Pack( X + Track::width(), Y, (W - Track::width()) - vscroll->w(), H - hscroll->h(), "rulers" ); + Fl_Pack *o = new Fl_Pack( X + Track::width(), Y, (W - Track::width()), H - hscroll->h(), "rulers" ); o->type( Fl_Pack::VERTICAL ); { @@ -701,7 +687,7 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : BASE( X, Y, W // length() = x_to_ts( W ); { - Fl_Pack *o = new Fl_Pack( X, rulers->y() + rulers->h(), W - vscroll->w(), 1 ); + Fl_Pack *o = new Fl_Pack( X, rulers->y() + rulers->h(), W, 1 ); o->type( Fl_Pack::VERTICAL ); o->spacing( 1 ); @@ -715,10 +701,9 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : BASE( X, Y, W add( rulers ); /* make sure scrollbars are on top */ - add( vscroll ); add( hscroll ); - vscroll->range( 0, tracks->h() ); +// vscroll->range( 0, tracks->h() ); redraw(); @@ -1082,13 +1067,12 @@ Timeline::resize ( int X, int Y, int W, int H ) BASE::resize( X, Y, W, H ); /* why is this necessary? */ - rulers->resize( BX + Track::width(), BY, W - Track::width() - vscroll->w(), rulers->h() ); + rulers->resize( BX + Track::width(), BY, W - Track::width(), rulers->h() ); /* why is THIS necessary? */ - hscroll->resize( BX, BY + H - 18, hscroll->w(), 18 ); - vscroll->size( vscroll->w(), H - 18 ); + hscroll->resize( BX, BY + H - 100, hscroll->w(), 100 ); - tracks->resize( BX, BY + rulers->h(), W - vscroll->w(), H - vscroll->h() ); + tracks->resize( BX, BY + rulers->h(), W, H - hscroll->h() ); } @@ -1122,6 +1106,55 @@ Timeline::add_cursor ( Cursor_Point *o ) punch_cursor_track->add( o ); } +void +Timeline::draw_thumbnail_view ( int X, int Y, int W, int H, void *v ) +{ + ((Timeline*)v)->draw_thumbnail_view( X,Y,W,H ); +} + +void +Timeline::draw_thumbnail_view ( int X, int Y, int W, int H ) const +{ + nframes_t sf = 0; + nframes_t ef = timeline->length(); + + double ty = Y; + + for ( int i = 0; i < timeline->tracks->children(); i++ ) + { + Track *t = (Track*)timeline->tracks->child( i ); + + Sequence *s = t->sequence(); + + if ( !s ) + continue; + + fl_color( FL_BLACK ); + + const double scale = (double)H / ( pack_visible_height( tracks ) ); + +// double th = (double)H / timeline->tracks->children(); + const double th = t->h() * scale; + + fl_line( X, ty, + X + W, ty ); + + for ( list ::const_iterator r = s->_widgets.begin(); + r != s->_widgets.end(); ++r ) + { + fl_rectf( + X + ( W * ( (double)(*r)->start() / ef ) ), + ty, + W * ( (double)(*r)->length() / ef ), + th, + (*r)->actual_box_color()); + } + + ty += th; + } +} + + void Timeline::draw_cursors ( Cursor_Sequence *o ) const { @@ -1165,9 +1198,6 @@ Timeline::draw_cursors ( void ) const void Timeline::draw ( void ) { - -// resize_rulers(); - int X, Y, W, H; int bdx = 0; @@ -1178,13 +1208,40 @@ Timeline::draw ( void ) W = tracks->w() - bdw - 1; H = tracks->h(); - adjust_vscroll(); + adjust_hscroll(); + hscroll->redraw(); -#ifndef USE_UNOPTIMIZED_DRAWING - if ( ( damage() & FL_DAMAGE_ALL ) ) -#else -#warning Optimized drawing of timeline disabled. This will waste your CPU. -#endif + int dx = ts_to_x( _old_xposition ) - ts_to_x( xoffset ); + int dy = _old_yposition - hscroll->y_value(); + + int c = damage(); + + if ( c & FL_DAMAGE_SCROLL ) + { + /* if ( dx && dy ) */ + /* { */ + /* /\* FIXME: scrolling both at once is... problematic *\/ */ + + /* c |= FL_DAMAGE_ALL; */ + /* } */ + /* else */ + { + /* draw_child( *rulers ); */ + + Y = rulers->y() + rulers->h(); + H = h() - rulers->h() - hscroll->h(); + + if ( dy ) + fl_scroll( X, Y, Track::width(), H, 0, dy, draw_clip, this ); + + if ( dx ) + fl_scroll( rulers->x(), rulers->y(), rulers->w(), rulers->h(), dx, 0, draw_clip, this ); + + fl_scroll( X + Track::width(), Y, W - Track::width(), H, dx, dy, draw_clip, this ); + } + } + + if ( c & FL_DAMAGE_ALL ) { DMESSAGE( "complete redraw" ); @@ -1202,59 +1259,38 @@ Timeline::draw ( void ) fl_pop_clip(); draw_child( *hscroll ); - draw_child( *vscroll ); - redraw_overlay(); goto done; } - if ( damage() & FL_DAMAGE_SCROLL ) - { - int dx = ts_to_x( _old_xposition ) - ts_to_x( xoffset ); - int dy = _old_yposition - _yposition; - -/* draw_child( *rulers ); */ - - if ( ! dy ) - fl_scroll( rulers->x(), rulers->y(), rulers->w(), rulers->h(), dx, 0, draw_clip, this ); - - Y = rulers->y() + rulers->h(); - H = h() - rulers->h() - hscroll->h(); - - if ( dy == 0 ) - fl_scroll( X + Track::width(), Y, W - Track::width(), H, dx, dy, draw_clip, this ); - else - fl_scroll( X, Y, W, H, dx, dy, draw_clip, this ); - } - - if ( damage() & FL_DAMAGE_CHILD ) + if ( c & FL_DAMAGE_CHILD ) { fl_push_clip( rulers->x(), rulers->y(), rulers->w(), rulers->h() ); update_child( *rulers ); fl_pop_clip(); - if ( ! ( damage() & FL_DAMAGE_SCROLL ) ) - { + /* if ( ! ( damage() & FL_DAMAGE_SCROLL ) ) */ + /* { */ fl_push_clip( tracks->x(), rulers->y() + rulers->h(), tracks->w(), h() - rulers->h() - hscroll->h() ); update_child( *tracks ); draw_cursors(); fl_pop_clip(); - } + /* } */ update_child( *hscroll ); - update_child( *vscroll ); } done: + /* hscroll->redraw(); */ + /* update_child( *hscroll ); */ + _old_xposition = xoffset; - _old_yposition = _yposition; - - + _old_yposition = hscroll->y_value(); } /** draw a single cursor line at /frame/ with color /color/ using symbol routine /symbol/ for the cap */ @@ -1377,6 +1413,7 @@ Timeline::redraw_playhead ( void ) xposition( max( 0, playhead_x - ( ( tracks->w() - Track::width() ) >> 1 ) ) ); else if ( playhead_x > ts_to_x( xoffset ) + ( tracks->w() - Track::width() ) ) xposition( playhead_x ); + adjust_hscroll(); } } } @@ -1481,7 +1518,7 @@ Timeline::handle_scroll ( int m ) if ( m == FL_KEYBOARD && Fl::event_key() != FL_Home && Fl::event_key() != FL_End ) - return menu->test_shortcut() || hscroll->handle( m ) || vscroll->handle( m ); + return menu->test_shortcut() || hscroll->handle( m ); else return 0; } @@ -1707,18 +1744,6 @@ Timeline::xposition ( int X ) damage( FL_DAMAGE_SCROLL ); } -/** set vertical scroll position to absolute pixel coordinate /Y/ */ -void -Timeline::yposition ( int Y ) -{ - _yposition = Y; - - int dy = _old_yposition - _yposition; - - if ( dy ) - damage( FL_DAMAGE_SCROLL ); -} - /** zoom in by one zoom step */ void Timeline::zoom_in ( void ) diff --git a/timeline/src/Timeline.H b/timeline/src/Timeline.H index 1f2c269..7faf4cb 100644 --- a/timeline/src/Timeline.H +++ b/timeline/src/Timeline.H @@ -50,11 +50,11 @@ class Time_Sequence; class Annotation_Sequence; class Cursor_Sequence; class Track; -class Scalebar; class Sequence; class Sequence_Widget; class Cursor_Region; class Cursor_Point; +class Fl_Panzoomer; namespace OSC { class Endpoint; } @@ -96,7 +96,8 @@ class Timeline : public Fl_Single_Window, public RWLock { static void draw_clip ( void * v, int X, int Y, int W, int H ); - + static void draw_thumbnail_view( int X, int Y,int W, int H, void *v); + void draw_thumbnail_view( int X, int Y,int W, int H) const; int _old_xposition; int _old_yposition; @@ -106,10 +107,8 @@ class Timeline : public Fl_Single_Window, public RWLock Fl_Scroll *scroll; Fl_Pack *tracks; Fl_Pack *rulers; - Scalebar *hscroll; - Fl_Scrollbar *vscroll; + Fl_Panzoomer *hscroll; - void adjust_vscroll ( void ); void adjust_hscroll ( void ); static void cb_scroll ( Fl_Widget *w, void *v ); void cb_scroll ( Fl_Widget *w ); @@ -133,7 +132,7 @@ class Timeline : public Fl_Single_Window, public RWLock void update_track_order ( void ); void apply_track_order ( void ); void insert_track ( Track *track, int n ); - + public: OSC::Endpoint *osc; @@ -180,8 +179,6 @@ public: nframes_t xoffset; - int _yposition; - nframes_t _sample_rate; Timeline ( int X, int Y, int W, int H, const char *L=0 ); @@ -228,7 +225,6 @@ public: position_info render_tempomap ( nframes_t start, nframes_t length, measure_line_callback *cb, void *arg ) const; void xposition ( int X ); - void yposition ( int Y ); void draw_cursor ( nframes_t frame, Fl_Color color, void (*symbol)(Fl_Color) ) const; void draw_cursors ( Cursor_Sequence *o ) const; void draw_cursors ( void ) const;