From bb75847ac1a241da44e792e6130817d22922028b Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Sun, 31 Jan 2010 12:51:55 -0600 Subject: [PATCH] Mixer: Implement mixer Strip import/export --- FL/Fl_Sometimes_Input.H | 2 +- mixer/src/Chain.C | 27 ++++++++++++++++++ mixer/src/Chain.H | 5 ++++ mixer/src/Mixer.C | 11 ++++++++ mixer/src/Mixer.H | 5 ++-- mixer/src/Mixer_Strip.C | 61 +++++++++++++++++++++++++++++++++++++++-- mixer/src/Mixer_Strip.H | 6 ++++ nonlib/Loggable.C | 25 +++++++++++++++++ nonlib/Loggable.H | 6 ++++ 9 files changed, 143 insertions(+), 5 deletions(-) diff --git a/FL/Fl_Sometimes_Input.H b/FL/Fl_Sometimes_Input.H index c25cbe3..a4322b2 100644 --- a/FL/Fl_Sometimes_Input.H +++ b/FL/Fl_Sometimes_Input.H @@ -38,7 +38,7 @@ public: { clear_visible_focus(); up_box( FL_NO_BOX ); - when(FL_WHEN_ENTER_KEY); + when(FL_WHEN_ENTER_KEY_ALWAYS); } void up_box ( Fl_Boxtype b ) { _up_box = b; } diff --git a/mixer/src/Chain.C b/mixer/src/Chain.C index 524c4dc..1f0b2c4 100644 --- a/mixer/src/Chain.C +++ b/mixer/src/Chain.C @@ -734,6 +734,33 @@ Chain::resize ( int X, int Y, int W, int H ) +/*****************/ +/* Import/Export */ +/*****************/ + +void +Chain::snapshot ( void *v ) +{ + ((Chain*)v)->snapshot(); +} + +void +Chain::snapshot ( void ) +{ + log_children(); +} + +bool +Chain::do_export ( const char *filename ) +{ + MESSAGE( "Exporting chain state" ); + Loggable::snapshot_callback( &Chain::snapshot, this ); + Loggable::snapshot( filename ); + return true; +} + + + /**********/ /* Engine */ /**********/ diff --git a/mixer/src/Chain.H b/mixer/src/Chain.H index a3a5778..783a4a7 100644 --- a/mixer/src/Chain.H +++ b/mixer/src/Chain.H @@ -57,6 +57,9 @@ class Chain : public Fl_Group, public Loggable { private: + static void snapshot ( void *v ); + void snapshot ( void ); + void cb_handle(Fl_Widget*); static void cb_handle(Fl_Widget*, void*); @@ -104,6 +107,8 @@ public: bool insert ( Module *m, Module *n ); void add_control ( Controller_Module *m ); + bool do_export ( const char *filename ); + void initialize_with_default ( void ); bool can_configure_outputs ( Module *m, int n ) const; diff --git a/mixer/src/Mixer.C b/mixer/src/Mixer.C index cc3045b..25bf57a 100644 --- a/mixer/src/Mixer.C +++ b/mixer/src/Mixer.C @@ -251,6 +251,16 @@ void Mixer::cb_menu(Fl_Widget* o) { command_add_strip(); } } + else if ( !strcmp( picked, "&Mixer/&Import Strip" ) ) + { + const char *s = fl_file_chooser( "Export strip to filename:", "*.strip", NULL, 0 ); + + if ( s ) + { + if (! Mixer_Strip::import_strip( s ) ) + fl_alert( "%s", "Failed to import strip!" ); + } + } else if (! strcmp( picked, "&Mixer/&Rows/One") ) { rows( 1 ); @@ -382,6 +392,7 @@ Mixer::Mixer ( int X, int Y, int W, int H, const char *L ) : o->add( "&Project/&Quit", FL_CTRL + 'q', 0, 0 ); o->add( "&Mixer/&Add Strip", 'a', 0, 0 ); o->add( "&Mixer/Add &N Strips" ); + o->add( "&Mixer/&Import Strip" ); o->add( "&Mixer/&Rows/One", '1', 0, 0 ); o->add( "&Mixer/&Rows/Two", '2', 0, 0 ); o->add( "&Mixer/&Rows/Three", '3', 0, 0 ); diff --git a/mixer/src/Mixer.H b/mixer/src/Mixer.H index 8e8f6a6..338b527 100644 --- a/mixer/src/Mixer.H +++ b/mixer/src/Mixer.H @@ -47,7 +47,6 @@ private: Fl_Color system_colors[3]; Mixer_Strip* track_by_name ( const char *name ); - char * get_unique_track_name ( const char *name ); void snapshot ( void ); static void snapshot ( void *v ) { ((Mixer*)v)->snapshot(); } @@ -74,7 +73,9 @@ protected: public: - int min_h ( void ) const { return Mixer_Strip::min_h() + (18 * 2); } + char * get_unique_track_name ( const char *name ); + + int min_h ( void ) const { return Mixer_Strip::min_h() + (18 * 2); } void rows ( int n ); virtual void resize ( int X, int Y, int W, int H ); diff --git a/mixer/src/Mixer_Strip.C b/mixer/src/Mixer_Strip.C index d91d518..cbd5230 100644 --- a/mixer/src/Mixer_Strip.C +++ b/mixer/src/Mixer_Strip.C @@ -56,6 +56,7 @@ #include #include "FL/test_press.H" #include "FL/menu_popup.H" +#include extern Mixer *mixer; @@ -242,7 +243,7 @@ void Mixer_Strip::cb_handle(Fl_Widget* o) { else if ( o == name_field ) { name( name_field->value() ); - take_focus(); + Fl::focus( this ); } else if ( o == width_button ) { @@ -261,8 +262,12 @@ void Mixer_Strip::cb_handle(Fl_Widget* o, void* v) { } void -Mixer_Strip::name ( const char *name ) { +Mixer_Strip::name ( const char *name ) +{ + if ( this->name() && !strcmp( name, this->name() ) ) + return; + name = mixer->get_unique_track_name( name ); char *s = strdup( name ); @@ -521,6 +526,43 @@ Mixer_Strip::draw ( void ) Fl_Group::draw_box( FL_UP_FRAME, x(), y(), w(), h(), Fl::focus() == this ? Fl_Group::selection_color() : FL_BLACK ); } +/*****************/ +/* Import/Export */ +/*****************/ + +void +Mixer_Strip::snapshot ( void *v ) +{ + ((Mixer_Strip*)v)->snapshot(); +} + +void +Mixer_Strip::snapshot ( void ) +{ + log_children(); +} + +bool +Mixer_Strip::export_strip ( const char *filename ) +{ + MESSAGE( "Exporting chain state" ); + Loggable::snapshot_callback( &Mixer_Strip::snapshot, this ); + Loggable::snapshot( filename ); + return true; +} + +bool +Mixer_Strip::import_strip ( const char *filename ) +{ + MESSAGE( "Importing new chain state" ); + Loggable::begin_relative_id_mode(); + int r = Loggable::replay( filename ); + Loggable::end_relative_id_mode(); + return r; +} + + + void @@ -559,6 +601,20 @@ Mixer_Strip::menu_cb ( const Fl_Menu_ *m ) redraw(); } + else if ( !strcmp( picked, "/Export Strip" ) ) + { + char *suggested_name; + asprintf( &suggested_name, "%s.strip", name() ); + + const char *s = fl_file_chooser( "Export strip to filename:", "*.strip", suggested_name, 0 ); + + free( suggested_name ); + + if ( s ) + export_strip( s ); + + fl_message( "Strip exported." ); + } else if ( ! strcmp( picked, "/Remove" ) ) { if ( Fl::event_shift() || 1 == fl_choice( "Are you sure you want to remove this strip?\n\n(this action cannot be undone)", "Cancel", "Remove", NULL ) ) @@ -598,6 +654,7 @@ Mixer_Strip::menu ( void ) const { "Move Left", '[', 0, 0 }, { "Move Right", ']', 0, 0 }, { "Color", 0, 0, 0 }, + { "Export Strip", 0, 0, 0 }, { "Rename", FL_CTRL + 'n', 0, 0 }, { "Remove", FL_Delete, 0, 0 }, { 0 }, diff --git a/mixer/src/Mixer_Strip.H b/mixer/src/Mixer_Strip.H index 2e62480..968f96a 100644 --- a/mixer/src/Mixer_Strip.H +++ b/mixer/src/Mixer_Strip.H @@ -125,6 +125,10 @@ private: static void menu_cb ( Fl_Widget *w, void *v ); Fl_Menu_Button & menu ( void ) const; + static void snapshot ( void *v ); + void snapshot ( void ); + bool export_strip ( const char *filename ); + protected: void get ( Log_Entry &e ) const; @@ -135,6 +139,8 @@ protected: public: + static bool import_strip ( const char *filename ); + void command_move_left ( void ); void command_move_right ( void ); void command_close ( void ); diff --git a/nonlib/Loggable.C b/nonlib/Loggable.C index b1950ad..2fc8b6d 100644 --- a/nonlib/Loggable.C +++ b/nonlib/Loggable.C @@ -88,6 +88,9 @@ Loggable::block_end ( void ) Loggable * Loggable::find ( unsigned int id ) { + if ( _relative_id ) + id += _relative_id; + return _loggables[ id ].loggable; } @@ -329,6 +332,25 @@ Loggable::escape ( const char *s ) return r; } +unsigned int Loggable::_relative_id = 0; + +/* calls to do_this() between invocation of this method and + * end_relative_id_mode() will have all their IDs made relative to the + * highest available ID at this time of this call. Non-Mixer uses + * this to allow importing of module chains */ +void +Loggable::begin_relative_id_mode ( void ) +{ + _relative_id = ++_log_id; +} + +void +Loggable::end_relative_id_mode ( void ) +{ + _relative_id = 0; +} + + /** 'do' a message like "Audio_Region 0xF1 set :r 123" */ bool Loggable::do_this ( const char *s, bool reverse ) @@ -395,6 +417,9 @@ Loggable::do_this ( const char *s, bool reverse ) ASSERT( _class_map[ std::string( classname ) ], "Journal contains an object of class \"%s\", but I don't know how to create such objects.", classname ); { + if ( _relative_id ) + id += _relative_id; + /* create */ Loggable *l = _class_map[ std::string( classname ) ]( e, id ); l->log_create(); diff --git a/nonlib/Loggable.H b/nonlib/Loggable.H index 34ce464..65b9357 100644 --- a/nonlib/Loggable.H +++ b/nonlib/Loggable.H @@ -89,6 +89,8 @@ class Loggable private: + static unsigned int _relative_id; + unsigned int _id; Log_Entry *_old_state; @@ -183,6 +185,10 @@ public: virtual void log_children ( void ) const { return; } + static void begin_relative_id_mode ( void ); + + static void end_relative_id_mode ( void ); + static bool do_this ( const char *s, bool reverse ); static int dirty ( void ) { return _dirty; }