From ea8c35d0fe257cff80dd792a87c32292002a3ad2 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Thu, 29 May 2008 01:11:35 -0500 Subject: [PATCH] Rewrite Audio_Region context menu. Use the menu for handling region specific shortcuts. --- Timeline/Audio_Region.C | 170 +++++++++++++++++++++++++--------------- Timeline/Audio_Region.H | 8 ++ Timeline/Sequence.C | 21 ++++- Timeline/Timeline.C | 6 +- Timeline/Timeline.H | 3 +- 5 files changed, 136 insertions(+), 72 deletions(-) diff --git a/Timeline/Audio_Region.C b/Timeline/Audio_Region.C index b2ab7dc..8c18572 100644 --- a/Timeline/Audio_Region.C +++ b/Timeline/Audio_Region.C @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "Sequence.H" @@ -48,6 +49,8 @@ Fl_Boxtype Audio_Region::_box = FL_UP_BOX; Fl_Color Audio_Region::_selection_color = FL_MAGENTA; +Fl_Menu_Button *Audio_Region::_menu = NULL; + static Fl_Color fl_invert_color ( Fl_Color c ) @@ -110,7 +113,6 @@ Audio_Region::set ( Log_Entry &e ) Sequence_Region::set( e ); } - void Audio_Region::init ( void ) { @@ -192,9 +194,98 @@ Audio_Region::source_name ( void ) const return _clip->name(); } -#include +void +Audio_Region::menu_cb ( Fl_Widget *w, void *v ) +{ + ((Audio_Region*)v)->menu_cb( (Fl_Menu_*) w ); +} + +void +Audio_Region::menu_cb ( const Fl_Menu_ *m ) +{ + char picked[256]; + + m->item_pathname( picked, sizeof( picked ) ); + + Logger log( this ); + + if ( ! strcmp( picked, "Fade/In/Linear" ) ) + _fade_in.type = Fade::Linear; + else if ( ! strcmp( picked, "Fade/In/Sigmoid" ) ) + _fade_in.type = Fade::Sigmoid; + else if ( ! strcmp( picked, "Fade/In/Logarithmic" ) ) + _fade_in.type = Fade::Logarithmic; + else if ( ! strcmp( picked, "Fade/In/Parabolic" ) ) + _fade_in.type = Fade::Parabolic; + else if ( ! strcmp( picked, "Fade/Out/Linear" ) ) + _fade_out.type = Fade::Linear; + else if ( ! strcmp( picked, "Fade/Out/Sigmoid" ) ) + _fade_out.type = Fade::Sigmoid; + else if ( ! strcmp( picked, "Fade/Out/Logarithmic" ) ) + _fade_out.type = Fade::Logarithmic; + else if ( ! strcmp( picked, "Fade/Out/Parabolic" ) ) + _fade_out.type = Fade::Parabolic; + else if ( ! strcmp( picked, "/Color" ) ) + box_color( fl_show_colormap( box_color() ) ); + else if ( ! strcmp( picked, "/Fade in to mouse" ) ) + { + nframes_t offset = x_to_offset( Fl::event_x() ); + + if ( offset < length() ) + _fade_in.length = offset; + + DMESSAGE( "set fade in duration" ); + } + else if ( ! strcmp( picked, "/Fade out to mouse" ) ) + { + long offset = length() - x_to_offset( Fl::event_x() ); + + if ( offset > 0 ) + _fade_out.length = offset; + } + else + FATAL( "Unknown menu choice \"%s\"", picked ); + + redraw(); +} + #include "FL/test_press.H" +/** build the context menu for this region */ +void +Audio_Region::update_menu ( void ) +{ + if ( ! Audio_Region::_menu ) + Audio_Region::_menu = new Fl_Menu_Button( 0, 0, 0, 0, "Region" ); + + Fade::fade_type_e it = _fade_in.type; + Fade::fade_type_e ot = _fade_out.type; + + Fl_Menu_Item items[] = + { + { "Fade", 0, &Audio_Region::menu_cb, this, FL_SUBMENU }, + { "In", 0, &Audio_Region::menu_cb, this, FL_SUBMENU }, + { "Linear", 0, &Audio_Region::menu_cb, this, FL_MENU_RADIO | ( it == Fade::Linear ? FL_MENU_VALUE : 0 ) }, + { "Sigmoid", 0, &Audio_Region::menu_cb, this, FL_MENU_RADIO | ( it == Fade::Sigmoid ? FL_MENU_VALUE : 0 ) }, + { "Logarithmic", 0, &Audio_Region::menu_cb, this, FL_MENU_RADIO | ( it == Fade::Logarithmic ? FL_MENU_VALUE : 0 ) }, + { "Parabolic", 0, &Audio_Region::menu_cb, this, FL_MENU_RADIO | ( it == Fade::Parabolic ? FL_MENU_VALUE : 0 ) }, + { 0 }, + { "Out", 0, &Audio_Region::menu_cb, this, FL_SUBMENU }, + { "Linear", 0, &Audio_Region::menu_cb, this, FL_MENU_RADIO | ( ot == Fade::Linear ? FL_MENU_VALUE : 0 ) }, + { "Sigmoid", 0, &Audio_Region::menu_cb, this, FL_MENU_RADIO | ( ot == Fade::Sigmoid ? FL_MENU_VALUE : 0 ) }, + { "Logarothmic", 0, &Audio_Region::menu_cb, this, FL_MENU_RADIO | ( ot == Fade::Logarithmic ? FL_MENU_VALUE : 0 ) }, + { "Parabolic", 0, &Audio_Region::menu_cb, this, FL_MENU_RADIO | ( ot == Fade::Parabolic ? FL_MENU_VALUE : 0 ) }, + { 0 }, + { 0 }, + { "Color", 0, &Audio_Region::menu_cb, this, inherit_track_color ? FL_MENU_INACTIVE : 0 }, + { "Fade in to mouse", FL_F + 3, &Audio_Region::menu_cb, this }, + { "Fade out to mouse", FL_F + 4, &Audio_Region::menu_cb, this }, + { 0 }, + }; + + _menu->copy( items ); +} + int Audio_Region::handle ( int m ) { @@ -210,38 +301,18 @@ Audio_Region::handle ( int m ) switch ( m ) { + case FL_FOCUS: + case FL_UNFOCUS: + return 1; case FL_KEYBOARD: + return _menu->test_shortcut() != 0; + case FL_ENTER: { - if ( Fl::event_key() == FL_F + 3 ) - { - nframes_t offset = x_to_offset( X ); - - if ( offset < length() ) - _fade_in.length = offset; - - DMESSAGE( "setting fade in length to %lu", _fade_in.length ); - - redraw(); - - return 1; - } - else if ( Fl::event_key() == FL_F + 4 ) - { - long offset = length() - x_to_offset( X ); - - if ( offset > 0 ) - _fade_out.length = offset; - - DMESSAGE( "setting fade out length to %lu", _fade_in.length ); - - redraw(); - - return 1; - } - - return 0; - + update_menu(); + return Sequence_Region::handle( m ); } + case FL_LEAVE: + return Sequence_Region::handle( m ); case FL_PUSH: { /* splitting */ @@ -283,43 +354,14 @@ Audio_Region::handle ( int m ) { /* context menu */ - Fade::fade_type_e it = _fade_in.type; - Fade::fade_type_e ot = _fade_out.type; + update_menu(); - Fl_Menu_Item menu[] = - { - { "Fade", 0, 0, 0, FL_SUBMENU }, - { "In", 0, 0, 0, FL_SUBMENU }, - { "Linear", 0, 0, 0, FL_MENU_RADIO | ( it == Fade::Linear ? FL_MENU_VALUE : 0 ) }, - { "Sigmoid", 0, 0, 0, FL_MENU_RADIO | ( it == Fade::Sigmoid ? FL_MENU_VALUE : 0 ) }, - { "Logarithmic", 0, 0, 0, FL_MENU_RADIO | ( it == Fade::Logarithmic ? FL_MENU_VALUE : 0 ) }, - { "Parabolic", 0, 0, 0, FL_MENU_RADIO | ( it == Fade::Parabolic ? FL_MENU_VALUE : 0 ) }, - { 0 }, - { "Out", 0, 0, 0, FL_SUBMENU }, - { "Linear", 0, 0, 0, FL_MENU_RADIO | ( ot == Fade::Linear ? FL_MENU_VALUE : 0 ) }, - { "Sigmoid", 0, 0, 0, FL_MENU_RADIO | ( ot == Fade::Sigmoid ? FL_MENU_VALUE : 0 ) }, - { "Logarothmic", 0, 0, 0, FL_MENU_RADIO | ( ot == Fade::Logarithmic ? FL_MENU_VALUE : 0 ) }, - { "Parabolic", 0, 0, 0, FL_MENU_RADIO | ( ot == Fade::Parabolic ? FL_MENU_VALUE : 0 ) }, - { 0 }, - { 0 }, - { "Color", 0, 0, 0, inherit_track_color ? FL_MENU_INACTIVE : 0 }, - { 0 }, - }; - - const Fl_Menu_Item *r = menu->popup( X, Y, "Audio_Region" ); + const Fl_Menu_Item *r = _menu->menu()->popup( X, Y, _menu->label() ); if ( r ) { - if ( r > &menu[1] && r < &menu[6] ) - _fade_in.type = (Fade::fade_type_e)(int)(r - &menu[2]); - else if ( r > &menu[7] && r < &menu[12] ) - _fade_out.type = (Fade::fade_type_e)(int)(r - &menu[8]); - else if ( r == &menu[ 14 ] ) - { - box_color( fl_show_colormap( box_color() ) ); - } - - redraw(); + _menu->value( r ); + r->do_callback( static_cast(_menu) ); } return 1; diff --git a/Timeline/Audio_Region.H b/Timeline/Audio_Region.H index 1228a5d..71fcdf8 100644 --- a/Timeline/Audio_Region.H +++ b/Timeline/Audio_Region.H @@ -25,6 +25,9 @@ class Audio_File; class Peaks_Redraw_Request; +class Fl_Menu_; +class Fl_Menu_Button; + class Audio_Region : public Sequence_Region { @@ -99,10 +102,15 @@ private: friend class Track; /* for _clip */ + static Fl_Menu_Button *_menu; + void update_menu ( void ); static void peaks_pending_cb ( void *v ); void peaks_pending_cb ( Peaks_Redraw_Request *r ); + static void menu_cb ( Fl_Widget *w, void *v ); + void menu_cb ( const Fl_Menu_ *m ); + protected: virtual void get ( Log_Entry &e ) const; diff --git a/Timeline/Sequence.C b/Timeline/Sequence.C index 12149a9..58195c7 100644 --- a/Timeline/Sequence.C +++ b/Timeline/Sequence.C @@ -340,6 +340,7 @@ Sequence::handle ( int m ) switch ( m ) { case FL_KEYBOARD: + case FL_SHORTCUT: if ( Fl::test_shortcut( FL_CTRL + FL_Right ) ) { transport->locate( next( transport->frame ) ); @@ -351,9 +352,23 @@ Sequence::handle ( int m ) return 1; } else - /* this is a hack to override FLTK's use of arrow keys for - * focus navigation */ - return timeline->handle_scroll( m ); + { + switch ( Fl::event_key() ) + { + case FL_Left: + case FL_Right: + case FL_Up: + case FL_Down: + /* this is a hack to override FLTK's use of arrow keys for + * focus navigation */ + return timeline->handle_scroll( m ); + default: + break; + } + } + + if ( Sequence_Widget::belowmouse() ) + return Sequence_Widget::belowmouse()->handle( m ); case FL_NO_EVENT: /* garbage from overlay window */ return 0; diff --git a/Timeline/Timeline.C b/Timeline/Timeline.C index 007d77e..4cec1c8 100644 --- a/Timeline/Timeline.C +++ b/Timeline/Timeline.C @@ -157,14 +157,12 @@ Timeline::cb_scroll ( Fl_Widget *w ) void Timeline::menu_cb ( Fl_Widget *w, void *v ) { - ((Timeline*)v)->menu_cb( w ); + ((Timeline*)v)->menu_cb( (Fl_Menu_*)w ); } void -Timeline::menu_cb ( Fl_Widget *w ) +Timeline::menu_cb ( Fl_Menu_ *m ) { - Fl_Menu_ *m = static_cast(w); - const char *picked = m->mvalue()->label(); /* m->item_pathname( picked, sizeof( picked ) ); */ diff --git a/Timeline/Timeline.H b/Timeline/Timeline.H index cdf9be9..82cf57f 100644 --- a/Timeline/Timeline.H +++ b/Timeline/Timeline.H @@ -37,6 +37,7 @@ class Fl_Scrollbar; class Fl_Widget; class Fl_Menu_Button; +class Fl_Menu_; class Timeline; extern Timeline *timeline; @@ -99,7 +100,7 @@ class Timeline : public Fl_Overlay_Window, public RWLock static void cb_scroll ( Fl_Widget *w, void *v ); void cb_scroll ( Fl_Widget *w ); static void menu_cb ( Fl_Widget *w, void *v ); - void menu_cb ( Fl_Widget *w ); + void menu_cb ( Fl_Menu_ *m ); int _fpp; /* frames per pixel, power of two */ nframes_t _length;