From 79905590daee6a57c47e7a2b4c9131f2d11c6d92 Mon Sep 17 00:00:00 2001 From: Paul Giblock Date: Mon, 26 May 2008 06:16:49 +0000 Subject: [PATCH] add class controllerConnection to model link between models and controllers git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1023 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 19 +++ Makefile.am | 3 + include/automatable_model.h | 18 +-- include/automatable_model_templates.h | 31 ++++- include/controller.h | 1 + include/controller_connection.h | 99 ++++++++++++++++ src/core/controller.cpp | 6 +- src/core/controller_connection.cpp | 159 ++++++++++++++++++++++++++ src/core/song.cpp | 11 +- src/gui/widgets/knob.cpp | 6 +- 10 files changed, 334 insertions(+), 19 deletions(-) create mode 100644 include/controller_connection.h create mode 100644 src/core/controller_connection.cpp diff --git a/ChangeLog b/ChangeLog index 953562df7..0cbd99829 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2008-05-26 Paul Giblock + + * include/automatable_model.h: + * include/automatable_model_templates.h: + * include/controller.h: + * include/controller_connection.h: + * src/gui/widgets/knob.cpp: + * src/core/song.cpp: + * src/core/controller.cpp: + * src/core/controller_connection.cpp: + * Makefile.am: + - add controller connection class for storing controller links. Used to + specify linkage for loading/saving as well as a model for all the options + in the dialog (mapping function, smoothing, etc..) + - add dummyController for unfinalized or missing controllers. Faster than + adding a branch to value() or currentValue() + - save controller links to project + - incomplete, experimental, most likely buggy! + 2008-05-25 Tobias Doerffel * plugins/singerbot/singerbot.cpp: diff --git a/Makefile.am b/Makefile.am index 6bbc2fdb8..d6e5e231b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -62,6 +62,7 @@ lmms_MOC = \ ./instrument_track.moc \ ./combobox.moc \ ./controller.moc \ + ./controller_connection.moc \ ./controller_connection_dialog.moc \ ./controller_dialog.moc \ ./controller_rack_view.moc \ @@ -170,6 +171,7 @@ lmms_SOURCES = \ $(srcdir)/src/core/clipboard.cpp \ $(srcdir)/src/core/config_mgr.cpp \ $(srcdir)/src/core/controller.cpp \ + $(srcdir)/src/core/controller_connection.cpp \ $(srcdir)/src/core/drumsynth.cpp \ $(srcdir)/src/core/effect_chain.cpp \ $(srcdir)/src/core/effect.cpp \ @@ -445,6 +447,7 @@ lmms_SOURCES = \ $(srcdir)/include/ladspa_control_view.h \ $(srcdir)/include/ladspa_base.h \ $(srcdir)/include/controller.h \ + $(srcdir)/include/controller_connection.h \ $(srcdir)/include/controller_rack_view.h \ $(srcdir)/include/controller_view.h \ $(srcdir)/include/controller_dialog.h \ diff --git a/include/automatable_model.h b/include/automatable_model.h index 248b41e20..1a61bdaf5 100644 --- a/include/automatable_model.h +++ b/include/automatable_model.h @@ -31,7 +31,7 @@ #include "journalling_object.h" #include "level_object.h" #include "mv_base.h" -#include "controller.h" +#include "controller_connection.h" #include #include @@ -106,26 +106,26 @@ public: inline virtual T value( int _frameOffset = 0 ) const { - if( m_controller != NULL ) + if( m_controllerConnection != NULL ) { return minValue() + castValue( m_range * - m_controller->currentValue( _frameOffset ) ); + m_controllerConnection->currentValue( _frameOffset ) ); } return m_value; } - inline controller * getController( void ) const + inline controllerConnection * getControllerConnection( void ) const { - return m_controller; + return m_controllerConnection; } - inline void setController( controller * _c ) + inline void setControllerConnection( controllerConnection * _c ) { - m_controller = _c; - QObject::connect( m_controller, SIGNAL( valueChanged() ), + m_controllerConnection = _c; + QObject::connect( m_controllerConnection, SIGNAL( valueChanged() ), this, SIGNAL( dataChanged() ) ); } @@ -223,7 +223,7 @@ protected: private: - controller * m_controller; + controllerConnection * m_controllerConnection; T m_value; T m_initValue; T m_minValue; diff --git a/include/automatable_model_templates.h b/include/automatable_model_templates.h index d33c8e1f5..174ebf4ea 100644 --- a/include/automatable_model_templates.h +++ b/include/automatable_model_templates.h @@ -45,7 +45,7 @@ automatableModel::automatableModel( ::model * _parent, bool _default_constructed ) : model( _parent, _default_constructed ), - m_controller( NULL ), + m_controllerConnection( NULL ), m_value( _val ), m_initValue( _val ), m_minValue( _min ), @@ -301,6 +301,24 @@ void automatableModel::saveSettings( QDomDocument & _doc, { _this.setAttribute( _name, value() ); } + + if( m_controllerConnection ) + { + QDomElement controller_element; + QDomNode node = _this.namedItem( "connection" ); + if( node.isElement() ) + { + controller_element = node.toElement(); + } + else + { + controller_element = _doc.createElement( "connection" ); + _this.appendChild( controller_element ); + } + QDomElement element = _doc.createElement( _name ); + m_controllerConnection->saveSettings( _doc, element ); + controller_element.appendChild( element ); + } } @@ -323,6 +341,17 @@ void automatableModel::loadSettings( } } + node = _this.namedItem( "connection" ); + if( node.isElement() ) + { + node = node.namedItem( _name ); + if( node.isElement() ) { + //m_controllerConnection = new controllerConnection( (controller*)NULL ); + setControllerConnection( new controllerConnection( (controller*)NULL ) ); + m_controllerConnection->loadSettings( node.toElement() ); + } + } + setInitValue( attributeValue( _this.attribute( _name ) ) ); } diff --git a/include/controller.h b/include/controller.h index 088e96ed8..deae5369e 100644 --- a/include/controller.h +++ b/include/controller.h @@ -47,6 +47,7 @@ class controller : public model, public journallingObject public: enum ControllerTypes { + DummyController, LfoController, /* MidiController, diff --git a/include/controller_connection.h b/include/controller_connection.h new file mode 100644 index 000000000..50bb5853c --- /dev/null +++ b/include/controller_connection.h @@ -0,0 +1,99 @@ +/* + * controller_connection.h - declaration of a controller connect, which + * provides a definition of the link between a controller and + * model, also handles deferred creation of links while + * loading project + * + * Copyright (c) 2008 Paul Giblock + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#ifndef _CONTROLLER_CONNECTION_H +#define _CONTROLLER_CONNECTION_H + +#include +#include + +#include "engine.h" +#include "controller.h" +#include "mv_base.h" +#include "journalling_object.h" + +class controllerConnection; + +typedef QVector controllerConnectionVector; + +class controllerConnection : public QObject, public journallingObject +{ + Q_OBJECT +public: + + controllerConnection( controller * _controller ); + controllerConnection( int _controllerId ); + + virtual ~controllerConnection(); + + inline controller * getController( void ) + { + return m_controller; + } + + inline void setController( controller * _controller ); + + inline void setController( int _controllerId ); + + float currentValue( int _offset ) + { + return m_controller->currentValue( _offset ); + } + + inline bool isFinalized( void ) + { + return m_controllerId < 0; + } + + static void finalizeConnections( void ); + + virtual void saveSettings( QDomDocument & _doc, QDomElement & _this ); + virtual void loadSettings( const QDomElement & _this ); + virtual QString nodeName( void ) const; + +protected: + //virtual controllerDialog * createDialog( QWidget * _parent ); + + controller * m_controller; + int m_controllerId; + + static controllerConnectionVector s_connections; + + static controller * dummyController(); + static controller * s_dummyController; + + +signals: + // The value changed while the mixer isn't running (i.e: MIDI CC) + void valueChanged( void ); + + friend class controllerConnectionDialog; +}; + +#endif + diff --git a/src/core/controller.cpp b/src/core/controller.cpp index a9368e2d2..ee0e46c85 100644 --- a/src/core/controller.cpp +++ b/src/core/controller.cpp @@ -45,9 +45,11 @@ QVector controller::s_controllers; controller::controller( ControllerTypes _type, model * _parent ) : model( _parent ), + journallingObject(), m_type( _type ) { - s_controllers.append( this ); + if( _type != DummyController ) + s_controllers.append( this ); } @@ -60,6 +62,8 @@ controller::~controller() { engine::getSong()->removeController( this ); } + + // TODO: Remove connections } diff --git a/src/core/controller_connection.cpp b/src/core/controller_connection.cpp new file mode 100644 index 000000000..aebc96ef3 --- /dev/null +++ b/src/core/controller_connection.cpp @@ -0,0 +1,159 @@ +#ifndef SINGLE_SOURCE_COMPILE + +/* + * controller_connection.cpp - implementation of class controller connection + * which handles the link between automatableModels and controllers + * + * Copyright (c) 2008 Paul Giblock + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include + + +#include "song.h" +#include "engine.h" +#include "mixer.h" +#include "controller_connection.h" + + +controllerConnectionVector controllerConnection::s_connections; +controller * controllerConnection::s_dummyController = NULL; + + + +controllerConnection::controllerConnection( controller * _controller ) : + m_controllerId( -1 ) +{ + setController( _controller ); + s_connections.append( this ); +} + + + +controllerConnection::controllerConnection( int _controllerId ) : + m_controller( dummyController() ), + m_controllerId( _controllerId ) +{ + s_connections.append( this ); +} + + + +controllerConnection::~controllerConnection() +{ + s_connections.remove( s_connections.indexOf( this ) ); +} + + + +void controllerConnection::setController( int _controllerId ) +{ +} + + + +void controllerConnection::setController( controller * _controller ) +{ + m_controller = _controller; + m_controllerId = -1; + + if( _controller->type() != controller::DummyController ) { + QObject::connect( _controller, SIGNAL( valueChanged() ), + this, SIGNAL( valueChanged() ) ); + } +} + + + +void controllerConnection::finalizeConnections( void ) +{ + for( int i = 0; i < s_connections.size(); ++i ) + { + controllerConnection * c = s_connections[i]; + if ( !c->isFinalized() ) + { + c->setController( engine::getSong()->controllers().at( c->m_controllerId ) ); + } + } +} + + + +void controllerConnection::saveSettings( QDomDocument & _doc, QDomElement & _this ) +{ + if( engine::getSong() ) { + int id = engine::getSong()->controllers().indexOf( m_controller ); + _this.setAttribute( "id", id ); + } +} + + + +void controllerConnection::loadSettings( const QDomElement & _this ) +{ + if( _this.attribute( "id" ).toInt() >= 0 ) + { + m_controllerId = _this.attribute( "id" ).toInt(); + m_controller = dummyController(); + } + else + { + qWarning( "controller index invalid\n" ); + m_controllerId = -1; + m_controller = dummyController(); + } + +} + + + +controller * controllerConnection::dummyController() +{ + if( s_dummyController == NULL ) + { + s_dummyController = new controller( controller::DummyController, NULL ); + } + return s_dummyController; +} + + + +QString controllerConnection::nodeName( void ) const +{ + return( "connection" ); +} + + +/* +controllerDialog * controller::createDialog( QWidget * _parent ) +{ + controllerDialog * d = new controllerDialog( this, _parent ); + + return d; +} +*/ + +#include "controller_connection.moc" + + +#endif diff --git a/src/core/song.cpp b/src/core/song.cpp index 1a14b2d82..edcf26337 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -49,6 +49,7 @@ #include "bb_track_container.h" #include "config_mgr.h" #include "controller_rack_view.h" +#include "controller_connection.h" #include "embed.h" #include "envelope_and_lfo_parameters.h" #include "export_project_dialog.h" @@ -727,12 +728,6 @@ void song::clearProject( void ) { delete m_controllers.last(); } -/* if( engine::getControllerRackView() ) - { - engine::getControllerRackView()->update(); - }*/ - - emit dataChanged(); engine::getProjectJournal()->clearInvalidJournallingObjects(); engine::getProjectJournal()->clearJournal(); @@ -906,6 +901,10 @@ void FASTCALL song::loadProject( const QString & _file_name ) node = node.nextSibling(); } + // Connect controller links to their controllers + // now that everything is loaded + controllerConnection::finalizeConnections(); + configManager::inst()->addRecentlyOpenedProject( _file_name ); engine::getProjectJournal()->setJournalling( TRUE ); diff --git a/src/gui/widgets/knob.cpp b/src/gui/widgets/knob.cpp index 3625c4696..137eb4f19 100644 --- a/src/gui/widgets/knob.cpp +++ b/src/gui/widgets/knob.cpp @@ -56,6 +56,7 @@ #include "text_float.h" #include "song.h" #include "controller_connection_dialog.h" +#include "controller_connection.h" float knob::s_copiedValue = 0.0f; @@ -737,7 +738,8 @@ void knob::connectToController( void ) if (d->chosenController() != NULL ) { - model()->setController( d->chosenController() ); + model()->setControllerConnection( + new controllerConnection( d->chosenController() ) ); } delete d; @@ -747,7 +749,7 @@ void knob::connectToController( void ) void knob::friendlyUpdate( void ) { - if( model()->getController() == NULL || controller::runningFrames() % (256*4) == 0 ) + if( model()->getControllerConnection() == NULL || controller::runningFrames() % (256*4) == 0 ) { update(); }