Mixer: Implement mixer Strip import/export
This commit is contained in:
parent
044414c4c2
commit
bb75847ac1
|
@ -38,7 +38,7 @@ public:
|
||||||
{
|
{
|
||||||
clear_visible_focus();
|
clear_visible_focus();
|
||||||
up_box( FL_NO_BOX );
|
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; }
|
void up_box ( Fl_Boxtype b ) { _up_box = b; }
|
||||||
|
|
|
@ -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 */
|
/* Engine */
|
||||||
/**********/
|
/**********/
|
||||||
|
|
|
@ -57,6 +57,9 @@ class Chain : public Fl_Group, public Loggable {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
static void snapshot ( void *v );
|
||||||
|
void snapshot ( void );
|
||||||
|
|
||||||
void cb_handle(Fl_Widget*);
|
void cb_handle(Fl_Widget*);
|
||||||
static void cb_handle(Fl_Widget*, void*);
|
static void cb_handle(Fl_Widget*, void*);
|
||||||
|
|
||||||
|
@ -104,6 +107,8 @@ public:
|
||||||
bool insert ( Module *m, Module *n );
|
bool insert ( Module *m, Module *n );
|
||||||
void add_control ( Controller_Module *m );
|
void add_control ( Controller_Module *m );
|
||||||
|
|
||||||
|
bool do_export ( const char *filename );
|
||||||
|
|
||||||
void initialize_with_default ( void );
|
void initialize_with_default ( void );
|
||||||
|
|
||||||
bool can_configure_outputs ( Module *m, int n ) const;
|
bool can_configure_outputs ( Module *m, int n ) const;
|
||||||
|
|
|
@ -251,6 +251,16 @@ void Mixer::cb_menu(Fl_Widget* o) {
|
||||||
command_add_strip();
|
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") )
|
else if (! strcmp( picked, "&Mixer/&Rows/One") )
|
||||||
{
|
{
|
||||||
rows( 1 );
|
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( "&Project/&Quit", FL_CTRL + 'q', 0, 0 );
|
||||||
o->add( "&Mixer/&Add Strip", 'a', 0, 0 );
|
o->add( "&Mixer/&Add Strip", 'a', 0, 0 );
|
||||||
o->add( "&Mixer/Add &N Strips" );
|
o->add( "&Mixer/Add &N Strips" );
|
||||||
|
o->add( "&Mixer/&Import Strip" );
|
||||||
o->add( "&Mixer/&Rows/One", '1', 0, 0 );
|
o->add( "&Mixer/&Rows/One", '1', 0, 0 );
|
||||||
o->add( "&Mixer/&Rows/Two", '2', 0, 0 );
|
o->add( "&Mixer/&Rows/Two", '2', 0, 0 );
|
||||||
o->add( "&Mixer/&Rows/Three", '3', 0, 0 );
|
o->add( "&Mixer/&Rows/Three", '3', 0, 0 );
|
||||||
|
|
|
@ -47,7 +47,6 @@ private:
|
||||||
Fl_Color system_colors[3];
|
Fl_Color system_colors[3];
|
||||||
|
|
||||||
Mixer_Strip* track_by_name ( const char *name );
|
Mixer_Strip* track_by_name ( const char *name );
|
||||||
char * get_unique_track_name ( const char *name );
|
|
||||||
|
|
||||||
void snapshot ( void );
|
void snapshot ( void );
|
||||||
static void snapshot ( void *v ) { ((Mixer*)v)->snapshot(); }
|
static void snapshot ( void *v ) { ((Mixer*)v)->snapshot(); }
|
||||||
|
@ -74,6 +73,8 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
char * get_unique_track_name ( const char *name );
|
||||||
|
|
||||||
int min_h ( void ) const { return Mixer_Strip::min_h() + (18 * 2); }
|
int min_h ( void ) const { return Mixer_Strip::min_h() + (18 * 2); }
|
||||||
|
|
||||||
void rows ( int n );
|
void rows ( int n );
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include <FL/Fl_Menu_Button.H>
|
#include <FL/Fl_Menu_Button.H>
|
||||||
#include "FL/test_press.H"
|
#include "FL/test_press.H"
|
||||||
#include "FL/menu_popup.H"
|
#include "FL/menu_popup.H"
|
||||||
|
#include <FL/Fl_File_Chooser.H>
|
||||||
|
|
||||||
extern Mixer *mixer;
|
extern Mixer *mixer;
|
||||||
|
|
||||||
|
@ -242,7 +243,7 @@ void Mixer_Strip::cb_handle(Fl_Widget* o) {
|
||||||
else if ( o == name_field )
|
else if ( o == name_field )
|
||||||
{
|
{
|
||||||
name( name_field->value() );
|
name( name_field->value() );
|
||||||
take_focus();
|
Fl::focus( this );
|
||||||
}
|
}
|
||||||
else if ( o == width_button )
|
else if ( o == width_button )
|
||||||
{
|
{
|
||||||
|
@ -261,8 +262,12 @@ void Mixer_Strip::cb_handle(Fl_Widget* o, void* v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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 );
|
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 );
|
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
|
void
|
||||||
|
@ -559,6 +601,20 @@ Mixer_Strip::menu_cb ( const Fl_Menu_ *m )
|
||||||
|
|
||||||
redraw();
|
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" ) )
|
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 ) )
|
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 Left", '[', 0, 0 },
|
||||||
{ "Move Right", ']', 0, 0 },
|
{ "Move Right", ']', 0, 0 },
|
||||||
{ "Color", 0, 0, 0 },
|
{ "Color", 0, 0, 0 },
|
||||||
|
{ "Export Strip", 0, 0, 0 },
|
||||||
{ "Rename", FL_CTRL + 'n', 0, 0 },
|
{ "Rename", FL_CTRL + 'n', 0, 0 },
|
||||||
{ "Remove", FL_Delete, 0, 0 },
|
{ "Remove", FL_Delete, 0, 0 },
|
||||||
{ 0 },
|
{ 0 },
|
||||||
|
|
|
@ -125,6 +125,10 @@ private:
|
||||||
static void menu_cb ( Fl_Widget *w, void *v );
|
static void menu_cb ( Fl_Widget *w, void *v );
|
||||||
Fl_Menu_Button & menu ( void ) const;
|
Fl_Menu_Button & menu ( void ) const;
|
||||||
|
|
||||||
|
static void snapshot ( void *v );
|
||||||
|
void snapshot ( void );
|
||||||
|
bool export_strip ( const char *filename );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void get ( Log_Entry &e ) const;
|
void get ( Log_Entry &e ) const;
|
||||||
|
@ -135,6 +139,8 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
static bool import_strip ( const char *filename );
|
||||||
|
|
||||||
void command_move_left ( void );
|
void command_move_left ( void );
|
||||||
void command_move_right ( void );
|
void command_move_right ( void );
|
||||||
void command_close ( void );
|
void command_close ( void );
|
||||||
|
|
|
@ -88,6 +88,9 @@ Loggable::block_end ( void )
|
||||||
Loggable *
|
Loggable *
|
||||||
Loggable::find ( unsigned int id )
|
Loggable::find ( unsigned int id )
|
||||||
{
|
{
|
||||||
|
if ( _relative_id )
|
||||||
|
id += _relative_id;
|
||||||
|
|
||||||
return _loggables[ id ].loggable;
|
return _loggables[ id ].loggable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,6 +332,25 @@ Loggable::escape ( const char *s )
|
||||||
return r;
|
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" */
|
/** 'do' a message like "Audio_Region 0xF1 set :r 123" */
|
||||||
bool
|
bool
|
||||||
Loggable::do_this ( const char *s, bool reverse )
|
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 );
|
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 */
|
/* create */
|
||||||
Loggable *l = _class_map[ std::string( classname ) ]( e, id );
|
Loggable *l = _class_map[ std::string( classname ) ]( e, id );
|
||||||
l->log_create();
|
l->log_create();
|
||||||
|
|
|
@ -89,6 +89,8 @@ class Loggable
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
static unsigned int _relative_id;
|
||||||
|
|
||||||
unsigned int _id;
|
unsigned int _id;
|
||||||
|
|
||||||
Log_Entry *_old_state;
|
Log_Entry *_old_state;
|
||||||
|
@ -183,6 +185,10 @@ public:
|
||||||
|
|
||||||
virtual void log_children ( void ) const { return; }
|
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 bool do_this ( const char *s, bool reverse );
|
||||||
|
|
||||||
static int dirty ( void ) { return _dirty; }
|
static int dirty ( void ) { return _dirty; }
|
||||||
|
|
Loading…
Reference in New Issue