diff options
Diffstat (limited to 'arts/modules/common')
17 files changed, 1533 insertions, 0 deletions
diff --git a/arts/modules/common/Makefile.am b/arts/modules/common/Makefile.am new file mode 100644 index 00000000..6742af36 --- /dev/null +++ b/arts/modules/common/Makefile.am @@ -0,0 +1,61 @@ + +INCLUDES = \ + -I$(top_builddir)/arts/modules/common \ + -I$(top_builddir)/arts/modules/synth \ + -I$(top_srcdir)/arts/modules/synth \ + -I$(top_builddir)/arts/modules \ + -I$(top_srcdir)/arts/modules \ + -I$(top_builddir)/arts/gui/common \ + -I$(top_srcdir)/arts/gui/common \ + -I$(top_builddir)/arts/midi \ + -I$(top_srcdir)/arts/midi \ + -I$(arts_includes) \ + $(all_includes) + +lib_LTLIBRARIES = libartsmodulescommon.la + +libartsmodulescommon_la_SOURCES = artsmodulescommon.cc \ + effectrackslot_impl.cc env_container_impl.cc \ + env_context_impl.cc env_effectrackitem_impl.cc \ + env_instrumentitem_impl.cc env_item_impl.cc \ + env_mixeritem_impl.cc +libartsmodulescommon_la_COMPILE_FIRST = artsmodulescommon.h + +libartsmodulescommon_la_LIBADD = \ + $(top_builddir)/arts/gui/common/libartsgui_idl.la \ + $(top_builddir)/arts/midi/libartsmidi_idl.la \ + $(top_builddir)/arts/modules/synth/libartsmodulessynth.la \ + -lartsflow -lartsflow_idl -lmcop $(LIB_KDECORE) + +libartsmodulescommon_la_LDFLAGS = $(all_libraries) -L$(arts_libraries) -no-undefined + +artsmodulescommon.cc artsmodulescommon.h artsmodulescommon.mcoptype artsmodulescommon.mcopclass: $(srcdir)/artsmodulescommon.idl $(MCOPIDL) + $(MCOPIDL) -t $(INCLUDES) $(srcdir)/artsmodulescommon.idl + +DISTCLEANFILES= artsmodulescommon.cc artsmodulescommon.h artsmodulescommon.mcop* + +artsincludedir = $(includedir)/arts +artsinclude_HEADERS = artsmodulescommon.h artsmodulescommon.idl + +mcoptypedir = $(libdir)/mcop +mcoptype_DATA = artsmodulescommon.mcoptype artsmodulescommon.mcopclass + +mcopclassdir = $(libdir)/mcop/Arts +mcopclass_DATA = \ + mcopclass/EffectRackGuiFactory.mcopclass mcopclass/MixerGuiFactory.mcopclass + +mcopclassenvdir = $(libdir)/mcop/Arts/Environment +mcopclassenv_DATA= \ + mcopclass/InstrumentItem.mcopclass mcopclass/Container.mcopclass \ + mcopclass/MixerItem.mcopclass mcopclass/EffectRackItem.mcopclass \ + mcopclass/InstrumentItemGuiFactory.mcopclass + +artsmodulescommon.lo: ../../gui/common/artsgui.h ../../midi/artsmidi.h ../synth/artsmodulessynth.h +effectrackslot_impl.lo: ../../gui/common/artsgui.h ../../midi/artsmidi.h ../synth/artsmodulessynth.h +env_container_impl.lo: ../../gui/common/artsgui.h ../../midi/artsmidi.h ../synth/artsmodulessynth.h +env_context_impl.lo: ../../gui/common/artsgui.h ../../midi/artsmidi.h ../synth/artsmodulessynth.h +env_effectrackitem_impl.lo: ../../gui/common/artsgui.h ../../midi/artsmidi.h ../synth/artsmodulessynth.h +env_instrumentitem_impl.lo: ../../gui/common/artsgui.h ../../midi/artsmidi.h ../synth/artsmodulessynth.h +env_item_impl.lo: ../../gui/common/artsgui.h ../../midi/artsmidi.h ../synth/artsmodulessynth.h +env_mixeritem_impl.lo: ../../gui/common/artsgui.h ../../midi/artsmidi.h ../synth/artsmodulessynth.h + diff --git a/arts/modules/common/artsmodulescommon.idl b/arts/modules/common/artsmodulescommon.idl new file mode 100644 index 00000000..299ca51d --- /dev/null +++ b/arts/modules/common/artsmodulescommon.idl @@ -0,0 +1,167 @@ +/* + + Copyright (C) 2000-2001 Stefan Westerfeld + stefan@space.twc.de + 2001-2003 Matthias Kretz + kretz@kde.org + 2002-2003 Arnold Krille + arnold@arnoldarts.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +/* +* DISCLAIMER: The interfaces in artsmodules.idl (and the derived .cc/.h files) +* DO NOT GUARANTEE BINARY COMPATIBILITY YET. +* +* They are intended for developers. You shouldn't expect that applications in +* binary form will be fully compatibile with further releases of these +* interfaces. +*/ + +#include <artsgui.idl> +#include <artsflow.idl> +#include <artsmidi.idl> + +#include <artsmodulessynth.idl> + +module Arts { + +module Environment { + interface Context { + void addEntry(string name, object obj); + string lookupEntry(object obj); + void removeEntry(object obj); + }; + + interface Item; + + interface Container { + attribute string dataDirectory; + attribute Context context; + readonly attribute sequence<Item> items; + + sequence<string> saveToList(); + void loadFromList(sequence<string> strlist); + + void addItem(Item item); + Item createItem(string name); + void removeItem(Item item); + }; + + interface Item { + /** + * true if item resides inside a container + */ + readonly attribute boolean active; + + /** + * the container the item lives in + */ + readonly attribute Container parent; + + /** + * called by the container to insert/remove item from/to the + * environment + */ + void setContainer(Container container); + + /** + * called by the container to save the item + */ + sequence<string> saveToList(); + + /** + * called by the container to restore the item + */ + void loadFromList(sequence<string> strlist); + }; + + interface InstrumentItem : Item { + readonly attribute Arts::MidiPort port; + attribute string filename; + attribute string busname; + }; + + interface InstrumentItemGuiFactory : Arts::GuiFactory { + }; + + interface StereoEffectItem : Item { + attribute Arts::SynthModule effect; + attribute Arts::StereoEffectStack stack; + }; + + interface MixerChannel : Arts::StereoEffect { + attribute string name; + }; + + interface MixerItem : Item { + readonly attribute sequence<MixerChannel> channels; + attribute long channelCount; + attribute string name; + attribute string type; + }; + + interface EffectRackItem : Item { + Arts::StereoEffect createEffect( string type, string name ); + void delEffect( long pos ); + void routeToMaster( long pos, boolean tomaster ); + readonly attribute sequence<Arts::StereoEffect> effects; + readonly attribute long effectCount; + attribute string name; + }; + +}; + +interface MixerItemGui { + /*writeonly*/ attribute boolean active; + /*writeonly*/ attribute long channelCount; + /*writeonly*/ attribute string type; + // builds a MixerItemGui for a specific MixerItem (call this exactly once) + Widget initialize(Environment::MixerItem item); +}; + +interface EffectRackSlot; + +interface EffectRackItemGui { + void removeSlot( EffectRackSlot slot ); + void routeToMaster( EffectRackSlot slot, boolean tomaster ); + + attribute boolean active; + attribute string type; + /*writeonly*/ attribute boolean addeffect; + + // builds a EffectRackItemGui for a specific EffectRackItem (call this exactly once) + Widget initialize(Environment::EffectRackItem item); +}; + +interface EffectRackSlot { + void constructor( Widget parent, Widget effect, EffectRackItemGui effectrackgui ); + /*writeonly*/ attribute boolean removeslot; + /*writeonly*/ attribute boolean tomaster; +}; + +// creates: Environment::MixerItem, SimpleMixerChannel +interface MixerGuiFactory : GuiFactory { +}; + +// creates: Environment::EffectRackItem +interface EffectRackGuiFactory : GuiFactory { +}; + +}; + diff --git a/arts/modules/common/effectrackslot_impl.cc b/arts/modules/common/effectrackslot_impl.cc new file mode 100644 index 00000000..3210e83e --- /dev/null +++ b/arts/modules/common/effectrackslot_impl.cc @@ -0,0 +1,116 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Matthias Kretz <kretz@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ +// $Id$ + +#include "artsmodulescommon.h" +#include <artsgui.h> +#include <debug.h> + +namespace Arts { +class EffectRackSlot_impl : virtual public EffectRackSlot_skel +{ + private: + HBox _hbox; + VBox _buttonbox; // Buttons + Button _removeButton; + Button _masterButton; + HBox _frame; + Widget _effect; + Frame _spacer; + EffectRackItemGui _effectrackgui; //XXX: need a WeakReference here? + + EffectRackSlot self() { return EffectRackSlot::_from_base( _copy() ); } + + public: + EffectRackSlot_impl() + { + } + + void constructor( Widget parent, Widget effect, EffectRackItemGui effectrackgui ) + { + _effectrackgui = effectrackgui; + + _hbox.parent( parent ); + _hbox.margin( 0 ); + _hbox.spacing( 0 ); + _hbox.framestyle( Sunken | Panel ); + _hbox.linewidth( 1 ); + _hbox.show(); + + _buttonbox.parent( _hbox ); + _buttonbox.margin( 0 ); + _buttonbox.spacing( 0 ); + _buttonbox.show(); + + _removeButton.parent( _buttonbox ); + _removeButton.text( "x" ); + _removeButton.hSizePolicy( spFixed ); + _removeButton.width( 20 ); + _removeButton.height( 20 ); + connect( _removeButton, "clicked_changed", self(), "removeslot" ); + _removeButton.show(); + + _masterButton.parent( _buttonbox ); + _masterButton.text( "MM" ); + _masterButton.toggle( true ); + _masterButton.hSizePolicy( spFixed ); + _masterButton.width( 20 ); + _masterButton.height( 20 ); + connect( _masterButton, "pressed_changed", self(), "tomaster" ); + _masterButton.show(); + + _frame.parent( _hbox ); + _frame.margin( 5 ); + _frame.spacing( 0 ); + _frame.framestyle( Raised | Panel ); + _frame.linewidth( 2 ); + _frame.midlinewidth( 2 ); + _frame.hSizePolicy( spExpanding ); + _frame.show(); + + _effect = effect; + _effect.parent( _frame ); + _effect.show(); + + _spacer.parent( _frame ); + _spacer.hSizePolicy( spExpanding ); + _spacer.show(); + } + + bool removeslot() { return false; } //unused + void removeslot( bool clicked ) + { + if( ! _removeButton.clicked() || ! clicked ) + return; + + // I need to be removed... + _effectrackgui.removeSlot( self() ); + // I should be deleted by now + } + + bool tomaster() { return false; } //unused + void tomaster( bool toggled ) + { + _effectrackgui.routeToMaster( self(), toggled ); + } +}; +REGISTER_IMPLEMENTATION( EffectRackSlot_impl ); +} + +// vim: sw=4 ts=4 diff --git a/arts/modules/common/env_container_impl.cc b/arts/modules/common/env_container_impl.cc new file mode 100644 index 00000000..0a6f87d7 --- /dev/null +++ b/arts/modules/common/env_container_impl.cc @@ -0,0 +1,136 @@ +#include "artsmodulescommon.h" +#include "../runtime/sequenceutils.h" +#include <debug.h> + +using namespace std; + +namespace Arts { +namespace Environment { + +class Container_impl : virtual public Container_skel { +protected: + string _dataDirectory; + Context _context; + vector<Item> _items; + + Container self() { return Container::_from_base(_copy()); } +public: + ~Container_impl() + { + // tell items we're going to leave before actually going away + clear(); + } + string dataDirectory() + { + return _dataDirectory; + } + void dataDirectory(const string& newDataDirectory) + { + if(newDataDirectory != _dataDirectory) + { + _dataDirectory = newDataDirectory; + dataDirectory_changed(newDataDirectory); + } + } + Context context() + { + return _context; + } + void context(Context newContext) + { + _context = newContext; + } + vector<Item> *items() + { + return new vector<Item>(_items); + } + vector<string> *saveToList() + { + vector<string> *result = new vector<string>; + + vector<Item>::iterator ii; + for(ii=_items.begin(); ii != _items.end(); ii++) + { + sqprintf(result,"item=%s",ii->_interfaceName().c_str()); + + vector<string> *itemresult = ii->saveToList(); + addSubStringSeq(result,itemresult); + delete itemresult; + } + return result; + } + + void clear() + { + /* FIXME: performance ;) */ + while(!_items.empty()) + removeItem(_items.front()); + } + + void loadFromList(const vector<string>& strlist) + { + string cmd,param; + unsigned long i; + + clear(); + + for(i=0;i<strlist.size();i++) + { + if(parse_line(strlist[i],cmd,param)) // otherwise: empty or comment + { + if(cmd == "item") + { + Item item = createItem(param); + vector<string> *itemlist = getSubStringSeq(&strlist,i); + + if(!item.isNull()) + item.loadFromList(*itemlist); + else + { + // error handling + assert(false); + } + delete itemlist; + } + } + } + } + + vector<Item>::iterator findItem(Item item) + { + vector<Item>::iterator i; + for(i = _items.begin(); i != _items.end(); i++) + if(i->_isEqual(item)) return i; + + return _items.end(); + } + + void addItem(Item item) + { + vector<Item>::iterator i = findItem(item); + arts_return_if_fail(i == _items.end()); + + _items.push_back(item); + item.setContainer(self()); + } + + Item createItem(const string& name) + { + Item item = SubClass(name); + addItem(item); + return item; + } + + void removeItem(Item item) + { + vector<Item>::iterator i = findItem(item); + arts_return_if_fail(i != _items.end()); + + _items.erase(i); + item.setContainer(Container::null()); + } +}; +REGISTER_IMPLEMENTATION(Container_impl); +} +} + diff --git a/arts/modules/common/env_context_impl.cc b/arts/modules/common/env_context_impl.cc new file mode 100644 index 00000000..a9b19a50 --- /dev/null +++ b/arts/modules/common/env_context_impl.cc @@ -0,0 +1,72 @@ +#include "artsmodulescommon.h" +#include <debug.h> + +using namespace std; + +namespace Arts { +namespace Environment { + +class Context_impl : virtual public Context_skel { +protected: + struct ContextEntry { + ContextEntry(const string& name, Object object) + : name(name), object(object) + { + } + ContextEntry(const ContextEntry& entry) + : name(entry.name), object(entry.object) + { + } + string name; + Object object; + }; + list<ContextEntry> entries; + + list<ContextEntry>::iterator findEntry(const string& name) + { + list<ContextEntry>::iterator i = entries.begin(); + for(i = entries.begin(); i != entries.end(); i++) + if(i->name == name) return i; + + return entries.end(); + } + + list<ContextEntry>::iterator findEntry(Object object) + { + list<ContextEntry>::iterator i = entries.begin(); + for(i = entries.begin(); i != entries.end(); i++) + if(object._isEqual(i->object)) return i; + + return entries.end(); + } + + +public: + void addEntry(const string& name, Object object) + { + arts_return_if_fail(findEntry(name) != entries.end()); + entries.push_back(ContextEntry(name, object)); + } + + string lookupEntry(Object object) + { + list<ContextEntry>::iterator i = findEntry(object); + + if(i == entries.end()) + return ""; + else + return i->name; + } + + void removeEntry(Object object) + { + list<ContextEntry>::iterator i = findEntry(object); + + arts_return_if_fail(i != entries.end()); + entries.erase(i); + } +}; +REGISTER_IMPLEMENTATION(Context_impl); +} +} + diff --git a/arts/modules/common/env_effectrackitem_impl.cc b/arts/modules/common/env_effectrackitem_impl.cc new file mode 100644 index 00000000..7872ce42 --- /dev/null +++ b/arts/modules/common/env_effectrackitem_impl.cc @@ -0,0 +1,400 @@ +/* This file is part of the KDE project + Copyright (C) 2002-2003 Matthias Kretz <kretz@kde.org> + 2002 Arnold Krille <arnold@arnoldarts.de> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ +// $Id$ + +#include "artsmodulescommon.h" +#include <debug.h> +#include "env_item_impl.h" +#include <connect.h> +#include <stdio.h> +#include <vector> +#include <map> + + +// Wether you are able to edit the name of the effectrack with an ugly LineInput or not. +//#define EFFECTRACK_NAME +// We should implement something like a ConfigWidget or at least a KLineInputBox or something... + +namespace Arts { +namespace Environment { + +class EffectRackItem_impl : virtual public EffectRackItem_skel, + virtual public Item_impl +{ +protected: + std::string _name; + AudioManagerClient _amClient; + + struct RackWiring { + RackWiring( const std::string & type, AudioManagerClient _amClient ) + : routedtomaster( false ) + , amClient( _amClient ) + { + effect = SubClass( type ); + + connect( input, effect ); + connect( effect, output ); + } + + inline void setName( const std::string & efname ) + { + name = efname; + input.busname( efname ); + if( ! routedtomaster ) + { + output.title( efname ); + output.autoRestoreID( efname ); + } + } + + inline void start() + { + input.start(); + effect.start(); + output.start(); + } + + inline void stop() + { + input.stop(); + effect.stop(); + output.stop(); + } + + inline void master( bool tomaster ) + { + routedtomaster = tomaster; + + output.stop(); + output = tomaster ? Synth_AMAN_PLAY( amClient ) : Synth_AMAN_PLAY(); + connect( effect, output ); + if( ! tomaster ) + { + output.title( name ); + output.autoRestoreID( name ); + } + output.start(); + } + + bool routedtomaster; + std::string name; + std::string effectName; + Synth_BUS_DOWNLINK input; + Arts::StereoEffect effect; + Synth_AMAN_PLAY output; + AudioManagerClient amClient; + }; + std::vector<RackWiring> _wirings; + +public: + EffectRackItem_impl() + : _name( "effect rack" ) + , _amClient( amPlay, _name + " Master", "effectrack_" + _name ) + { + // TODO: check if there's another effect rack with the same name already - if so prefix with 2./3./4. + } + + // readonly attribute sequence<Arts::StereoEffect> effects; + std::vector<Arts::StereoEffect> *effects() + { + std::vector<Arts::StereoEffect> * effects = new std::vector<Arts::StereoEffect>; + for( std::vector<RackWiring>::iterator it = _wirings.begin(); it != _wirings.end(); ++it ) + effects->push_back( it->effect ); + return effects; + } + + // attribute long effectCount; + long effectCount() { return _wirings.size(); } + + // attribute string name; + void name(const std::string& newName) { + if(newName != _name) + { + _name = newName; + _amClient.title( _name + " Master" ); + _amClient.autoRestoreID( "effectrack_" + _name ); + for( unsigned int i = 0; i < _wirings.size(); i++ ) + _wirings[i].setName( effectName( i, _wirings[ i ].effectName ) ); + name_changed( newName ); + } + } + std::string name() { return _name; } + + void loadFromList(const std::vector<std::string>& /*list*/) + { + } + + std::vector<std::string> *saveToList() + { + std::vector<std::string> *result = new std::vector<std::string>; + return result; + } + + std::string effectName( int n, const std::string & en ) + { + char * efname = new char[ _name.length() + en.length() + 128 ]; + sprintf( efname, "%s%02d (%s)", _name.c_str(), n, en.c_str() ); + return efname; + } + + Arts::StereoEffect createEffect( const std::string & type, const std::string & name ) + { + RackWiring wiring( type, _amClient ); + wiring.setName( effectName( _wirings.size() + 1, name ) ); + wiring.start(); + _wirings.push_back( wiring ); + return wiring.effect; + } + + void delEffect( long pos ) + { + _wirings[ pos ].stop(); + _wirings.erase( _wirings.begin() + pos ); + for( unsigned int i = pos; i < _wirings.size(); ++i ) + _wirings[ i ].setName( effectName( i, _wirings[ i ].effectName ) ); + } + + void routeToMaster( long pos, bool tomaster ) + { + _wirings[ pos ].master( tomaster ); + } +}; +REGISTER_IMPLEMENTATION(EffectRackItem_impl); +} + +using namespace Environment; + +typedef WeakReference<VBox> VBox_wref; + +class EffectRackItemGui_impl : virtual public EffectRackItemGui_skel { +private: + bool _active; + long _effectCount; + std::string _type; + EffectRackItem _effectRack; + + /* widgets */ + VBox_wref _widget; + HBox hbox; + VBox effect_vbox; +#ifdef EFFECTRACK_NAME + LineEdit name; +#endif + ComboBox typebox; + Button addbutton; + GenericGuiFactory guiFactory; + std::vector<EffectRackSlot> _slots; + std::map<std::string, std::string> typeforname; + std::map<std::string, std::string> namefortype; + +public: + EffectRackItemGui self() { return EffectRackItemGui::_from_base(_copy()); } + + void redoGui() + { + VBox vbox = _widget; + if(vbox.isNull()) + arts_warning("update with vbox null"); + if(_effectRack.isNull()) + arts_warning("update with _effectRack null"); + if(!_effectRack.isNull() && !vbox.isNull()) + { + vbox.spacing( 0 ); + vbox.margin( 10 ); + hbox = HBox( vbox ); + hbox.spacing( 5 ); + hbox.margin( 0 ); + +#ifdef EFFECTRACK_NAME + name = LineEdit(); + name.caption("name"); + name.text(_effectRack.name()); + name.parent(hbox); + connect(name,"text_changed", _effectRack, "name"); +#endif + + std::vector<std::string> choices; + TraderQuery query; + query.supports( "Interface", "Arts::StereoEffect" ); + query.supports( "Features", "RackGUI" ); + std::vector<TraderOffer> *queryResults = query.query(); + for(std::vector<TraderOffer>::iterator it = queryResults->begin(); it != queryResults->end(); ++it) + { + std::vector<std::string> * names = it->getProperty( "Name" ); + std::string name = names->empty() ? it->interfaceName() : names->front(); + delete names; + choices.push_back( name ); + typeforname[ name ] = it->interfaceName(); + namefortype[ it->interfaceName() ] = name; + } + delete queryResults; + typebox = ComboBox(); + typebox.choices(choices); + typebox.value(_type); + typebox.parent(hbox); + connect(typebox,"value_changed", self(), "type"); + + addbutton = Button( "add", hbox ); + connect( addbutton, "clicked_changed", self(), "addeffect" ); + + effect_vbox = VBox( vbox ); + effect_vbox.margin( 0 ); + effect_vbox.spacing( 5 ); + effect_vbox.show(); + + Frame spacer; + spacer.parent( effect_vbox ); + spacer.vSizePolicy( spExpanding ); + spacer.show(); + effect_vbox._addChild( spacer, "spacer" ); + + _slots.clear(); + + // add Arts::StereoEffect widgets + std::vector<Arts::StereoEffect> * effects = _effectRack.effects(); + for( std::vector<Arts::StereoEffect>::iterator it = effects->begin(); it != effects->end(); ++it ) + createEffectGui( *it ); + delete effects; + } + else + { + /* FIXME: maybe insert a "dead" label here */ + if(!vbox.isNull()) + vbox.show(); + effect_vbox = VBox::null(); + hbox = HBox::null(); + // name = LineEdit::null(); + typebox = ComboBox::null(); + _slots.clear(); + } + } + + void createEffectGui( Arts::StereoEffect effect ) + { + Widget w = guiFactory.createGui( effect ); + if( ! w.isNull() ) + { + // insert effect GUI into the "Rack" + EffectRackSlot slot( effect_vbox, w, self() ); + _slots.push_back( slot ); + } + } + + void removeSlot( EffectRackSlot slot ) + { + unsigned int i; + for( i = 0; i < _slots.size() && ! _slots[ i ]._isEqual( slot ) ; ++i ); + if( i < _slots.size() ) + { + _slots.erase( _slots.begin() + i ); + _effectRack.delEffect( i ); + } + else + arts_warning( "WARNING: Trying to remove an unknown slot" ); + } + + void routeToMaster( EffectRackSlot slot, bool tomaster ) + { + unsigned int i; + for( i = 0; i < _slots.size() && ! _slots[ i ]._isEqual( slot ) ; ++i ); + if( i < _slots.size() ) + _effectRack.routeToMaster( i, tomaster ); + else + arts_warning( "WARNING: Trying to route an unknown slot" ); + } + + bool active() { return _active; } + void active(bool newActive) + { + if(newActive != _active) + { + _active = newActive; + if(!newActive) + _effectRack = EffectRackItem::null(); + redoGui(); + } + } + + std::string type() + { + return _type; + } + void type(const std::string& t) + { + _type = typeforname[ t ]; + } + + bool addeffect() { return false; } //unused + void addeffect( bool clicked ) + { + if( ! addbutton.clicked() || ! clicked ) + return; + + Arts::StereoEffect effect = _effectRack.createEffect( _type, namefortype[ _type ] ); + createEffectGui( effect ); + } + + Widget initialize(EffectRackItem item) + { + VBox vbox; + vbox._addChild(self(),"the_gui_updating_widget"); + + _widget = vbox; + _effectRack = item; + _active = item.active(); + _type = "Arts::Synth_VOICE_REMOVAL"; + _effectCount = item.effectCount(); + + if(!_effectRack.isNull()) + { + connect(_effectRack, "active_changed", self(), "active"); + } + redoGui(); + + return vbox; + } +}; + +REGISTER_IMPLEMENTATION(EffectRackItemGui_impl); + +class EffectRackGuiFactory_impl : virtual public EffectRackGuiFactory_skel +{ +public: + Widget createGui(Object object) + { + arts_return_val_if_fail(!object.isNull(), Arts::Widget::null()); + + std::string iface = object._interfaceName(); + arts_return_val_if_fail(iface == "Arts::Environment::EffectRackItem", + Arts::Widget::null()); + if(iface == "Arts::Environment::EffectRackItem") + { + EffectRackItem effectRack = DynamicCast(object); + arts_return_val_if_fail(!effectRack.isNull(), Arts::Widget::null()); + + EffectRackItemGui gui; + return gui.initialize(effectRack); + } + return Arts::Widget::null(); + } +}; +REGISTER_IMPLEMENTATION(EffectRackGuiFactory_impl); +} +// vim:ts=4:sw=4 diff --git a/arts/modules/common/env_instrumentitem_impl.cc b/arts/modules/common/env_instrumentitem_impl.cc new file mode 100644 index 00000000..17959ca0 --- /dev/null +++ b/arts/modules/common/env_instrumentitem_impl.cc @@ -0,0 +1,113 @@ +#include <vector> +#include "artsmodulescommon.h" +#include "debug.h" +#include "env_item_impl.h" +#include "connect.h" +#include "../runtime/sequenceutils.h" + +namespace Arts { +namespace Environment { + +class InstrumentItem_impl : virtual public InstrumentItem_skel, + virtual public Item_impl +{ +protected: + Synth_MIDI_TEST instrument; + bool running; + +public: + InstrumentItem_impl() : running(false) + { + } + ~InstrumentItem_impl() + { + /* this will allow freeing the instrument */ + if(running) + instrument.stop(); + } + void filename(const std::string& newFilename) + { + if(newFilename != instrument.filename()) + { + instrument.filename(newFilename); + filename_changed(newFilename); + + if(!running) { + instrument.start(); + running = true; + } + } + } + std::string filename() + { + return instrument.filename(); + } + void busname(const std::string& newBusname) + { + if(newBusname != instrument.busname()) + { + instrument.busname(newBusname); + busname_changed(newBusname); + } + } + std::string busname() + { + return instrument.busname(); + } + MidiPort port() + { + return instrument; + } + void loadFromList(const std::vector<std::string>& list) + { + unsigned long i; + std::string cmd,param; + for(i=0;i<list.size();i++) + { + if(parse_line(list[i],cmd,param)) // otherwise: empty or comment + { + if(cmd == "filename") { + filename(param.c_str()); + } + } + } + } + std::vector<std::string> *saveToList() + { + std::vector<std::string> *result = new std::vector<std::string>; + sqprintf(result,"filename=%s",filename().c_str()); + return result; + } +}; +REGISTER_IMPLEMENTATION(InstrumentItem_impl); + +class InstrumentItemGuiFactory_impl + : virtual public InstrumentItemGuiFactory_skel +{ +public: + Widget createGui(Object object) + { + arts_return_val_if_fail(!object.isNull(), Arts::Widget::null()); + + InstrumentItem instrument = DynamicCast(object); + arts_return_val_if_fail(!instrument.isNull(), Arts::Widget::null()); + + Widget panel; + panel.width(150); panel.height(60); panel.show(); + + LineEdit edit; + edit.x(20); edit.y(10); edit.width(120); edit.height(40); + edit.text(instrument.filename()); + edit.parent(panel); + edit.show(); + connect(edit,"text_changed", instrument, "filename"); + panel._addChild(edit,"editWidget"); + + return panel; + } +}; + +REGISTER_IMPLEMENTATION(InstrumentItemGuiFactory_impl); + +} +} diff --git a/arts/modules/common/env_item_impl.cc b/arts/modules/common/env_item_impl.cc new file mode 100644 index 00000000..6bc960d8 --- /dev/null +++ b/arts/modules/common/env_item_impl.cc @@ -0,0 +1,48 @@ +#include "artsmodulescommon.h" +#include "debug.h" +#include "env_item_impl.h" + +using namespace Arts; +using namespace std; + +Environment::Item_impl::Item_impl() + : _active(false) +{ +} + +Environment::Item_impl::~Item_impl() +{ + // Items can't be deleted while they are still inside a Container + arts_assert(_active == false); +} + +Environment::Container Environment::Item_impl::parent() +{ + Container p = _parent; + return p; +} + +void Environment::Item_impl::setContainer(Environment::Container container) +{ + if(container.isNull()) // remove from container + { + arts_return_if_fail(_active == true); + + _parent = container; + _active = false; + } + else // add to container + { + Container p = _parent; + arts_return_if_fail(p.isNull() && _active == false); + + _parent = container; + _active = true; + } + active_changed(_active); +} + +bool Environment::Item_impl::active() +{ + return _active; +} diff --git a/arts/modules/common/env_item_impl.h b/arts/modules/common/env_item_impl.h new file mode 100644 index 00000000..dbdca1f9 --- /dev/null +++ b/arts/modules/common/env_item_impl.h @@ -0,0 +1,28 @@ + +#ifndef env_item_impl_h +#define env_item_impl_h + +#include "artsmodulescommon.h" +#include "weakreference.h" + +namespace Arts { +namespace Environment { +typedef WeakReference<Container> Container_wref; +class Item_impl : virtual public Item_skel { +protected: + Container_wref _parent; + bool _active; + +public: + Item_impl(); + ~Item_impl(); + + bool active(); + Container parent(); + void setContainer(Container container); +}; +} +} + + +#endif diff --git a/arts/modules/common/env_mixeritem_impl.cc b/arts/modules/common/env_mixeritem_impl.cc new file mode 100644 index 00000000..632d8187 --- /dev/null +++ b/arts/modules/common/env_mixeritem_impl.cc @@ -0,0 +1,368 @@ +#include "artsmodulescommon.h" +#include "debug.h" +#include "env_item_impl.h" +#include "connect.h" +#include "../runtime/sequenceutils.h" +#include <stdio.h> +#include <kglobal.h> +#include <klocale.h> + +#include <vector> + +namespace Arts { +namespace Environment { + +class MixerItem_impl : virtual public MixerItem_skel, + virtual public Item_impl +{ +protected: + std::vector<Synth_BUS_DOWNLINK> _inputs; + std::vector<MixerChannel> _channels; + std::vector<Synth_AMAN_PLAY> _outputs; + std::string _name; + std::string _type; + AudioManagerClient amClient; + +public: + MixerItem_impl() + : _name("mixer"), _type("Arts::SimpleMixerChannel"), + amClient(amPlay, "Mixer (mixer)","mixer_mixer") + { + } + // readonly attribute sequence<MixerChannel> channels; + std::vector<MixerChannel> *channels() { + return new std::vector<MixerChannel>(_channels); + } + // attribute long channelCount; + void channelCount(long newChannelCount) + { + if((unsigned long)newChannelCount != _channels.size()) + { + while(_channels.size() < (unsigned long)newChannelCount) addChannel(); + while(_channels.size() > (unsigned long)newChannelCount) delChannel(); + channelCount_changed(newChannelCount); + } + } + long channelCount() { return _channels.size(); } + // attribute string name; + void name(const std::string& newName) { + if(newName != _name) + { + _name = newName; + amClient.title(i18n("Mixer (\"%1\")").arg(QString::fromUtf8(_name.c_str())).utf8().data()); + amClient.autoRestoreID("mixer_"+_name); + for(unsigned int i = 0; i < _inputs.size(); i++) + _inputs[i].busname(channelName(i)); + name_changed(newName); + } + } + std::string name() { return _name; } + // attribute string type; + void type(const std::string& newType) { + if(newType != _type) + { + _type = newType; + type_changed(newType); + } + } + std::string type() { return _type; } + void loadFromList(const std::vector<std::string>& /*list*/) + { + /* + unsigned long i; + std::string cmd,param; + for(i=0;i<list.size();i++) + { + if(parse_line(list[i],cmd,param)) // otherwise: empty or comment + { + if(cmd == "filename") { + filename(param.c_str()); + } + } + } + */ + } + std::vector<std::string> *saveToList() + { + std::vector<std::string> *result = new std::vector<std::string>; + /* + sqprintf(result,"filename=%s",filename().c_str()); + */ + return result; + } + std::string channelName(int n) + { + char chname[1024]; + sprintf(chname, "%s%02d", _name.c_str(), n); + return chname; + } + void addChannel() + { + Synth_BUS_DOWNLINK input; + MixerChannel channel = SubClass(_type); + Synth_AMAN_PLAY output(amClient); + + std::string chname = channelName(_channels.size()+1); + input.busname(chname); + channel.name(chname); + + input.start(); + channel.start(); + output.start(); + + connect(input, channel); + connect(channel, output); + + _inputs.push_back(input); + _channels.push_back(channel); + _outputs.push_back(output); + } + + void delChannel() + { + unsigned long cc = _channels.size()-1; + + _inputs.resize(cc); + _channels.resize(cc); + _outputs.resize(cc); + } +}; +REGISTER_IMPLEMENTATION(MixerItem_impl); +} + +using namespace Environment; + +typedef WeakReference<VBox> VBox_wref; + +class MixerItemGui_impl : virtual public MixerItemGui_skel { +private: + bool _active; + long _channelCount; + std::string _type; + MixerItem _item; + + /* widgets */ + VBox_wref _widget; + HBox hbox, channel_hbox; + SpinBox spinbox; + LineEdit name; + ComboBox typebox; + GenericGuiFactory guiFactory; + std::vector<Widget> channelWidgets; + +public: + MixerItemGui self() { return MixerItemGui::_from_base(_copy()); } + + void updateChannelGui() + { + if(channelWidgets.size() > (unsigned)_item.channelCount()) + channelWidgets.resize(_item.channelCount()); + else + { + std::vector<MixerChannel> *channels = _item.channels(); + for(unsigned int i = channelWidgets.size(); i < channels->size(); ++i) + { + Widget w = guiFactory.createGui((*channels)[i]); + if(!w.isNull()) + { + w.parent(channel_hbox); + w.show(); + channelWidgets.push_back(w); + } + } + } + } + + void redoGui() + { + VBox vbox = _widget; + if(vbox.isNull()) + arts_warning("update with vbox null"); + if(_item.isNull()) + arts_warning("update with _item null"); + if(!_item.isNull() && !vbox.isNull()) + { + hbox = HBox(); + hbox.parent(vbox); + hbox.show(); + + spinbox = SpinBox(); + spinbox.caption(i18n("channels").utf8().data()); + spinbox.min(0); spinbox.max(32); + spinbox.value(_item.channelCount()); + spinbox.parent(hbox); + spinbox.show(); + connect(spinbox,"value_changed", _item, "channelCount"); + + name = LineEdit(); + name.caption(i18n("name").utf8().data()); + name.text(_item.name()); + name.parent(hbox); + name.show(); + connect(name,"text_changed", _item, "name"); + + typebox = ComboBox(); + typebox.caption(i18n("type").utf8().data()); + std::vector<std::string> choices; + TraderQuery query; + query.supports("Interface", "Arts::Environment::MixerChannel"); + std::vector<TraderOffer> *queryResults = query.query(); + for(std::vector<TraderOffer>::iterator it = queryResults->begin(); it != queryResults->end(); ++it) + choices.push_back(it->interfaceName()); + delete queryResults; + typebox.choices(choices); + typebox.value(_type); + typebox.parent(hbox); + typebox.show(); + connect(typebox,"value_changed", _item, "type"); + + channel_hbox = HBox(); + channel_hbox.parent(vbox); + channel_hbox.show(); + + channelWidgets.clear(); + updateChannelGui(); + + vbox.show(); + } + else + { + /* FIXME: maybe insert a "dead" label here */ + if(!vbox.isNull()) + vbox.show(); + channel_hbox = HBox::null(); + hbox = HBox::null(); + spinbox = SpinBox::null(); + name = LineEdit::null(); + typebox = ComboBox::null(); + channelWidgets.clear(); + } + } + + bool active() { return _active; } + void active(bool newActive) + { + if(newActive != _active) + { + _active = newActive; + if(!newActive) + _item = MixerItem::null(); + redoGui(); + } + } + long channelCount() { return _channelCount; } + void channelCount(long ch) + { + if(_channelCount != ch) + { + _channelCount = ch; + updateChannelGui(); + } + } + std::string type() { + return _type; + } + void type(const std::string& t) + { + if(_type != t) + { + _type = t; + //redoGui(); + } + } + Widget initialize(MixerItem item) + { + KGlobal::locale()->insertCatalogue( "artsmodules" ); + VBox vbox; + vbox._addChild(self(),"the_gui_updating_widget"); + + _widget = vbox; + _item = item; + _active = item.active(); + _type = item.type(); + _channelCount = item.channelCount(); + + if(!_item.isNull()) + { + connect(_item, "channelCount_changed", self(), "channelCount"); + connect(_item, "type_changed", self(), "type"); + connect(_item, "active_changed", self(), "active"); + } + redoGui(); + + return vbox; + } +}; + +REGISTER_IMPLEMENTATION(MixerItemGui_impl); + +class MixerGuiFactory_impl : virtual public MixerGuiFactory_skel +{ +public: + Widget createGui(Object object) + { + KGlobal::locale()->insertCatalogue( "artsmodules" ); + arts_return_val_if_fail(!object.isNull(), Arts::Widget::null()); + + std::string iface = object._interfaceName(); + arts_return_val_if_fail(iface == "Arts::Environment::MixerItem", + Arts::Widget::null()); + if(iface == "Arts::Environment::MixerItem") + { + MixerItem mixerItem = DynamicCast(object); + arts_return_val_if_fail(!mixerItem.isNull(), Arts::Widget::null()); + +#if 0 + VBox vbox; + vbox.show(); + vbox.width(330); vbox.height(500); + + HBox hbox; + hbox.show(); + hbox.width(330); hbox.height(50); + hbox.parent(vbox); + vbox._addChild(hbox,"hbox"); + + SpinBox spinbox; + spinbox.caption(i18n("channels").utf8().data()); + spinbox.min(0); spinbox.max(32); + spinbox.value(mixerItem.channelCount()); + spinbox.parent(hbox); + spinbox.show(); + connect(spinbox,"value_changed", mixerItem, "channelCount"); + hbox._addChild(spinbox,"channelsWidget"); + + LineEdit name; + name.caption(i18n("name").utf8().data()); + name.caption(mixerItem.name()); + name.parent(hbox); + name.show(); + connect(name,"caption_changed", mixerItem, "name"); + hbox._addChild(name,"nameWidget"); + + HBox channel_hbox; + channel_hbox.show(); + channel_hbox.width(330); hbox.height(450); + channel_hbox.parent(vbox); + vbox._addChild(channel_hbox,"channel_hbox"); + + GenericGuiFactory gf; + + std::vector<MixerChannel> *channels = mixerItem.channels(); + std::vector<MixerChannel>::iterator i; + for(i = channels->begin(); i != channels->end(); i++) + { + Widget w = gf.createGui(*i); + w.parent(channel_hbox); + channel_hbox._addChild(w,"channel"); + } +#endif + MixerItemGui gui; + return gui.initialize(mixerItem); + } + return Arts::Widget::null(); + } +}; +REGISTER_IMPLEMENTATION(MixerGuiFactory_impl); +} +// vim:ts=4:sw=4 diff --git a/arts/modules/common/mcopclass/Container.mcopclass b/arts/modules/common/mcopclass/Container.mcopclass new file mode 100644 index 00000000..174b8d8d --- /dev/null +++ b/arts/modules/common/mcopclass/Container.mcopclass @@ -0,0 +1,3 @@ +Interface=Arts::Environment::Container,Arts::Object +Language=C++ +Library=libartsmodulescommon.la diff --git a/arts/modules/common/mcopclass/EffectRackGuiFactory.mcopclass b/arts/modules/common/mcopclass/EffectRackGuiFactory.mcopclass new file mode 100644 index 00000000..7ee37168 --- /dev/null +++ b/arts/modules/common/mcopclass/EffectRackGuiFactory.mcopclass @@ -0,0 +1,4 @@ +Interface=Arts::EffectRackGuiFactory,Arts::GuiFactory,Arts::Object +CanCreate=Arts::Environment::EffectRackItem +Language=C++ +Library=libartsmodulescommon.la diff --git a/arts/modules/common/mcopclass/EffectRackItem.mcopclass b/arts/modules/common/mcopclass/EffectRackItem.mcopclass new file mode 100644 index 00000000..700f7b7f --- /dev/null +++ b/arts/modules/common/mcopclass/EffectRackItem.mcopclass @@ -0,0 +1,3 @@ +Interface=Arts::Environment::EffectRackItem,Arts::Environment::Item,Arts::Object +Language=C++ +Library=libartsmodulescommon.la diff --git a/arts/modules/common/mcopclass/InstrumentItem.mcopclass b/arts/modules/common/mcopclass/InstrumentItem.mcopclass new file mode 100644 index 00000000..8d525f8e --- /dev/null +++ b/arts/modules/common/mcopclass/InstrumentItem.mcopclass @@ -0,0 +1,3 @@ +Interface=Arts::Environment::InstrumentItem,Arts::Environment::Item,Arts::Object +Language=C++ +Library=libartsmodulescommon.la diff --git a/arts/modules/common/mcopclass/InstrumentItemGuiFactory.mcopclass b/arts/modules/common/mcopclass/InstrumentItemGuiFactory.mcopclass new file mode 100644 index 00000000..f4ee305b --- /dev/null +++ b/arts/modules/common/mcopclass/InstrumentItemGuiFactory.mcopclass @@ -0,0 +1,4 @@ +Interface=Arts::Environment::InstrumentItemGuiFactory,Arts::GuiFactory,Arts::Object +CanCreate=Arts::Environment::InstrumentItem +Language=C++ +Library=libartsmodulescommon.la diff --git a/arts/modules/common/mcopclass/MixerGuiFactory.mcopclass b/arts/modules/common/mcopclass/MixerGuiFactory.mcopclass new file mode 100644 index 00000000..447e1d47 --- /dev/null +++ b/arts/modules/common/mcopclass/MixerGuiFactory.mcopclass @@ -0,0 +1,4 @@ +Interface=Arts::MixerGuiFactory,Arts::GuiFactory,Arts::Object +CanCreate=Arts::Environment::MixerItem +Language=C++ +Library=libartsmodulescommon.la diff --git a/arts/modules/common/mcopclass/MixerItem.mcopclass b/arts/modules/common/mcopclass/MixerItem.mcopclass new file mode 100644 index 00000000..3ebe4a01 --- /dev/null +++ b/arts/modules/common/mcopclass/MixerItem.mcopclass @@ -0,0 +1,3 @@ +Interface=Arts::Environment::MixerItem,Arts::Environment::Item,Arts::Object +Language=C++ +Library=libartsmodulescommon.la |