Implement plugin browser, with search and favorites.
This commit is contained in:
parent
5d35f37d4e
commit
dd9eb35ab2
|
@ -292,6 +292,12 @@ LADSPAInfo::GetMenuList(void)
|
||||||
return m_SSMMenuList;
|
return m_SSMMenuList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const vector<LADSPAInfo::PluginInfo>
|
||||||
|
LADSPAInfo::GetPluginInfo(void)
|
||||||
|
{
|
||||||
|
return m_Plugins;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
LADSPAInfo::GetPluginListEntryByID(unsigned long unique_id)
|
LADSPAInfo::GetPluginListEntryByID(unsigned long unique_id)
|
||||||
{
|
{
|
||||||
|
@ -599,6 +605,13 @@ LADSPAInfo::ExaminePluginLibrary(const string path,
|
||||||
library_added = true;
|
library_added = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! desc->Name )
|
||||||
|
{
|
||||||
|
printf( "WARNING: LADSPA Plugin with id %lu has no name!\n", desc->UniqueID );
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Add plugin info
|
// Add plugin info
|
||||||
PluginInfo pi;
|
PluginInfo pi;
|
||||||
pi.LibraryIndex = m_Libraries.size() - 1;
|
pi.LibraryIndex = m_Libraries.size() - 1;
|
||||||
|
@ -607,19 +620,34 @@ LADSPAInfo::ExaminePluginLibrary(const string path,
|
||||||
pi.Label = desc->Label;
|
pi.Label = desc->Label;
|
||||||
pi.Name = desc->Name;
|
pi.Name = desc->Name;
|
||||||
pi.Descriptor = NULL;
|
pi.Descriptor = NULL;
|
||||||
m_Plugins.push_back(pi);
|
pi.Maker = desc->Maker;
|
||||||
|
pi.AudioInputs = 0;
|
||||||
|
pi.AudioOutputs = 0;
|
||||||
|
|
||||||
// Find number of input ports
|
// Find number of input ports
|
||||||
unsigned long in_port_count = 0;
|
unsigned long in_port_count = 0;
|
||||||
for (unsigned long p = 0; p < desc->PortCount; p++) {
|
for (unsigned long p = 0; p < desc->PortCount; p++) {
|
||||||
if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[p])) {
|
if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[p])) {
|
||||||
in_port_count++;
|
in_port_count++;
|
||||||
}
|
if ( LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[p] ) )
|
||||||
|
pi.AudioInputs++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
for (unsigned long p = 0; p < desc->PortCount; p++) {
|
||||||
|
if (LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[p])) {
|
||||||
|
|
||||||
|
if ( LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[p] ) )
|
||||||
|
pi.AudioOutputs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (in_port_count > m_MaxInputPortCount) {
|
if (in_port_count > m_MaxInputPortCount) {
|
||||||
m_MaxInputPortCount = in_port_count;
|
m_MaxInputPortCount = in_port_count;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_Plugins.push_back(pi);
|
||||||
|
|
||||||
// Add to index
|
// Add to index
|
||||||
m_IDLookup[desc->UniqueID] = m_Plugins.size() - 1;
|
m_IDLookup[desc->UniqueID] = m_Plugins.size() - 1;
|
||||||
|
|
||||||
|
|
|
@ -97,9 +97,28 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// For cached plugin information
|
||||||
|
struct PluginInfo
|
||||||
|
{
|
||||||
|
unsigned long LibraryIndex; // Index of library in m_Libraries
|
||||||
|
unsigned long Index; // Plugin index in library
|
||||||
|
unsigned long UniqueID; // Unique ID
|
||||||
|
std::string Label; // Plugin label
|
||||||
|
std::string Name; // Plugin Name
|
||||||
|
std::string Maker;
|
||||||
|
unsigned int AudioInputs;
|
||||||
|
unsigned int AudioOutputs;
|
||||||
|
const LADSPA_Descriptor *Descriptor; // Descriptor, NULL
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// Get ordered list of plugin names and IDs for plugin menu
|
// Get ordered list of plugin names and IDs for plugin menu
|
||||||
const std::vector<PluginEntry> GetMenuList(void);
|
const std::vector<PluginEntry> GetMenuList(void);
|
||||||
|
|
||||||
|
const std::vector<PluginInfo> GetPluginInfo(void);
|
||||||
|
|
||||||
// Get the index in the above list for given Unique ID
|
// Get the index in the above list for given Unique ID
|
||||||
// If not found, this returns the size of the above list
|
// If not found, this returns the size of the above list
|
||||||
unsigned long GetPluginListEntryByID(unsigned long unique_id);
|
unsigned long GetPluginListEntryByID(unsigned long unique_id);
|
||||||
|
@ -140,17 +159,6 @@ private:
|
||||||
void *Handle; // DLL Handle, NULL
|
void *Handle; // DLL Handle, NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
// For cached plugin information
|
|
||||||
struct PluginInfo
|
|
||||||
{
|
|
||||||
unsigned long LibraryIndex; // Index of library in m_Libraries
|
|
||||||
unsigned long Index; // Plugin index in library
|
|
||||||
unsigned long UniqueID; // Unique ID
|
|
||||||
std::string Label; // Plugin label
|
|
||||||
std::string Name; // Plugin Name
|
|
||||||
const LADSPA_Descriptor *Descriptor; // Descriptor, NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
// For cached RDF uri information
|
// For cached RDF uri information
|
||||||
struct RDFURIInfo
|
struct RDFURIInfo
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "FL/menu_popup.H"
|
#include "FL/menu_popup.H"
|
||||||
#include "Mixer.H"
|
#include "Mixer.H"
|
||||||
|
|
||||||
|
#include "Plugin_Chooser.H"
|
||||||
#include "OSC/Endpoint.H"
|
#include "OSC/Endpoint.H"
|
||||||
|
|
||||||
#include "string_util.h"
|
#include "string_util.h"
|
||||||
|
@ -602,61 +603,55 @@ Module::draw_label ( void )
|
||||||
void
|
void
|
||||||
Module::insert_menu_cb ( const Fl_Menu_ *m )
|
Module::insert_menu_cb ( const Fl_Menu_ *m )
|
||||||
{
|
{
|
||||||
if ( ! m->mvalue() || m->mvalue()->flags & FL_SUBMENU_POINTER || m->mvalue()->flags & FL_SUBMENU )
|
unsigned long id = Plugin_Chooser::plugin_chooser( this->ninputs() );
|
||||||
return;
|
|
||||||
|
|
||||||
void * v = m->mvalue()->user_data();
|
Module *mod = NULL;
|
||||||
|
|
||||||
if ( v )
|
switch ( id )
|
||||||
{
|
{
|
||||||
unsigned long id = *((unsigned long *)v);
|
case 0:
|
||||||
|
return;
|
||||||
Module *mod = NULL;
|
case 1:
|
||||||
|
mod = new JACK_Module();
|
||||||
switch ( id )
|
break;
|
||||||
|
case 2:
|
||||||
|
mod = new Gain_Module();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mod = new Meter_Module();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
mod = new Mono_Pan_Module();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
{
|
{
|
||||||
case 1:
|
Plugin_Module *m = new Plugin_Module();
|
||||||
mod = new JACK_Module();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
mod = new Gain_Module();
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
mod = new Meter_Module();
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
mod = new Mono_Pan_Module();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
Plugin_Module *m = new Plugin_Module();
|
|
||||||
|
|
||||||
m->load( id );
|
m->load( id );
|
||||||
|
|
||||||
mod = m;
|
mod = m;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mod )
|
||||||
|
{
|
||||||
|
if ( !strcmp( mod->name(), "JACK" ) )
|
||||||
|
{
|
||||||
|
DMESSAGE( "Special casing JACK module" );
|
||||||
|
JACK_Module *jm = (JACK_Module*)mod;
|
||||||
|
jm->chain( chain() );
|
||||||
|
jm->configure_inputs( ninputs() );
|
||||||
|
jm->configure_outputs( ninputs() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mod )
|
if ( ! chain()->insert( this, mod ) )
|
||||||
{
|
{
|
||||||
if ( !strcmp( mod->name(), "JACK" ) )
|
fl_alert( "Cannot insert this module at this point in the chain" );
|
||||||
{
|
delete mod;
|
||||||
DMESSAGE( "Special casing JACK module" );
|
return;
|
||||||
JACK_Module *jm = (JACK_Module*)mod;
|
|
||||||
jm->chain( chain() );
|
|
||||||
jm->configure_inputs( ninputs() );
|
|
||||||
jm->configure_outputs( ninputs() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! chain()->insert( this, mod ) )
|
|
||||||
{
|
|
||||||
fl_alert( "Cannot insert this module at this point in the chain" );
|
|
||||||
delete mod;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
redraw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -733,7 +728,10 @@ Module::menu ( void ) const
|
||||||
insert_menu->add( "Meter", 0, 0, new unsigned long(3) );
|
insert_menu->add( "Meter", 0, 0, new unsigned long(3) );
|
||||||
insert_menu->add( "Mono Pan", 0, 0, new unsigned long(4) );
|
insert_menu->add( "Mono Pan", 0, 0, new unsigned long(4) );
|
||||||
|
|
||||||
Plugin_Module::add_plugins_to_menu( insert_menu );
|
insert_menu->add( "Plugin", 0, 0, new unsigned long(4) );
|
||||||
|
|
||||||
|
|
||||||
|
/* Plugin_Module::add_plugins_to_menu( insert_menu ); */
|
||||||
|
|
||||||
// menu_set_callback( insert_menu, &Module::insert_menu_cb, (void*)this );
|
// menu_set_callback( insert_menu, &Module::insert_menu_cb, (void*)this );
|
||||||
insert_menu->callback( &Module::insert_menu_cb, (void*)this );
|
insert_menu->callback( &Module::insert_menu_cb, (void*)this );
|
||||||
|
|
|
@ -0,0 +1,384 @@
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* Copyright (C) 2013 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. */
|
||||||
|
/*******************************************************************************/
|
||||||
|
|
||||||
|
#include <FL/Fl.H>
|
||||||
|
#include <FL/Fl_Browser.H>
|
||||||
|
#include <FL/Fl_Input.H>
|
||||||
|
#include <FL/Fl_Scalepack.H>
|
||||||
|
#include "Plugin_Chooser_UI.H"
|
||||||
|
#include "Plugin_Module.H"
|
||||||
|
#include "Plugin_Chooser.H"
|
||||||
|
#include "stdio.h"
|
||||||
|
#include <FL/Fl_Box.H>
|
||||||
|
#include <FL/fl_draw.H>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
static std::vector <Plugin_Module::Plugin_Info*> _plugin_rows;
|
||||||
|
|
||||||
|
unsigned long
|
||||||
|
Plugin_Chooser::plugin_chooser ( int ninputs )
|
||||||
|
{
|
||||||
|
Plugin_Chooser *o = new Plugin_Chooser( 0,0,735,500,"Plugin Chooser");
|
||||||
|
|
||||||
|
o->ui->inputs_input->value( ninputs );
|
||||||
|
|
||||||
|
o->search( "", "", ninputs, 0, o->ui->favorites_button->value() );
|
||||||
|
|
||||||
|
o->show();
|
||||||
|
|
||||||
|
while ( o->shown() )
|
||||||
|
Fl::wait();
|
||||||
|
|
||||||
|
unsigned long picked = o->value();
|
||||||
|
|
||||||
|
delete o;
|
||||||
|
|
||||||
|
return picked;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Plugin_Chooser::search ( const char *name, const char *author, int ninputs, int noutputs, bool favorites )
|
||||||
|
{
|
||||||
|
_plugin_rows.clear();
|
||||||
|
|
||||||
|
for ( std::list<Plugin_Module::Plugin_Info>::iterator i = _plugins.begin(); i != _plugins.end(); i++ )
|
||||||
|
{
|
||||||
|
Plugin_Module::Plugin_Info *p = &(*i);
|
||||||
|
|
||||||
|
if ( strcasestr( p->name, name ) &&
|
||||||
|
strcasestr( p->author, author ) )
|
||||||
|
{
|
||||||
|
if ( !
|
||||||
|
((( ( ninputs == 0 || ninputs == p->audio_inputs ) ) &&
|
||||||
|
( noutputs == 0 || noutputs == p->audio_outputs )) ||
|
||||||
|
( p->audio_inputs == 1 && p->audio_outputs == 1 ) ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( p->audio_outputs == 0 || p->audio_inputs == 0 )
|
||||||
|
/* we don't support these */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( favorites > 0 && ! p->favorite )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_plugin_rows.push_back( p );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->table->rows( _plugin_rows.size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Plugin_Chooser::cb_handle ( Fl_Widget *w, void *v )
|
||||||
|
{
|
||||||
|
((Plugin_Chooser*)v)->cb_handle( w );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Plugin_Chooser::cb_handle ( Fl_Widget *w )
|
||||||
|
{
|
||||||
|
if ( w == ui->all_button )
|
||||||
|
{
|
||||||
|
ui->favorites_button->value( !ui->all_button->value() );
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
search( ui->name_input->value(), ui->author_input->value(), ui->inputs_input->value(), ui->outputs_input->value(), ui->favorites_button->value() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Plugin_Table : public Fl_Table_Row
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void draw_cell(TableContext context, // table cell drawing
|
||||||
|
int R=0, int C=0, int X=0, int Y=0, int W=0, int H=0);
|
||||||
|
public:
|
||||||
|
Plugin_Table(int x, int y, int w, int h, const char *l=0) : Fl_Table_Row(x,y,w,h,l)
|
||||||
|
{
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
~Plugin_Table() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
void Plugin_Table::draw_cell(TableContext context,
|
||||||
|
int R, int C, int X, int Y, int W, int H)
|
||||||
|
{
|
||||||
|
const char *headings[] = { "Fav.", "Name", "Author", "Type", "In", "Out" };
|
||||||
|
|
||||||
|
static char s[40];
|
||||||
|
|
||||||
|
switch ( context )
|
||||||
|
{
|
||||||
|
case CONTEXT_STARTPAGE:
|
||||||
|
fl_font(FL_HELVETICA, 12);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case CONTEXT_COL_HEADER:
|
||||||
|
fl_push_clip(X, Y, W, H);
|
||||||
|
{
|
||||||
|
fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, col_header_color());
|
||||||
|
fl_color(FL_FOREGROUND_COLOR);
|
||||||
|
fl_draw(headings[C], X, Y, W, H, FL_ALIGN_CENTER);
|
||||||
|
}
|
||||||
|
fl_pop_clip();
|
||||||
|
return;
|
||||||
|
|
||||||
|
case CONTEXT_ROW_HEADER:
|
||||||
|
return;
|
||||||
|
|
||||||
|
case CONTEXT_CELL:
|
||||||
|
{
|
||||||
|
const char *s2 = (char*)s;
|
||||||
|
Fl_Align a = FL_ALIGN_CENTER;
|
||||||
|
int symbol = 0;
|
||||||
|
|
||||||
|
switch ( C )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
sprintf( s, "%s", _plugin_rows[R]->favorite ? "@circle" : "" );
|
||||||
|
symbol = 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
a = FL_ALIGN_LEFT;
|
||||||
|
s2 = _plugin_rows[R]->name;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
a = FL_ALIGN_LEFT;
|
||||||
|
s2 = _plugin_rows[R]->author;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
s2 = _plugin_rows[R]->type;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
sprintf( s, "%i", _plugin_rows[R]->audio_inputs );
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
sprintf( s, "%i", _plugin_rows[R]->audio_outputs );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fl_push_clip(X, Y, W, H);
|
||||||
|
{
|
||||||
|
// BG COLOR
|
||||||
|
fl_color( row_selected(R) ? selection_color() : FL_DARK1);
|
||||||
|
fl_rectf(X, Y, W, H);
|
||||||
|
|
||||||
|
// TEXT
|
||||||
|
fl_color(FL_FOREGROUND_COLOR);
|
||||||
|
fl_draw(s2, X, Y, W, H, a, 0, symbol );
|
||||||
|
|
||||||
|
// BORDER
|
||||||
|
fl_color(color());
|
||||||
|
fl_rect(X, Y, W, H);
|
||||||
|
}
|
||||||
|
fl_pop_clip();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case CONTEXT_TABLE:
|
||||||
|
fprintf(stderr, "TABLE CONTEXT CALLED\n");
|
||||||
|
return;
|
||||||
|
|
||||||
|
case CONTEXT_ENDPAGE:
|
||||||
|
case CONTEXT_RC_RESIZE:
|
||||||
|
case CONTEXT_NONE:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Plugin_Chooser::cb_table ( Fl_Widget *w, void *v )
|
||||||
|
{
|
||||||
|
((Plugin_Chooser*)v)->cb_table(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Plugin_Chooser::cb_table ( Fl_Widget *w )
|
||||||
|
{
|
||||||
|
Fl_Table_Row *o = (Fl_Table_Row*)w;
|
||||||
|
|
||||||
|
int R = o->callback_row();
|
||||||
|
int C = o->callback_col();
|
||||||
|
|
||||||
|
Fl_Table::TableContext context = o->callback_context();
|
||||||
|
|
||||||
|
if ( context == Fl_Table::CONTEXT_CELL )
|
||||||
|
{
|
||||||
|
if ( C == 0 )
|
||||||
|
{
|
||||||
|
_plugin_rows[R]->favorite = ! _plugin_rows[R]->favorite;
|
||||||
|
o->redraw();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_value = _plugin_rows[R]->id;
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern char *user_config_dir;
|
||||||
|
|
||||||
|
static FILE *open_favorites( const char *mode )
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
asprintf( &path, "%s/%s", user_config_dir, "favorite_plugins" );
|
||||||
|
|
||||||
|
FILE *fp = fopen( path, mode );
|
||||||
|
|
||||||
|
free( path );
|
||||||
|
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
Plugin_Chooser::load_favorites ( void )
|
||||||
|
{
|
||||||
|
FILE *fp = open_favorites( "r" );
|
||||||
|
|
||||||
|
if ( !fp )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long id;
|
||||||
|
char *type;
|
||||||
|
int favorites = 0;
|
||||||
|
|
||||||
|
while ( 2 == fscanf( fp, "%a[^:]:%lu\n", &type, &id ) )
|
||||||
|
{
|
||||||
|
for ( std::list<Plugin_Module::Plugin_Info>::iterator i = _plugins.begin();
|
||||||
|
i != _plugins.end();
|
||||||
|
i++ )
|
||||||
|
{
|
||||||
|
if ( !strcmp( (*i).type, type ) &&
|
||||||
|
(*i).id == id )
|
||||||
|
{
|
||||||
|
(*i).favorite = 1;
|
||||||
|
|
||||||
|
favorites++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return favorites;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Plugin_Chooser::save_favorites ( void )
|
||||||
|
{
|
||||||
|
FILE *fp = open_favorites( "w" );
|
||||||
|
|
||||||
|
if ( !fp )
|
||||||
|
return;
|
||||||
|
|
||||||
|
for ( std::list<Plugin_Module::Plugin_Info>::iterator i = _plugins.begin();
|
||||||
|
i != _plugins.end();
|
||||||
|
i++ )
|
||||||
|
{
|
||||||
|
if ( (*i).favorite )
|
||||||
|
{
|
||||||
|
fprintf( fp, "%s:%lu\n", i->type, i->id );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose( fp );
|
||||||
|
}
|
||||||
|
|
||||||
|
Plugin_Chooser::Plugin_Chooser ( int X,int Y,int W,int H, const char *L )
|
||||||
|
: Fl_Double_Window ( X,Y,W,H,L )
|
||||||
|
{
|
||||||
|
set_modal();
|
||||||
|
_value = 0;
|
||||||
|
|
||||||
|
_plugins = Plugin_Module::get_all_plugins();
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
Plugin_Chooser_UI *o = ui = new Plugin_Chooser_UI(X,Y,W,H);
|
||||||
|
|
||||||
|
o->name_input->callback( &Plugin_Chooser::cb_handle, this );
|
||||||
|
o->name_input->when( FL_WHEN_CHANGED );
|
||||||
|
|
||||||
|
|
||||||
|
o->author_input->callback( &Plugin_Chooser::cb_handle, this );
|
||||||
|
o->author_input->when( FL_WHEN_CHANGED );
|
||||||
|
|
||||||
|
|
||||||
|
o->inputs_input->callback( &Plugin_Chooser::cb_handle, this );
|
||||||
|
o->inputs_input->when( FL_WHEN_CHANGED );
|
||||||
|
|
||||||
|
o->outputs_input->callback( &Plugin_Chooser::cb_handle, this );
|
||||||
|
o->outputs_input->when( FL_WHEN_CHANGED );
|
||||||
|
|
||||||
|
o->favorites_button->callback( &Plugin_Chooser::cb_handle, this );
|
||||||
|
o->favorites_button->when( FL_WHEN_CHANGED );
|
||||||
|
|
||||||
|
o->all_button->callback( &Plugin_Chooser::cb_handle, this );
|
||||||
|
o->all_button->when( FL_WHEN_CHANGED );
|
||||||
|
|
||||||
|
{
|
||||||
|
Plugin_Table *o = new Plugin_Table(ui->table->x(),ui->table->y(),ui->table->w(),ui->table->h() );
|
||||||
|
ui->table_group->add(o);
|
||||||
|
ui->table_group->resizable(o);
|
||||||
|
delete ui->table;
|
||||||
|
ui->table = o;
|
||||||
|
/* ui->scalepack->add( o ); */
|
||||||
|
/* ui->scalepack->resizable( o ); */
|
||||||
|
o->col_header(1);
|
||||||
|
o->col_resize(1);
|
||||||
|
o->row_resize(1);
|
||||||
|
o->cols(6);
|
||||||
|
o->col_resize_min(4);
|
||||||
|
o->col_width(0,30);
|
||||||
|
o->col_width(1,350 - 7);
|
||||||
|
o->col_width(2,200);
|
||||||
|
o->col_width(3,75);
|
||||||
|
o->col_width(4,30);
|
||||||
|
o->col_width(5,30);
|
||||||
|
o->color(FL_BLACK);
|
||||||
|
o->box(FL_NO_BOX);
|
||||||
|
o->when(FL_WHEN_CHANGED);
|
||||||
|
o->callback( &Plugin_Chooser::cb_table, this );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
resizable(o);
|
||||||
|
}
|
||||||
|
size_range( 735, 300, 735, 0 );
|
||||||
|
|
||||||
|
end();
|
||||||
|
|
||||||
|
if ( load_favorites() )
|
||||||
|
{
|
||||||
|
ui->all_button->value(0);
|
||||||
|
ui->favorites_button->value(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Plugin_Chooser::~Plugin_Chooser( )
|
||||||
|
{
|
||||||
|
save_favorites();
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
|
||||||
|
/*******************************************************************************/
|
||||||
|
/* Copyright (C) 2013 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 <FL/Fl_Double_Window.H>
|
||||||
|
#include "Plugin_Module.H"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Plugin_Chooser_UI;
|
||||||
|
class Plugin_Chooser : public Fl_Double_Window
|
||||||
|
{
|
||||||
|
Plugin_Chooser_UI *ui;
|
||||||
|
|
||||||
|
std::list <Plugin_Module::Plugin_Info> _plugins;
|
||||||
|
|
||||||
|
static void cb_handle ( Fl_Widget *w, void *v );
|
||||||
|
void cb_handle ( Fl_Widget *w );
|
||||||
|
static void cb_table ( Fl_Widget *w, void *v );
|
||||||
|
void cb_table ( Fl_Widget *w );
|
||||||
|
|
||||||
|
void search ( const char *name, const char *author, int ninputs, int noutputs, bool favorites );
|
||||||
|
|
||||||
|
unsigned long _value;
|
||||||
|
|
||||||
|
int load_favorites ( void );
|
||||||
|
|
||||||
|
void save_favorites ( void );
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
unsigned long value ( void ) const { return _value; }
|
||||||
|
|
||||||
|
Plugin_Chooser ( int X,int Y,int W,int H, const char *L=0 );
|
||||||
|
|
||||||
|
virtual ~Plugin_Chooser( );
|
||||||
|
|
||||||
|
static unsigned long plugin_chooser ( int ninputs );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
# data file for the Fltk User Interface Designer (fluid)
|
||||||
|
version 1.0300
|
||||||
|
header_name {.h}
|
||||||
|
code_name {.cxx}
|
||||||
|
decl {\#include <FL/Fl_Scalepack.H>} {public global
|
||||||
|
}
|
||||||
|
|
||||||
|
decl {\#include <FL/Fl_Table_Row.H>} {public global
|
||||||
|
}
|
||||||
|
|
||||||
|
widget_class Plugin_Chooser_UI {
|
||||||
|
label {Plugin Selector} open selected
|
||||||
|
xywh {821 343 735 500} type Double resizable size_range {740 0 740 0} visible
|
||||||
|
} {
|
||||||
|
Fl_Group {} {open
|
||||||
|
xywh {10 5 155 20}
|
||||||
|
} {
|
||||||
|
Fl_Round_Button all_button {
|
||||||
|
label All
|
||||||
|
xywh {10 5 50 20} type Radio down_box ROUND_DOWN_BOX value 1
|
||||||
|
}
|
||||||
|
Fl_Round_Button favorites_button {
|
||||||
|
label Favorites
|
||||||
|
xywh {65 5 100 20} type Radio down_box ROUND_DOWN_BOX
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {} {open
|
||||||
|
xywh {5 29 725 77} box UP_FRAME
|
||||||
|
code0 {o->resizable(0);}
|
||||||
|
} {
|
||||||
|
Fl_Input name_input {
|
||||||
|
label {Name:}
|
||||||
|
xywh {65 38 555 24} labelsize 12 textsize 13
|
||||||
|
}
|
||||||
|
Fl_Input author_input {
|
||||||
|
label {Author:}
|
||||||
|
xywh {65 72 415 24} labelsize 12 textsize 13
|
||||||
|
}
|
||||||
|
Fl_Value_Input outputs_input {
|
||||||
|
label {Outputs:}
|
||||||
|
xywh {693 70 30 26} labelsize 12
|
||||||
|
}
|
||||||
|
Fl_Value_Input inputs_input {
|
||||||
|
label {Inputs:}
|
||||||
|
xywh {693 39 30 24} labelsize 12
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group table_group {open
|
||||||
|
xywh {5 115 725 380} resizable
|
||||||
|
} {
|
||||||
|
Fl_Table table {open
|
||||||
|
xywh {5 115 725 380} resizable
|
||||||
|
} {}
|
||||||
|
}
|
||||||
|
Fl_Choice type_choice {
|
||||||
|
label {Type:} open
|
||||||
|
xywh {520 135 100 28} down_box BORDER_BOX labelsize 12 hide
|
||||||
|
} {
|
||||||
|
MenuItem {} {
|
||||||
|
label LADSPA
|
||||||
|
xywh {0 -68 34 18}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,8 @@
|
||||||
|
|
||||||
#include <dsp.h>
|
#include <dsp.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static LADSPAInfo *ladspainfo;
|
static LADSPAInfo *ladspainfo;
|
||||||
|
@ -119,64 +121,6 @@ Plugin_Module::set ( Log_Entry &e )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Plugin_Module::add_plugins_to_menu ( Fl_Menu_Button *menu )
|
|
||||||
{
|
|
||||||
Plugin_Module::Plugin_Info *pia = Plugin_Module::get_all_plugins();
|
|
||||||
|
|
||||||
char path[1024];
|
|
||||||
for ( Plugin_Module::Plugin_Info *pi = pia; pi->path; ++pi )
|
|
||||||
{
|
|
||||||
snprintf( path, sizeof( path ), "Plugin/%s", pi->path );
|
|
||||||
|
|
||||||
menu->add(path, 0, NULL, new unsigned long( pi->id ), 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] pia;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allow the user to pick a plugin */
|
|
||||||
Plugin_Module *
|
|
||||||
Plugin_Module::pick_plugin ( void )
|
|
||||||
{
|
|
||||||
/**************/
|
|
||||||
/* build menu */
|
|
||||||
/**************/
|
|
||||||
|
|
||||||
Fl_Menu_Button *menu = new Fl_Menu_Button( 0, 0, 400, 400 );
|
|
||||||
menu->type( Fl_Menu_Button::POPUP3 );
|
|
||||||
|
|
||||||
Plugin_Module::Plugin_Info *pia = Plugin_Module::get_all_plugins();
|
|
||||||
|
|
||||||
for ( Plugin_Module::Plugin_Info *pi = pia; pi->path; ++pi )
|
|
||||||
{
|
|
||||||
menu->add(pi->path, 0, NULL, pi, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
menu->popup();
|
|
||||||
|
|
||||||
if ( menu->value() <= 0 )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/************************/
|
|
||||||
/* load selected plugin */
|
|
||||||
/************************/
|
|
||||||
|
|
||||||
Plugin_Module::Plugin_Info *pi = (Plugin_Module::Plugin_Info*)menu->menu()[ menu->value() ].user_data();
|
|
||||||
|
|
||||||
if ( ! pi )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
Plugin_Module *m = new Plugin_Module();
|
|
||||||
|
|
||||||
m->load( pi->id );
|
|
||||||
|
|
||||||
delete[] pia;
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Plugin_Module::init ( void )
|
Plugin_Module::init ( void )
|
||||||
{
|
{
|
||||||
|
@ -319,7 +263,7 @@ Plugin_Module::join_discover_thread ( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return a list of available plugins */
|
/* return a list of available plugins */
|
||||||
Plugin_Module::Plugin_Info *
|
std::list<Plugin_Module::Plugin_Info>
|
||||||
Plugin_Module::get_all_plugins ( void )
|
Plugin_Module::get_all_plugins ( void )
|
||||||
{
|
{
|
||||||
if ( !ladspainfo )
|
if ( !ladspainfo )
|
||||||
|
@ -330,19 +274,30 @@ Plugin_Module::get_all_plugins ( void )
|
||||||
plugin_discover_thread->join();
|
plugin_discover_thread->join();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<LADSPAInfo::PluginEntry> plugins = ladspainfo->GetMenuList();
|
std::vector<LADSPAInfo::PluginInfo> plugins = ladspainfo->GetPluginInfo();
|
||||||
|
|
||||||
Plugin_Info* pi = new Plugin_Info[plugins.size() + 1];
|
std::list<Plugin_Module::Plugin_Info> pr;
|
||||||
|
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (std::vector<LADSPAInfo::PluginEntry>::iterator i=plugins.begin();
|
for (std::vector<LADSPAInfo::PluginInfo>::iterator i=plugins.begin();
|
||||||
i!=plugins.end(); i++, j++)
|
i!=plugins.end(); i++, j++)
|
||||||
{
|
{
|
||||||
pi[j].path = i->Name.c_str();
|
Plugin_Info pi;
|
||||||
pi[j].id = i->UniqueID;
|
|
||||||
|
// pi[j].path = i->Name.c_str();
|
||||||
|
pi.path = NULL;
|
||||||
|
pi.id = i->UniqueID;
|
||||||
|
pi.author = i->Maker.c_str();
|
||||||
|
pi.name = i->Name.c_str();
|
||||||
|
pi.audio_inputs = i->AudioInputs;
|
||||||
|
pi.audio_outputs = i->AudioOutputs;
|
||||||
|
|
||||||
|
pr.push_back( pi );
|
||||||
}
|
}
|
||||||
|
|
||||||
return pi;
|
pr.sort();
|
||||||
|
|
||||||
|
return pr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -35,12 +35,30 @@ public:
|
||||||
{
|
{
|
||||||
const char *path;
|
const char *path;
|
||||||
unsigned long id;
|
unsigned long id;
|
||||||
|
const char *name;
|
||||||
|
const char *author;
|
||||||
|
const char *category;
|
||||||
|
int audio_inputs;
|
||||||
|
int audio_outputs;
|
||||||
|
const char *type;
|
||||||
|
bool favorite;
|
||||||
|
|
||||||
Plugin_Info ( )
|
Plugin_Info ( )
|
||||||
{
|
{
|
||||||
path = 0;
|
path = 0;
|
||||||
id = 0;
|
id = 0;
|
||||||
|
name = 0;
|
||||||
|
author = 0;
|
||||||
|
category = 0;
|
||||||
|
audio_inputs = 0;
|
||||||
|
audio_outputs = 0;
|
||||||
|
type = "LADSPA";
|
||||||
|
favorite = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator< ( const Plugin_Info &rhs ) {
|
||||||
|
return strcmp( name, rhs.name ) < 1;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool load ( unsigned long id );
|
bool load ( unsigned long id );
|
||||||
|
@ -71,7 +89,6 @@ private:
|
||||||
bool _crosswire;
|
bool _crosswire;
|
||||||
|
|
||||||
static void *discover_thread ( void * );
|
static void *discover_thread ( void * );
|
||||||
static Plugin_Info* get_all_plugins ( void );
|
|
||||||
|
|
||||||
|
|
||||||
void set_input_buffer ( int n, void *buf );
|
void set_input_buffer ( int n, void *buf );
|
||||||
|
@ -89,15 +106,14 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
static std::list<Plugin_Info> get_all_plugins ( void );
|
||||||
|
|
||||||
static void spawn_discover_thread ( void );
|
static void spawn_discover_thread ( void );
|
||||||
static void join_discover_thread ( void );
|
static void join_discover_thread ( void );
|
||||||
|
|
||||||
Plugin_Module ( );
|
Plugin_Module ( );
|
||||||
virtual ~Plugin_Module();
|
virtual ~Plugin_Module();
|
||||||
|
|
||||||
static Plugin_Module * pick_plugin ( void );
|
|
||||||
static void add_plugins_to_menu ( Fl_Menu_Button *menu );
|
|
||||||
|
|
||||||
int plugin_ins ( void ) const { return _plugin_ins; }
|
int plugin_ins ( void ) const { return _plugin_ins; }
|
||||||
int plugin_outs ( void ) const { return _plugin_outs; }
|
int plugin_outs ( void ) const { return _plugin_outs; }
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,8 @@ src/Mixer_Strip.C
|
||||||
src/Module.C
|
src/Module.C
|
||||||
src/Module_Parameter_Editor.C
|
src/Module_Parameter_Editor.C
|
||||||
src/Mono_Pan_Module.C
|
src/Mono_Pan_Module.C
|
||||||
|
src/Plugin_Chooser_UI.fl
|
||||||
|
src/Plugin_Chooser.C
|
||||||
src/NSM.C
|
src/NSM.C
|
||||||
src/Panner.C
|
src/Panner.C
|
||||||
src/Plugin_Module.C
|
src/Plugin_Module.C
|
||||||
|
|
Loading…
Reference in New Issue