From 569a9ddfebcb41167476597b005ee009d9b7391f Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Mon, 26 Jun 2006 21:14:10 +0000 Subject: [PATCH] - added levelObject inheritance and related functions - added time pattern - moved linkObject methods to private for safety - save/load settings can use generic names and types other than double git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@160 0778d3d1-df1d-0410-868b-ea421aaaa00d --- include/automatable_object.h | 227 +++++++++++++++++++++++++++++------ 1 file changed, 193 insertions(+), 34 deletions(-) diff --git a/include/automatable_object.h b/include/automatable_object.h index 7a0bc8d52..52b617b2d 100755 --- a/include/automatable_object.h +++ b/include/automatable_object.h @@ -28,42 +28,60 @@ #include +#include "qt3support.h" #include "journalling_object.h" #include "templates.h" +#include "midi_time.h" +#include "level_object.h" +#include "time_pattern.h" +#include "time_roll.h" #ifndef QT3 #include #include +#include #else #include #include +#include #endif template -class automatableObject : public journallingObject +class automatableObject : public journallingObject, public levelObject { public: typedef automatableObject autoObj; - automatableObject( engine * _engine, const T _val = 0, const T _min = 0, - const T _max = 0, - const T _step = defaultRelStep() ) : + automatableObject( engine * _engine, track * _track = NULL, + const T _val = 0, const T _min = 0, + const T _max = 0, + const T _step = defaultRelStep() ) : journallingObject( _engine ), m_oldValue( _val ), m_value( _val ), m_minValue( _min ), m_maxValue( _max ), - m_step( _step ) + m_step( _step ), + m_curLevel( (int)( _val / _step ) ), + m_time_pattern( NULL ), + m_track( _track ), + m_update_first( TRUE ) { + m_minLevel = level( _min ); + m_maxLevel = level( _max ); } virtual ~automatableObject() { + if( m_time_pattern ) + { + delete m_time_pattern; + } while( m_linkedObjects.empty() == FALSE ) { m_linkedObjects.last()->unlinkObject( this ); @@ -107,6 +125,11 @@ public: return( m_step ); } + inline int curLevel( void ) const + { + return( m_curLevel ); + } + inline T fittedValue( T _value ) { _value = tLimit( _value, minValue(), maxValue() ); @@ -141,6 +164,10 @@ public: { saveJournallingState( FALSE ); setValue( _value ); + if( m_time_pattern ) + { + setFirstValue(); + } restoreJournallingState(); } @@ -151,6 +178,8 @@ public: m_value = fittedValue( _value ); if( old_val != m_value ) { + m_curLevel = level( m_value ); + // add changes to history so user can undo it addJournalEntry( journalEntry( 0, static_cast( m_value ) - @@ -188,11 +217,11 @@ public: { m_minValue = _min; m_maxValue = _max; - setStep( _step ); if( m_minValue > m_maxValue ) { qSwap( m_minValue, m_maxValue ); } + setStep( _step ); // re-adjust value autoObj::setInitValue( value() ); } @@ -224,22 +253,9 @@ public: } }*/ m_step = _step; - } - - inline void linkObject( autoObj * _object ) - { - if( qFind( m_linkedObjects.begin(), m_linkedObjects.end(), - _object ) == m_linkedObjects.end() ) - { - m_linkedObjects.push_back( _object ); - } - } - - inline void unlinkObject( autoObj * _object ) - { - m_linkedObjects.erase( qFind( m_linkedObjects.begin(), - m_linkedObjects.end(), - _object ) ); + m_curLevel = level( m_value ); + m_minLevel = level( m_minValue ); + m_maxLevel = level( m_maxValue ); } static inline void linkObjects( autoObj * _object1, @@ -247,6 +263,64 @@ public: { _object1->linkObject( _object2 ); _object2->linkObject( _object1 ); + + if( _object1->m_time_pattern != _object2->m_time_pattern ) + { + if( _object2->m_time_pattern ) + { + delete _object2->m_time_pattern; + } + _object2->m_time_pattern = _object1->m_time_pattern; + } + } + + virtual void FASTCALL saveSettings( QDomDocument & _doc, + QDomElement & _this, + const QString & _name = "value" ) + { + if( m_time_pattern ) + { + QDomElement pattern_element; + QDomNode node = _this.namedItem( + timePattern::classNodeName() ); + if( node.isElement() ) + { + pattern_element = node.toElement(); + } + else + { + pattern_element = _doc.createElement( + timePattern::classNodeName() ); + _this.appendChild( pattern_element ); + } + QDomElement element = _doc.createElement( _name ); + m_time_pattern->saveSettings( _doc, element ); + pattern_element.appendChild( element ); + } + else + { + _this.setAttribute( _name, value() ); + } + } + + virtual void FASTCALL loadSettings( const QDomElement & _this, + const QString & _name = "value" ) + { + QDomNode node = _this.namedItem( timePattern::classNodeName() ); + if( node.isElement() ) + { + node = node.namedItem( _name ); + if( node.isElement() ) + { + m_time_pattern->loadSettings( + node.toElement() ); + setLevel( m_time_pattern->valueAt( + midiTime( 0 ) ) ); + return; + } + } + + setInitValue( attributeValue( _this.attribute( _name ) ) ); } virtual QString nodeName( void ) const @@ -291,18 +365,6 @@ protected: redoStep( je ); } - virtual void FASTCALL saveSettings( QDomDocument & _doc, - QDomElement & _this ) - { - _this.setAttribute( "value", value() ); - } - - virtual void FASTCALL loadSettings( const QDomElement & _this ) - { - setValue( static_cast( - _this.attribute( "value" ).toDouble() ) ); - } - // most objects will need this temporarily T m_oldValue; @@ -312,18 +374,90 @@ protected: addJournalEntry( journalEntry( 0, value() - m_oldValue ) ); } + inline timePattern * getTimePattern( void ) + { + if( !m_time_pattern ) + { + m_time_pattern = new timePattern( m_track, this ); + syncTimePattern(); + } + return( m_time_pattern ); + } + + inline void setFirstValue( void ) + { + if( m_update_first ) + { + m_time_pattern->putValue( midiTime( 0 ), m_curLevel, + FALSE ); + if( eng()->getTimeRoll()->currentPattern() + == m_time_pattern ) + { + eng()->getTimeRoll()->update(); + } + } + } + private: T m_value; T m_minValue; T m_maxValue; T m_step; + int m_curLevel; + QPointer m_time_pattern; + track * m_track; + bool m_update_first; QVariant m_data; typedef vvector autoObjVector; autoObjVector m_linkedObjects; + inline void linkObject( autoObj * _object ) + { + if( qFind( m_linkedObjects.begin(), m_linkedObjects.end(), + _object ) == m_linkedObjects.end() ) + { + m_linkedObjects.push_back( _object ); + } + } + + inline void unlinkObject( autoObj * _object ) + { + m_linkedObjects.erase( qFind( m_linkedObjects.begin(), + m_linkedObjects.end(), + _object ) ); + } + + static T attributeValue( QString _value ); + + inline void syncTimePattern( void ) + { + for( csize i = 0; i < m_linkedObjects.size(); ++i ) + { + autoObj * it = m_linkedObjects[i]; + if( m_time_pattern != it->m_time_pattern ) + { + it->m_time_pattern = m_time_pattern; + } + } + } + + void setLevel( int _level ) + { + saveJournallingState( FALSE ); + m_update_first = FALSE; + setValue( _level * m_step ); + m_update_first = TRUE; + restoreJournallingState(); + } + + inline int level( T _value ) const + { + return( (int)( _value / m_step ) ); + } + } ; @@ -351,6 +485,31 @@ inline float automatableObject::minEps( void ) +template<> +inline float automatableObject::attributeValue( QString _value ) +{ + return( _value.toFloat() ); +} + + + +template<> +inline int automatableObject::attributeValue( QString _value ) +{ + return( _value.toInt() ); +} + + + +template<> +inline bool automatableObject::attributeValue( + QString _value ) +{ + return( static_cast( _value.toInt() ) ); +} + + + #endif