diff --git a/ChangeLog b/ChangeLog index 0c8a91176..45fb2ef6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,113 @@ +2008-06-23 Tobias Doerffel + + * plugins/ladspa_effect/ladspa_effect.cpp: + * plugins/ladspa_effect/ladspa_controls.cpp: + * plugins/ladspa_effect/ladspa_controls.h: + * plugins/organic/organic.cpp: + * plugins/organic/organic.h: + * plugins/lb302/lb302.cpp: + * plugins/vibed/nine_button_selector.cpp: + * plugins/triple_oscillator/triple_oscillator.h: + * plugins/triple_oscillator/triple_oscillator.cpp: + * plugins/audio_file_processor/audio_file_processor.cpp: + * plugins/stk/mallets/mallets.cpp: + * plugins/kicker/kicker.cpp: + * plugins/midi_import/midi_import.cpp: + * include/effect.h: + * include/meter_model.h: + * include/track.h: + * include/automatable_model.h: + * include/instrument_functions.h: + * include/ladspa_control.h: + * include/audio_port.h: + * include/automation_pattern.h: + * include/effect_view.h: + * include/graph.h: + * include/song.h: + * include/pattern.h: + * include/envelope_and_lfo_parameters.h: + * include/song_editor.h: + * include/journalling_object.h: + * include/automatable_model_view.h: + * include/surround_area.h: + * include/mv_base.h: + * include/controller_view.h: + * include/effect_controls.h: + * include/midi_port.h: + * include/automation_editor.h: + * include/effect_chain.h: + * include/automation_track.h: + * include/track_container.h: + * include/plugin_view.h: + * src/gui/piano_roll.cpp: + * src/gui/track_container_view.cpp: + * src/gui/controller_dialog.cpp: + * src/gui/automatable_model_view.cpp: + * src/gui/effect_control_dialog.cpp: + * src/gui/fx_mixer_view.cpp: + * src/gui/song_editor.cpp: + * src/gui/widgets/ladspa_control_view.cpp: + * src/gui/widgets/graph.cpp: + * src/gui/widgets/combobox.cpp: + * src/gui/widgets/midi_port_menu.cpp: + * src/gui/widgets/controller_rack_view.cpp: + * src/gui/widgets/instrument_sound_shaping_view.cpp: + * src/gui/widgets/envelope_and_lfo_view.cpp: + * src/gui/widgets/knob.cpp: + * src/gui/widgets/instrument_function_views.cpp: + * src/gui/widgets/instrument_midi_io_view.cpp: + * src/gui/widgets/automatable_slider.cpp: + * src/gui/widgets/group_box.cpp: + * src/gui/widgets/lcd_spinbox.cpp: + * src/gui/widgets/controller_view.cpp: + * src/gui/widgets/fader.cpp: + * src/gui/widgets/effect_rack_view.cpp: + * src/gui/widgets/tempo_sync_knob.cpp: + * src/gui/widgets/automatable_button.cpp: + * src/gui/widgets/meter_dialog.cpp: + * src/gui/automation_editor.cpp: + * src/tracks/automation_track.cpp: + * src/tracks/sample_track.cpp: + * src/tracks/bb_track.cpp: + * src/tracks/instrument_track.cpp: + * src/tracks/pattern.cpp: + * src/core/effect_chain.cpp: + * src/core/project_journal.cpp: + * src/core/midi/midi_controller.cpp: + * src/core/midi/midi_port.cpp: + * src/core/note_play_handle.cpp: + * src/core/song.cpp: + * src/core/track_container.cpp: + * src/core/bb_track_container.cpp: + * src/core/journalling_object.cpp: + * src/core/automatable_model.cpp: + * src/core/audio/audio_port.cpp: + * src/core/sample_play_handle.cpp: + * src/core/envelope_and_lfo_parameters.cpp: + * src/core/mmp.cpp: + * src/core/instrument_sound_shaping.cpp: + * src/core/meter_model.cpp: + * src/core/instrument_functions.cpp: + * src/core/track.cpp: + * src/core/ladspa_control.cpp: + * src/core/note.cpp: + * src/core/piano.cpp: + * src/core/surround_area.cpp: + * src/core/mv_base.cpp: + * src/core/automation_pattern.cpp: + * src/core/fx_mixer.cpp: + * data/themes/default/add_automation.png: + - completely new automation-system with automation-tracks and + automation-patterns as well as song-global automation + - made modelView take a QWidget-pointer argument + - trackContentObject-ctor now calls track::addTCO() directly + - optimize various loops to use iterators/const_iterators instead of + a running index variable + - drag'n'drop doesn't fool around with pointers anymore - instead use + unique journalling-IDs + - moved drag'n'drop handling code from knob to automatableModelView so + that all controls can benefit from that + 2008-06-23 Paul Giblock * include/lfo_controller.h: @@ -10,7 +120,8 @@ * data/themes/default/lfo_x1_active.png: * data/themes/default/lfo_x1_inactive.png: Add multiplier to lfo-controller and fix tempo-sync knob. Breaks old - projects that use LFO, but shouldn't matter since 0.4 hasn't been released + projects that use LFO, but shouldn't matter since 0.4 hasn't been + released * src/gui/widgets/tempo_sync_knob.cpp: Allow tempo-sync knob to work with ranges other than [0..1] diff --git a/data/themes/default/add_automation.png b/data/themes/default/add_automation.png new file mode 100644 index 000000000..dac8efe9d Binary files /dev/null and b/data/themes/default/add_automation.png differ diff --git a/include/audio_port.h b/include/audio_port.h index 225493a0b..85e7e7f37 100644 --- a/include/audio_port.h +++ b/include/audio_port.h @@ -36,7 +36,7 @@ class audioPort { public: - audioPort( const QString & _name, track * _track ); + audioPort( const QString & _name ); ~audioPort(); inline sampleFrame * firstBuffer( void ) diff --git a/include/automatable_model.h b/include/automatable_model.h index 97c71d52b..752ed7f08 100644 --- a/include/automatable_model.h +++ b/include/automatable_model.h @@ -32,9 +32,6 @@ #include "mv_base.h" #include "controller_connection.h" -class automationPattern; -class track; - // simple way to map a property of a view to a model #define mapPropertyFromModelPtr(type,getfunc,setfunc,modelname) \ @@ -67,6 +64,8 @@ class EXPORT automatableModel : public model, public journallingObject { Q_OBJECT public: + typedef QVector autoModelVector; + enum DataType { Float, @@ -91,24 +90,7 @@ public: return( __copiedValue ); } - automationPattern * getAutomationPattern( void ); - - inline void setTrack( track * _track ) - { - m_track = _track; - } - - inline bool nullTrack( void ) const - { - return( m_track == NULL ); - } - - inline track * getTrack( void ) const - { - return( m_track ); - } - - void initAutomationPattern( void ); + bool isAutomated( void ) const; inline controllerConnection * getControllerConnection( void ) const { @@ -212,8 +194,6 @@ public: void addJournalEntryFromOldToCurVal( void ); - void syncAutomationPattern( void ); - QString displayValue( const float _val ) const { @@ -249,7 +229,6 @@ public slots: protected: - void setFirstValue( void ); virtual void redoStep( journalEntry & _je ); virtual void undoStep( journalEntry & _je ); @@ -257,6 +236,10 @@ protected: private: + void linkModel( automatableModel * _model ); + void unlinkModel( automatableModel * _model ); + + DataType m_dataType; float m_value; float m_initValue; @@ -270,23 +253,18 @@ private: QString m_displayName; bool m_journalEntryReady; - typedef QVector autoModelVector; autoModelVector m_linkedModels; - void linkModel( automatableModel * _model ); - - void unlinkModel( automatableModel * _model ); - - - controllerConnection * m_controllerConnection; - automationPattern * m_automationPattern; - track * m_track; static float __copiedValue; + +signals: + void initValueChanged( float _val ); + } ; diff --git a/include/automatable_model_view.h b/include/automatable_model_view.h index 39e6ca6e6..9138efd67 100644 --- a/include/automatable_model_view.h +++ b/include/automatable_model_view.h @@ -37,12 +37,8 @@ class QMenu; class EXPORT automatableModelView : public modelView { public: - automatableModelView( ::model * _model ) : - modelView( _model ), - m_description( QString::null ), - m_unit( QString::null ) - { - } + automatableModelView( ::model * _model, QWidget * _this ); + virtual ~automatableModelView(); // some basic functions for convenience automatableModel * modelUntyped( void ) @@ -86,6 +82,8 @@ public: protected: + virtual void mousePressEvent( QMouseEvent * _ev ); + QString m_description; QString m_unit; @@ -105,6 +103,8 @@ public: public slots: void execConnectionDialog( void ); void removeConnection( void ); + void editSongGlobalAutomation( void ); + protected: automatableModelView * amv; @@ -115,23 +115,23 @@ protected: #define generateTypedModelView(type) \ -class EXPORT type##ModelView : public automatableModelView \ -{\ -public:\ - type##ModelView( ::model * _model ) :\ - automatableModelView( _model )\ - {\ - }\ -\ - type##Model * model( void )\ - {\ - return( castModel() );\ - }\ -\ - const type##Model * model( void ) const\ - {\ - return( castModel() );\ - }\ +class EXPORT type##ModelView : public automatableModelView \ +{ \ +public: \ + type##ModelView( ::model * _model, QWidget * _this ) : \ + automatableModelView( _model, _this ) \ + { \ + } \ + \ + type##Model * model( void ) \ + { \ + return( castModel() ); \ + } \ + \ + const type##Model * model( void ) const \ + { \ + return( castModel() ); \ + } \ } ; diff --git a/include/automation_editor.h b/include/automation_editor.h index 12d4a2f87..9bb559ff8 100644 --- a/include/automation_editor.h +++ b/include/automation_editor.h @@ -33,13 +33,14 @@ #include "journalling_object.h" #include "midi_time.h" #include "automation_pattern.h" -#include "combobox.h" +#include "combobox_model.h" class QPainter; class QPixmap; class QScrollBar; +class comboBox; class notePlayHandle; class timeLine; class toolButton; diff --git a/include/automation_pattern.h b/include/automation_pattern.h index 965dc0518..f1051627a 100644 --- a/include/automation_pattern.h +++ b/include/automation_pattern.h @@ -2,6 +2,7 @@ * automation_pattern.h - declaration of class automationPattern, which contains * all information about an automation pattern * + * Copyright (c) 2008 Tobias Doerffel * Copyright (c) 2006-2008 Javier Serrano Polo * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -27,30 +28,30 @@ #ifndef _AUTOMATION_PATTERN_H #define _AUTOMATION_PATTERN_H -#include +#include -#include "journalling_object.h" +#include "track.h" -class automatableModel; +class automationTrack; class midiTime; -class track; -class EXPORT automationPattern : public QObject, public journallingObject +class EXPORT automationPattern : public trackContentObject { Q_OBJECT public: typedef QMap timeMap; + typedef QVector > objectVector; - automationPattern( track * _track, automatableModel * _object ); + automationPattern( automationTrack * _auto_track ); automationPattern( const automationPattern & _pat_to_copy ); - automationPattern( const automationPattern & _pat_to_copy, - automatableModel * _object ); virtual ~automationPattern(); + const automatableModel * firstObject( void ); + virtual midiTime length( void ) const; midiTime putValue( const midiTime & _time, const float _value, @@ -60,7 +61,7 @@ public: inline timeMap & getTimeMap( void ) { - return( m_time_map ); + return( m_timeMap ); } float valueAt( const midiTime & _time ); @@ -73,7 +74,7 @@ public: static inline const QString classNodeName( void ) { - return( "automation-pattern" ); + return( "automationpattern" ); } inline virtual QString nodeName( void ) const @@ -81,37 +82,25 @@ public: return( classNodeName() ); } - inline const track * getTrack( void ) const - { - return( m_track ); - } - - inline const automatableModel * object( void ) const - { - return( m_object ); - } - - inline automatableModel * object( void ) - { - return( m_object ); - } - void processMidiTime( const midiTime & _time ); inline bool updateFirst( void ) const { - return( m_update_first ); + return( m_updateFirst ); } inline void setUpdateFirst( bool _update ) { - m_update_first = _update; + m_updateFirst = _update; } - void forgetTrack( void ) - { - m_track = NULL; - } + virtual trackContentObjectView * createView( trackView * _tv ); + + + static bool isAutomated( const automatableModel * _m ); + static automationPattern * globalAutomationPattern( + automatableModel * _m ); + static void resolveAllIDs( void ); public slots: @@ -120,15 +109,57 @@ public slots: private: - track * m_track; - automatableModel * m_object; - timeMap m_time_map; - bool m_update_first; - bool m_dynamic; + automationTrack * m_autoTrack; + QVector m_idsToResolve; + objectVector m_objects; + timeMap m_timeMap; // actual values + bool m_updateFirst; // init-value set? + bool m_dynamic; // more than 1 value? + + + friend class automationPatternView; } ; +class automationPatternView : public trackContentObjectView +{ + Q_OBJECT +public: + automationPatternView( automationPattern * _pat, trackView * _parent ); + virtual ~automationPatternView(); + + +public slots: + virtual void update( void ); + + +protected slots: + void resetName( void ); + void changeName( void ); + + +protected: + virtual void constructContextMenu( QMenu * ); + virtual void mouseDoubleClickEvent( QMouseEvent * _me ); + virtual void paintEvent( QPaintEvent * _pe ); + virtual void resizeEvent( QResizeEvent * _re ) + { + m_needsUpdate = TRUE; + trackContentObjectView::resizeEvent( _re ); + } + virtual void dragEnterEvent( QDragEnterEvent * _dee ); + virtual void dropEvent( QDropEvent * _de ); + + +private: + automationPattern * m_pat; + QPixmap m_paintPixmap; + bool m_needsUpdate; + +} ; + + #endif diff --git a/include/automation_track.h b/include/automation_track.h index 2f97a2391..9991eca0d 100644 --- a/include/automation_track.h +++ b/include/automation_track.h @@ -2,6 +2,7 @@ * automation_track.h - declaration of class automationTrack, which handles * automation of objects without a track * + * Copyright (c) 2008 Tobias Doerffel * Copyright (c) 2006-2008 Javier Serrano Polo * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -30,10 +31,13 @@ #include "track.h" +class nameLabel; + + class automationTrack : public track { public: - automationTrack( trackContainer * _tc ); + automationTrack( trackContainer * _tc, bool _hidden = FALSE ); virtual ~automationTrack(); virtual bool play( const midiTime & _start, const fpp_t _frames, @@ -45,17 +49,35 @@ public: return( "automationtrack" ); } - virtual trackView * createView( trackContainerView * ) - { - return( NULL ); - } + virtual trackView * createView( trackContainerView * ); virtual trackContentObject * createTCO( const midiTime & _pos ); virtual void saveTrackSpecificSettings( QDomDocument & _doc, QDomElement & _parent ); virtual void loadTrackSpecificSettings( const QDomElement & _this ); +private: + friend class automationTrackView; + } ; + +class automationTrackView : public trackView +{ +public: + automationTrackView( automationTrack * _at, trackContainerView * _tcv ); + virtual ~automationTrackView(); + + +private: + bbTrack * m_bbTrack; + nameLabel * m_trackLabel; + +} ; + + + + + #endif diff --git a/include/controller_view.h b/include/controller_view.h index e9200f3d9..57e00a6e9 100644 --- a/include/controller_view.h +++ b/include/controller_view.h @@ -36,11 +36,7 @@ class QLabel; class QPushButton; class QMdiSubWindow; -//class controllerControlDialog; -//class knob; class ledCheckBox; -//class tempoSyncKnob; -//class track; class controllerView : public QWidget, public modelView @@ -50,7 +46,7 @@ public: controllerView( controller * _controller, QWidget * _parent ); virtual ~controllerView(); - inline controller * getController( void ) + inline controller * getController( void ) { return( castModel() ); } diff --git a/include/effect.h b/include/effect.h index 4692624ad..25f176b2c 100644 --- a/include/effect.h +++ b/include/effect.h @@ -38,7 +38,6 @@ class effectChain; class effectControls; -class track; class EXPORT effect : public plugin diff --git a/include/effect_chain.h b/include/effect_chain.h index cd831f1c4..02d1f4efc 100644 --- a/include/effect_chain.h +++ b/include/effect_chain.h @@ -37,7 +37,7 @@ class effect; class effectChain : public journallingObject, public model { public: - effectChain( track * _track ); + effectChain( model * _parent ); virtual ~effectChain(); virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); @@ -58,18 +58,11 @@ public: void clear( void ); - track * getTrack( void ) - { - return( m_track ); - } - private: typedef QVector effectList; effectList m_effects; - track * m_track; - boolModel m_enabledModel; diff --git a/include/effect_controls.h b/include/effect_controls.h index c1fc72be0..28cf35bc4 100644 --- a/include/effect_controls.h +++ b/include/effect_controls.h @@ -30,7 +30,6 @@ #include "effect.h" -class track; class effectControlDialog; diff --git a/include/effect_view.h b/include/effect_view.h index c423a4d00..99c42ad8a 100644 --- a/include/effect_view.h +++ b/include/effect_view.h @@ -40,7 +40,6 @@ class effectControlDialog; class knob; class ledCheckBox; class tempoSyncKnob; -class track; class effectView : public pluginView diff --git a/include/envelope_and_lfo_parameters.h b/include/envelope_and_lfo_parameters.h index b18a6d030..cf8673e19 100644 --- a/include/envelope_and_lfo_parameters.h +++ b/include/envelope_and_lfo_parameters.h @@ -35,16 +35,12 @@ #include "types.h" -class track; - - class EXPORT envelopeAndLFOParameters : public model, public journallingObject { Q_OBJECT public: envelopeAndLFOParameters( float _value_for_zero_amount, - track * _track, model * _parent ); virtual ~envelopeAndLFOParameters(); diff --git a/include/graph.h b/include/graph.h index aa8cd6369..49cb551e5 100644 --- a/include/graph.h +++ b/include/graph.h @@ -35,7 +35,7 @@ #include "types.h" class graphModel; -class track; + class EXPORT graph : public QWidget, public modelView { @@ -106,7 +106,7 @@ public: graphModel( float _min, float _max, Uint32 _size, - :: model * _parent, track * _track = NULL, + :: model * _parent, bool _default_constructed = FALSE ); virtual ~graphModel(); diff --git a/include/instrument_functions.h b/include/instrument_functions.h index 7958a67d8..acb3f042f 100644 --- a/include/instrument_functions.h +++ b/include/instrument_functions.h @@ -44,7 +44,7 @@ class chordCreator : public model, public journallingObject { Q_OBJECT public: - chordCreator( instrumentTrack * _instrument_track ); + chordCreator( model * _parent ); virtual ~chordCreator(); void processNote( notePlayHandle * _n ); @@ -103,7 +103,7 @@ public: NumArpDirections } ; - arpeggiator( instrumentTrack * _instrument_track ); + arpeggiator( model * _parent ); virtual ~arpeggiator(); void processNote( notePlayHandle * _n ); diff --git a/include/journalling_object.h b/include/journalling_object.h index c726243f6..49d848d1e 100644 --- a/include/journalling_object.h +++ b/include/journalling_object.h @@ -152,6 +152,8 @@ public: protected: + void changeID( jo_id_t _id ); + void addJournalEntry( const journalEntry & _je ); // to be implemented by sub-objects diff --git a/include/ladspa_control.h b/include/ladspa_control.h index a9027bc29..d90793eed 100644 --- a/include/ladspa_control.h +++ b/include/ladspa_control.h @@ -1,6 +1,7 @@ /* * ladspa_control.h - model for controlling a LADSPA port * + * Copyright (c) 2008 Tobias Doerffel * Copyright (c) 2006-2008 Danny McRae * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -39,8 +40,6 @@ #include "tempo_sync_knob.h" -class track; - typedef struct portDescription port_desc_t; @@ -49,7 +48,7 @@ class EXPORT ladspaControl : public model, public journallingObject { Q_OBJECT public: - ladspaControl( model * _parent, port_desc_t * _port, track * _track, + ladspaControl( model * _parent, port_desc_t * _port, bool _link = FALSE ); ~ladspaControl(); diff --git a/include/meter_model.h b/include/meter_model.h index 5c4182a99..ee3bd153a 100644 --- a/include/meter_model.h +++ b/include/meter_model.h @@ -34,7 +34,7 @@ class meterModel : public model mapPropertyFromModel(int,getNumerator,setNumerator,m_numeratorModel); mapPropertyFromModel(int,getDenominator,setDenominator,m_denominatorModel); public: - meterModel( ::model * _parent, track * _track ); + meterModel( ::model * _parent ); ~meterModel(); void saveSettings( QDomDocument & _doc, QDomElement & _this, diff --git a/include/midi_port.h b/include/midi_port.h index e3a0ca10d..46d78d29a 100644 --- a/include/midi_port.h +++ b/include/midi_port.h @@ -70,7 +70,6 @@ public: midiClient * _mc, midiEventProcessor * _mep, model * _parent = NULL, - track * _track = NULL, Modes _mode = Disabled ); virtual ~midiPort(); diff --git a/include/mv_base.h b/include/mv_base.h index 72be47a7e..c9e13e2df 100644 --- a/include/mv_base.h +++ b/include/mv_base.h @@ -90,7 +90,7 @@ signals: class EXPORT modelView { public: - modelView( model * _model ); + modelView( model * _model, QWidget * _this ); virtual ~modelView() { } @@ -116,10 +116,16 @@ protected: { } + QWidget * widget( void ) + { + return( m_widget ); + } + virtual void doConnections( void ); private: + QWidget * m_widget; model * m_model; } ; diff --git a/include/pattern.h b/include/pattern.h index 6ff0507a8..5bb7d5f74 100644 --- a/include/pattern.h +++ b/include/pattern.h @@ -48,8 +48,6 @@ class sampleBuffer; - - class EXPORT pattern : public trackContentObject { Q_OBJECT @@ -78,7 +76,7 @@ public: const bool _quant_pos = TRUE ); void clearNotes( void ); - + inline const noteVector & notes( void ) { return( m_notes ); @@ -111,7 +109,7 @@ public: { return( m_freezing ); } - + inline bool frozen( void ) const { return( m_frozenPattern != NULL ); @@ -197,7 +195,6 @@ public slots: protected slots: - void openInPianoRoll( bool _c ); void openInPianoRoll( void ); void resetName( void ); diff --git a/include/plugin_view.h b/include/plugin_view.h index aeb794d52..201bfc6a0 100644 --- a/include/plugin_view.h +++ b/include/plugin_view.h @@ -36,7 +36,7 @@ class EXPORT pluginView : public QWidget, public modelView public: pluginView( plugin * _plugin, QWidget * _parent ) : QWidget( _parent ), - modelView( _plugin ) + modelView( _plugin, this ) { } diff --git a/include/song.h b/include/song.h index fbc07ff24..ff508579a 100644 --- a/include/song.h +++ b/include/song.h @@ -36,6 +36,7 @@ #include "meter_model.h" +class automationTrack; class pattern; class timeLine; @@ -139,9 +140,9 @@ public: bpm_t getTempo( void ); virtual automationPattern * tempoAutomationPattern( void ); - track * getAutomationTrack( void ) + automationTrack * globalAutomationTrack( void ) { - return( m_automationTrack ); + return( m_globalAutomationTrack ); } // file management @@ -215,6 +216,7 @@ private slots: void removeBar( void ); void addBBTrack( void ); void addSampleTrack( void ); + void addAutomationTrack( void ); void setTempo( void ); void setTimeSignature( void ); @@ -255,7 +257,7 @@ private: void restoreControllerStates( const QDomElement & _this ); - track * m_automationTrack; + automationTrack * m_globalAutomationTrack; lcdSpinBoxModel m_tempoModel; meterModel m_timeSigModel; diff --git a/include/song_editor.h b/include/song_editor.h index 23efceed7..ef981c31c 100644 --- a/include/song_editor.h +++ b/include/song_editor.h @@ -107,7 +107,7 @@ private: toolButton * m_addBBTrackButton; toolButton * m_addSampleTrackButton; - toolButton * m_addControllerButton; + toolButton * m_addAutomationTrackButton; toolButton * m_drawModeButton; toolButton * m_editModeButton; diff --git a/include/surround_area.h b/include/surround_area.h index 25f8a2f83..7a3ad3c09 100644 --- a/include/surround_area.h +++ b/include/surround_area.h @@ -36,7 +36,6 @@ class QPixmap; class knob; -class track; const int SURROUND_AREA_SIZE = 1024; @@ -48,7 +47,7 @@ class surroundAreaModel : public model mapPropertyFromModel(int,x,setX,m_posX); mapPropertyFromModel(int,y,setY,m_posY); public: - surroundAreaModel( ::model * _parent, track * _track = NULL, + surroundAreaModel( ::model * _parent, bool _default_constructed = FALSE ); surroundVolumeVector getVolumeVector( float _v_scale ) const; @@ -70,8 +69,8 @@ public: m_posY.addJournalEntryFromOldToCurVal(); } - automationPattern * automationPatternX( void ); - automationPattern * automationPatternY( void ); +// automationPattern * automationPatternX( void ); +// automationPattern * automationPatternY( void ); private: diff --git a/include/track.h b/include/track.h index a58af5913..bb88af7d4 100644 --- a/include/track.h +++ b/include/track.h @@ -41,7 +41,6 @@ class QMenu; class QPushButton; -class automationPattern; class bbTrack; class pixmapButton; class pixmapLoader; @@ -290,17 +289,11 @@ protected: private slots: void cloneTrack( void ); - void disableAutomation( void ); - void enableAutomation( void ); void removeTrack( void ); void updateMenu( void ); private: - bbTrack * currentBBTrack( void ); - bool inBBEditor( void ); - - static QPixmap * s_grip; static QPixmap * s_muteOffDisabled; static QPixmap * s_muteOffEnabled; @@ -313,13 +306,9 @@ private: pixmapButton * m_muteBtn; pixmapButton * m_soloBtn; - bool m_automationDisabled; - - friend class trackView; - signals: void trackRemovalScheduled( trackView * _t ); @@ -335,6 +324,8 @@ class EXPORT track : public model, public journallingObject Q_OBJECT mapPropertyFromModel(bool,isMuted,setMuted,m_mutedModel); public: + typedef QVector tcoVector; + enum TrackTypes { InstrumentTrack, @@ -343,6 +334,7 @@ public: EventTrack, VideoTrack, AutomationTrack, + HiddenAutomationTrack, NumTrackTypes } ; @@ -387,24 +379,26 @@ public: trackContentObject * getTCO( int _tco_num ); int getTCONum( trackContentObject * _tco ); - void getTCOsInRange( QList & _tco_v, - const midiTime & _start, + const tcoVector & getTCOs( void ) const + { + return( m_trackContentObjects ); + } + void getTCOsInRange( tcoVector & _tco_v, const midiTime & _start, const midiTime & _end ); void swapPositionOfTCOs( int _tco_num1, int _tco_num2 ); + void insertTact( const midiTime & _pos ); void removeTact( const midiTime & _pos ); tact length( void ) const; + inline trackContainer * getTrackContainer( void ) const { return( m_trackContainer ); } - void addAutomationPattern( automationPattern * _pattern ); - void removeAutomationPattern( automationPattern * _pattern ); - // name-stuff virtual const QString & name( void ) const { @@ -428,10 +422,6 @@ public slots: void toggleSolo( void ); -protected: - void sendMidiTime( const midiTime & _time ); - - private: trackContainer * m_trackContainer; TrackTypes m_type; @@ -443,11 +433,8 @@ private: bool m_mutedBeforeSolo; - typedef QVector tcoVector; tcoVector m_trackContentObjects; - QList m_automationPatterns; - friend class trackView; diff --git a/include/track_container.h b/include/track_container.h index df887796b..42a9dc766 100644 --- a/include/track_container.h +++ b/include/track_container.h @@ -31,15 +31,16 @@ #include "journalling_object.h" -class trackContainerView; +class automationPattern; class instrumentTrack; +class trackContainerView; class EXPORT trackContainer : public model, public journallingObject { Q_OBJECT public: - typedef QList trackList; + typedef QVector trackList; trackContainer( void ); virtual ~trackContainer(); @@ -63,6 +64,11 @@ public: void clearAllTracks( void ); + trackList & tracks( void ) + { + return( m_tracks ); + } + const trackList & tracks( void ) const { return( m_tracks ); diff --git a/plugins/audio_file_processor/audio_file_processor.cpp b/plugins/audio_file_processor/audio_file_processor.cpp index d185bc6c3..74254525d 100644 --- a/plugins/audio_file_processor/audio_file_processor.cpp +++ b/plugins/audio_file_processor/audio_file_processor.cpp @@ -86,11 +86,6 @@ audioFileProcessor::audioFileProcessor( instrumentTrack * _instrument_track ) : this, SLOT( startPointModelChanged() ) ); connect( &m_endPointModel, SIGNAL( dataChanged() ), this, SLOT( endPointModelChanged() ) ); - m_ampModel.setTrack( _instrument_track ); - m_startPointModel.setTrack( _instrument_track ); - m_endPointModel.setTrack( _instrument_track ); - m_reverseModel.setTrack( _instrument_track ); - m_loopModel.setTrack( _instrument_track ); } diff --git a/plugins/kicker/kicker.cpp b/plugins/kicker/kicker.cpp index 3f61dde3e..fed097846 100644 --- a/plugins/kicker/kicker.cpp +++ b/plugins/kicker/kicker.cpp @@ -64,11 +64,6 @@ kickerInstrument::kickerInstrument( instrumentTrack * _instrument_track ) : m_distModel( 0.8f, 0.0f, 100.0f, 0.1f, this, tr( "Distortion" ) ), m_gainModel( 1.0f, 0.1f, 5.0f, 0.05f, this, tr( "Gain" ) ) { - m_startFreqModel.setTrack( _instrument_track ); - m_endFreqModel.setTrack( _instrument_track ); - m_decayModel.setTrack( _instrument_track ); - m_distModel.setTrack( _instrument_track ); - m_gainModel.setTrack( _instrument_track ); } diff --git a/plugins/ladspa_effect/ladspa_controls.cpp b/plugins/ladspa_effect/ladspa_controls.cpp index bb26ae51b..0a12bc59e 100644 --- a/plugins/ladspa_effect/ladspa_controls.cpp +++ b/plugins/ladspa_effect/ladspa_controls.cpp @@ -27,12 +27,10 @@ #include "ladspa_effect.h" -ladspaControls::ladspaControls( ladspaEffect * _eff, - track * _track ) : +ladspaControls::ladspaControls( ladspaEffect * _eff ) : effectControls( _eff ), m_effect( _eff ), m_processors( _eff->getProcessorCount() ), - m_track( _track ), m_noLink( FALSE ), m_stereoLinkModel( TRUE, this ) { @@ -52,7 +50,6 @@ ladspaControls::ladspaControls( ladspaEffect * _eff, if( (*it)->proc == proc ) { (*it)->control = new ladspaControl( this, *it, - m_track, linked_control ); last_port = (*it)->data_type; diff --git a/plugins/ladspa_effect/ladspa_controls.h b/plugins/ladspa_effect/ladspa_controls.h index 72baf8f75..2c882f919 100644 --- a/plugins/ladspa_effect/ladspa_controls.h +++ b/plugins/ladspa_effect/ladspa_controls.h @@ -39,7 +39,7 @@ class ladspaControls : public effectControls { Q_OBJECT public: - ladspaControls( ladspaEffect * _eff, track * _track ); + ladspaControls( ladspaEffect * _eff ); virtual ~ladspaControls(); inline int getControlCount( void ) @@ -69,7 +69,6 @@ private: ladspaEffect * m_effect; ch_cnt_t m_processors; ch_cnt_t m_controlCount; - track * m_track; bool m_noLink; boolModel m_stereoLinkModel; QVector m_controls; diff --git a/plugins/ladspa_effect/ladspa_effect.cpp b/plugins/ladspa_effect/ladspa_effect.cpp index c03f3527c..52f2f1e29 100644 --- a/plugins/ladspa_effect/ladspa_effect.cpp +++ b/plugins/ladspa_effect/ladspa_effect.cpp @@ -488,10 +488,7 @@ void ladspaEffect::pluginInstantiation( void ) { manager->activate( m_key, m_handles[proc] ); } - track * t = dynamic_cast( parent() ) ? - dynamic_cast( parent() )->getTrack() : - NULL; - m_controls = new ladspaControls( this, t ); + m_controls = new ladspaControls( this ); } diff --git a/plugins/lb302/lb302.cpp b/plugins/lb302/lb302.cpp index c2d28a081..7c9ce7174 100644 --- a/plugins/lb302/lb302.cpp +++ b/plugins/lb302/lb302.cpp @@ -362,22 +362,6 @@ lb302Synth::lb302Synth( instrumentTrack * _instrumentTrack ) : connect( &wave_knob, SIGNAL( dataChanged( ) ), this, SLOT ( waveChanged( ))); - vcf_cut_knob.setTrack( _instrumentTrack ); - vcf_res_knob.setTrack( _instrumentTrack ); - vcf_mod_knob.setTrack( _instrumentTrack ); - vcf_dec_knob.setTrack( _instrumentTrack ); - - vco_fine_detune_knob.setTrack( _instrumentTrack ); - - dist_knob.setTrack( _instrumentTrack ); - wave_knob.setTrack( _instrumentTrack ); - slide_dec_knob.setTrack( _instrumentTrack ); - - slideToggle.setTrack( _instrumentTrack ); - accentToggle.setTrack( _instrumentTrack ); - deadToggle.setTrack( _instrumentTrack ); - db24Toggle.setTrack( _instrumentTrack ); - // SYNTH diff --git a/plugins/midi_import/midi_import.cpp b/plugins/midi_import/midi_import.cpp index adfc7b11f..87077ffef 100644 --- a/plugins/midi_import/midi_import.cpp +++ b/plugins/midi_import/midi_import.cpp @@ -182,7 +182,8 @@ invalid_format: automationPattern * tap = _tc->tempoAutomationPattern(); if( tap != NULL ) { - tap->object()->setValue( 120 ); +#warning BLAH +// tap->firstObject()->setValue( 120 ); tap->putValue( 0, 120 ); } diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp index 415f6f7de..827d57c72 100644 --- a/plugins/organic/organic.cpp +++ b/plugins/organic/organic.cpp @@ -73,8 +73,8 @@ QPixmap * organicInstrumentView::s_artwork = NULL; ***********************************************************************/ -organicInstrument::organicInstrument( instrumentTrack * _channel_track ) : - instrument( _channel_track, &organic_plugin_descriptor ), +organicInstrument::organicInstrument( instrumentTrack * _instrument_track ) : + instrument( _instrument_track, &organic_plugin_descriptor ), m_modulationAlgo( oscillator::SignalMix ), m_fx1Model( 0.0f, 0.0f, 0.99f, 0.01f , this, tr( "Distortion" ) ), m_volModel( 100.0f, 0.0f, 200.0f, 1.0f, this, tr( "Volume" ) ) @@ -84,7 +84,7 @@ organicInstrument::organicInstrument( instrumentTrack * _channel_track ) : m_osc = new oscillatorObject*[ m_numOscillators ]; for (int i=0; i < m_numOscillators; i++) { - m_osc[i] = new oscillatorObject( this, _channel_track, i ); + m_osc[i] = new oscillatorObject( this, i ); m_osc[i]->m_numOscillators = m_numOscillators; // Connect events @@ -97,11 +97,6 @@ organicInstrument::organicInstrument( instrumentTrack * _channel_track ) : connect( &m_osc[i]->m_detuneModel, SIGNAL( dataChanged() ), m_osc[i], SLOT( updateDetuning() ) ); - m_osc[i]->m_oscModel.setTrack( _channel_track ); - m_osc[i]->m_volModel.setTrack( _channel_track ); - m_osc[i]->m_panModel.setTrack( _channel_track ); - m_osc[i]->m_detuneModel.setTrack( _channel_track ); - m_osc[i]->updateVolume(); } @@ -498,7 +493,7 @@ void organicInstrumentView::modelChanged( void ) -oscillatorObject::oscillatorObject( model * _parent, track * _track, int _index ) : +oscillatorObject::oscillatorObject( model * _parent, int _index ) : model( _parent ), m_waveShape( oscillator::SineWave, 0, oscillator::NumWaveShapes-1, this ), m_oscModel( 0.0f, 0.0f, 5.0f, 1.0f, diff --git a/plugins/organic/organic.h b/plugins/organic/organic.h index 023d9f0a7..2c55783c3 100644 --- a/plugins/organic/organic.h +++ b/plugins/organic/organic.h @@ -60,7 +60,7 @@ private: float m_phaseOffsetLeft; float m_phaseOffsetRight; - oscillatorObject( model * _parent, track * _track, int _index ); + oscillatorObject( model * _parent, int _index ); virtual ~oscillatorObject(); friend class organicInstrument; @@ -79,7 +79,7 @@ class organicInstrument : public instrument { Q_OBJECT public: - organicInstrument( instrumentTrack * _channel_track ); + organicInstrument( instrumentTrack * _instrument_track ); virtual ~organicInstrument(); virtual void playNote( notePlayHandle * _n, bool _try_parallelizing, diff --git a/plugins/stk/mallets/mallets.cpp b/plugins/stk/mallets/mallets.cpp index 55191f3f2..57e3cd07a 100644 --- a/plugins/stk/mallets/mallets.cpp +++ b/plugins/stk/mallets/mallets.cpp @@ -78,22 +78,6 @@ malletsInstrument::malletsInstrument( instrumentTrack * _instrument_track ): m_spreadModel(0, 0, 255, 1, this, tr( "Spread" )), m_filesMissing( FALSE ) { - m_hardnessModel.setTrack( _instrument_track ); - m_positionModel.setTrack( _instrument_track ); - m_vibratoGainModel.setTrack( _instrument_track ); - m_vibratoFreqModel.setTrack( _instrument_track ); - m_stickModel.setTrack( _instrument_track ); - m_modulatorModel.setTrack( _instrument_track ); - m_crossfadeModel.setTrack( _instrument_track ); - m_lfoSpeedModel.setTrack( _instrument_track ); - m_lfoDepthModel.setTrack( _instrument_track ); - m_adsrModel.setTrack( _instrument_track ); - m_pressureModel.setTrack( _instrument_track ); - m_motionModel.setTrack( _instrument_track ); - m_velocityModel.setTrack( _instrument_track ); - m_strikeModel.setTrack( _instrument_track ); - m_spreadModel.setTrack( _instrument_track ); - // ModalBar m_presetsModel.addItem( tr( "Marimba" ) ); m_scalers.append( 4.0 ); diff --git a/plugins/triple_oscillator/triple_oscillator.cpp b/plugins/triple_oscillator/triple_oscillator.cpp index 319b05eb2..61e33c2dd 100644 --- a/plugins/triple_oscillator/triple_oscillator.cpp +++ b/plugins/triple_oscillator/triple_oscillator.cpp @@ -65,7 +65,7 @@ plugin::descriptor PLUGIN_EXPORT tripleoscillator_plugin_descriptor = -oscillatorObject::oscillatorObject( model * _parent, track * _track, int _idx ) : +oscillatorObject::oscillatorObject( model * _parent, int _idx ) : model( _parent ), m_volumeModel( DefaultVolume / NUM_OF_OSCILLATORS, MinVolume, MaxVolume, 1.0f, this, tr( "Osc %1 volume" ).arg( _idx+1 ) ), @@ -96,16 +96,6 @@ oscillatorObject::oscillatorObject( model * _parent, track * _track, int _idx ) m_phaseOffsetLeft( 0.0f ), m_phaseOffsetRight( 0.0f ) { - m_volumeModel.setTrack( _track ); - m_panModel.setTrack( _track ); - m_coarseModel.setTrack( _track ); - m_fineLeftModel.setTrack( _track ); - m_fineRightModel.setTrack( _track ); - m_phaseOffsetModel.setTrack( _track ); - m_stereoPhaseDetuningModel.setTrack( _track ); - m_waveShapeModel.setTrack( _track ); - m_modulationAlgoModel.setTrack( _track ); - // Connect knobs with oscillators' inputs connect( &m_volumeModel, SIGNAL( dataChanged() ), this, SLOT( updateVolume() ) ); @@ -225,7 +215,7 @@ tripleOscillator::tripleOscillator( instrumentTrack * _instrument_track ) : { for( int i = 0; i < NUM_OF_OSCILLATORS; ++i ) { - m_osc[i] = new oscillatorObject( this, _instrument_track, i ); + m_osc[i] = new oscillatorObject( this, i ); } diff --git a/plugins/triple_oscillator/triple_oscillator.h b/plugins/triple_oscillator/triple_oscillator.h index 4a0d8d935..a07531a7f 100644 --- a/plugins/triple_oscillator/triple_oscillator.h +++ b/plugins/triple_oscillator/triple_oscillator.h @@ -46,7 +46,7 @@ class oscillatorObject : public model { Q_OBJECT public: - oscillatorObject( model * _parent, track * _track, int _idx ); + oscillatorObject( model * _parent, int _idx ); virtual ~oscillatorObject(); diff --git a/plugins/vibed/nine_button_selector.cpp b/plugins/vibed/nine_button_selector.cpp index 48b288810..95bab7906 100644 --- a/plugins/vibed/nine_button_selector.cpp +++ b/plugins/vibed/nine_button_selector.cpp @@ -54,7 +54,7 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on, QWidget * _parent ): QWidget( _parent ), intModelView( new nineButtonSelectorModel(0, 8, _default, NULL, - QString::null, TRUE ) ) + QString::null, TRUE ), this ) { setFixedSize( 50, 50 ); m_base = QPixmap::grabWidget( _parent, _x, _y ); diff --git a/src/core/audio/audio_port.cpp b/src/core/audio/audio_port.cpp index 2ee84baf0..f2ec583ec 100644 --- a/src/core/audio/audio_port.cpp +++ b/src/core/audio/audio_port.cpp @@ -33,7 +33,7 @@ #include "engine.h" -audioPort::audioPort( const QString & _name, track * _track ) : +audioPort::audioPort( const QString & _name ) : m_bufferUsage( NoUsage ), m_firstBuffer( new sampleFrame[engine::getMixer()->framesPerPeriod()] ), m_secondBuffer( new sampleFrame[ @@ -41,7 +41,7 @@ audioPort::audioPort( const QString & _name, track * _track ) : m_extOutputEnabled( FALSE ), m_nextFxChannel( 0 ), m_name( "unnamed port" ), - m_effects( _track ) + m_effects( NULL ) { engine::getMixer()->clearAudioBuffer( m_firstBuffer, engine::getMixer()->framesPerPeriod() ); diff --git a/src/core/automatable_model.cpp b/src/core/automatable_model.cpp index e43639a87..8aa61ed90 100644 --- a/src/core/automatable_model.cpp +++ b/src/core/automatable_model.cpp @@ -28,7 +28,6 @@ #include "automatable_model.h" #include "automation_pattern.h" -#include "automation_editor.h" #include "controller_connection.h" @@ -63,9 +62,7 @@ automatableModel::automatableModel( DataType _type, m_range( _max - _min ), m_displayName( _display_name ), m_journalEntryReady( FALSE ), - m_controllerConnection( NULL ), - m_automationPattern( NULL ), - m_track( NULL ) + m_controllerConnection( NULL ) { } @@ -74,7 +71,6 @@ automatableModel::automatableModel( DataType _type, automatableModel::~automatableModel() { - delete m_automationPattern; while( m_linkedModels.empty() == FALSE ) { m_linkedModels.last()->unlinkModel( this ); @@ -89,28 +85,24 @@ automatableModel::~automatableModel() + +bool automatableModel::isAutomated( void ) const +{ + return( automationPattern::isAutomated( this ) ); +} + + + + void automatableModel::saveSettings( QDomDocument & _doc, QDomElement & _this, const QString & _name ) { - if( m_automationPattern && m_automationPattern->getTimeMap().size() - > 1 ) + if( isAutomated() ) { - QDomElement pattern_element; - QDomNode node = _this.namedItem( - automationPattern::classNodeName() ); - if( node.isElement() ) - { - pattern_element = node.toElement(); - } - else - { - pattern_element = _doc.createElement( - automationPattern::classNodeName() ); - _this.appendChild( pattern_element ); - } - QDomElement element = _doc.createElement( _name ); - m_automationPattern->saveSettings( _doc, element ); - pattern_element.appendChild( element ); + QDomElement me = _doc.createElement( _name ); + me.setAttribute( "id", id() ); + me.setAttribute( "value", m_value ); + _this.appendChild( me ); } else { @@ -142,18 +134,29 @@ void automatableModel::saveSettings( QDomDocument & _doc, QDomElement & _this, void automatableModel::loadSettings( const QDomElement & _this, const QString & _name ) { + // compat code QDomNode node = _this.namedItem( automationPattern::classNodeName() ); - if( node.isElement() && getAutomationPattern() ) + if( node.isElement() ) { node = node.namedItem( _name ); if( node.isElement() ) { - m_automationPattern->loadSettings( node.toElement() ); - setValue( m_automationPattern->valueAt( 0 ) ); + automationPattern * p = automationPattern:: + globalAutomationPattern( this ); + p->loadSettings( node.toElement() ); + setValue( p->valueAt( 0 ) ); return; } } + node = _this.namedItem( _name ); + if( node.isElement() ) + { + changeID( node.toElement().attribute( "id" ).toInt() ); + setValue( node.toElement().attribute( "value" ).toFloat() ); + return; + } + node = _this.namedItem( "connection" ); if( node.isElement() ) { @@ -197,7 +200,6 @@ void automatableModel::setValue( const float _value ) (*it)->setJournalling( journalling ); } } - setFirstValue(); emit dataChanged(); } else @@ -384,11 +386,11 @@ void automatableModel::linkModels( automatableModel * _model1, _model1->linkModel( _model2 ); _model2->linkModel( _model1 ); - if( _model1->m_automationPattern != _model2->m_automationPattern ) +/* if( _model1->m_automationPattern != _model2->m_automationPattern ) { delete _model2->m_automationPattern; _model2->m_automationPattern = _model1->m_automationPattern; - } + }*/ } @@ -399,21 +401,13 @@ void automatableModel::unlinkModels( automatableModel * _model1, { _model1->unlinkModel( _model2 ); _model2->unlinkModel( _model1 ); - +/* if( _model1->m_automationPattern && _model1->m_automationPattern == _model2->m_automationPattern ) { _model2->m_automationPattern = new automationPattern( *_model1->m_automationPattern, _model2 ); - } -} - - - - -void automatableModel::initAutomationPattern( void ) -{ - m_automationPattern = new automationPattern( NULL, this ); + }*/ } @@ -434,49 +428,18 @@ void automatableModel::setControllerConnection( controllerConnection * _c ) -automationPattern * automatableModel::getAutomationPattern( void ) -{ - if( !m_automationPattern ) - { - m_automationPattern = new automationPattern( m_track, this ); - setFirstValue(); -// syncAutomationPattern(); - } - return( m_automationPattern ); -} - - -void automatableModel::setFirstValue( void ) -{ - if( m_automationPattern && m_automationPattern->updateFirst() ) - { - m_automationPattern->putValue( 0, m_value, FALSE ); - if( engine::getAutomationEditor() && - engine::getAutomationEditor()->currentPattern() - == m_automationPattern ) - { - engine::getAutomationEditor()->update(); - } - } -} - - - - void automatableModel::setInitValue( const float _value ) { m_initValue = _value; bool journalling = testAndSetJournalling( FALSE ); setValue( _value ); - if( m_automationPattern ) - { - setFirstValue(); - } setJournalling( journalling ); + emit initValueChanged( _value ); } + void automatableModel::reset( void ) { setValue( initValue() ); diff --git a/src/core/automation_pattern.cpp b/src/core/automation_pattern.cpp index 254610f52..8d619d41d 100644 --- a/src/core/automation_pattern.cpp +++ b/src/core/automation_pattern.cpp @@ -4,6 +4,7 @@ * automation_pattern.cpp - implementation of class automationPattern which * holds dynamic values * + * Copyright (c) 2008 Tobias Doerffel * Copyright (c) 2006-2008 Javier Serrano Polo * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -27,69 +28,53 @@ #include +#include +#include #include "automation_pattern.h" +#include "automation_track.h" #include "automation_editor.h" +#include "bb_track_container.h" +#include "embed.h" #include "engine.h" +#include "gui_templates.h" #include "note.h" +#include "project_journal.h" +#include "rename_dialog.h" +#include "song.h" +#include "string_pair_drag.h" #include "templates.h" -#include "track.h" +#include "tooltip.h" +#include "track_container.h" -automationPattern::automationPattern( track * _track, - automatableModel * _object ) : - m_track( _track ), - m_object( _object ), - m_update_first( TRUE ), +automationPattern::automationPattern( automationTrack * _auto_track ) : + trackContentObject( _auto_track ), + m_autoTrack( _auto_track ), + m_objects(), + m_updateFirst( TRUE ), m_dynamic( FALSE ) { + changeLength( midiTime( 1, 0 ) ); } automationPattern::automationPattern( const automationPattern & _pat_to_copy ) : - QObject(), - journallingObject(), - m_track( _pat_to_copy.m_track ), - m_object( _pat_to_copy.m_object ), - m_update_first( _pat_to_copy.m_update_first ), + trackContentObject( _pat_to_copy.m_autoTrack ), + m_autoTrack( _pat_to_copy.m_autoTrack ), + m_objects( _pat_to_copy.m_objects ), + m_updateFirst( _pat_to_copy.m_updateFirst ), m_dynamic( _pat_to_copy.m_dynamic ) { - for( timeMap::const_iterator it = _pat_to_copy.m_time_map.begin(); - it != _pat_to_copy.m_time_map.end(); ++it ) + for( timeMap::const_iterator it = _pat_to_copy.m_timeMap.begin(); + it != _pat_to_copy.m_timeMap.end(); ++it ) { - m_time_map[it.key()] = it.value(); - } - - if( m_dynamic && m_track ) - { - m_track->addAutomationPattern( this ); - } -} - - - - -automationPattern::automationPattern( const automationPattern & _pat_to_copy, - automatableModel * _object ) : - m_track( _pat_to_copy.m_track ), - m_object( _object ), - m_update_first( _pat_to_copy.m_update_first ), - m_dynamic( _pat_to_copy.m_dynamic ) -{ - for( timeMap::const_iterator it = _pat_to_copy.m_time_map.begin(); - it != _pat_to_copy.m_time_map.end(); ++it ) - { - m_time_map[it.key()] = it.value(); - } - - if( m_dynamic && m_track ) - { - m_track->addAutomationPattern( this ); + m_timeMap[it.key()] = it.value(); } } @@ -98,31 +83,35 @@ automationPattern::automationPattern( const automationPattern & _pat_to_copy, automationPattern::~automationPattern() { - if( m_dynamic && m_track ) - { - m_track->removeAutomationPattern( this ); - } - - if( engine::getAutomationEditor() - && engine::getAutomationEditor()->currentPattern() == this ) - { - engine::getAutomationEditor()->setCurrentPattern( NULL ); - } } +const automatableModel * automationPattern::firstObject( void ) +{ + if( !m_objects.isEmpty() ) + { + return( m_objects.first() ); + } + static floatModel _fm; + return( &_fm ); +} + + + + + //TODO: Improve this midiTime automationPattern::length( void ) const { tick max_length = 0; - for( timeMap::const_iterator it = m_time_map.begin(); - it != m_time_map.end(); + for( timeMap::const_iterator it = m_timeMap.begin(); + it != m_timeMap.end(); ++it ) { - max_length = tMax( max_length, -it.key() ); + max_length = tMax( max_length, it.key() ); } if( max_length % DefaultTicksPerTact == 0 ) { @@ -136,7 +125,8 @@ midiTime automationPattern::length( void ) const -midiTime automationPattern::putValue( const midiTime & _time, const float _value, +midiTime automationPattern::putValue( const midiTime & _time, + const float _value, const bool _quant_pos ) { midiTime new_time = _quant_pos && engine::getAutomationEditor() ? @@ -144,17 +134,20 @@ midiTime automationPattern::putValue( const midiTime & _time, const float _value engine::getAutomationEditor()->quantization() ) : _time; - m_time_map[-new_time] = _value; + m_timeMap[new_time] = _value; if( !m_dynamic && new_time != 0 ) { m_dynamic = TRUE; - if( m_track ) - { - m_track->addAutomationPattern( this ); - } } + if( getTrack()->type() == track::HiddenAutomationTrack ) + { + changeLength( length() ); + } + + emit dataChanged(); + return( new_time ); } @@ -165,17 +158,31 @@ void automationPattern::removeValue( const midiTime & _time ) { if( _time != 0 ) { - m_time_map.remove( -_time ); + m_timeMap.remove( _time ); - if( m_time_map.size() == 1 ) + if( m_timeMap.size() == 1 ) { m_dynamic = FALSE; - m_object->setValue( m_time_map[0] ); - if( m_track ) + for( objectVector::iterator it = m_objects.begin(); + it != m_objects.end(); ++it ) { - m_track->removeAutomationPattern( this ); + if( *it ) + { + ( *it )->setValue( m_timeMap[0] ); + } + else + { + it = m_objects.erase( it ); + } } } + + if( getTrack()->type() == track::HiddenAutomationTrack ) + { + changeLength( length() ); + } + + emit dataChanged(); } } @@ -184,7 +191,10 @@ void automationPattern::removeValue( const midiTime & _time ) void automationPattern::clear( void ) { - m_time_map.clear(); + m_timeMap.clear(); + m_dynamic = FALSE; + m_timeMap[0] = firstObject()->value(); + if( engine::getAutomationEditor() && engine::getAutomationEditor()->currentPattern() == this ) { @@ -195,58 +205,6 @@ void automationPattern::clear( void ) -float automationPattern::valueAt( const midiTime & _time ) -{ - return( m_time_map.lowerBound( -_time ).value() ); -} - - - - -void automationPattern::saveSettings( QDomDocument & _doc, QDomElement & _this ) -{ - for( timeMap::iterator it = m_time_map.begin(); it != m_time_map.end(); - ++it ) - { - QDomElement element = _doc.createElement( "time" ); - element.setAttribute( "pos", -it.key() ); - element.setAttribute( "value", it.value() ); - _this.appendChild( element ); - } -} - - - - -void automationPattern::loadSettings( const QDomElement & _this ) -{ - clear(); - - for( QDomNode node = _this.firstChild(); !node.isNull(); - node = node.nextSibling() ) - { - QDomElement element = node.toElement(); - if( element.isNull() || element.tagName() != "time" ) - { - continue; - } - m_time_map[-element.attribute( "pos" ).toInt()] - = element.attribute( "value" ).toFloat(); - } - - if( !m_dynamic ) - { - m_dynamic = TRUE; - if( m_track ) - { - m_track->addAutomationPattern( this ); - } - } -} - - - - void automationPattern::openInAutomationEditor( void ) { engine::getAutomationEditor()->setCurrentPattern( this ); @@ -257,18 +215,77 @@ void automationPattern::openInAutomationEditor( void ) +float automationPattern::valueAt( const midiTime & _time ) +{ + timeMap::const_iterator v = m_timeMap.lowerBound( _time ); + return( ( v != m_timeMap.end() ) ? v.value() : (v-1).value() ); +} + + + + +void automationPattern::saveSettings( QDomDocument & _doc, QDomElement & _this ) +{ + for( timeMap::const_iterator it = m_timeMap.begin(); + it != m_timeMap.end(); ++it ) + { + QDomElement element = _doc.createElement( "time" ); + element.setAttribute( "pos", it.key() ); + element.setAttribute( "value", it.value() ); + _this.appendChild( element ); + } + for( objectVector::const_iterator it = m_objects.begin(); + it != m_objects.end(); ++it ) + { + QDomElement element = _doc.createElement( "object" ); + element.setAttribute( "id", ( *it )->id() ); + _this.appendChild( element ); + } +} + + + + +void automationPattern::loadSettings( const QDomElement & _this ) +{ + clear(); + + m_objects.clear(); + + for( QDomNode node = _this.firstChild(); !node.isNull(); + node = node.nextSibling() ) + { + QDomElement element = node.toElement(); + if( element.isNull() ) + { + continue; + } + if( element.tagName() == "time" ) + { + m_timeMap[element.attribute( "pos" ).toInt()] + = element.attribute( "value" ).toFloat(); + } + else if( element.tagName() == "object" ) + { + m_idsToResolve << element.attribute( "id" ).toInt(); + } + } + + m_dynamic = m_timeMap.size() > 1; + + changeLength( length() ); +} + + + + const QString automationPattern::name( void ) { - if( m_track ) + if( !m_objects.isEmpty() ) { - QString widget_name = m_object->displayName(); -/* dynamic_cast( m_object )->accessibleName();*/ - return( m_track->name() + " - " + widget_name ); - } - else - { - return( m_object->displayName() ); + return( m_objects.first()->fullDisplayName() ); } + return( tr( "No control assigned" ) ); } @@ -276,16 +293,383 @@ const QString automationPattern::name( void ) void automationPattern::processMidiTime( const midiTime & _time ) { - if( _time >= 0 ) + if( _time >= 0 && m_dynamic ) { - m_object->setAutomatedValue( - m_time_map.lowerBound( -_time ).value() ); + const float val = valueAt( _time ); + for( objectVector::iterator it = m_objects.begin(); + it != m_objects.end(); ++it ) + { + if( *it ) + { + ( *it )->setAutomatedValue( val ); + } + + } } } + +trackContentObjectView * automationPattern::createView( trackView * _tv ) +{ + return( new automationPatternView( this, _tv ) ); +} + + + + + +bool automationPattern::isAutomated( const automatableModel * _m ) +{ + const trackContainer::trackList l = engine::getSong()->tracks() + + engine::getBBTrackContainer()->tracks(); + for( trackContainer::trackList::const_iterator it = l.begin(); + it != l.end(); ++it ) + { + if( ( *it )->type() == track::AutomationTrack ) + { + const track::tcoVector & v = ( *it )->getTCOs(); + for( track::tcoVector::const_iterator j = v.begin(); + j != v.end(); ++j ) + { + const automationPattern * a = + dynamic_cast( *j ); + if( a && a->m_dynamic ) + { + for( objectVector::const_iterator k = a->m_objects.begin(); + k != a->m_objects.end(); ++k ) + { + if( *k == _m ) + { + return( TRUE ); + } + } + } + } + } + } + return( FALSE ); +} + + + + + +automationPattern * automationPattern::globalAutomationPattern( + automatableModel * _m ) +{ + automationTrack * t = engine::getSong()->globalAutomationTrack(); + track::tcoVector v = t->getTCOs(); + for( track::tcoVector::const_iterator j = v.begin(); j != v.end(); ++j ) + { + automationPattern * a = dynamic_cast( *j ); + if( a ) + { + for( objectVector::const_iterator k = + a->m_objects.begin(); + k != a->m_objects.end(); ++k ) + { + if( *k == _m ) + { + return( a ); + } + } + } + } + + automationPattern * a = new automationPattern( t ); + a->m_objects += _m; + return( a ); +} + + + + +void automationPattern::resolveAllIDs( void ) +{ + trackContainer::trackList l = engine::getSong()->tracks() + + engine::getBBTrackContainer()->tracks(); + for( trackContainer::trackList::iterator it = l.begin(); + it != l.end(); ++it ) + { + if( ( *it )->type() == track::AutomationTrack || + ( *it )->type() == track::HiddenAutomationTrack ) + { + track::tcoVector v = ( *it )->getTCOs(); + for( track::tcoVector::iterator j = v.begin(); + j != v.end(); ++j ) + { + automationPattern * a = + dynamic_cast( *j ); + if( a ) + { + for( QVector::iterator k = a->m_idsToResolve.begin(); + k != a->m_idsToResolve.end(); ++k ) + { + journallingObject * o = engine::getProjectJournal()-> + getJournallingObject( *k ); + if( o && dynamic_cast( o ) ) + { + a->m_objects += dynamic_cast( o ); + } + } + a->m_idsToResolve.clear(); + } + } + } + } +} + + + + + + +automationPatternView::automationPatternView( automationPattern * _pattern, + trackView * _parent ) : + trackContentObjectView( _pattern, _parent ), + m_pat( _pattern ), + m_paintPixmap(), + m_needsUpdate( TRUE ) +{ + connect( m_pat, SIGNAL( dataChanged() ), + this, SLOT( update() ) ); + + setFixedHeight( parentWidget()->height() - 2 ); + setAutoResizeEnabled( FALSE ); + + toolTip::add( this, tr( "double-click to open this pattern in " + "automation editor" ) ); +} + + + + + + +automationPatternView::~automationPatternView() +{ + if( engine::getAutomationEditor() + && engine::getAutomationEditor()->currentPattern() == m_pat ) + { + engine::getAutomationEditor()->setCurrentPattern( NULL ); + } +} + + + + + +void automationPatternView::update( void ) +{ + m_needsUpdate = TRUE; +// m_pat->changeLength( m_pat->length() ); + trackContentObjectView::update(); +} + + + + +void automationPatternView::resetName( void ) +{ + //m_pat->setName( m_pat->m_autoTrack->name() ); +} + + + + +void automationPatternView::changeName( void ) +{ + QString s = m_pat->name(); + renameDialog rename_dlg( s ); + rename_dlg.exec(); +// m_pat->setName( s ); +} + + + + + +void automationPatternView::constructContextMenu( QMenu * _cm ) +{ + QAction * a = new QAction( embed::getIconPixmap( "automation" ), + tr( "Open in Automation editor" ), _cm ); + _cm->insertAction( _cm->actions()[0], a ); + connect( a, SIGNAL( triggered( bool ) ), + m_pat, SLOT( openInAutomationEditor() ) ); + _cm->insertSeparator( _cm->actions()[1] ); + + _cm->addSeparator(); + + _cm->addAction( embed::getIconPixmap( "edit_erase" ), + tr( "Clear" ), m_pat, SLOT( clear() ) ); + _cm->addSeparator(); + + _cm->addAction( embed::getIconPixmap( "reload" ), tr( "Reset name" ), + this, SLOT( resetName() ) ); + _cm->addAction( embed::getIconPixmap( "rename" ), tr( "Change name" ), + this, SLOT( changeName() ) ); + _cm->addSeparator(); +} + + + + +void automationPatternView::mouseDoubleClickEvent( QMouseEvent * _me ) +{ + if( _me->button() != Qt::LeftButton ) + { + _me->ignore(); + return; + } + m_pat->openInAutomationEditor(); +} + + + + +void automationPatternView::paintEvent( QPaintEvent * ) +{ + if( m_needsUpdate == FALSE ) + { + QPainter p( this ); + p.drawPixmap( 0, 0, m_paintPixmap ); + return; + } + + m_needsUpdate = FALSE; + + if( m_paintPixmap.isNull() == TRUE || m_paintPixmap.size() != size() ) + { + m_paintPixmap = QPixmap( size() ); + } + + QPainter p( &m_paintPixmap ); + + QLinearGradient lingrad( 0, 0, 0, height() ); + const QColor c = isSelected() ? QColor( 0, 0, 224 ) : + QColor( 96, 96, 96 ); + lingrad.setColorAt( 0, c ); + lingrad.setColorAt( 0.5, Qt::black ); + lingrad.setColorAt( 1, c ); + p.setBrush( lingrad ); + p.setPen( QColor( 0, 0, 0 ) ); + p.drawRect( QRect( 0, 0, width() - 1, height() - 1 ) ); + + const float ppt = fixedTCOs() ? + ( parentWidget()->width() - 2 * TCO_BORDER_WIDTH ) + / (float) m_pat->length().getTact() : + pixelsPerTact(); + + const int x_base = TCO_BORDER_WIDTH; + p.setPen( QColor( 0, 0, 0 ) ); + + for( tact t = 1; t < m_pat->length().getTact(); ++t ) + { + p.drawLine( x_base + static_cast( ppt * t ) - 1, + TCO_BORDER_WIDTH, x_base + static_cast( + ppt * t ) - 1, 5 ); + p.drawLine( x_base + static_cast( ppt * t ) - 1, + height() - ( 4 + 2 * TCO_BORDER_WIDTH ), + x_base + static_cast( ppt * t ) - 1, + height() - 2 * TCO_BORDER_WIDTH ); + } + + const float y_scale = m_pat->firstObject()->maxValue(); + + for( automationPattern::timeMap::const_iterator it = + m_pat->getTimeMap().begin(); + it != m_pat->getTimeMap().end(); ++it ) + { + const float x1 = 2 * x_base + it.key() * ppt / + midiTime::ticksPerTact(); + float x2; + if( it+1 != m_pat->getTimeMap().end() ) + { + x2 = (it+1).key() * ppt / midiTime::ticksPerTact() + 2; + } + else + { + x2 = width() - TCO_BORDER_WIDTH + 1; + } + const float h = ( height()-2*TCO_BORDER_WIDTH ) * it.value() / + y_scale; + p.fillRect( QRectF( x1, height()-TCO_BORDER_WIDTH-h, x2-x1, h ), + QColor( 255, 224, 0 ) ); + } + + p.setFont( pointSize<7>( p.font() ) ); + if( m_pat->isMuted() || m_pat->getTrack()->isMuted() ) + { + p.setPen( QColor( 192, 192, 192 ) ); + } + else + { + p.setPen( QColor( 32, 240, 32 ) ); + } + + if( m_pat->name() != m_pat->m_autoTrack->name() ) + { + p.drawText( 2, p.fontMetrics().height() - 1, m_pat->name() ); + } + + if( m_pat->isMuted() ) + { + p.drawPixmap( 3, p.fontMetrics().height() + 1, + embed::getIconPixmap( "muted", 16, 16 ) ); + } + + p.end(); + + p.begin( this ); + p.drawPixmap( 0, 0, m_paintPixmap ); + +} + + + + +void automationPatternView::dragEnterEvent( QDragEnterEvent * _dee ) +{ + stringPairDrag::processDragEnterEvent( _dee, "automatable_model" ); +} + + + + +void automationPatternView::dropEvent( QDropEvent * _de ) +{ + QString type = stringPairDrag::decodeKey( _de ); + QString val = stringPairDrag::decodeValue( _de ); + if( type == "automatable_model" ) + { + automatableModel * mod = dynamic_cast( + engine::getProjectJournal()-> + getJournallingObject( val.toInt() ) ); + if( mod != NULL ) + { + m_pat->m_objects += mod; + } + } + + update(); + + if( engine::getAutomationEditor() && + engine::getAutomationEditor()->currentPattern() == m_pat ) + { + engine::getAutomationEditor()->setCurrentPattern( m_pat ); + } +} + + + + + + + #include "automation_pattern.moc" diff --git a/src/core/bb_track_container.cpp b/src/core/bb_track_container.cpp index f4d744043..9e2d15628 100644 --- a/src/core/bb_track_container.cpp +++ b/src/core/bb_track_container.cpp @@ -244,14 +244,13 @@ void bbTrackContainer::createTCOsForBB( int _bb ) return; } - QList tl = tracks(); + trackList tl = tracks(); for( int i = 0; i < tl.size(); ++i ) { while( tl[i]->numOfTCOs() < _bb + 1 ) { midiTime position = midiTime( tl[i]->numOfTCOs(), 0 ); - trackContentObject * tco = tl[i]->addTCO( - tl[i]->createTCO( position ) ); + trackContentObject * tco = tl[i]->createTCO( position ); tco->movePosition( position ); tco->changeLength( midiTime( 1, 0 ) ); } diff --git a/src/core/effect_chain.cpp b/src/core/effect_chain.cpp index 6b6a3b0a2..60a141ff8 100644 --- a/src/core/effect_chain.cpp +++ b/src/core/effect_chain.cpp @@ -29,15 +29,13 @@ #include "effect_chain.h" #include "effect.h" #include "engine.h" -#include "track.h" #include "debug.h" -effectChain::effectChain( track * _track ) : - model( _track ), - m_track( _track ), +effectChain::effectChain( model * _parent ) : + model( _parent ), m_enabledModel( FALSE ) { } @@ -111,21 +109,18 @@ void effectChain::loadSettings( const QDomElement & _this ) - void effectChain::appendEffect( effect * _effect ) { engine::getMixer()->lock(); - _effect->m_enabledModel.setTrack( m_track ); - _effect->m_wetDryModel.setTrack( m_track ); - _effect->m_gateModel.setTrack( m_track ); - _effect->m_autoQuitModel.setTrack( m_track ); m_effects.append( _effect ); engine::getMixer()->unlock(); + emit dataChanged(); } + void effectChain::removeEffect( effect * _effect ) { engine::getMixer()->lock(); diff --git a/src/core/envelope_and_lfo_parameters.cpp b/src/core/envelope_and_lfo_parameters.cpp index d56e0473b..7735c000a 100644 --- a/src/core/envelope_and_lfo_parameters.cpp +++ b/src/core/envelope_and_lfo_parameters.cpp @@ -49,7 +49,6 @@ QVector envelopeAndLFOParameters::s_EaLParametersIns envelopeAndLFOParameters::envelopeAndLFOParameters( float _value_for_zero_amount, - track * _track, model * _parent ) : model( _parent ), m_used( FALSE ), @@ -80,24 +79,6 @@ envelopeAndLFOParameters::envelopeAndLFOParameters( { s_EaLParametersInstances.push_back( this ); - - m_predelayModel.setTrack( _track ); - m_attackModel.setTrack( _track ); - m_holdModel.setTrack( _track ); - m_decayModel.setTrack( _track ); - m_sustainModel.setTrack( _track ); - m_releaseModel.setTrack( _track ); - m_amountModel.setTrack( _track ); - - m_lfoPredelayModel.setTrack( _track ); - m_lfoAttackModel.setTrack( _track ); - m_lfoSpeedModel.setTrack( _track ); - m_lfoAmountModel.setTrack( _track ); - m_lfoWaveModel.setTrack( _track ); - m_x100Model.setTrack( _track ); - m_controlEnvAmountModel.setTrack( _track ); - - connect( &m_predelayModel, SIGNAL( dataChanged() ), this, SLOT( updateSampleVars() ) ); connect( &m_attackModel, SIGNAL( dataChanged() ), diff --git a/src/core/fx_mixer.cpp b/src/core/fx_mixer.cpp index f08a85827..16244d348 100644 --- a/src/core/fx_mixer.cpp +++ b/src/core/fx_mixer.cpp @@ -45,7 +45,6 @@ fxChannel::fxChannel( model * _parent ) : { engine::getMixer()->clearAudioBuffer( m_buffer, engine::getMixer()->framesPerPeriod() ); - m_volumeModel.setTrack( engine::getSong()->getAutomationTrack() ); } diff --git a/src/core/instrument_functions.cpp b/src/core/instrument_functions.cpp index 8befda984..d7e3eb38e 100644 --- a/src/core/instrument_functions.cpp +++ b/src/core/instrument_functions.cpp @@ -167,23 +167,17 @@ const int ARP_GROUPBOX_HEIGHT = 240 - ARP_GROUPBOX_Y; -chordCreator::chordCreator( instrumentTrack * _instrument_track ) : - model( _instrument_track ), +chordCreator::chordCreator( model * _parent ) : + model( _parent ), m_chordsEnabledModel( FALSE, this ), m_chordsModel( this, tr( "Chord type" ) ), m_chordRangeModel( 1.0f, 1.0f, 9.0f, 1.0f, this, tr( "Chord range" ) ) { - m_chordsEnabledModel.setTrack( _instrument_track ); - - m_chordsModel.setTrack( _instrument_track ); for( int i = 0; s_chordTable[i].interval[0] != -1; ++i ) { m_chordsModel.addItem( tr( s_chordTable[i].name.toAscii(). constData() ) ); } - - m_chordRangeModel.setTrack( _instrument_track ); - } @@ -280,8 +274,8 @@ void chordCreator::loadSettings( const QDomElement & _this ) -arpeggiator::arpeggiator( instrumentTrack * _instrument_track ) : - model( _instrument_track ), +arpeggiator::arpeggiator( model * _parent ) : + model( _parent ), m_arpEnabledModel( FALSE ), m_arpModel( this, tr( "Arpeggio type" ) ), m_arpRangeModel( 1.0f, 1.0f, 9.0f, 1.0f, this, tr( "Arpeggio range" ) ), @@ -290,9 +284,6 @@ arpeggiator::arpeggiator( instrumentTrack * _instrument_track ) : m_arpDirectionModel( 0, 0, NumArpDirections, this, tr( "Arpeggio direction" ) ), m_arpModeModel( this, tr( "Arpeggio mode" ) ) { - m_arpEnabledModel.setTrack( _instrument_track ); - - m_arpModel.setTrack( _instrument_track ); for( int i = 0; chordCreator::s_chordTable[i].interval[0] != -1; ++i ) { m_arpModel.addItem( chordCreator::tr( @@ -300,16 +291,8 @@ arpeggiator::arpeggiator( instrumentTrack * _instrument_track ) : name.toAscii().constData() ) ); } - m_arpRangeModel.setTrack( _instrument_track ); - - m_arpTimeModel.setTrack( _instrument_track ); - - m_arpGateModel.setTrack( _instrument_track ); - - m_arpDirectionModel.setTrack( _instrument_track ); m_arpDirectionModel.setInitValue( ArpDirUp ); - m_arpModeModel.setTrack( _instrument_track ); m_arpModeModel.addItem( tr( "Free" ), new pixmapLoader( "arp_free" ) ); m_arpModeModel.addItem( tr( "Sort" ), new pixmapLoader( "arp_sort" ) ); m_arpModeModel.addItem( tr( "Sync" ), new pixmapLoader( "arp_sync" ) ); diff --git a/src/core/instrument_sound_shaping.cpp b/src/core/instrument_sound_shaping.cpp index 0cef622df..d0ff7b4ee 100644 --- a/src/core/instrument_sound_shaping.cpp +++ b/src/core/instrument_sound_shaping.cpp @@ -76,12 +76,9 @@ instrumentSoundShaping::instrumentSoundShaping( } m_envLFOParameters[i] = new envelopeAndLFOParameters( value_for_zero_amount, - _instrument_track, this ); } - m_filterEnabledModel.setTrack( _instrument_track ); - m_filterModel.addItem( tr( "LowPass" ), new pixmapLoader( "filter_lp" ) ); m_filterModel.addItem( tr( "HiPass" ), @@ -98,11 +95,6 @@ instrumentSoundShaping::instrumentSoundShaping( new pixmapLoader( "filter_lp" ) ); m_filterModel.addItem( tr( "2x LowPass" ), new pixmapLoader( "filter_2lp" ) ); - - m_filterModel.setTrack( _instrument_track ); - m_filterCutModel.setTrack( _instrument_track ); - m_filterResModel.setTrack( _instrument_track ); - } diff --git a/src/core/journalling_object.cpp b/src/core/journalling_object.cpp index 6772ebd87..bd8b44c3f 100644 --- a/src/core/journalling_object.cpp +++ b/src/core/journalling_object.cpp @@ -138,6 +138,26 @@ void journallingObject::addJournalEntry( const journalEntry & _je ) +void journallingObject::changeID( jo_id_t _id ) +{ + if( id() != _id ) + { + if( engine::getProjectJournal()->getJournallingObject( _id ) + != NULL ) + { + printf( "JO-ID %d already in use by another " + "object!\n", _id ); + return; + } + engine::getProjectJournal()->forgetAboutID( id() ); + engine::getProjectJournal()->reallocID( _id, this ); + m_id = _id; + } +} + + + + void journallingObject::saveJournal( QDomDocument & _doc, QDomElement & _parent ) { @@ -181,12 +201,7 @@ void journallingObject::loadJournal( const QDomElement & _this ) return; } - if( id() != new_id ) - { - engine::getProjectJournal()->forgetAboutID( id() ); - engine::getProjectJournal()->reallocID( new_id, this ); - m_id = new_id; - } + changeID( new_id ); m_journalEntries.resize( _this.attribute( "entries" ).toInt() ); diff --git a/src/core/ladspa_control.cpp b/src/core/ladspa_control.cpp index c2d308918..08a0f9f74 100644 --- a/src/core/ladspa_control.cpp +++ b/src/core/ladspa_control.cpp @@ -1,6 +1,7 @@ /* * ladspa_control.cpp - model for controlling a LADSPA port * + * Copyright (c) 2008 Tobias Doerffel * Copyright (c) 2006-2008 Danny McRae * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -28,7 +29,7 @@ ladspaControl::ladspaControl( model * _parent, port_desc_t * _port, - track * _track, bool _link ) : + bool _link ) : model( _parent ), m_link( _link ), m_port( _port ), @@ -39,7 +40,6 @@ ladspaControl::ladspaControl( model * _parent, port_desc_t * _port, { if( m_link ) { - m_linkEnabledModel.setTrack( _track ); connect( &m_linkEnabledModel, SIGNAL( dataChanged() ), this, SLOT( linkStateChanged() ) ); @@ -48,7 +48,6 @@ ladspaControl::ladspaControl( model * _parent, port_desc_t * _port, switch( m_port->data_type ) { case TOGGLED: - m_toggledModel.setTrack( _track ); connect( &m_toggledModel, SIGNAL( dataChanged() ), this, SLOT( ledChanged() ) ); if( m_port->def == 1.0f ) @@ -58,7 +57,6 @@ ladspaControl::ladspaControl( model * _parent, port_desc_t * _port, break; case INTEGER: - m_knobModel.setTrack( _track ); m_knobModel.setRange( static_cast( m_port->max ), static_cast( m_port->min ), 1 + static_cast( m_port->max - @@ -70,7 +68,6 @@ ladspaControl::ladspaControl( model * _parent, port_desc_t * _port, break; case FLOAT: - m_knobModel.setTrack( _track ); m_knobModel.setRange( m_port->min, m_port->max, ( m_port->max - m_port->min ) / ( m_port->name.toUpper() == "GAIN" @@ -82,7 +79,6 @@ ladspaControl::ladspaControl( model * _parent, port_desc_t * _port, break; case TIME: - m_tempoSyncKnobModel.setTrack( _track ); m_tempoSyncKnobModel.setRange( m_port->min, m_port->max, ( m_port->max - m_port->min ) / 400.0f ); diff --git a/src/core/meter_model.cpp b/src/core/meter_model.cpp index e997ec2ff..7a3430eb8 100644 --- a/src/core/meter_model.cpp +++ b/src/core/meter_model.cpp @@ -26,14 +26,11 @@ #include "meter_model.h" -meterModel::meterModel( ::model * _parent, track * _track ) : +meterModel::meterModel( ::model * _parent ) : model( _parent ), m_numeratorModel( 4, 1, 32, this ), m_denominatorModel( 4, 1, 32, this ) { - m_numeratorModel.setTrack( _track ); - m_denominatorModel.setTrack( _track ); - connect( &m_numeratorModel, SIGNAL( dataChanged() ), this, SIGNAL( dataChanged() ) ); connect( &m_denominatorModel, SIGNAL( dataChanged() ), diff --git a/src/core/midi/midi_controller.cpp b/src/core/midi/midi_controller.cpp index 6db715640..2196abb40 100644 --- a/src/core/midi/midi_controller.cpp +++ b/src/core/midi/midi_controller.cpp @@ -42,8 +42,8 @@ midiController::midiController( model * _parent ) : controller( MidiController, _parent ), midiEventProcessor(), m_midiPort( tr( "unnamed_midi_controller" ), - engine::getMixer()->getMIDIClient(), this, - this, NULL, midiPort::Input ), + engine::getMixer()->getMIDIClient(), this, this, + midiPort::Input ), m_lastValue( 0.0f ) { connect( &m_midiPort, SIGNAL( modeChanged() ), @@ -52,6 +52,7 @@ midiController::midiController( model * _parent ) : + midiController::~midiController() { } diff --git a/src/core/midi/midi_port.cpp b/src/core/midi/midi_port.cpp index 07d121dc1..3baf4e0cc 100644 --- a/src/core/midi/midi_port.cpp +++ b/src/core/midi/midi_port.cpp @@ -36,7 +36,7 @@ midiPort::midiPort( const QString & _name, midiClient * _mc, midiEventProcessor * _mep, model * _parent, - track * _track, Modes _mode ) : + Modes _mode ) : model( _parent ), m_readablePortsMenu( NULL ), m_writablePortsMenu( NULL ), @@ -61,11 +61,6 @@ midiPort::midiPort( const QString & _name, midiClient * _mc, { m_midiClient->addPort( this ); - m_inputChannelModel.setTrack( _track ); - m_outputChannelModel.setTrack( _track ); - m_defaultVelocityInEnabledModel.setTrack( _track ); - m_defaultVelocityOutEnabledModel.setTrack( _track ); - m_readableModel.setValue( m_mode == Input || m_mode == Duplex ); m_writableModel.setValue( m_mode == Output || m_mode == Duplex ); diff --git a/src/core/mmp.cpp b/src/core/mmp.cpp index 360bb1f81..b267b4be8 100644 --- a/src/core/mmp.cpp +++ b/src/core/mmp.cpp @@ -641,6 +641,16 @@ void multimediaProject::upgrade( void ) } } + if( version < "0.4.0-svn20080622" ) + { + QDomNodeList list = elementsByTagName( "automation-pattern" ); + for( int i = 0; !list.item( i ).isNull(); ++i ) + { + QDomElement el = list.item( i ).toElement(); + el.setTagName( "automationpattern" ); + } + } + // Time-signature if ( !m_head.hasAttribute( "timesig_numerator" ) ) diff --git a/src/core/mv_base.cpp b/src/core/mv_base.cpp index b2268cdbd..440a9132b 100644 --- a/src/core/mv_base.cpp +++ b/src/core/mv_base.cpp @@ -36,25 +36,25 @@ QString model::fullDisplayName( void ) const const QString & n = displayName(); if( parentModel() ) { - if( !n.isEmpty() ) + const QString p = parentModel()->fullDisplayName(); + if( n.isEmpty() && p.isEmpty() ) { - return parentModel()->fullDisplayName() + ": " + n; + return QString::null; } - else + else if( p.isEmpty() ) { - return parentModel()->fullDisplayName(); + return( n ); } + return p + ">" + n; } - else - { - return n; - } + return n; } -modelView::modelView( model * _model ) : +modelView::modelView( model * _model, QWidget * _this ) : + m_widget( _this ), m_model( _model ) { } @@ -64,9 +64,6 @@ modelView::modelView( model * _model ) : void modelView::setModel( model * _model, bool _old_model_valid ) { - QWidget * w = dynamic_cast( this ); - assert( w != NULL ); - if( _old_model_valid && m_model != NULL ) { if( m_model->defaultConstructed() ) @@ -75,14 +72,14 @@ void modelView::setModel( model * _model, bool _old_model_valid ) } else { - m_model->disconnect( w ); + m_model->disconnect( widget() ); } } m_model = _model; doConnections(); - w->update(); + widget()->update(); modelChanged(); } @@ -94,13 +91,13 @@ void modelView::doConnections( void ) { if( m_model != NULL ) { - QWidget * w = dynamic_cast( this ); QObject::connect( m_model, SIGNAL( dataChanged() ), - w, SLOT( update() ), - Qt::QueuedConnection ); + widget(), SLOT( update() ), + Qt::QueuedConnection ); QObject::connect( m_model, SIGNAL( propertiesChanged() ), - w, SLOT( update() ), Qt::QueuedConnection ); + widget(), SLOT( update() ), + Qt::QueuedConnection ); } } diff --git a/src/core/note.cpp b/src/core/note.cpp index 48223304b..aa804e851 100644 --- a/src/core/note.cpp +++ b/src/core/note.cpp @@ -3,7 +3,7 @@ /* * note.cpp - implementation of class note * - * Copyright (c) 2004-2007 Tobias Doerffel + * Copyright (c) 2004-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -239,7 +239,8 @@ void note::redoStep( journalEntry & _je ) void note::editDetuningPattern( void ) { - m_detuning->getAutomationPattern()->openInAutomationEditor(); +#warning: TODO +// m_detuning->getAutomationPattern()->openInAutomationEditor(); } @@ -247,8 +248,9 @@ void note::editDetuningPattern( void ) void note::createDetuning( void ) { +#warning: TODO m_detuning = new detuningHelper; - m_detuning->initAutomationPattern(); +// m_detuning->initAutomationPattern(); m_detuning->setRange( -MaxDetuning, MaxDetuning, 0.1f ); } @@ -257,9 +259,11 @@ void note::createDetuning( void ) bool note::hasDetuningInfo( void ) { - automationPattern::timeMap map = +#warning: TODO +/* automationPattern::timeMap map = m_detuning->getAutomationPattern()->getTimeMap(); - return( map.size() > 1 || map[0] != 0 ); + return( map.size() > 1 || map[0] != 0 );*/ + return( FALSE ); } diff --git a/src/core/note_play_handle.cpp b/src/core/note_play_handle.cpp index 45f153b85..ace83e962 100644 --- a/src/core/note_play_handle.cpp +++ b/src/core/note_play_handle.cpp @@ -39,7 +39,7 @@ inline notePlayHandle::baseDetuning::baseDetuning( detuningHelper * _detuning ) : m_detuning( _detuning ), - m_value( m_detuning->getAutomationPattern()->valueAt( 0 ) ) + m_value( /*m_detuning->getAutomationPattern()->valueAt( 0 )*/ 0 ) { } @@ -451,13 +451,14 @@ void notePlayHandle::processMidiTime( const midiTime & _time ) { if( _time >= pos() ) { - float v = detuning()->getAutomationPattern()->valueAt( _time - +#warning: TODO +/* float v = detuning()->getAutomationPattern()->valueAt( _time - pos() ); if( v != m_base_detuning->value() ) { m_base_detuning->setValue( v ); updateFrequency(); - } + }*/ } } diff --git a/src/core/piano.cpp b/src/core/piano.cpp index a2aa1f887..7a9f530d8 100644 --- a/src/core/piano.cpp +++ b/src/core/piano.cpp @@ -179,7 +179,7 @@ void piano::handleKeyRelease( int _key ) */ pianoView::pianoView( QWidget * _parent ) : QWidget( _parent ), /*!< Our parent */ - modelView( NULL ), /*!< Our view model */ + modelView( NULL, this ), /*!< Our view model */ m_piano( NULL ), /*!< Our piano model */ m_startKey( Key_C + Octave_3*KeysPerOctave ), /*!< The first key displayed? */ m_lastKey( -1 ) /*!< The last key displayed? */ @@ -400,7 +400,8 @@ void pianoView::contextMenuEvent( QContextMenuEvent * _me ) } captionMenu contextMenu( tr( "Base note" ) ); - automatableModelView amv( m_piano->m_instrumentTrack->baseNoteModel() ); + automatableModelView amv( m_piano->m_instrumentTrack->baseNoteModel(), + &contextMenu ); amv.addDefaultActions( &contextMenu ); contextMenu.exec( QCursor::pos() ); } diff --git a/src/core/project_journal.cpp b/src/core/project_journal.cpp index d1299e511..4f03fd3a9 100644 --- a/src/core/project_journal.cpp +++ b/src/core/project_journal.cpp @@ -122,7 +122,7 @@ jo_id_t projectJournal::allocID( journallingObject * _obj ) void projectJournal::reallocID( const jo_id_t _id, journallingObject * _obj ) { //printf("realloc %d %d\n", _id, _obj ); - if( m_joIDs.contains( _id ) ) +// if( m_joIDs.contains( _id ) ) { m_joIDs[_id] = _obj; } diff --git a/src/core/sample_play_handle.cpp b/src/core/sample_play_handle.cpp index 17f167093..7e5417528 100644 --- a/src/core/sample_play_handle.cpp +++ b/src/core/sample_play_handle.cpp @@ -41,7 +41,7 @@ samplePlayHandle::samplePlayHandle( const QString & _sample_file ) : m_sampleBuffer( new sampleBuffer( _sample_file ) ), m_doneMayReturnTrue( TRUE ), m_frame( 0 ), - m_audioPort( new audioPort( "samplePlayHandle", NULL ) ), + m_audioPort( new audioPort( "samplePlayHandle" ) ), m_ownAudioPort( TRUE ), m_defaultVolumeModel( 1.0f, 0.0f, 4.0f, 0.001f/* this*/ ), m_volumeModel( &m_defaultVolumeModel ), @@ -58,7 +58,7 @@ samplePlayHandle::samplePlayHandle( sampleBuffer * _sample_buffer ) : m_sampleBuffer( sharedObject::ref( _sample_buffer ) ), m_doneMayReturnTrue( TRUE ), m_frame( 0 ), - m_audioPort( new audioPort( "samplePlayHandle", NULL ) ), + m_audioPort( new audioPort( "samplePlayHandle" ) ), m_ownAudioPort( TRUE ), m_defaultVolumeModel( 1.0f, 0.0f, 4.0f, 0.001f/* this*/ ), m_volumeModel( &m_defaultVolumeModel ), diff --git a/src/core/song.cpp b/src/core/song.cpp index 0252e6161..da06d0c9a 100644 --- a/src/core/song.cpp +++ b/src/core/song.cpp @@ -69,9 +69,11 @@ tick midiTime::s_ticksPerTact = DefaultTicksPerTact; song::song( void ) : trackContainer(), - m_automationTrack( track::create( track::AutomationTrack, this ) ), + m_globalAutomationTrack( dynamic_cast( + track::create( track::HiddenAutomationTrack, + this ) ) ), m_tempoModel( DefaultTempo, MinTempo, MaxTempo, this ), - m_timeSigModel( this, m_automationTrack ), + m_timeSigModel( this ), m_oldTicksPerTact( DefaultTicksPerTact ), m_masterVolumeModel( 100, 0, 200, this ), m_masterPitchModel( 0, -12, 12, this ), @@ -88,7 +90,6 @@ song::song( void ) : m_patternToPlay( NULL ), m_loopPattern( FALSE ) { - m_tempoModel.setTrack( m_automationTrack ); connect( &m_tempoModel, SIGNAL( dataChanged() ), this, SLOT( setTempo() ) ); connect( &m_tempoModel, SIGNAL( dataUnchanged() ), @@ -101,9 +102,6 @@ song::song( void ) : SLOT( updateFramesPerTick() ) ); - m_masterVolumeModel.setTrack( m_automationTrack ); - m_masterPitchModel.setTrack( m_automationTrack ); - connect( &m_masterVolumeModel, SIGNAL( dataChanged() ), this, SLOT( masterVolumeChanged() ) ); /* connect( &m_masterPitchModel, SIGNAL( dataChanged() ), @@ -119,7 +117,7 @@ song::song( void ) : song::~song() { m_playing = FALSE; - delete m_automationTrack; + delete m_globalAutomationTrack; } @@ -289,13 +287,13 @@ void song::processNextBuffer( void ) return; } - QList trackList; + trackList track_list; Sint16 tco_num = -1; switch( m_playMode ) { case Mode_PlaySong: - trackList = tracks(); + track_list = tracks(); // at song-start we have to reset the LFOs if( m_playPos[Mode_PlaySong] == 0 ) { @@ -304,7 +302,7 @@ void song::processNextBuffer( void ) break; case Mode_PlayTrack: - trackList.push_back( m_trackToPlay ); + track_list.push_back( m_trackToPlay ); break; case Mode_PlayBB: @@ -312,7 +310,7 @@ void song::processNextBuffer( void ) { tco_num = engine::getBBTrackContainer()-> currentBB(); - trackList.push_back( bbTrack::findBBTrack( + track_list.push_back( bbTrack::findBBTrack( tco_num ) ); } break; @@ -322,7 +320,7 @@ void song::processNextBuffer( void ) { tco_num = m_patternToPlay->getTrack()-> getTCONum( m_patternToPlay ); - trackList.push_back( + track_list.push_back( m_patternToPlay->getTrack() ); } break; @@ -332,7 +330,7 @@ void song::processNextBuffer( void ) } - if( trackList.empty() == TRUE ) + if( track_list.empty() == TRUE ) { return; } @@ -441,15 +439,16 @@ void song::processNextBuffer( void ) { if( m_playMode == Mode_PlaySong ) { - m_automationTrack->play( m_playPos[m_playMode], + m_globalAutomationTrack->play( + m_playPos[m_playMode], played_frames, total_frames_played, tco_num ); } // loop through all tracks and play them - for( int i = 0; i < trackList.size(); ++i ) + for( int i = 0; i < track_list.size(); ++i ) { - trackList[i]->play( m_playPos[m_playMode], + track_list[i]->play( m_playPos[m_playMode], played_frames, total_frames_played, tco_num ); } @@ -543,10 +542,10 @@ void song::playPattern( pattern * _patternToPlay, bool _loop ) void song::updateLength( void ) { m_length = 0; - const QList & ctl = tracks(); - for( int i = 0; i < ctl.size(); ++i ) + for( trackList::const_iterator it = tracks().begin(); + it != tracks().end(); ++it ) { - const tact cur = ctl[i]->length(); + const tact cur = ( *it )->length(); if( cur > m_length ) { m_length = cur; @@ -617,10 +616,10 @@ void song::stopExport( void ) void song::insertBar( void ) { - QList tl = tracks(); - for( int i = 0; i < tl.size(); ++i ) + for( trackList::iterator it = tracks().begin(); + it != tracks().end(); ++it ) { - tl[i]->insertTact( m_playPos[Mode_PlaySong] ); + ( *it )->insertTact( m_playPos[Mode_PlaySong] ); } } @@ -629,10 +628,10 @@ void song::insertBar( void ) void song::removeBar( void ) { - QList tl = tracks(); - for( int i = 0; i < tl.size(); ++i ) + for( trackList::iterator it = tracks().begin(); + it != tracks().end(); ++it ) { - tl[i]->removeTact( m_playPos[Mode_PlaySong] ); + ( *it )->removeTact( m_playPos[Mode_PlaySong] ); } } @@ -657,6 +656,14 @@ void song::addSampleTrack( void ) +void song::addAutomationTrack( void ) +{ + (void) track::create( track::AutomationTrack, this ); +} + + + + bpm_t song::getTempo( void ) { return( m_tempoModel.value() ); @@ -667,7 +674,7 @@ bpm_t song::getTempo( void ) automationPattern * song::tempoAutomationPattern( void ) { - return( m_tempoModel.getAutomationPattern() ); + return( automationPattern::globalAutomationPattern( &m_tempoModel ) ); } @@ -705,9 +712,11 @@ void song::clearProject( void ) { engine::getAutomationEditor()->setCurrentPattern( NULL ); } - m_tempoModel.getAutomationPattern()->clear(); - m_masterVolumeModel.getAutomationPattern()->clear(); - m_masterPitchModel.getAutomationPattern()->clear(); + automationPattern::globalAutomationPattern( &m_tempoModel )->clear(); + automationPattern::globalAutomationPattern( &m_masterVolumeModel )-> + clear(); + automationPattern::globalAutomationPattern( &m_masterPitchModel )-> + clear(); engine::getMixer()->unlock(); @@ -907,15 +916,17 @@ void song::loadProject( const QString & _file_name ) node = node.nextSibling(); } - engine::getMixer()->unlock(); - // Connect controller links to their controllers // now that everything is loaded controllerConnection::finalizeConnections(); - configManager::inst()->addRecentlyOpenedProject( _file_name ); + // resolve all IDs so that autoModels are automated + automationPattern::resolveAllIDs(); - QCoreApplication::instance()->processEvents(); + + engine::getMixer()->unlock(); + + configManager::inst()->addRecentlyOpenedProject( _file_name ); engine::getProjectJournal()->setJournalling( TRUE ); diff --git a/src/core/surround_area.cpp b/src/core/surround_area.cpp index da4438402..729132bb2 100644 --- a/src/core/surround_area.cpp +++ b/src/core/surround_area.cpp @@ -184,14 +184,12 @@ void surroundArea::mouseReleaseEvent( QMouseEvent * ) -surroundAreaModel::surroundAreaModel( ::model * _parent, track * _track, +surroundAreaModel::surroundAreaModel( ::model * _parent, bool _default_constructed ) : model( _parent, _default_constructed ), m_posX( 0, -SURROUND_AREA_SIZE, SURROUND_AREA_SIZE, _parent ), m_posY( 0, -SURROUND_AREA_SIZE, SURROUND_AREA_SIZE, _parent ) { - m_posX.setTrack( _track ); - m_posY.setTrack( _track ); connect( &m_posX, SIGNAL( dataChanged() ), this, SIGNAL( dataChanged() ) ); connect( &m_posY, SIGNAL( dataChanged() ), @@ -271,6 +269,7 @@ void surroundAreaModel::loadSettings( const QDomElement & _this, +/* automationPattern * surroundAreaModel::automationPatternX( void ) { return( m_posX.getAutomationPattern() ); @@ -280,9 +279,7 @@ automationPattern * surroundAreaModel::automationPatternY( void ) { return( m_posY.getAutomationPattern() ); } - - - +*/ #include "surround_area.moc" diff --git a/src/core/track.cpp b/src/core/track.cpp index 787a565d5..f57242e6d 100644 --- a/src/core/track.cpp +++ b/src/core/track.cpp @@ -113,7 +113,7 @@ trackContentObject::trackContentObject( track * _track ) : m_length(), m_mutedModel( FALSE, this ) { - m_mutedModel.setTrack( _track ); + m_track->addTCO( this ); setJournalling( FALSE ); movePosition( 0 ); changeLength( 0 ); @@ -302,7 +302,7 @@ void trackContentObject::toggleMute( void ) trackContentObjectView::trackContentObjectView( trackContentObject * _tco, trackView * _tv ) : selectableObject( _tv->getTrackContentWidget() ), - modelView( NULL ), + modelView( NULL, this ), m_tco( _tco ), m_trackView( _tv ), m_action( NoAction ), @@ -1069,8 +1069,7 @@ void trackContentWidget::dropEvent( QDropEvent * _de ) { const midiTime pos = getPosition( _de->pos().x() ).toNearestTact(); - trackContentObject * tco = getTrack()->addTCO( - getTrack()->createTCO( pos ) ); + trackContentObject * tco = getTrack()->createTCO( pos ); // value contains our XML-data so simply create a // multimediaProject which does the rest for us... @@ -1109,8 +1108,7 @@ void trackContentWidget::mousePressEvent( QMouseEvent * _me ) { const midiTime pos = getPosition( _me->x() ).getTact() * midiTime::ticksPerTact(); - trackContentObject * tco = getTrack()->addTCO( - getTrack()->createTCO( pos ) ); + trackContentObject * tco = getTrack()->createTCO( pos ); tco->saveJournallingState( FALSE ); tco->movePosition( pos ); @@ -1241,9 +1239,8 @@ void trackContentWidget::undoStep( journalEntry & _je ) case RemoveTrackContentObject: { - trackContentObject * tco = - getTrack()->addTCO( getTrack()->createTCO( - midiTime( 0 ) ) ); + trackContentObject * tco = getTrack()->createTCO( + midiTime( 0 ) ); multimediaProject mmp( _je.data().toMap()["state"].toString(), FALSE ); tco->restoreState( @@ -1346,8 +1343,7 @@ QPixmap * trackOperationsWidget::s_muteOnEnabled; /*!< Mute on and enabled pix */ trackOperationsWidget::trackOperationsWidget( trackView * _parent ) : QWidget( _parent ), /*!< The parent widget */ - m_trackView( _parent ), /*!< The parent track view */ - m_automationDisabled( FALSE ) /*!< Automation enabled flag */ + m_trackView( _parent ) /*!< The parent track view */ { if( s_grip == NULL ) { @@ -1405,13 +1401,6 @@ trackOperationsWidget::trackOperationsWidget( trackView * _parent ) : m_soloBtn->show(); toolTip::add( m_soloBtn, tr( "Solo" ) ); - if( inBBEditor() ) - { - connect( engine::getBBEditor(), - SIGNAL( positionChanged( const midiTime & ) ), - this, SLOT( update() ) ); - } - connect( this, SIGNAL( trackRemovalScheduled( trackView * ) ), m_trackView->getTrackContainerView(), SLOT( deleteTrackView( trackView * ) ), @@ -1486,37 +1475,6 @@ void trackOperationsWidget::paintEvent( QPaintEvent * _pe ) if( m_trackView->isMovingTrack() == FALSE ) { p.drawPixmap( 2, 2, *s_grip ); - if( inBBEditor() ) - { - bbTrack * bb_track = currentBBTrack(); - if( !bb_track || bb_track->automationDisabled( - m_trackView->getTrack() ) ) - { - if( !m_automationDisabled ) - { - m_automationDisabled = TRUE; - setObjectName( "automationDisabled" ); - setStyle( NULL ); -/* m_muteBtn->setActiveGraphic( - *s_muteOffEnabled ); - m_muteBtn->setInactiveGraphic( - *s_muteOnEnabled );*/ - } - } - else - { - if( m_automationDisabled ) - { - m_automationDisabled = FALSE; - setObjectName( "automationEnabled" ); - setStyle( NULL ); -/* m_muteBtn->setActiveGraphic( - *s_muteOffEnabled ); - m_muteBtn->setInactiveGraphic( - *s_muteOnEnabled );*/ - } - } - } m_trackOps->show(); m_muteBtn->show(); } @@ -1565,28 +1523,6 @@ void trackOperationsWidget::updateMenu( void ) { QMenu * to_menu = m_trackOps->menu(); to_menu->clear(); - if( inBBEditor() ) - { - bbTrack * bb_track = currentBBTrack(); - if( bb_track ) - { - if( bb_track->automationDisabled( - m_trackView->getTrack() ) ) - { - to_menu->addAction( embed::getIconPixmap( - "led_off", 16, 16 ), - tr( "Enable automation" ), - this, SLOT( enableAutomation() ) ); - } - else - { - to_menu->addAction( embed::getIconPixmap( - "led_green", 16, 16 ), - tr( "Disable automation" ), - this, SLOT( disableAutomation() ) ); - } - } - } to_menu->addAction( embed::getIconPixmap( "edit_copy", 16, 16 ), tr( "Clone this track" ), this, SLOT( cloneTrack() ) ); @@ -1598,53 +1534,6 @@ void trackOperationsWidget::updateMenu( void ) -/*! \brief Enable automation on this track - * - */ -void trackOperationsWidget::enableAutomation( void ) -{ - currentBBTrack()->enableAutomation( m_trackView->getTrack() ); -} - - - - -/*! \brief Disable automation on this track - * - */ -void trackOperationsWidget::disableAutomation( void ) -{ - currentBBTrack()->disableAutomation( m_trackView->getTrack() ); -} - - - - -/*! \brief Return the current Beat+Bassline track - * - */ -bbTrack * trackOperationsWidget::currentBBTrack( void ) -{ - return( bbTrack::findBBTrack( - engine::getBBTrackContainer()->currentBB() ) ); -} - - - - -/*! \brief Are we in the Beat+Bassline Editor? - * - */ -bool trackOperationsWidget::inBBEditor( void ) -{ - return( m_trackView->getTrackContainerView() - == engine::getBBEditor() ); -} - - - - - // =========================================================================== // track @@ -1668,11 +1557,8 @@ track::track( TrackTypes _type, trackContainer * _tc ) : m_pixmapLoader( NULL ), /*!< For loading the track's pixmaps */ m_mutedModel( FALSE, this ), /*!< For controlling track muting */ m_soloModel( FALSE, this ), /*!< For controlling track soloing */ - m_trackContentObjects(), /*!< The track content objects (segments) */ - m_automationPatterns() /*!< The automation patterns applying */ + m_trackContentObjects() /*!< The track content objects (segments) */ { - m_mutedModel.setTrack( this ); - m_soloModel.setTrack( this ); m_trackContainer->addTrack( this ); } @@ -1691,38 +1577,12 @@ track::track( TrackTypes _type, trackContainer * _tc ) : */ track::~track() { - if( m_trackContainer == engine::getBBTrackContainer() - && engine::getSong() ) - { - QList tracks = engine::getSong()->tracks(); - for( int i = 0; i < tracks.size(); ++i ) - { - if( tracks[i]->type() == BBTrack ) - { - bbTrack * bb_track = (bbTrack *)tracks[i]; - if( bb_track->automationDisabled( this ) ) - { - // Remove reference from bbTrack - bb_track->enableAutomation( this ); - } - } - } - } - while( !m_trackContentObjects.isEmpty() ) { delete m_trackContentObjects.last(); } m_trackContainer->removeTrack( this ); - - for( QList::iterator it = - m_automationPatterns.begin(); - it != m_automationPatterns.end(); - ++it ) - { - ( *it )->forgetTrack(); - } } @@ -1745,6 +1605,8 @@ track * track::create( TrackTypes _tt, trackContainer * _tc ) // case EVENT_TRACK: // case VIDEO_TRACK: case AutomationTrack: t = new automationTrack( _tc ); break; + case HiddenAutomationTrack: + t = new automationTrack( _tc, TRUE ); break; default: break; } @@ -1872,7 +1734,7 @@ void track::loadSettings( const QDomElement & _this ) midiTime( 0 ) ); tco->restoreState( node.toElement() ); saveJournallingState( FALSE ); - addTCO( tco ); +// addTCO( tco ); restoreJournallingState(); } } @@ -1958,7 +1820,7 @@ trackContentObject * track::getTCO( int _tco_num ) } printf( "called track::getTCO( %d ), " "but TCO %d doesn't exist\n", _tco_num, _tco_num ); - return( addTCO( createTCO( _tco_num * midiTime::ticksPerTact() ) ) ); + return( createTCO( _tco_num * midiTime::ticksPerTact() ) ); } @@ -2004,8 +1866,7 @@ int track::getTCONum( trackContentObject * _tco ) * \param _start The MIDI start time of the range. * \param _end The MIDI endi time of the range. */ -void track::getTCOsInRange( QList & _tco_v, - const midiTime & _start, +void track::getTCOsInRange( tcoVector & _tco_v, const midiTime & _start, const midiTime & _end ) { for( tcoVector::iterator it_o = m_trackContentObjects.begin(); @@ -2020,8 +1881,7 @@ void track::getTCOsInRange( QList & _tco_v, // now let's search according position for TCO in list // -> list is ordered by TCO's position afterwards bool inserted = FALSE; - for( QList::iterator it = - _tco_v.begin(); + for( tcoVector::iterator it = _tco_v.begin(); it != _tco_v.end(); ++it ) { if( ( *it )->startPosition() >= s ) @@ -2139,30 +1999,6 @@ tact track::length( void ) const -/*! \brief Add an automation pattern to this track - * - * \param _pattern the automation pattern to add. - */ -void track::addAutomationPattern( automationPattern * _pattern ) -{ - m_automationPatterns.append( _pattern ); -} - - - - -/*! \brief Remove an automation pattern from this track - * - * \param _pattern the automation pattern to remove. - */ -void track::removeAutomationPattern( automationPattern * _pattern ) -{ - m_automationPatterns.removeAll( _pattern ); -} - - - - /*! \brief Invert the track's solo state. * * We have to go through all the tracks determining if any other track @@ -2171,7 +2007,7 @@ void track::removeAutomationPattern( automationPattern * _pattern ) */ void track::toggleSolo( void ) { - trackContainer::trackList & tl = m_trackContainer->m_tracks; + trackContainer::trackList & tl = m_trackContainer->tracks(); bool solo_before = FALSE; for( trackContainer::trackList::iterator it = tl.begin(); @@ -2214,24 +2050,6 @@ void track::toggleSolo( void ) -/*! \brief Send a time code to all tracks to process. - * - * \param _time the MIDI time to send. - */ -void track::sendMidiTime( const midiTime & _time ) -{ - for( QList::iterator it = - m_automationPatterns.begin(); - it != m_automationPatterns.end(); - ++it ) - { - ( *it )->processMidiTime( _time ); - } -} - - - - // =========================================================================== @@ -2249,7 +2067,7 @@ void track::sendMidiTime( const midiTime & _time ) */ trackView::trackView( track * _track, trackContainerView * _tcv ) : QWidget( _tcv->contentWidget() ), /*!< The Track Container View's content widget. */ - modelView( NULL/*_track*/ ), /*!< The model view of this track */ + modelView( NULL, this ), /*!< The model view of this track */ m_track( _track ), /*!< The track we're displaying */ m_trackContainerView( _tcv ), /*!< The track Container View we're displayed in */ m_trackOperationsWidget( this ), /*!< Our trackOperationsWidget */ diff --git a/src/core/track_container.cpp b/src/core/track_container.cpp index 5186264cb..ed70b8bcb 100644 --- a/src/core/track_container.cpp +++ b/src/core/track_container.cpp @@ -45,10 +45,7 @@ trackContainer::trackContainer( void ) : trackContainer::~trackContainer() { - while( !m_tracks.empty() ) - { - delete m_tracks.takeLast(); - } + clearAllTracks(); } @@ -137,7 +134,7 @@ void trackContainer::loadSettings( const QDomElement & _this ) void trackContainer::addTrack( track * _track ) { - if( _track->type() != track::AutomationTrack ) + if( _track->type() != track::HiddenAutomationTrack ) { m_tracks.push_back( _track ); emit trackAdded( _track ); @@ -152,7 +149,7 @@ void trackContainer::removeTrack( track * _track ) int index = m_tracks.indexOf( _track ); if( index != -1 ) { - m_tracks.removeAt( index ); + m_tracks.remove( index ); if( engine::getSong() ) { @@ -175,10 +172,12 @@ void trackContainer::updateAfterTrackAdd( void ) void trackContainer::clearAllTracks( void ) { - while( !m_tracks.empty() ) + for( trackList::iterator it = m_tracks.begin(); + it != m_tracks.end(); ++it ) { - delete m_tracks.takeLast(); + delete *it; } + m_tracks.clear(); } diff --git a/src/gui/automatable_model_view.cpp b/src/gui/automatable_model_view.cpp index 58a282b79..c929594b4 100644 --- a/src/gui/automatable_model_view.cpp +++ b/src/gui/automatable_model_view.cpp @@ -24,13 +24,33 @@ #include - +#include #include "automatable_model_view.h" #include "automation_pattern.h" #include "controller_connection_dialog.h" #include "controller_connection.h" #include "embed.h" +#include "main_window.h" +#include "string_pair_drag.h" + + + +automatableModelView::automatableModelView( ::model * _model, + QWidget * _this ) : + modelView( _model, _this ), + m_description( QString::null ), + m_unit( QString::null ) +{ + widget()->setAcceptDrops( TRUE ); +} + + + + +automatableModelView::~automatableModelView() +{ +} @@ -64,14 +84,11 @@ void automatableModelView::addDefaultActions( QMenu * _menu ) _menu->addSeparator(); - if( !_model->nullTrack() ) - { - _menu->addAction( embed::getIconPixmap( "automation" ), - automatableModel::tr( "&Open in automation editor" ), - _model->getAutomationPattern(), - SLOT( openInAutomationEditor() ) ); - _menu->addSeparator(); - } + _menu->addAction( embed::getIconPixmap( "automation" ), + automatableModel::tr( "Edit song-global automation" ), + amvSlots, + SLOT( editSongGlobalAutomation() ) ); + _menu->addSeparator(); QString controllerTxt; if( _model->getControllerConnection() ) @@ -120,9 +137,30 @@ void automatableModelView::setModel( model * _model, bool _old_model_valid ) +void automatableModelView::mousePressEvent( QMouseEvent * _me ) +{ + if( _me->button() == Qt::LeftButton && + engine::getMainWindow()->isCtrlPressed() == TRUE ) + { + new stringPairDrag( "automatable_model", + QString::number( modelUntyped()->id() ), + QPixmap(), widget() ); + _me->accept(); + } + else if( _me->button() == Qt::MidButton ) + { + modelUntyped()->reset(); + } +} + + + + + + automatableModelViewSlots::automatableModelViewSlots( - automatableModelView * _amv, - QObject * _parent ) : + automatableModelView * _amv, + QObject * _parent ) : QObject(), amv( _amv ) { @@ -189,4 +227,15 @@ void automatableModelViewSlots::removeConnection( void ) } + + +void automatableModelViewSlots::editSongGlobalAutomation( void ) +{ + automationPattern::globalAutomationPattern( amv->modelUntyped() )-> + openInAutomationEditor(); +} + + + + #include "automatable_model_view.moc" diff --git a/src/gui/automation_editor.cpp b/src/gui/automation_editor.cpp index 161935618..a20165ca9 100644 --- a/src/gui/automation_editor.cpp +++ b/src/gui/automation_editor.cpp @@ -4,6 +4,7 @@ * automation_editor.cpp - implementation of automationEditor which is used for * actual setting of dynamic values * + * Copyright (c) 2008 Tobias Doerffel * Copyright (c) 2006-2008 Javier Serrano Polo * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -391,9 +392,9 @@ void automationEditor::setCurrentPattern( automationPattern * _new_pattern ) return; } - m_minLevel = m_pattern->object()->minValue(); - m_maxLevel = m_pattern->object()->maxValue(); - m_step = m_pattern->object()->step(); + m_minLevel = m_pattern->firstObject()->minValue(); + m_maxLevel = m_pattern->firstObject()->maxValue(); + m_step = m_pattern->firstObject()->step(); m_scrollLevel = ( m_minLevel + m_maxLevel ) / 2; // resizeEvent() does the rest for us (scrolling, range-checking @@ -674,9 +675,9 @@ void automationEditor::mousePressEvent( QMouseEvent * _me ) // and check whether the user clicked on an // existing value - if( pos_ticks >= -it.key() && + if( pos_ticks >= it.key() && len > 0 && - pos_ticks <= -it.key() + len && + pos_ticks <= it.key() + len && it.value() == level ) { break; @@ -702,13 +703,13 @@ void automationEditor::mousePressEvent( QMouseEvent * _me ) // reset it so that it can be used for // ops (move, resize) after this // code-block - it = time_map.find( -new_time ); + it = time_map.find( new_time ); } // move it m_action = MOVE_VALUE; int aligned_x = (int)( (float)( ( - -it.key() - + it.key() - m_currentPosition ) * m_ppt ) / DefaultTicksPerTact ); m_moveXOffset = x - aligned_x - 1; @@ -726,7 +727,7 @@ void automationEditor::mousePressEvent( QMouseEvent * _me ) if( it != time_map.end() ) { - m_pattern->removeValue( -it.key() ); + m_pattern->removeValue( it.key() ); engine::getSong()->setModified(); } } @@ -859,8 +860,8 @@ void automationEditor::mouseMoveEvent( QMouseEvent * _me ) { // and check whether the cursor is over an // existing value - if( pos_ticks >= -it.key() && - pos_ticks <= -it.key() + + if( pos_ticks >= it.key() && + pos_ticks <= it.key() + //TODO: Add constant 4 && it.value() == level ) { @@ -938,10 +939,8 @@ void automationEditor::mouseMoveEvent( QMouseEvent * _me ) int pos_ticks = x * DefaultTicksPerTact / m_ppt + m_currentPosition; - m_selectedTick = pos_ticks - - m_selectStartTick; - if( (int) m_selectStartTick + m_selectedTick < - 0 ) + m_selectedTick = pos_ticks - m_selectStartTick; + if( (int) m_selectStartTick + m_selectedTick < 0 ) { m_selectedTick = -static_cast( m_selectStartTick ); @@ -1031,11 +1030,12 @@ void automationEditor::mouseMoveEvent( QMouseEvent * _me ) it != m_selValuesForMove.end(); ++it ) { midiTime new_value_pos; - if( -it.key() ) + if( it.key() ) { - int value_tact = ( -it.key() >> 6 ) +#warning broken time-sigs + int value_tact = ( it.key() >> 6 ) + tact_diff; - int value_ticks = ( -it.key() & 63 ) + int value_ticks = ( it.key() & 63 ) + ticks_diff; // ensure value_ticks range if( value_ticks >> 6 ) @@ -1044,12 +1044,12 @@ void automationEditor::mouseMoveEvent( QMouseEvent * _me ) >> 6; value_ticks &= 63; } - m_pattern->removeValue( -it.key() ); + m_pattern->removeValue( it.key() ); new_value_pos = midiTime( value_tact, value_ticks ); } new_selValuesForMove[ - -m_pattern->putValue( new_value_pos, + m_pattern->putValue( new_value_pos, it.value () + level_diff, FALSE )] = it.value() + level_diff; @@ -1190,7 +1190,7 @@ void automationEditor::paintEvent( QPaintEvent * _pe ) float level[] = { m_minLevel, m_maxLevel }; for( int i = 0; i < 2; ++i ) { - const QString & label = m_pattern->object() + const QString & label = m_pattern->firstObject() ->displayValue( level[i] ); p.setPen( QColor( 240, 240, 240 ) ); p.drawText( 1, y[i] - font_height + 1, @@ -1219,7 +1219,7 @@ void automationEditor::paintEvent( QPaintEvent * _pe ) for( ; y >= TOP_MARGIN && level <= m_topLevel; y -= printable * m_y_delta, level += printable ) { - const QString & label = m_pattern->object() + const QString & label = m_pattern->firstObject() ->displayValue( level ); p.setPen( QColor( 240, 240, 240 ) ); p.drawText( 1, y - font_height + 1, @@ -1334,15 +1334,14 @@ void automationEditor::paintEvent( QPaintEvent * _pe ) if( validPattern() == TRUE ) { timeMap & time_map = m_pattern->getTimeMap(); - timeMap::iterator it = time_map.end(); + timeMap::iterator it = time_map.begin(); do { - --it; Sint32 len_ticks = 4; const float level = it.value(); - Sint32 pos_ticks = -it.key(); + Sint32 pos_ticks = it.key(); const int x = ( pos_ticks - m_currentPosition ) * m_ppt / DefaultTicksPerTact; @@ -1352,18 +1351,17 @@ void automationEditor::paintEvent( QPaintEvent * _pe ) } int rect_width; - if( it != time_map.begin() ) + if( it+1 != time_map.end() ) { - timeMap::iterator it_prev = it; - --it_prev; - Sint32 next_pos_ticks = -it_prev.key(); + timeMap::iterator it_prev = it+1; + Sint32 next_pos_ticks = it_prev.key(); int next_x = ( next_pos_ticks - m_currentPosition ) * m_ppt / DefaultTicksPerTact; // skip this value if not in visible area at all - if( next_x < 0 ) + if( next_x > width() ) { - continue; + break; } rect_width = next_x - x; } @@ -1428,7 +1426,8 @@ void automationEditor::paintEvent( QPaintEvent * _pe ) is_selected ); } else printf("not in range\n"); - } while( it != time_map.begin() ); + ++it; + } while( it != time_map.end() ); } else { @@ -1782,7 +1781,7 @@ void automationEditor::selectAll( void ) timeMap::iterator it = time_map.begin(); m_selectStartTick = 0; - m_selectedTick = -it.key() + len_ticks; + m_selectedTick = it.key() + len_ticks; m_selectStartLevel = it.value(); m_selectedLevels = 1; @@ -1839,7 +1838,7 @@ void automationEditor::getSelectedValues( timeMap & _selected_values ) tick len_ticks = DefaultTicksPerTact / 16; float level = it.value(); - tick pos_ticks = -it.key(); + tick pos_ticks = it.key(); if( level >= selLevel_start && level <= selLevel_end && pos_ticks >= sel_pos_start && @@ -1897,7 +1896,7 @@ void automationEditor::cutSelectedValues( void ) it != selected_values.end(); ++it ) { m_valuesToCopy[it.key()] = it.value(); - m_pattern->removeValue( -it.key() ); + m_pattern->removeValue( it.key() ); } } @@ -1920,7 +1919,7 @@ void automationEditor::pasteValues( void ) for( timeMap::iterator it = m_valuesToCopy.begin(); it != m_valuesToCopy.end(); ++it ) { - m_pattern->putValue( -it.key() + m_currentPosition, + m_pattern->putValue( it.key() + m_currentPosition, it.value() ); } @@ -1950,7 +1949,7 @@ void automationEditor::deleteSelectedValues( void ) for( timeMap::iterator it = selected_values.begin(); it != selected_values.end(); ++it ) { - m_pattern->removeValue( -it.key() ); + m_pattern->removeValue( it.key() ); } if( update_after_delete == TRUE ) diff --git a/src/gui/controller_dialog.cpp b/src/gui/controller_dialog.cpp index 0cbe22b52..afe2ff78c 100644 --- a/src/gui/controller_dialog.cpp +++ b/src/gui/controller_dialog.cpp @@ -34,7 +34,7 @@ controllerDialog::controllerDialog( controller * _controller, QWidget * _parent ) : QWidget( _parent ), - modelView( _controller ) + modelView( _controller, this ) { } diff --git a/src/gui/effect_control_dialog.cpp b/src/gui/effect_control_dialog.cpp index 980eb631f..9cff5efee 100644 --- a/src/gui/effect_control_dialog.cpp +++ b/src/gui/effect_control_dialog.cpp @@ -36,7 +36,7 @@ effectControlDialog::effectControlDialog( effectControls * _controls ) : QWidget( NULL ), - modelView( _controls ), + modelView( _controls, this ), m_effectControls( _controls ) { setWindowTitle( m_effectControls->getEffect()->publicName() ); diff --git a/src/gui/fx_mixer_view.cpp b/src/gui/fx_mixer_view.cpp index 00f6e6d2c..b2c3c38eb 100644 --- a/src/gui/fx_mixer_view.cpp +++ b/src/gui/fx_mixer_view.cpp @@ -106,7 +106,7 @@ private: fxMixerView::fxMixerView() : QWidget(), - modelView( NULL ) + modelView( NULL, this ) { fxMixer * m = engine::getFxMixer(); diff --git a/src/gui/piano_roll.cpp b/src/gui/piano_roll.cpp index e33a690bf..ad013e8d8 100644 --- a/src/gui/piano_roll.cpp +++ b/src/gui/piano_roll.cpp @@ -602,7 +602,8 @@ inline void pianoRoll::drawDetuningInfo( QPainter & _p, note * _n, int _x, int middle_y = _y + KEY_LINE_HEIGHT / 2; _p.setPen( QColor( 0xFF, 0xDF, 0x20 ) ); - timeMap & map = _n->detuning()->getAutomationPattern()->getTimeMap(); +#warning BLAH +/* timeMap & map = _n->detuning()->getAutomationPattern()->getTimeMap(); timeMap::iterator it = map.end(); do { @@ -620,7 +621,7 @@ inline void pianoRoll::drawDetuningInfo( QPainter & _p, note * _n, int _x, _p.drawLine( pos_x - 1, pos_y, pos_x + 1, pos_y ); _p.drawLine( pos_x, pos_y - 1, pos_x, pos_y + 1 ); - } while( it != map.begin() ); + } while( it != map.begin() );*/ } diff --git a/src/gui/song_editor.cpp b/src/gui/song_editor.cpp index c1371ab3a..9668873c4 100644 --- a/src/gui/song_editor.cpp +++ b/src/gui/song_editor.cpp @@ -236,10 +236,10 @@ songEditor::songEditor( song * _song, songEditor * & _engine_ptr ) : m_s, SLOT( addSampleTrack() ), m_toolBar ); - m_addControllerButton = new toolButton( embed::getIconPixmap( - "add_controller", 24, 24 ), - tr( "Add controller" ), - m_s, SLOT( addSampleTrack() ), + m_addAutomationTrackButton = new toolButton( embed::getIconPixmap( + "add_automation", 24, 24 ), + tr( "Add automation-track" ), + m_s, SLOT( addAutomationTrack() ), m_toolBar ); m_drawModeButton = new toolButton( embed::getIconPixmap( @@ -307,7 +307,7 @@ songEditor::songEditor( song * _song, songEditor * & _engine_ptr ) : tb_layout->addSpacing( 10 ); tb_layout->addWidget( m_addBBTrackButton ); tb_layout->addWidget( m_addSampleTrackButton ); - tb_layout->addWidget( m_addControllerButton ); + tb_layout->addWidget( m_addAutomationTrackButton ); tb_layout->addSpacing( 10 ); tb_layout->addWidget( m_drawModeButton ); tb_layout->addWidget( m_editModeButton ); diff --git a/src/gui/track_container_view.cpp b/src/gui/track_container_view.cpp index ee55aa31d..1e4d6cfe7 100644 --- a/src/gui/track_container_view.cpp +++ b/src/gui/track_container_view.cpp @@ -50,7 +50,7 @@ trackContainerView::trackContainerView( trackContainer * _tc ) : QWidget(), - modelView( NULL ), + modelView( NULL, this ), m_currentPosition( 0, 0 ), m_tc( _tc ), m_trackViews(), @@ -156,7 +156,7 @@ void trackContainerView::moveTrackViewUp( trackView * _tv ) m_trackViews[i - 1]->getTrack() ); m_scrollLayout->removeWidget( t ); m_scrollLayout->insertWidget( i - 1, t ); - m_tc->m_tracks.swap( i - 1, i ); + qSwap( m_tc->m_tracks[i-1], m_tc->m_tracks[i] ); m_trackViews.swap( i - 1, i ); realignTracks(); break; @@ -178,7 +178,7 @@ void trackContainerView::moveTrackViewDown( trackView * _tv ) m_trackViews[i + 1]->getTrack() ); m_scrollLayout->removeWidget( t ); m_scrollLayout->insertWidget( i + 1, t ); - m_tc->m_tracks.swap( i, i + 1 ); + qSwap( m_tc->m_tracks[i], m_tc->m_tracks[i+1] ); m_trackViews.swap( i, i + 1 ); realignTracks(); break; diff --git a/src/gui/widgets/automatable_button.cpp b/src/gui/widgets/automatable_button.cpp index b975664c9..f6c223c7b 100644 --- a/src/gui/widgets/automatable_button.cpp +++ b/src/gui/widgets/automatable_button.cpp @@ -33,6 +33,7 @@ #include "caption_menu.h" #include "embed.h" +#include "main_window.h" @@ -40,7 +41,7 @@ automatableButton::automatableButton( QWidget * _parent, const QString & _name ) : QPushButton( _parent ), - boolModelView( new boolModel( FALSE, NULL, _name, TRUE ) ), + boolModelView( new boolModel( FALSE, NULL, _name, TRUE ), this ), m_group( NULL ) { setAccessibleName( _name ); @@ -86,8 +87,9 @@ void automatableButton::update( void ) void automatableButton::contextMenuEvent( QContextMenuEvent * _me ) { - if( model()->nullTrack() && - ( m_group == NULL || m_group->model()->nullTrack() ) ) +/* if( model()->nullTrack() && + ( m_group == NULL || m_group->model()->nullTrack() ) )*/ + if( m_group != NULL && !m_group->model()->isAutomated() ) { QPushButton::contextMenuEvent( _me ); return; @@ -99,20 +101,14 @@ void automatableButton::contextMenuEvent( QContextMenuEvent * _me ) // an QApplication::restoreOverrideCursor()-call... mouseReleaseEvent( NULL ); - QWidget * target; QString targetName; - automationPattern * pattern; if ( m_group != NULL ) { - target = m_group; targetName = m_group->model()->displayName(); - pattern = m_group->model()->getAutomationPattern(); } else { - target = this; targetName = model()->displayName(); - pattern = model()->getAutomationPattern(); } captionMenu contextMenu( targetName ); @@ -125,7 +121,8 @@ void automatableButton::contextMenuEvent( QContextMenuEvent * _me ) void automatableButton::mousePressEvent( QMouseEvent * _me ) { - if( _me->button() == Qt::LeftButton ) + if( _me->button() == Qt::LeftButton && + engine::getMainWindow()->isCtrlPressed() == FALSE ) { if( isCheckable() ) { @@ -135,6 +132,7 @@ void automatableButton::mousePressEvent( QMouseEvent * _me ) } else { + automatableModelView::mousePressEvent( _me ); QPushButton::mousePressEvent( _me ); } } @@ -177,7 +175,7 @@ void automatableButton::toggle( void ) automatableButtonGroup::automatableButtonGroup( QWidget * _parent, const QString & _name ) : QWidget( _parent ), - intModelView( new intModel( 0, 0, 0, NULL, _name, TRUE ) ) + intModelView( new intModel( 0, 0, 0, NULL, _name, TRUE ), this ) { hide(); setAccessibleName( _name ); diff --git a/src/gui/widgets/automatable_slider.cpp b/src/gui/widgets/automatable_slider.cpp index 54da9e28f..216b2b8a3 100644 --- a/src/gui/widgets/automatable_slider.cpp +++ b/src/gui/widgets/automatable_slider.cpp @@ -33,14 +33,15 @@ #include "caption_menu.h" #include "embed.h" -#include "knob.h" +#include "main_window.h" -automatableSlider::automatableSlider( QWidget * _parent, const QString & _name ) : +automatableSlider::automatableSlider( QWidget * _parent, + const QString & _name ) : QSlider( _parent ), - intModelView( new intModel( 0, 0, 0, NULL, _name, TRUE ) ), + intModelView( new intModel( 0, 0, 0, NULL, _name, TRUE ), this ), m_showStatus( FALSE ) { setAccessibleName( _name ); @@ -73,8 +74,16 @@ void automatableSlider::contextMenuEvent( QContextMenuEvent * _me ) void automatableSlider::mousePressEvent( QMouseEvent * _me ) { - m_showStatus = TRUE; - QSlider::mousePressEvent( _me ); + if( _me->button() == Qt::LeftButton && + engine::getMainWindow()->isCtrlPressed() == FALSE ) + { + m_showStatus = TRUE; + QSlider::mousePressEvent( _me ); + } + else + { + automatableModelView::mousePressEvent( _me ); + } } diff --git a/src/gui/widgets/combobox.cpp b/src/gui/widgets/combobox.cpp index 6be951920..0e9b956bd 100644 --- a/src/gui/widgets/combobox.cpp +++ b/src/gui/widgets/combobox.cpp @@ -39,6 +39,7 @@ #include "caption_menu.h" #include "embed.h" #include "gui_templates.h" +#include "main_window.h" QPixmap * comboBox::s_background = NULL; @@ -50,7 +51,7 @@ const int CB_ARROW_BTN_WIDTH = 20; comboBox::comboBox( QWidget * _parent, const QString & _name ) : QWidget( _parent ), - intModelView( new comboBoxModel ), + intModelView( new comboBoxModel, this ), m_menu( this ), m_pressed( FALSE ) { @@ -94,7 +95,7 @@ comboBox::~comboBox() void comboBox::contextMenuEvent( QContextMenuEvent * _me ) { - if( model()->nullTrack() || _me->x() <= width() - CB_ARROW_BTN_WIDTH ) + if( _me->x() <= width() - CB_ARROW_BTN_WIDTH ) { QWidget::contextMenuEvent( _me ); return; @@ -110,50 +111,55 @@ void comboBox::contextMenuEvent( QContextMenuEvent * _me ) void comboBox::mousePressEvent( QMouseEvent * _me ) { - if( _me->x() > width() - CB_ARROW_BTN_WIDTH ) + if( _me->button() == Qt::LeftButton && + engine::getMainWindow()->isCtrlPressed() == FALSE ) { - if( _me->button() == Qt::RightButton ) + if( _me->x() > width() - CB_ARROW_BTN_WIDTH ) { - return; - } + m_pressed = TRUE; + update(); - m_pressed = TRUE; - update(); - - m_menu.clear(); - for( int i = 0; i < model()->size(); ++i ) - { - QAction * a = m_menu.addAction( - model()->itemPixmap( i ) ? - model()->itemPixmap( i )->pixmap() : - QPixmap(), + m_menu.clear(); + for( int i = 0; i < model()->size(); ++i ) + { + QAction * a = m_menu.addAction( + model()->itemPixmap( i ) ? + model()->itemPixmap( i )-> + pixmap() : + QPixmap(), model()->itemText( i ) ); - a->setData( i ); - } + a->setData( i ); + } - QPoint gpos = mapToGlobal( QPoint( 0, height() ) ); - if( gpos.y() + m_menu.sizeHint().height() < + QPoint gpos = mapToGlobal( QPoint( 0, height() ) ); + if( gpos.y() + m_menu.sizeHint().height() < qApp->desktop()->height() ) - { - m_menu.exec( gpos ); + { + m_menu.exec( gpos ); + } + else + { + m_menu.exec( mapToGlobal( + QPoint( width(), 0 ) ) ); + } + m_pressed = FALSE; + update(); } - else + else if( _me->button() == Qt::LeftButton ) { - m_menu.exec( mapToGlobal( QPoint( width(), 0 ) ) ); + model()->setInitValue( model()->value() + 1 ); + update(); } - m_pressed = FALSE; - update(); - } - else if( _me->button() == Qt::LeftButton ) - { - model()->setInitValue( model()->value() + 1 ); - update(); } else if( _me->button() == Qt::RightButton ) { model()->setInitValue( model()->value() - 1 ); update(); } + else + { + automatableModelView::mousePressEvent( _me ); + } } diff --git a/src/gui/widgets/controller_rack_view.cpp b/src/gui/widgets/controller_rack_view.cpp index d2456ca4f..582587b73 100644 --- a/src/gui/widgets/controller_rack_view.cpp +++ b/src/gui/widgets/controller_rack_view.cpp @@ -43,7 +43,7 @@ controllerRackView::controllerRackView( ) : QWidget(), - modelView( NULL ) + modelView( NULL, this ) { setFixedSize( 250, 250 ); setWindowIcon( embed::getIconPixmap( "controller" ) ); diff --git a/src/gui/widgets/controller_view.cpp b/src/gui/widgets/controller_view.cpp index 5d9142976..90f2d28fd 100644 --- a/src/gui/widgets/controller_view.cpp +++ b/src/gui/widgets/controller_view.cpp @@ -47,7 +47,7 @@ controllerView::controllerView( controller * _model, QWidget * _parent ) : QWidget( _parent ), - modelView( _model ), + modelView( _model, this ), m_bg( embed::getIconPixmap( "controller_bg" ) ), m_subWindow( NULL ), m_controllerDlg( NULL ), diff --git a/src/gui/widgets/effect_rack_view.cpp b/src/gui/widgets/effect_rack_view.cpp index 1f081a87f..a9f196092 100644 --- a/src/gui/widgets/effect_rack_view.cpp +++ b/src/gui/widgets/effect_rack_view.cpp @@ -40,7 +40,7 @@ effectRackView::effectRackView( effectChain * _model, QWidget * _parent ) : QWidget( _parent ), - modelView( NULL ) + modelView( NULL, this ) { setFixedSize( 250, 250 ); diff --git a/src/gui/widgets/envelope_and_lfo_view.cpp b/src/gui/widgets/envelope_and_lfo_view.cpp index f9b07a403..52852f200 100644 --- a/src/gui/widgets/envelope_and_lfo_view.cpp +++ b/src/gui/widgets/envelope_and_lfo_view.cpp @@ -91,7 +91,7 @@ QPixmap * envelopeAndLFOView::s_lfoGraph = NULL; envelopeAndLFOView::envelopeAndLFOView( QWidget * _parent ) : QWidget( _parent ), - modelView( NULL ), + modelView( NULL, this ), m_params( NULL ) { if( s_envGraph == NULL ) diff --git a/src/gui/widgets/fader.cpp b/src/gui/widgets/fader.cpp index 8cb3560a5..2ae24ec1f 100644 --- a/src/gui/widgets/fader.cpp +++ b/src/gui/widgets/fader.cpp @@ -52,13 +52,13 @@ #include "fader.h" #include "embed.h" #include "caption_menu.h" -#include "automation_pattern.h" +#include "main_window.h" fader::fader( floatModel * _model, QWidget * _parent ) : QWidget( _parent ), - floatModelView( _model ), + floatModelView( _model, this ), m_model( _model ), m_fPeakValue_L( 0.0 ), m_fPeakValue_R( 0.0 ), @@ -86,13 +86,10 @@ fader::~fader() void fader::contextMenuEvent( QContextMenuEvent * _ev ) { - if( !model()->nullTrack() ) - { - captionMenu contextMenu( accessibleName() ); - addDefaultActions( &contextMenu ); - contextMenu.exec( QCursor::pos() ); - _ev->accept(); - } + captionMenu contextMenu( accessibleName() ); + addDefaultActions( &contextMenu ); + contextMenu.exec( QCursor::pos() ); + _ev->accept(); } @@ -110,17 +107,24 @@ void fader::mouseMoveEvent( QMouseEvent *ev ) -void fader::mousePressEvent(QMouseEvent *ev) + +void fader::mousePressEvent( QMouseEvent * _me ) { - if( ev->button() == Qt::LeftButton ) + if( _me->button() == Qt::LeftButton && + engine::getMainWindow()->isCtrlPressed() == FALSE ) { - mouseMoveEvent( ev ); - ev->accept(); + mouseMoveEvent( _me ); + _me->accept(); + } + else + { + automatableModelView::mousePressEvent( _me ); } } + void fader::wheelEvent ( QWheelEvent *ev ) { ev->accept(); @@ -178,6 +182,7 @@ void fader::setPeak_R( float fPeak ) + void fader::paintEvent( QPaintEvent * ev) { QPainter painter(this); @@ -226,6 +231,7 @@ void fader::paintEvent( QPaintEvent * ev) + void fader::setMaxPeak( float fMax ) { m_fMaxPeak = fMax; @@ -233,6 +239,7 @@ void fader::setMaxPeak( float fMax ) + void fader::setMinPeak( float fMin ) { m_fMinPeak = fMin; diff --git a/src/gui/widgets/graph.cpp b/src/gui/widgets/graph.cpp index 2b2543f24..1cc0306f3 100644 --- a/src/gui/widgets/graph.cpp +++ b/src/gui/widgets/graph.cpp @@ -42,7 +42,7 @@ using namespace std; graph::graph( QWidget * _parent, graphStyle _style ) : QWidget( _parent ), /* TODO: size, background? */ - modelView( new graphModel( -1.0, 1.0, 128, NULL, NULL, TRUE ) ), + modelView( new graphModel( -1.0, 1.0, 128, NULL, TRUE ), this ), m_graphStyle( _style ) { m_mouseDown = false; @@ -343,8 +343,7 @@ void graph::updateGraph( void ) graphModel::graphModel( float _min, float _max, Uint32 _length, - ::model * _parent, track * _track, - bool _default_constructed ) : + ::model * _parent, bool _default_constructed ) : model( _parent, _default_constructed ), m_samples( _length ), m_minValue( _min ), diff --git a/src/gui/widgets/group_box.cpp b/src/gui/widgets/group_box.cpp index 0ef40903b..e20d6cc29 100644 --- a/src/gui/widgets/group_box.cpp +++ b/src/gui/widgets/group_box.cpp @@ -46,7 +46,7 @@ QPixmap * groupBox::s_ledBg = NULL; groupBox::groupBox( const QString & _caption, QWidget * _parent ) : QWidget( _parent ), - boolModelView( NULL ), + boolModelView( NULL, this ), m_caption( _caption ) { if( s_ledBg == NULL ) diff --git a/src/gui/widgets/instrument_function_views.cpp b/src/gui/widgets/instrument_function_views.cpp index 31cf28e8c..dc55040f0 100644 --- a/src/gui/widgets/instrument_function_views.cpp +++ b/src/gui/widgets/instrument_function_views.cpp @@ -55,7 +55,7 @@ const int ARP_GROUPBOX_HEIGHT = 240 - ARP_GROUPBOX_Y; chordCreatorView::chordCreatorView( chordCreator * _cc, QWidget * _parent ) : QWidget( _parent ), - modelView( NULL ), + modelView( NULL, this ), m_cc( _cc ), m_chordsGroupBox( new groupBox( tr( "CHORDS" ), this ) ), m_chordsComboBox( new comboBox( m_chordsGroupBox ) ), @@ -108,7 +108,7 @@ void chordCreatorView::modelChanged( void ) arpeggiatorView::arpeggiatorView( arpeggiator * _arp, QWidget * _parent ) : QWidget( _parent ), - modelView( NULL ), + modelView( NULL, this ), m_a( _arp ), m_arpGroupBox( new groupBox( tr( "ARPEGGIO" ), this ) ), m_arpComboBox( new comboBox( m_arpGroupBox) ), diff --git a/src/gui/widgets/instrument_midi_io_view.cpp b/src/gui/widgets/instrument_midi_io_view.cpp index 4a149208f..0d6177a51 100644 --- a/src/gui/widgets/instrument_midi_io_view.cpp +++ b/src/gui/widgets/instrument_midi_io_view.cpp @@ -43,7 +43,7 @@ instrumentMidiIOView::instrumentMidiIOView( QWidget * _parent ) : QWidget( _parent ), - modelView( NULL ), + modelView( NULL, this ), m_rpBtn( NULL ), m_wpBtn( NULL ) { diff --git a/src/gui/widgets/instrument_sound_shaping_view.cpp b/src/gui/widgets/instrument_sound_shaping_view.cpp index f3f51feee..b08aed95f 100644 --- a/src/gui/widgets/instrument_sound_shaping_view.cpp +++ b/src/gui/widgets/instrument_sound_shaping_view.cpp @@ -48,7 +48,7 @@ const int FILTER_GROUPBOX_HEIGHT = 245-FILTER_GROUPBOX_Y; instrumentSoundShapingView::instrumentSoundShapingView( QWidget * _parent ) : QWidget( _parent ), - modelView( NULL ), + modelView( NULL, this ), m_ss( NULL ) { m_targetsTabWidget = new tabWidget( tr( "TARGET" ), this ); diff --git a/src/gui/widgets/knob.cpp b/src/gui/widgets/knob.cpp index 9120c6149..92d1d0ef8 100644 --- a/src/gui/widgets/knob.cpp +++ b/src/gui/widgets/knob.cpp @@ -60,7 +60,7 @@ textFloat * knob::s_textFloat = NULL; knob::knob( int _knob_num, QWidget * _parent, const QString & _name ) : QWidget( _parent ), - floatModelView( new knobModel( 0, 0, 0, 1, NULL, _name, TRUE ) ), + floatModelView( new knobModel( 0, 0, 0, 1, NULL, _name, TRUE ), this ), m_knobNum( _knob_num ), m_label( "" ), m_knobPixmap( NULL ), @@ -75,8 +75,6 @@ knob::knob( int _knob_num, QWidget * _parent, const QString & _name ) : s_textFloat = new textFloat; } - setAcceptDrops( TRUE ); - setAccessibleName( _name ); if( m_knobNum != knobStyled ) { @@ -404,7 +402,7 @@ void knob::contextMenuEvent( QContextMenuEvent * ) void knob::dragEnterEvent( QDragEnterEvent * _dee ) { stringPairDrag::processDragEnterEvent( _dee, "float_value," - "link_object" ); + "automatable_model" ); } @@ -419,7 +417,7 @@ void knob::dropEvent( QDropEvent * _de ) model()->setValue( val.toFloat() ); _de->accept(); } - else if( type == "link_object" ) + else if( type == "automatable_model" ) { automatableModel * mod = dynamic_cast( engine::getProjectJournal()-> @@ -456,23 +454,15 @@ void knob::mousePressEvent( QMouseEvent * _me ) m_buttonPressed = TRUE; } else if( _me->button() == Qt::LeftButton && - engine::getMainWindow()->isCtrlPressed() == TRUE/* && - engine::getMainWindow()->isShiftPressed() == FALSE*/ ) + engine::getMainWindow()->isShiftPressed() == TRUE ) { new stringPairDrag( "float_value", QString::number( model()->value() ), QPixmap(), this ); } - else if( _me->button() == Qt::LeftButton && - engine::getMainWindow()->isShiftPressed() == TRUE ) + else { - new stringPairDrag( "link_object", - QString::number( model()->id() ), - QPixmap(), this ); - } - else if( _me->button() == Qt::MidButton ) - { - model()->reset(); + automatableModelView::mousePressEvent( _me ); } } @@ -498,10 +488,7 @@ void knob::mouseReleaseEvent( QMouseEvent * /* _me*/ ) { model()->addJournalEntryFromOldToCurVal(); - if( m_buttonPressed ) - { - m_buttonPressed = TRUE; - } + m_buttonPressed = FALSE; m_mouseOffset = 0; emit sliderReleased(); diff --git a/src/gui/widgets/ladspa_control_view.cpp b/src/gui/widgets/ladspa_control_view.cpp index 51d1ca184..5de7005b6 100644 --- a/src/gui/widgets/ladspa_control_view.cpp +++ b/src/gui/widgets/ladspa_control_view.cpp @@ -36,7 +36,7 @@ ladspaControlView::ladspaControlView( QWidget * _parent, ladspaControl * _ctl ) : QWidget( _parent ), - modelView( _ctl ), + modelView( _ctl, this ), m_ctl( _ctl ) { QHBoxLayout * layout = new QHBoxLayout( this ); diff --git a/src/gui/widgets/lcd_spinbox.cpp b/src/gui/widgets/lcd_spinbox.cpp index a7e9137d2..d1f78c854 100644 --- a/src/gui/widgets/lcd_spinbox.cpp +++ b/src/gui/widgets/lcd_spinbox.cpp @@ -4,7 +4,7 @@ * lcd_spinbox.cpp - class lcdSpinBox, an improved QLCDNumber * * Copyright (c) 2005-2008 Tobias Doerffel - * Paul Giblock + * Copyright (c) 2008 Paul Giblock * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -26,7 +26,6 @@ */ -#include "lcd_spinbox.h" #include #include @@ -35,16 +34,19 @@ #include #include +#include "lcd_spinbox.h" #include "caption_menu.h" #include "embed.h" #include "gui_templates.h" #include "templates.h" +#include "main_window.h" + lcdSpinBox::lcdSpinBox( int _num_digits, QWidget * _parent, const QString & _name ) : QWidget( _parent ), - intModelView( new intModel( 0, 0, 0, NULL, _name, TRUE ) ), + intModelView( new intModel( 0, 0, 0, NULL, _name, TRUE ), this ), m_label(), m_numDigits( _num_digits ), m_origMousePos() @@ -69,7 +71,7 @@ lcdSpinBox::lcdSpinBox( int _num_digits, QWidget * _parent, lcdSpinBox::lcdSpinBox( int _num_digits, const QString & _lcd_style, QWidget * _parent, const QString & _name ) : QWidget( _parent ), - intModelView( new intModel( 0, 0, 0, NULL, _name, TRUE ) ), + intModelView( new intModel( 0, 0, 0, NULL, _name, TRUE ), this ), m_label(), m_numDigits( _num_digits ), m_origMousePos() @@ -264,12 +266,6 @@ void lcdSpinBox::contextMenuEvent( QContextMenuEvent * _me ) { m_origMousePos = _me->globalPos(); - if( model()->nullTrack() ) - { - QWidget::contextMenuEvent( _me ); - return; - } - // for the case, the user clicked right while pressing left mouse- // button, the context-menu appears while mouse-cursor is still hidden // and it isn't shown again until user does something which causes @@ -286,12 +282,18 @@ void lcdSpinBox::contextMenuEvent( QContextMenuEvent * _me ) void lcdSpinBox::mousePressEvent( QMouseEvent * _me ) { - if( _me->button() == Qt::LeftButton && _me->y() < m_cellHeight + 2 ) + if( _me->button() == Qt::LeftButton && + engine::getMainWindow()->isCtrlPressed() == FALSE && + _me->y() < m_cellHeight + 2 ) { m_origMousePos = _me->globalPos(); QApplication::setOverrideCursor( Qt::BlankCursor ); model()->prepareJournalEntryFromOldVal(); } + else + { + automatableModelView::mousePressEvent( _me ); + } } diff --git a/src/gui/widgets/meter_dialog.cpp b/src/gui/widgets/meter_dialog.cpp index 2ba620f87..86b625063 100644 --- a/src/gui/widgets/meter_dialog.cpp +++ b/src/gui/widgets/meter_dialog.cpp @@ -34,7 +34,7 @@ meterDialog::meterDialog( QWidget * _parent, bool _simple ) : QWidget( _parent ), - modelView( NULL ) + modelView( NULL, this ) { QVBoxLayout * vlayout = new QVBoxLayout( this ); vlayout->setSpacing( 0 ); diff --git a/src/gui/widgets/midi_port_menu.cpp b/src/gui/widgets/midi_port_menu.cpp index ade2550c7..deedbf95b 100644 --- a/src/gui/widgets/midi_port_menu.cpp +++ b/src/gui/widgets/midi_port_menu.cpp @@ -30,7 +30,7 @@ midiPortMenu::midiPortMenu( midiPort::Modes _mode ) : - modelView( NULL ), + modelView( NULL, this ), m_mode( _mode ) { setFont( pointSize<9>( font() ) ); diff --git a/src/gui/widgets/tempo_sync_knob.cpp b/src/gui/widgets/tempo_sync_knob.cpp index 2dccbf074..81a5e8636 100644 --- a/src/gui/widgets/tempo_sync_knob.cpp +++ b/src/gui/widgets/tempo_sync_knob.cpp @@ -47,7 +47,7 @@ tempoSyncKnobModel::tempoSyncKnobModel( const float _val, const float _min, m_tempoSyncMode( SyncNone ), m_tempoLastSyncMode( SyncNone ), m_scale( _scale ), - m_custom( _parent, NULL ) + m_custom( _parent ) { connect( engine::getSong(), SIGNAL( tempoChanged( bpm_t ) ), this, SLOT( calculateTempoSyncTime( bpm_t ) ) ); diff --git a/src/tracks/automation_track.cpp b/src/tracks/automation_track.cpp index 1a302b7de..0512fba85 100644 --- a/src/tracks/automation_track.cpp +++ b/src/tracks/automation_track.cpp @@ -4,6 +4,7 @@ * automation_track.cpp - automationTrack handles automation of objects without * a track * + * Copyright (c) 2008 Tobias Doerffel * Copyright (c) 2006-2008 Javier Serrano Polo * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net @@ -27,12 +28,15 @@ #include "automation_track.h" +#include "automation_pattern.h" +#include "embed.h" +#include "name_label.h" -automationTrack::automationTrack( trackContainer * _tc ) : - track( AutomationTrack, _tc ) +automationTrack::automationTrack( trackContainer * _tc, bool _hidden ) : + track( _hidden ? HiddenAutomationTrack : AutomationTrack, _tc ) { } @@ -49,16 +53,36 @@ automationTrack::~automationTrack() bool automationTrack::play( const midiTime & _start, const fpp_t _frames, const f_cnt_t _frame_base, Sint16 _tco_num ) { - sendMidiTime( _start ); + tcoVector tcos; + getTCOsInRange( tcos, _start, _start + static_cast( + _frames / engine::framesPerTick() ) ); + for( tcoVector::iterator it = tcos.begin(); it != tcos.end(); ++it ) + { + automationPattern * p = + dynamic_cast( *it ); + if( p == NULL || ( *it )->isMuted() ) + { + continue; + } + p->processMidiTime( _start - p->startPosition() ); + } return( FALSE ); } +trackView * automationTrack::createView( trackContainerView * _tcv ) +{ + return( new automationTrackView( this, _tcv ) ); +} + + + + trackContentObject * automationTrack::createTCO( const midiTime & ) { - return( NULL ); + return( new automationPattern( this ) ); } @@ -78,4 +102,31 @@ void automationTrack::loadTrackSpecificSettings( const QDomElement & _this ) + + +automationTrackView::automationTrackView( automationTrack * _at, + trackContainerView * _tcv ) : + trackView( _at, _tcv ) +{ + setFixedHeight( 32 ); + m_trackLabel = new nameLabel( _at->name(), getTrackSettingsWidget() ); + m_trackLabel->setPixmap( embed::getIconPixmap( "automation" ) ); + m_trackLabel->setGeometry( 1, 1, DEFAULT_SETTINGS_WIDGET_WIDTH - 2, + 29 ); + m_trackLabel->show(); + connect( m_trackLabel, SIGNAL( nameChanged( const QString & ) ), + _at, SLOT( setName( const QString & ) ) ); + setModel( _at ); +} + + + + +automationTrackView::~automationTrackView() +{ +} + + + + #endif diff --git a/src/tracks/bb_track.cpp b/src/tracks/bb_track.cpp index 4ee2e3244..4e38a4acf 100644 --- a/src/tracks/bb_track.cpp +++ b/src/tracks/bb_track.cpp @@ -351,8 +351,6 @@ bbTrack::~bbTrack() bool bbTrack::play( const midiTime & _start, const fpp_t _frames, const f_cnt_t _offset, Sint16 _tco_num ) { - sendMidiTime( _start ); - if( _tco_num >= 0 ) { return( engine::getBBTrackContainer()->play( _start, _frames, @@ -360,7 +358,7 @@ bool bbTrack::play( const midiTime & _start, const fpp_t _frames, s_infoMap[this] ) ); } - QList tcos; + tcoVector tcos; getTCOsInRange( tcos, _start, _start + static_cast( _frames / engine::framesPerTick() ) ); @@ -371,8 +369,7 @@ bool bbTrack::play( const midiTime & _start, const fpp_t _frames, midiTime lastPosition; midiTime lastLen; - for( QList::iterator it = tcos.begin(); - it != tcos.end(); ++it ) + for( tcoVector::iterator it = tcos.begin(); it != tcos.end(); ++it ) { if( !( *it )->isMuted() && ( *it )->startPosition() >= lastPosition ) @@ -409,7 +406,7 @@ trackContentObject * bbTrack::createTCO( const midiTime & _pos ) // if we're creating a new bbTCO, we colorize it according to the // previous bbTCO, so we have to get all TCOs from 0 to _pos and // pickup the last and take the color if it - QList tcos; + tcoVector tcos; getTCOsInRange( tcos, 0, _pos ); if( tcos.size() > 0 && dynamic_cast( tcos.back() ) != NULL ) { @@ -439,19 +436,6 @@ void bbTrack::saveTrackSpecificSettings( QDomDocument & _doc, ( (journallingObject *)( engine::getBBTrackContainer() ) )-> saveState( _doc, _this ); } - - int track_num = 0; - QList tracks = engine::getBBTrackContainer()->tracks(); - for( int i = 0; i < tracks.size(); ++i, ++track_num ) - { - if( automationDisabled( tracks[i] ) ) - { - QDomElement disabled = _doc.createElement( - "automation-disabled" ); - disabled.setAttribute( "track", track_num ); - _this.appendChild( disabled ); - } - } } @@ -479,19 +463,6 @@ void bbTrack::loadTrackSpecificSettings( const QDomElement & _this ) { engine::getBBEditor()->setCurrentBB( s_infoMap[this] ); }*/ - - QList tracks = engine::getBBTrackContainer()->tracks(); - node = _this.firstChild(); - while( !node.isNull() ) - { - if( node.isElement() - && node.nodeName() == "automation-disabled" ) - { - disableAutomation( tracks[node.toElement().attribute( - "track" ).toInt()] ); - } - node = node.nextSibling(); - } } diff --git a/src/tracks/instrument_track.cpp b/src/tracks/instrument_track.cpp index 49b365082..737f606ad 100644 --- a/src/tracks/instrument_track.cpp +++ b/src/tracks/instrument_track.cpp @@ -103,9 +103,9 @@ const int INSTRUMENT_WINDOW_CACHE_SIZE = 8; instrumentTrack::instrumentTrack( trackContainer * _tc ) : track( InstrumentTrack, _tc ), midiEventProcessor(), - m_audioPort( tr( "unnamed_track" ), this ), + m_audioPort( tr( "unnamed_track" ) ), m_midiPort( tr( "unnamed_track" ), engine::getMixer()->getMIDIClient(), - this, this, this ), + this, this ), m_notes(), m_baseNoteModel( 0, 0, KeysPerOctave * NumOctaves - 1, this ), m_volumeModel( DefaultVolume, MinVolume, MaxVolume, 1.0f, this, @@ -120,18 +120,12 @@ instrumentTrack::instrumentTrack( trackContainer * _tc ) : m_chordCreator( this ), m_piano( this ) { - m_baseNoteModel.setTrack( this ); m_baseNoteModel.setInitValue( DefaultKey ); connect( &m_baseNoteModel, SIGNAL( dataChanged() ), this, SLOT( updateBaseNote() ) ); connect( &m_pitchModel, SIGNAL( dataChanged() ), this, SLOT( updateBaseNote() ) ); - m_volumeModel.setTrack( this ); - m_panningModel.setTrack( this ); - m_pitchModel.setTrack( this ); - m_effectChannelModel.setTrack( this ); - for( int i = 0; i < NumKeys; ++i ) { @@ -525,25 +519,18 @@ bool instrumentTrack::play( const midiTime & _start, { const float frames_per_tick = engine::framesPerTick(); - QList tcos; + tcoVector tcos; bbTrack * bb_track; if( _tco_num >= 0 ) { trackContentObject * tco = getTCO( _tco_num ); tcos.push_back( tco ); - bb_track = bbTrack::findBBTrack( _tco_num ); - if( !( ( bb_track && bb_track->automationDisabled( this ) ) - || dynamic_cast( tco )->empty() ) ) - { - sendMidiTime( _start ); - } } else { getTCOsInRange( tcos, _start, _start + static_cast( _frames / frames_per_tick ) ); bb_track = NULL; - sendMidiTime( _start ); } // Handle automation: detuning @@ -560,8 +547,7 @@ bool instrumentTrack::play( const midiTime & _start, bool played_a_note = FALSE; // will be return variable - for( QList::iterator it = tcos.begin(); - it != tcos.end(); ++it ) + for( tcoVector::iterator it = tcos.begin(); it != tcos.end(); ++it ) { pattern * p = dynamic_cast( *it ); // everything which is not a pattern or muted won't be played @@ -705,9 +691,9 @@ void instrumentTrack::loadTrackSpecificSettings( const QDomElement & _this ) m_volumeModel.loadSettings( _this, "vol" ); // compat-hacks - move to mmp::upgrade - if( _this.hasAttribute( "surpos" ) || _this.hasAttribute( "surpos-x" ) || - !_this.firstChildElement( "automation-pattern" ). - firstChildElement( "surpos-x" ).isNull() ) + if( _this.hasAttribute( "surpos" ) || _this.hasAttribute( "surpos-x" ) + || !_this.firstChildElement( "automationpattern" ). + firstChildElement( "surpos-x" ).isNull() ) { surroundAreaModel m( this, this ); m.loadSettings( _this, "surpos" ); @@ -765,7 +751,8 @@ void instrumentTrack::loadTrackSpecificSettings( const QDomElement & _this ) node.toElement() ); } else if( automationPattern::classNodeName() != - node.nodeName() ) + node.nodeName() && + !node.toElement().hasAttribute( "id" ) ) { // if node-name doesn't match any known one, // we assume that it is an instrument-plugin @@ -1085,7 +1072,7 @@ class fxLineLcdSpinBox : public lcdSpinBox // #### ITW: instrumentTrackWindow::instrumentTrackWindow( instrumentTrackView * _itv ) : QWidget(), - modelView( NULL ), + modelView( NULL, this ), m_track( _itv->model() ), m_itv( _itv ), m_instrumentView( NULL ) diff --git a/src/tracks/pattern.cpp b/src/tracks/pattern.cpp index c8e1e4c30..6ffb48a05 100644 --- a/src/tracks/pattern.cpp +++ b/src/tracks/pattern.cpp @@ -857,14 +857,6 @@ void patternView::update( void ) void patternView::openInPianoRoll( void ) -{ - openInPianoRoll( FALSE ); -} - - - - -void patternView::openInPianoRoll( bool ) { engine::getPianoRoll()->setCurrentPattern( m_pat ); engine::getPianoRoll()->parentWidget()->show(); @@ -915,8 +907,8 @@ void patternView::constructContextMenu( QMenu * _cm ) QAction * a = new QAction( embed::getIconPixmap( "piano" ), tr( "Open in piano-roll" ), _cm ); _cm->insertAction( _cm->actions()[0], a ); - connect( a, SIGNAL( triggered( bool ) ), this, - SLOT( openInPianoRoll( bool ) ) ); + connect( a, SIGNAL( triggered( bool ) ), + this, SLOT( openInPianoRoll() ) ); _cm->insertSeparator( _cm->actions()[1] ); _cm->addSeparator(); @@ -988,7 +980,7 @@ void patternView::mouseDoubleClickEvent( QMouseEvent * _me ) _me->y() > height() - s_stepBtnOff->height() ) ) { openInPianoRoll(); - } + } } @@ -1136,28 +1128,20 @@ void patternView::paintEvent( QPaintEvent * ) / (float) m_pat->length().getTact() : pixelsPerTact(); - const int x_base = TCO_BORDER_WIDTH; - p.setPen( QColor( 0, 0, 0 ) ); - for( tact tact_num = 1; tact_num < - m_pat->length().getTact(); ++tact_num ) - { - p.drawLine( - x_base + static_cast( - ppt * tact_num ) - 1, - TCO_BORDER_WIDTH, - x_base + static_cast( - ppt * tact_num ) - 1, - 5 ); - p.drawLine( - x_base + static_cast( - ppt * tact_num ) - 1, - height() - ( 4 + 2 * - TCO_BORDER_WIDTH ), - x_base + static_cast( - ppt * tact_num ) - 1, - height() - 2 * - TCO_BORDER_WIDTH ); - } + const int x_base = TCO_BORDER_WIDTH; + p.setPen( QColor( 0, 0, 0 ) ); + + for( tact t = 1; t < m_pat->length().getTact(); ++t ) + { + p.drawLine( x_base + static_cast( ppt * t ) - 1, + TCO_BORDER_WIDTH, x_base + static_cast( + ppt * t ) - 1, 5 ); + p.drawLine( x_base + static_cast( ppt * t ) - 1, + height() - ( 4 + 2 * TCO_BORDER_WIDTH ), + x_base + static_cast( ppt * t ) - 1, + height() - 2 * TCO_BORDER_WIDTH ); + } + if( m_pat->m_patternType == pattern::MelodyPattern ) { int central_key = 0; @@ -1183,20 +1167,8 @@ void patternView::paintEvent( QPaintEvent * ) int central_y = height() / 2; int y_base = central_y + TCO_BORDER_WIDTH -1; -/* for( tact tact_num = 1; tact_num < - m_pat->length().getTact(); ++tact_num ) - { - p.drawLine( - x_base + static_cast( - ppt * tact_num ) - 1, - TCO_BORDER_WIDTH, - x_base + static_cast( - ppt * tact_num ) - 1, - height() - 2 * - TCO_BORDER_WIDTH ); - }*/ if( m_pat->getTrack()->isMuted() || - m_pat->isMuted() ) + m_pat->isMuted() ) { p.setPen( QColor( 160, 160, 160 ) ); } diff --git a/src/tracks/sample_track.cpp b/src/tracks/sample_track.cpp index 0b07441aa..c844436ee 100644 --- a/src/tracks/sample_track.cpp +++ b/src/tracks/sample_track.cpp @@ -218,8 +218,7 @@ midiTime sampleTCO::getSampleLength( void ) const -void FASTCALL sampleTCO::saveSettings( QDomDocument & _doc, - QDomElement & _this ) +void sampleTCO::saveSettings( QDomDocument & _doc, QDomElement & _this ) { if( _this.parentNode().nodeName() == "clipboard" ) { @@ -243,7 +242,7 @@ void FASTCALL sampleTCO::saveSettings( QDomDocument & _doc, -void FASTCALL sampleTCO::loadSettings( const QDomElement & _this ) +void sampleTCO::loadSettings( const QDomElement & _this ) { if( _this.attribute( "pos" ).toInt() >= 0 ) { @@ -377,8 +376,7 @@ sampleTrack::~sampleTrack() -bool FASTCALL sampleTrack::play( const midiTime & _start, - const fpp_t _frames, +bool sampleTrack::play( const midiTime & _start, const fpp_t _frames, const f_cnt_t _offset, Sint16 /*_tco_num*/ ) {