From ce128add004a150cd06064a98ede528181ad9b94 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Wed, 2 Jan 2008 22:19:58 +0000 Subject: [PATCH] inital M/V-hacks, improve project-unloading speed, fix wrong signal-slot-connection which made gate-parameter of effects not working git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms-mv@634 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 99 ++++++ Makefile.am | 8 +- README | 4 +- configure.in | 4 +- include/arp_and_chords_tab_widget.h | 14 + include/automatable_button.h | 35 +- ...tomatable_object.h => automatable_model.h} | 146 ++++++-- ...plates.h => automatable_model_templates.h} | 222 +++++++----- include/automatable_slider.h | 20 +- include/bb_editor.h | 14 +- include/combobox.h | 99 ++++-- include/detuning_helper.h | 6 +- include/effect.h | 51 ++- include/envelope_and_lfo_widget.h | 29 +- include/envelope_tab_widget.h | 7 + include/export_project_dialog.h | 8 +- include/group_box.h | 24 +- include/instrument_track.h | 38 +- include/journalling_object.h | 8 +- include/knob.h | 45 +-- include/ladspa_control.h | 30 +- include/lcd_spinbox.h | 22 +- include/led_checkbox.h | 4 +- include/meter_dialog.h | 17 +- include/midi_tab_widget.h | 18 +- include/mv_base.h | 107 ++++++ include/piano_roll.h | 8 +- include/piano_widget.h | 10 +- include/pixmap_button.h | 3 +- include/rack_plugin.h | 15 +- include/sample_play_handle.h | 14 +- include/sample_track.h | 3 +- include/setup_dialog.h | 2 - include/song_editor.h | 26 +- include/surround_area.h | 87 +++-- include/tempo_sync_knob.h | 6 +- include/volume_knob.h | 3 +- src/audio/audio_alsa.cpp | 13 +- src/audio/audio_jack.cpp | 13 +- src/audio/audio_oss.cpp | 13 +- src/core/about_dialog.cpp | 4 +- src/core/arp_and_chords_tab_widget.cpp | 168 +++++---- src/core/automation_editor.cpp | 44 ++- src/core/automation_pattern.cpp | 4 +- src/core/bb_editor.cpp | 48 ++- src/core/effect.cpp | 10 +- src/core/effect_tab_widget.cpp | 10 +- src/core/envelope_and_lfo_widget.cpp | 332 ++++++++++-------- src/core/envelope_tab_widget.cpp | 97 ++--- src/core/export_project_dialog.cpp | 63 ++-- src/core/instrument.cpp | 1 + src/core/ladspa_control.cpp | 135 ++++--- src/core/meter_dialog.cpp | 70 ++-- src/core/midi_tab_widget.cpp | 160 +++++---- src/core/mv_base.cpp | 64 ++++ src/core/note.cpp | 2 +- src/core/note_play_handle.cpp | 12 +- src/core/piano_roll.cpp | 65 ++-- src/core/piano_widget.cpp | 74 +--- src/core/preset_preview_play_handle.cpp | 1 + src/core/sample_play_handle.cpp | 33 +- src/core/setup_dialog.cpp | 60 +--- src/core/song_editor.cpp | 138 ++++---- src/core/surround_area.cpp | 186 ++++------ src/core/track.cpp | 6 +- src/core/track_container.cpp | 5 +- src/tracks/instrument_track.cpp | 210 +++-------- src/tracks/sample_track.cpp | 22 +- src/widgets/automatable_button.cpp | 109 +++--- src/widgets/automatable_slider.cpp | 117 ++---- src/widgets/combobox.cpp | 156 ++++---- src/widgets/group_box.cpp | 60 ++-- src/widgets/knob.cpp | 241 ++++--------- src/widgets/lcd_spinbox.cpp | 57 +-- src/widgets/led_checkbox.cpp | 8 +- src/widgets/pixmap_button.cpp | 8 +- src/widgets/rack_plugin.cpp | 99 +++--- src/widgets/tempo_sync_knob.cpp | 74 ++-- src/widgets/volume_knob.cpp | 47 +-- 79 files changed, 2284 insertions(+), 2011 deletions(-) rename include/{automatable_object.h => automatable_model.h} (50%) rename include/{automatable_object_templates.h => automatable_model_templates.h} (54%) create mode 100644 include/mv_base.h create mode 100644 src/core/mv_base.cpp diff --git a/ChangeLog b/ChangeLog index 3a3d1ca62c..dd04c8d473 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,102 @@ +2008-01-02 Tobias Doerffel + + * include/knob.h: + * include/effect.h: + * include/automatable_slider.h: + * include/lcd_spinbox.h: + * include/meter_dialog.h: + * include/midi_tab_widget.h: + * include/instrument_track.h: + * include/ladspa_control.h: + * include/piano_widget.h: + * include/detuning_helper.h: + * include/sample_play_handle.h: + * include/piano_roll.h: + * include/group_box.h: + * include/envelope_tab_widget.h: + * include/song_editor.h: + * include/automatable_button.h: + * include/tempo_sync_knob.h: + * include/journalling_object.h: + * include/setup_dialog.h: + * include/export_project_dialog.h: + * include/pixmap_button.h: + * include/sample_track.h: + * include/surround_area.h: + * include/volume_knob.h: + * include/bb_editor.h: + * include/rack_plugin.h: + * include/arp_and_chords_tab_widget.h: + * include/envelope_and_lfo_widget.h: + * include/combobox.h: + * include/led_checkbox.h: + * configure.in: + * src/audio/audio_alsa.cpp: + * src/audio/audio_oss.cpp: + * src/audio/audio_jack.cpp: + * src/widgets/rack_plugin.cpp: + * src/widgets/automatable_slider.cpp: + * src/widgets/lcd_spinbox.cpp: + * src/widgets/group_box.cpp: + * src/widgets/combobox.cpp: + * src/widgets/led_checkbox.cpp: + * src/widgets/volume_knob.cpp: + * src/widgets/pixmap_button.cpp: + * src/widgets/knob.cpp: + * src/widgets/automatable_button.cpp: + * src/widgets/tempo_sync_knob.cpp: + * src/tracks/sample_track.cpp: + * src/tracks/instrument_track.cpp: + * src/core/arp_and_chords_tab_widget.cpp: + * src/core/envelope_and_lfo_widget.cpp: + * src/core/preset_preview_play_handle.cpp: + * src/core/note_play_handle.cpp: + * src/core/midi_tab_widget.cpp: + * src/core/setup_dialog.cpp: + * src/core/sample_play_handle.cpp: + * src/core/export_project_dialog.cpp: + * src/core/effect.cpp: + * src/core/piano_roll.cpp: + * src/core/track.cpp: + * src/core/ladspa_control.cpp: + * src/core/note.cpp: + * src/core/envelope_tab_widget.cpp: + * src/core/instrument.cpp: + * src/core/piano_widget.cpp: + * src/core/surround_area.cpp: + * src/core/song_editor.cpp: + * src/core/automation_pattern.cpp: + * src/core/effect_tab_widget.cpp: + * src/core/automation_editor.cpp: + * src/core/bb_editor.cpp: + * src/core/meter_dialog.cpp: + * Makefile.am: + adaption of M/V-architecture + + * include/automatable_object_templates.h: + * include/automatable_object.h: + removed as replaced by automatable_model.h and + automatable_model_templates.h + + * include/mv_base.h: + * src/core/mv_base.cpp: + * include/automatable_model.h: + * include/automatable_model_templates.h: + added base-files for new M/V-architecture + + * src/widgets/rack_plugin.cpp: + fixed wrong signal-slot-connection which made gate-parameter of + effects not working + + * src/core/track_container.cpp: + when removing tracks start removing at the end of track-vector (i.e. + use m_trackWidgets.last() instead of m_trackWidgets.first()) - speeds + up things *a lot* + + * README: + * src/core/about_dialog.cpp: + fixed version and extended copyright from 2007 to 2008 + 2007-12-18 Tobias Doerffel * plugins/midi_import/midi_import.cpp: diff --git a/Makefile.am b/Makefile.am index 39af1179d6..0032df353a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -77,6 +77,7 @@ lmms_MOC = \ ./led_checkbox.moc \ ./main_window.moc \ ./mixer.moc \ + ./mv_base.moc \ ./name_label.moc \ ./nstate_button.moc \ ./meter_dialog.moc \ @@ -93,7 +94,6 @@ lmms_MOC = \ ./rubberband.moc \ ./rename_dialog.moc \ ./sample_buffer.moc \ - ./sample_play_handle.moc \ ./sample_track.moc \ ./setup_dialog.moc \ ./side_bar.moc \ @@ -176,6 +176,7 @@ lmms_SOURCES = \ $(srcdir)/src/core/meter_dialog.cpp \ $(srcdir)/src/core/midi_tab_widget.cpp \ $(srcdir)/src/core/mixer.cpp \ + $(srcdir)/src/core/mv_base.cpp \ $(srcdir)/src/core/name_label.cpp \ $(srcdir)/src/core/note.cpp \ $(srcdir)/src/core/note_play_handle.cpp \ @@ -288,6 +289,9 @@ lmms_SOURCES = \ $(srcdir)/include/oscillator.h \ $(srcdir)/include/arp_and_chords_tab_widget.h \ $(srcdir)/include/export.h \ + $(srcdir)/include/mv_base.h \ + $(srcdir)/include/automatable_model.h \ + $(srcdir)/include/automatable_model_templates.h \ $(srcdir)/include/group_box.h \ $(srcdir)/include/tab_widget.h \ $(srcdir)/include/knob.h \ @@ -358,8 +362,6 @@ lmms_SOURCES = \ $(srcdir)/include/combobox.h \ $(srcdir)/include/rubberband.h \ $(srcdir)/include/base64.h \ - $(srcdir)/include/automatable_object.h \ - $(srcdir)/include/automatable_object_templates.h \ $(srcdir)/include/journalling_object.h \ $(srcdir)/include/level_object.h \ $(srcdir)/include/project_journal.h \ diff --git a/README b/README index 8b6b14b739..792f2d9906 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ -Linux MultiMedia Studio 0.3.0 +Linux MultiMedia Studio 0.4.0 ============================== -Copyright (c) 2004-2007 by LMMS-developers +Copyright (c) 2004-2008 by LMMS-developers This program is free software; you can redistribute it and/or modify diff --git a/configure.in b/configure.in index 9b4e280f9b..ec351903f9 100644 --- a/configure.in +++ b/configure.in @@ -2,8 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.50) -AC_INIT(lmms, 0.4.0-svn20071218, lmms-devel/at/lists/dot/sf/dot/net) -AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20071218) +AC_INIT(lmms, 0.4.0-svn20080102-mv, lmms-devel/at/lists/dot/sf/dot/net) +AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20080102-mv) AM_CONFIG_HEADER(config.h) diff --git a/include/arp_and_chords_tab_widget.h b/include/arp_and_chords_tab_widget.h index 5d0b03bb53..21797cedb8 100644 --- a/include/arp_and_chords_tab_widget.h +++ b/include/arp_and_chords_tab_widget.h @@ -31,6 +31,7 @@ #include "journalling_object.h" #include "types.h" +#include "automatable_model.h" class QLabel; @@ -44,6 +45,7 @@ class groupBox; class knob; class notePlayHandle; class tempoSyncKnob; +class comboBoxModel; const int MAX_CHORD_POLYPHONY = 10; @@ -101,20 +103,32 @@ private: // chord-stuff groupBox * m_chordsGroupBox; + boolModel * m_chordsEnabledModel; comboBox * m_chordsComboBox; + comboBoxModel * m_chordsModel; knob * m_chordRangeKnob; + floatModel * m_chordRangeModel; // arpeggio-stuff groupBox * m_arpGroupBox; + boolModel * m_arpEnabledModel; comboBox * m_arpComboBox; + comboBoxModel * m_arpModel; knob * m_arpRangeKnob; + floatModel * m_arpRangeModel; tempoSyncKnob * m_arpTimeKnob; + floatModel * m_arpTimeModel; knob * m_arpGateKnob; + floatModel * m_arpGateModel; + QLabel * m_arpDirectionLbl; automatableButtonGroup * m_arpDirectionBtnGrp; + intModel * m_arpDirectionModel; comboBox * m_arpModeComboBox; + comboBoxModel * m_arpModeModel; + friend class flpImport; diff --git a/include/automatable_button.h b/include/automatable_button.h index 117d4b13b6..0ef28a1123 100644 --- a/include/automatable_button.h +++ b/include/automatable_button.h @@ -28,37 +28,33 @@ #include -#include "automatable_object.h" +#include "automatable_model.h" class automatableButtonGroup; -class automatableButton : public QPushButton, public automatableObject +class automatableButton : public QPushButton, public boolModelView { Q_OBJECT public: - automatableButton( QWidget * _parent, const QString & _name, - track * _track ); + automatableButton( QWidget * _parent, const QString & _name ); virtual ~automatableButton(); - - virtual void setValue( const bool _on ); - inline void setCheckable( bool _on ) { QPushButton::setCheckable( _on ); - setJournalling( _on ); + model()->setJournalling( _on ); } public slots: + virtual void update( void ); virtual void toggle( void ); virtual void setChecked( bool _on ) { - // QPushButton::setChecked is called in setValue() - setValue( _on ); + // QPushButton::setChecked is called in update-slot + model()->setValue( _on ); } @@ -74,16 +70,17 @@ private: friend class automatableButtonGroup; + using QPushButton::setChecked; + using QPushButton::isChecked; } ; -class automatableButtonGroup : public QWidget, public automatableObject +class automatableButtonGroup : public QWidget, public intModelView { Q_OBJECT public: - automatableButtonGroup( QWidget * _parent, const QString & _name, - track * _track ); + automatableButtonGroup( QWidget * _parent, const QString & _name ); virtual ~automatableButtonGroup(); void addButton( automatableButton * _btn ); @@ -91,16 +88,16 @@ public: void activateButton( automatableButton * _btn ); - virtual void setValue( const int _value ); + virtual void modelChanged( void ); + + +private slots: + void updateButtons( void ); private: QList m_buttons; - -signals: - void valueChanged( int ); - } ; diff --git a/include/automatable_object.h b/include/automatable_model.h similarity index 50% rename from include/automatable_object.h rename to include/automatable_model.h index 4b7f642049..7a56e85a0f 100644 --- a/include/automatable_object.h +++ b/include/automatable_model.h @@ -1,7 +1,7 @@ /* - * automatable_object.h - declaration of class automatableObject + * automatable_model.h - declaration of class automatableModel * - * Copyright (c) 2006-2007 Tobias Doerffel + * Copyright (c) 2007 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -23,13 +23,14 @@ */ -#ifndef _AUTOMATABLE_OBJECT_H -#define _AUTOMATABLE_OBJECT_H +#ifndef _AUTOMATABLE_MODEL_H +#define _AUTOMATABLE_MODEL_H #include #include "journalling_object.h" #include "level_object.h" +#include "mv_base.h" #include @@ -38,18 +39,47 @@ class automationPattern; class track; +// simple way to map a property of a view to a model +#define mapPropertyFromModelPtr(type,getfunc,setfunc,modelname) \ + public: \ + inline type getfunc( void ) const \ + { \ + return( modelname->value() ); \ + } \ + public slots: \ + inline void setfunc( const type _val ) \ + { \ + modelname->setValue( _val ); \ + } + +#define mapPropertyFromModel(type,getfunc,setfunc,modelname) \ + public: \ + inline type getfunc( void ) const \ + { \ + return( modelname.value() ); \ + } \ + public slots: \ + inline void setfunc( const type _val ) \ + { \ + modelname.setValue( _val ); \ + } + template -class automatableObject : public journallingObject, public levelObject +class automatableModel : public model, public journallingObject, + public levelObject { public: - typedef automatableObject autoObj; + typedef automatableModel autoModel; - automatableObject( track * _track = NULL, const T _val = 0, - const T _min = 0, const T _max = 0, - const T _step = defaultRelStep() ); + automatableModel( const T _val = 0, + const T _min = 0, + const T _max = 0, + const T _step = defaultRelStep(), + ::model * _parent = NULL, + bool _default_constructed = FALSE ); - virtual ~automatableObject(); + virtual ~automatableModel(); static inline T minRelStep( void ) { @@ -72,6 +102,11 @@ public: return( m_value ); } + inline virtual T initValue( void ) const + { + return( m_initValue ); + } + inline virtual T minValue( void ) const { return( m_minValue ); @@ -94,14 +129,14 @@ public: inline T fittedValue( T _value ) const; - T value( int _level ) const + inline T value( int _level ) const { return( fittedValue( _level * m_step ) ); } virtual void setInitValue( const T _value ); - inline virtual void setValue( const T _value ); + virtual void setValue( const T _value ); inline virtual void incValue( int _steps ) { @@ -111,11 +146,11 @@ public: virtual void setRange( const T _min, const T _max, const T _step = defaultRelStep() ); - inline virtual void setStep( const T _step ); + virtual void setStep( const T _step ); - static void linkObjects( autoObj * _object1, autoObj * _object2 ); + static void linkModels( autoModel * _model1, autoModel * _model2 ); - static void unlinkObjects( autoObj * _object1, autoObj * _object2 ); + static void unlinkModels( autoModel * _model1, autoModel * _model2 ); virtual void FASTCALL saveSettings( QDomDocument & _doc, QDomElement & _this, @@ -126,11 +161,16 @@ public: virtual QString nodeName( void ) const { - return( "automatableobject" ); + return( "automatablemodel" ); } inline automationPattern * getAutomationPattern( void ); + inline void setTrack( track * _track ) + { + m_track = _track; + } + inline bool nullTrack( void ) { return( m_track == NULL ); @@ -138,43 +178,44 @@ public: void initAutomationPattern( void ) { - m_automation_pattern = new automationPattern( NULL, this ); + m_automationPattern = new automationPattern( NULL, this ); } + void prepareJournalEntryFromOldVal( void ); + + void addJournalEntryFromOldToCurVal( void ); + protected: virtual void redoStep( journalEntry & _je ); virtual void undoStep( journalEntry & _je ); - void prepareJournalEntryFromOldVal( void ); - - void addJournalEntryFromOldToCurVal( void ); - inline void setFirstValue( void ); private: T m_value; + T m_initValue; T m_minValue; T m_maxValue; T m_step; int m_curLevel; - QPointer m_automation_pattern; + QPointer m_automationPattern; track * m_track; // most objects will need this temporarily T m_oldValue; bool m_journalEntryReady; - typedef QVector autoObjVector; - autoObjVector m_linkedObjects; + typedef QVector autoModelVector; + autoModelVector m_linkedModels; - inline void linkObject( autoObj * _object ); + inline void linkModel( autoModel * _model ); - inline void unlinkObject( autoObj * _object ); + inline void unlinkModel( autoModel * _model ); - static inline T attributeValue( QString _value ); + inline static T attributeValue( QString _value ); inline void syncAutomationPattern( void ); @@ -199,6 +240,57 @@ private: +template +class automatableModelView : public modelView +{ +public: + typedef automatableModel autoModel; + typedef automatableModelView autoModelView; + + automatableModelView( void ) : modelView() + { + } + + // some basic functions for convenience + autoModel * model( void ) + { + return( castModel() ); + } + + const autoModel * model( void ) const + { + return( castModel() ); + } + + inline virtual T value( void ) const + { + return( model() ? model()->value() : 0 ); + } + + inline virtual void setValue( const T _value ) + { + if( model() ) + { + model()->setValue( _value ); + } + } + +} ; + + +//#include "automatable_model_templates.h" + + +#define generateModelPrimitive(type,type2) \ + typedef automatableModel type##Model; \ + typedef automatableModelView type##ModelView; \ + +// some model-primitives + +generateModelPrimitive(bool,signed char); +generateModelPrimitive(float,float); +generateModelPrimitive(int,int); + #endif diff --git a/include/automatable_object_templates.h b/include/automatable_model_templates.h similarity index 54% rename from include/automatable_object_templates.h rename to include/automatable_model_templates.h index 9328351ef9..e8b9769aea 100644 --- a/include/automatable_object_templates.h +++ b/include/automatable_model_templates.h @@ -1,7 +1,7 @@ /* - * automatable_object_templates.h - definition of automatableObject templates + * automatable_model_templates.h - definition of automatableModel templates * - * Copyright (c) 2006-2007 Tobias Doerffel + * Copyright (c) 2007 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -23,12 +23,12 @@ */ -#ifndef _AUTOMATABLE_OBJECT_TEMPLATES_H -#define _AUTOMATABLE_OBJECT_TEMPLATES_H +#ifndef _AUTOMATABLE_MODEL_TEMPLATES_H +#define _AUTOMATABLE_MODEL_TEMPLATES_H #include -#include "automatable_object.h" +#include "automatable_model.h" #include "automation_editor.h" #include "automation_pattern.h" #include "engine.h" @@ -37,15 +37,21 @@ template -automatableObject::automatableObject( track * _track, - const T _val, const T _min, - const T _max, const T _step ) : +automatableModel::automatableModel( + const T _val, + const T _min, + const T _max, + const T _step, + ::model * _parent, + bool _default_constructed ) : + model( _parent, _default_constructed ), m_value( _val ), + m_initValue( _val ), m_minValue( _min ), m_maxValue( _max ), m_step( _step ), - m_automation_pattern( NULL ), - m_track( _track ), + m_automationPattern( NULL ), + m_track( NULL ), m_journalEntryReady( FALSE ) { m_curLevel = level( _val ); @@ -57,13 +63,13 @@ automatableObject::automatableObject( track * _track, template -automatableObject::~automatableObject() +automatableModel::~automatableModel() { - delete m_automation_pattern; - while( m_linkedObjects.empty() == FALSE ) + delete m_automationPattern; + while( m_linkedModels.empty() == FALSE ) { - m_linkedObjects.last()->unlinkObject( this ); - m_linkedObjects.erase( m_linkedObjects.end() - 1 ); + m_linkedModels.last()->unlinkModel( this ); + m_linkedModels.erase( m_linkedModels.end() - 1 ); } } @@ -71,7 +77,7 @@ automatableObject::~automatableObject() template -T automatableObject::fittedValue( T _value ) const +T automatableModel::fittedValue( T _value ) const { _value = tLimit( _value, minValue(), maxValue() ); @@ -104,11 +110,12 @@ T automatableObject::fittedValue( T _value ) const template -void automatableObject::setInitValue( const T _value ) +void automatableModel::setInitValue( const T _value ) { + m_initValue = _value; bool journalling = testAndSetJournalling( FALSE ); setValue( _value ); - if( m_automation_pattern ) + if( m_automationPattern ) { setFirstValue(); } @@ -119,7 +126,7 @@ void automatableObject::setInitValue( const T _value ) template -void automatableObject::setValue( const T _value ) +void automatableModel::setValue( const T _value ) { const T old_val = m_value; @@ -133,15 +140,15 @@ void automatableObject::setValue( const T _value ) static_cast( m_value ) - static_cast( old_val ) ) ); - // notify linked objects + // notify linked models // doesn't work because of implicit typename T - // for( autoObjVector::iterator it = - // m_linkedObjects.begin(); - // it != m_linkedObjects.end(); ++it ) - for( int i = 0; i < m_linkedObjects.size(); ++i ) + // for( autoModelVector::iterator it = + // m_linkedModels.begin(); + // it != m_linkedModels.end(); ++it ) + for( int i = 0; i < m_linkedModels.size(); ++i ) { - autoObj * it = m_linkedObjects[i]; + autoModel * it = m_linkedModels[i]; if( value() != it->value() && it->fittedValue( value() ) != it->value() ) { @@ -151,6 +158,8 @@ void automatableObject::setValue( const T _value ) it->setJournalling( journalling ); } } + setFirstValue(); + emit dataChanged(); } } @@ -158,25 +167,30 @@ void automatableObject::setValue( const T _value ) template -void automatableObject::setRange( const T _min, const T _max, +void automatableModel::setRange( const T _min, const T _max, const T _step ) { - m_minValue = _min; - m_maxValue = _max; - if( m_minValue > m_maxValue ) + if( ( m_maxValue != _max ) || ( m_minValue != _min ) ) { - qSwap( m_minValue, m_maxValue ); + m_minValue = _min; + m_maxValue = _max; + if( m_minValue > m_maxValue ) + { + qSwap( m_minValue, m_maxValue ); + } + setStep( _step ); + // re-adjust value + autoModel::setInitValue( value() ); + + emit propertiesChanged(); } - setStep( _step ); - // re-adjust value - autoObj::setInitValue( value() ); } template -void automatableObject::setStep( const T _step ) +void automatableModel::setStep( const T _step ) { /* const T intv = maxValue() - minValue(); @@ -201,26 +215,32 @@ void automatableObject::setStep( const T _step ) m_step = minRelStep() * intv; } }*/ - m_step = _step; - m_curLevel = level( m_value ); - m_minLevel = level( m_minValue ); - m_maxLevel = level( m_maxValue ); + if( m_step != _step ) + { + m_step = _step; + m_curLevel = level( m_value ); + m_minLevel = level( m_minValue ); + m_maxLevel = level( m_maxValue ); + + emit propertiesChanged(); + } } -template -void automatableObject::linkObjects( autoObj * _object1, - autoObj * _object2 ) -{ - _object1->linkObject( _object2 ); - _object2->linkObject( _object1 ); - if( _object1->m_automation_pattern != _object2->m_automation_pattern ) +template +void automatableModel::linkModels( autoModel * _model1, + autoModel * _model2 ) +{ + _model1->linkModel( _model2 ); + _model2->linkModel( _model1 ); + + if( _model1->m_automationPattern != _model2->m_automationPattern ) { - delete _object2->m_automation_pattern; - _object2->m_automation_pattern = _object1->m_automation_pattern; + delete _model2->m_automationPattern; + _model2->m_automationPattern = _model1->m_automationPattern; } } @@ -228,17 +248,17 @@ void automatableObject::linkObjects( autoObj * _object1, template -void automatableObject::unlinkObjects( autoObj * _object1, - autoObj * _object2 ) +void automatableModel::unlinkModels( autoModel * _model1, + autoModel * _model2 ) { - _object1->unlinkObject( _object2 ); - _object2->unlinkObject( _object1 ); + _model1->unlinkModel( _model2 ); + _model2->unlinkModel( _model1 ); - if( _object1->m_automation_pattern && _object1->m_automation_pattern - == _object2->m_automation_pattern ) + if( _model1->m_automationPattern && _model1->m_automationPattern + == _model2->m_automationPattern ) { - _object2->m_automation_pattern = new automationPattern( - *_object1->m_automation_pattern, _object2 ); + _model2->m_automationPattern = new automationPattern( + *_model1->m_automationPattern, _model2 ); } } @@ -246,11 +266,11 @@ void automatableObject::unlinkObjects( autoObj * _object1, template -void automatableObject::saveSettings( QDomDocument & _doc, +void automatableModel::saveSettings( QDomDocument & _doc, QDomElement & _this, const QString & _name ) { - if( m_automation_pattern && m_automation_pattern->getTimeMap().size() + if( m_automationPattern && m_automationPattern->getTimeMap().size() > 1 ) { QDomElement pattern_element; @@ -267,7 +287,7 @@ void automatableObject::saveSettings( QDomDocument & _doc, _this.appendChild( pattern_element ); } QDomElement element = _doc.createElement( _name ); - m_automation_pattern->saveSettings( _doc, element ); + m_automationPattern->saveSettings( _doc, element ); pattern_element.appendChild( element ); } else @@ -280,7 +300,7 @@ void automatableObject::saveSettings( QDomDocument & _doc, template -void automatableObject::loadSettings( +void automatableModel::loadSettings( const QDomElement & _this, const QString & _name ) { @@ -290,8 +310,8 @@ void automatableObject::loadSettings( node = node.namedItem( _name ); if( node.isElement() ) { - m_automation_pattern->loadSettings( node.toElement() ); - setLevel( m_automation_pattern->valueAt( 0 ) ); + m_automationPattern->loadSettings( node.toElement() ); + setLevel( m_automationPattern->valueAt( 0 ) ); return; } } @@ -303,22 +323,22 @@ void automatableObject::loadSettings( template -automationPattern * automatableObject::getAutomationPattern( +automationPattern * automatableModel::getAutomationPattern( void ) { - if( !m_automation_pattern ) + if( !m_automationPattern ) { - m_automation_pattern = new automationPattern( m_track, this ); + m_automationPattern = new automationPattern( m_track, this ); syncAutomationPattern(); } - return( m_automation_pattern ); + return( m_automationPattern ); } template -void automatableObject::redoStep( journalEntry & _je ) +void automatableModel::redoStep( journalEntry & _je ) { bool journalling = testAndSetJournalling( FALSE ); setValue( static_cast( value() + static_cast( @@ -330,7 +350,7 @@ void automatableObject::redoStep( journalEntry & _je ) template -void automatableObject::undoStep( journalEntry & _je ) +void automatableModel::undoStep( journalEntry & _je ) { journalEntry je( _je.actionID(), static_cast( -_je.data().toDouble() ) ); @@ -341,7 +361,7 @@ void automatableObject::undoStep( journalEntry & _je ) template -void automatableObject::prepareJournalEntryFromOldVal( void ) +void automatableModel::prepareJournalEntryFromOldVal( void ) { m_oldValue = value(); saveJournallingState( FALSE ); @@ -352,7 +372,7 @@ void automatableObject::prepareJournalEntryFromOldVal( void ) template -void automatableObject::addJournalEntryFromOldToCurVal( +void automatableModel::addJournalEntryFromOldToCurVal( void ) { if( m_journalEntryReady ) @@ -371,14 +391,14 @@ void automatableObject::addJournalEntryFromOldToCurVal( template -void automatableObject::setFirstValue( void ) +void automatableModel::setFirstValue( void ) { - if( m_automation_pattern && m_automation_pattern->updateFirst() ) + if( m_automationPattern && m_automationPattern->updateFirst() ) { - m_automation_pattern->putValue( 0, m_curLevel, FALSE ); + m_automationPattern->putValue( 0, m_curLevel, FALSE ); if( engine::getAutomationEditor() && engine::getAutomationEditor()->currentPattern() - == m_automation_pattern ) + == m_automationPattern ) { engine::getAutomationEditor()->update(); } @@ -389,12 +409,12 @@ void automatableObject::setFirstValue( void ) template -void automatableObject::linkObject( autoObj * _object ) +void automatableModel::linkModel( autoModel * _model ) { - if( qFind( m_linkedObjects.begin(), m_linkedObjects.end(), _object ) - == m_linkedObjects.end() ) + if( qFind( m_linkedModels.begin(), m_linkedModels.end(), _model ) + == m_linkedModels.end() ) { - m_linkedObjects.push_back( _object ); + m_linkedModels.push_back( _model ); } } @@ -402,14 +422,14 @@ void automatableObject::linkObject( autoObj * _object ) template -void automatableObject::unlinkObject( autoObj * _object ) +void automatableModel::unlinkModel( autoModel * _model ) { - if( qFind( m_linkedObjects.begin(), m_linkedObjects.end(), _object ) - != m_linkedObjects.end() ) + if( qFind( m_linkedModels.begin(), m_linkedModels.end(), _model ) + != m_linkedModels.end() ) { - m_linkedObjects.erase( qFind( m_linkedObjects.begin(), - m_linkedObjects.end(), - _object ) ); + m_linkedModels.erase( qFind( m_linkedModels.begin(), + m_linkedModels.end(), + _model ) ); } } @@ -417,14 +437,14 @@ void automatableObject::unlinkObject( autoObj * _object ) template -void automatableObject::syncAutomationPattern( void ) +void automatableModel::syncAutomationPattern( void ) { - for( int i = 0; i < m_linkedObjects.size(); ++i ) + for( int i = 0; i < m_linkedModels.size(); ++i ) { - autoObj * it = m_linkedObjects[i]; - if( m_automation_pattern != it->m_automation_pattern ) + autoModel * it = m_linkedModels[i]; + if( m_automationPattern != it->m_automationPattern ) { - it->m_automation_pattern = m_automation_pattern; + it->m_automationPattern = m_automationPattern; } } } @@ -433,16 +453,16 @@ void automatableObject::syncAutomationPattern( void ) template -void automatableObject::setLevel( int _level ) +void automatableModel::setLevel( int _level ) { if( m_curLevel == _level ) { return; } bool journalling = testAndSetJournalling( FALSE ); - m_automation_pattern->setUpdateFirst( FALSE ); + m_automationPattern->setUpdateFirst( FALSE ); setValue( _level * m_step ); - m_automation_pattern->setUpdateFirst( TRUE ); + m_automationPattern->setUpdateFirst( TRUE ); setJournalling( journalling ); } @@ -450,7 +470,7 @@ void automatableObject::setLevel( int _level ) template<> -inline float automatableObject::minRelStep( void ) +inline float automatableModel::minRelStep( void ) { return( 1.0e-10 ); } @@ -459,7 +479,7 @@ inline float automatableObject::minRelStep( void ) template<> -inline float automatableObject::defaultRelStep( void ) +inline float automatableModel::defaultRelStep( void ) { return( 1.0e-2 ); } @@ -468,7 +488,7 @@ inline float automatableObject::defaultRelStep( void ) template<> -inline float automatableObject::minEps( void ) +inline float automatableModel::minEps( void ) { return( 1.0e-10 ); } @@ -477,7 +497,7 @@ inline float automatableObject::minEps( void ) template<> -inline float automatableObject::attributeValue( QString _value ) +inline float automatableModel::attributeValue( QString _value ) { return( _value.toFloat() ); } @@ -486,7 +506,7 @@ inline float automatableObject::attributeValue( QString _value ) template<> -inline int automatableObject::attributeValue( QString _value ) +inline int automatableModel::attributeValue( QString _value ) { return( _value.toInt() ); } @@ -495,7 +515,15 @@ inline int automatableObject::attributeValue( QString _value ) template<> -inline bool automatableObject::attributeValue( +inline bool automatableModel::attributeValue( QString _value ) +{ + return( static_cast( _value.toInt() ) ); +} + + + +template<> +inline bool automatableModel::attributeValue( QString _value ) { return( static_cast( _value.toInt() ) ); diff --git a/include/automatable_slider.h b/include/automatable_slider.h index cdd6a67c9d..2d719d17cb 100644 --- a/include/automatable_slider.h +++ b/include/automatable_slider.h @@ -30,18 +30,18 @@ #include -class knob; +#include "automatable_model.h" -class automatableSlider : public QSlider + +class automatableSlider : public QSlider, public automatableModelView { Q_OBJECT public: - automatableSlider( QWidget * _parent, const QString & _name, - class track * _track ); + automatableSlider( QWidget * _parent, const QString & _name ); virtual ~automatableSlider(); - virtual void setRange( int _min, int _max ); +/* virtual void setRange( int _min, int _max ); virtual void setValue( int _value ); virtual void setInitValue( int _value ); @@ -51,11 +51,11 @@ public: const QString & _name ); int logicValue( void ); - void clearAutomationValues( void ); + void clearAutomationValues( void );*/ bool showStatus( void ) { - return( m_show_status ); + return( m_showStatus ); } @@ -70,10 +70,11 @@ protected: virtual void mouseReleaseEvent( QMouseEvent * _me ); virtual void wheelEvent( QWheelEvent * _me ); + virtual void modelChanged( void ); + private: - knob * m_knob; - bool m_show_status; + bool m_showStatus; private slots: @@ -84,6 +85,7 @@ private slots: } ; +typedef automatableSlider::autoModel sliderModel; #endif diff --git a/include/bb_editor.h b/include/bb_editor.h index 05e7b58c4d..e9df4580f9 100644 --- a/include/bb_editor.h +++ b/include/bb_editor.h @@ -27,17 +27,18 @@ #define _BB_EDITOR_H #include "track_container.h" +#include "combobox.h" class QPixmap; -class comboBox; class toolButton; class bbEditor : public trackContainer { Q_OBJECT + mapPropertyFromModelPtr(int,currentBB,setCurrentBB,m_bbComboBoxModel); public: virtual bool FASTCALL play( midiTime _start, const fpp_t _frames, const f_cnt_t _frame_base, @@ -58,11 +59,6 @@ public: return( TRUE ); } - int currentBB( void ) const - { - return( m_currentBB ); - } - tact FASTCALL lengthOfBB( const int _bb ); inline tact lengthOfCurrentBB( void ) { @@ -80,7 +76,7 @@ public slots: void play( void ); void stop( void ); void updateComboBox( void ); - void setCurrentBB( int _bb ); + void currentBBChanged( void ); protected: @@ -95,15 +91,13 @@ private: void FASTCALL createTCOsForBB( const int _bb ); - int m_currentBB; - QWidget * m_toolBar; toolButton * m_playButton; toolButton * m_stopButton; comboBox * m_bbComboBox; - + comboBoxModel * m_bbComboBoxModel; friend class engine; diff --git a/include/combobox.h b/include/combobox.h index d15e9fbf83..7a73164620 100644 --- a/include/combobox.h +++ b/include/combobox.h @@ -29,41 +29,93 @@ #include #include #include -#include #include -#include "automatable_object.h" +#include "automatable_model.h" +#include "automatable_model_templates.h" -class QAction; - - -class comboBox : public QWidget, public automatableObject +class comboBoxModel : public intModel { Q_OBJECT public: - comboBox( QWidget * _parent, const QString & _name, track * _track ); - virtual ~comboBox(); - - void addItem( const QString & _item, const QPixmap & _pixmap = - QPixmap() ); - - inline void clear( void ) + comboBoxModel( ::model * _parent = NULL ) : + automatableModel( 0, 0, 0, defaultRelStep(), _parent ) { - setRange( 0, 0 ); - m_items.clear(); - m_menu.clear(); - update(); } + void addItem( const QString & _item, QPixmap * _data = NULL ); + + void clear( void ); + int findText( const QString & _txt ) const; - QString currentText( void ) const + inline const QString & currentText( void ) const { return( m_items[value()].first ); } - void setValue( const int _idx ); + inline const QPixmap * currentData( void ) const + { + return( m_items[value()].second ); + } + + inline const QString & itemText( int _i ) const + { + return( m_items[tLimit( _i, minValue(), maxValue() )]. + first ); + } + + inline const QPixmap * itemPixmap( int _i ) const + { + return( m_items[tLimit( _i, minValue(), maxValue() )]. + second ); + } + + inline int size( void ) const + { + return( m_items.size() ); + } + +private: + typedef QPair item; + + QVector m_items; + + +signals: + void itemPixmapRemoved( QPixmap * _item ); + +} ; + + + +class comboBox : public QWidget, public intModelView +{ + Q_OBJECT +public: + comboBox( QWidget * _parent, const QString & _name = QString::null ); + virtual ~comboBox(); + + comboBoxModel * model( void ) + { + return( castModel() ); + } + + const comboBoxModel * model( void ) const + { + return( castModel() ); + } + + + virtual void modelChanged( void ) + { + if( model() != NULL ) + { + connect( model(), SIGNAL( itemPixmapRemoved( QPixmap * ) ), + this, SLOT( deletePixmap( QPixmap * ) ) ); + } + } protected: @@ -79,20 +131,17 @@ private: QMenu m_menu; - typedef QPair item; - - QVector m_items; - bool m_pressed; private slots: + void deletePixmap( QPixmap * _pixmap ); void setItem( QAction * _item ); - +/* signals: void activated( const QString & ); - void valueChanged( int ); + void valueChanged( int );*/ } ; diff --git a/include/detuning_helper.h b/include/detuning_helper.h index 1fd174d9b1..21fb79104c 100644 --- a/include/detuning_helper.h +++ b/include/detuning_helper.h @@ -27,14 +27,16 @@ #define _DETUNING_HELPER_H +#include "automatable_model.h" #include "shared_object.h" +#include "automation_editor.h" -class detuningHelper : public automatableObject, public sharedObject +class detuningHelper : public floatModel, public sharedObject { public: detuningHelper( void ) : - autoObj( NULL ) + autoModel( NULL ) { } diff --git a/include/effect.h b/include/effect.h index a07cafa656..a44655a4a6 100644 --- a/include/effect.h +++ b/include/effect.h @@ -34,11 +34,14 @@ #include #include "plugin.h" +#include "engine.h" #include "mixer.h" +#include "automatable_model.h" class effectControlDialog; class track; +class rackPlugin; class effect : public plugin @@ -88,14 +91,9 @@ public: m_running = FALSE; } - inline bool isBypassed( void ) + inline bool enabled( void ) { - return( m_bypass ); - } - - inline void setBypass( bool _mode ) - { - m_bypass = _mode; + return( m_enabledModel.value() ); } inline Uint32 getTimeout( void ) @@ -110,45 +108,41 @@ public: inline float getWetLevel( void ) { - return( m_wetDry ); + return( m_wetDryModel.value() ); } inline float getDryLevel( void ) { - return( 1.0f - m_wetDry ); + return( 1.0f - m_wetDryModel.value() ); } - inline void setWetLevel( float _wet ) - { - m_wetDry = _wet; - } inline float getGate( void ) { - return( m_gate ); + const float level = m_gateModel.value(); + return( level*level * m_processors * + engine::getMixer()->framesPerPeriod() ); } - - void setGate( float _level ); - + inline Uint32 getBufferCount( void ) { return( m_bufferCount ); } - + inline void resetBufferCount( void ) { m_bufferCount = 0; } - + inline void incrementBufferCount( void ) { m_bufferCount++; } - + inline bool dontRun( void ) { return( m_noRun ); } - + inline void setDontRun( bool _state ) { m_noRun = _state; @@ -169,17 +163,20 @@ private: descriptor::subPluginFeatures::key m_key; ch_cnt_t m_processors; - + bool m_okay; bool m_noRun; bool m_running; - bool m_bypass; - + boolModel m_enabledModel; + Uint32 m_bufferCount; Uint32 m_silenceTimeout; - - float m_wetDry; - float m_gate; + + floatModel m_wetDryModel; + floatModel m_gateModel; + + + friend class rackPlugin; } ; diff --git a/include/envelope_and_lfo_widget.h b/include/envelope_and_lfo_widget.h index 4edd517951..a2e5011413 100644 --- a/include/envelope_and_lfo_widget.h +++ b/include/envelope_and_lfo_widget.h @@ -33,6 +33,7 @@ #include "journalling_object.h" +#include "automatable_model.h" #include "sample_buffer.h" #include "types.h" @@ -102,10 +103,7 @@ protected: protected slots: - void updateAfterKnobChange( float ); - void lfoWaveCh( int ); - void lfoUserWaveCh( bool ); - void x100Toggled( bool ); + void lfoUserWaveChanged( void ); private: @@ -126,6 +124,15 @@ private: knob * m_releaseKnob; knob * m_amountKnob; + // models + floatModel m_predelayModel; + floatModel m_attackModel; + floatModel m_holdModel; + floatModel m_decayModel; + floatModel m_sustainModel; + floatModel m_releaseModel; + floatModel m_amountModel; + float m_sustainLevel; float m_amount; float m_valueForZeroAmount; @@ -135,6 +142,7 @@ private: sample_t * m_pahdEnv; sample_t * m_rEnv; + // LFO-stuff knob * m_lfoPredelayKnob; knob * m_lfoAttackKnob; @@ -146,6 +154,17 @@ private: ledCheckBox * m_x100Cb; ledCheckBox * m_controlEnvAmountCb; + // models + floatModel m_lfoPredelayModel; + floatModel m_lfoAttackModel; + floatModel m_lfoSpeedModel; + floatModel m_lfoAmountModel; + intModel m_lfoWaveModel; + + boolModel m_x100Model; + boolModel m_controlEnvAmountModel; + + f_cnt_t m_lfoPredelayFrames; f_cnt_t m_lfoAttackFrames; f_cnt_t m_lfoOscillationFrames; @@ -163,7 +182,7 @@ private: SAW, SQUARE, USER - } m_lfoShape; + } ; sample_t lfoShapeSample( fpp_t _frame_offset ); void updateLFOShapeData( void ); diff --git a/include/envelope_tab_widget.h b/include/envelope_tab_widget.h index 2599c19941..65f92cd7ec 100644 --- a/include/envelope_tab_widget.h +++ b/include/envelope_tab_widget.h @@ -31,10 +31,12 @@ #include #include "mixer.h" +#include "automatable_model.h" class QLabel; +class comboBoxModel; class instrumentTrack; class comboBox; class envelopeAndLFOWidget; @@ -92,6 +94,11 @@ private: knob * m_filterCutKnob; knob * m_filterResKnob; + boolModel * m_filterEnabledModel; + comboBoxModel * m_filterModel; + floatModel * m_filterCutModel; + floatModel * m_filterResModel; + friend class flpImport; } ; diff --git a/include/export_project_dialog.h b/include/export_project_dialog.h index c513669305..61be5eb960 100644 --- a/include/export_project_dialog.h +++ b/include/export_project_dialog.h @@ -30,6 +30,7 @@ #include #include "export.h" +#include "automatable_model.h" class QLabel; @@ -37,6 +38,7 @@ class QPushButton; class QProgressBar; class comboBox; +class comboBoxModel; class ledCheckBox; class pixmapButton; @@ -71,18 +73,22 @@ private: static Sint16 s_availableBitrates[]; - QString m_fileName; QLabel * m_typeLbl; comboBox * m_typeCombo; + comboBoxModel * m_typeModel; QLabel * m_kbpsLbl; comboBox * m_kbpsCombo; + comboBoxModel * m_kbpsModel; ledCheckBox * m_vbrCb; + boolModel * m_vbrEnabledModel; ledCheckBox * m_hqmCb; + boolModel * m_hqmEnabledModel; QLabel * m_hourglassLbl; QPushButton * m_exportBtn; QPushButton * m_cancelBtn; QProgressBar * m_exportProgressBar; + QString m_fileName; fileTypes m_fileType; bool m_deleteFile; diff --git a/include/group_box.h b/include/group_box.h index 379dbc1e5e..54fed76bd7 100644 --- a/include/group_box.h +++ b/include/group_box.h @@ -28,38 +28,28 @@ #include +#include "automatable_model.h" #include "pixmap_button.h" class QPixmap; -class groupBox : public QWidget +class groupBox : public QWidget, public boolModelView { Q_OBJECT public: - groupBox( const QString & _caption, QWidget * _parent, track * _track ); + groupBox( const QString & _caption, QWidget * _parent ); virtual ~groupBox(); - bool isActive( void ) const - { - return( m_led->isChecked() ); - } - - void saveSettings( QDomDocument & _doc, QDomElement & _this, - const QString & _name ); - void loadSettings( const QDomElement & _this, const QString & _name ); + virtual void modelChanged( void ); public slots: - void setState( bool _on, bool _anim = FALSE ); +// void setState( bool _on, bool _anim = FALSE ); void animate( void ); -signals: - void toggled( bool _state ); - - protected: virtual void resizeEvent( QResizeEvent * _re ); virtual void mousePressEvent( QMouseEvent * _me ); @@ -78,4 +68,8 @@ private: } ; + +typedef groupBox::autoModel groupBoxModel; + + #endif diff --git a/include/instrument_track.h b/include/instrument_track.h index 6f3dd9e291..7f2f9dd438 100644 --- a/include/instrument_track.h +++ b/include/instrument_track.h @@ -30,8 +30,11 @@ #include #include +#include "automatable_model.h" +#include "lcd_spinbox.h" #include "midi_event_processor.h" #include "mixer.h" +#include "surround_area.h" #include "tab_widget.h" #include "track.h" @@ -56,6 +59,7 @@ class volumeKnob; class instrumentTrack : public QWidget, public track, public midiEventProcessor { Q_OBJECT + mapPropertyFromModel(int,getVolume,setVolume,m_volumeModel); public: instrumentTrack( trackContainer * _tc ); virtual ~instrumentTrack(); @@ -100,13 +104,12 @@ public: void FASTCALL setName( const QString & _new_name ); // volume & surround-position-stuff - void FASTCALL setVolume( volume _new_volume ); - volume getVolume( void ) const; - void FASTCALL setSurroundAreaPos( const QPoint & _p ); +/* void FASTCALL setVolume( volume _new_volume ); + volume getVolume( void ) const;*/ - void FASTCALL setBaseNote( Uint32 _new_note, bool _modified = TRUE ); +// void FASTCALL setBaseNote( Uint32 _new_note, bool _modified = TRUE ); - inline tones baseTone( void ) const +/* inline tones baseTone( void ) const { return( m_baseTone ); } @@ -114,7 +117,7 @@ public: inline octaves baseOctave( void ) const { return( m_baseOctave ); - } + }*/ int FASTCALL masterKey( notePlayHandle * _n ) const; @@ -158,9 +161,13 @@ public: return( m_audioPort ); } + intModel * baseNoteModel( void ) + { + return( &m_baseNoteModel ); + } + public slots: - void surroundAreaPosChanged( const QPoint & _new_p ); void textChanged( const QString & _new_name ); void toggledInstrumentTrackButton( bool _on ); @@ -192,6 +199,8 @@ protected slots: void midiOutSelected( void ); void midiConfigChanged( bool ); + void updateBaseNote( void ); + private: trackTypes m_trackType; @@ -204,13 +213,12 @@ private: notePlayHandle * m_notes[NOTES_PER_OCTAVE * OCTAVES]; - tones m_baseTone; - octaves m_baseOctave; + intModel m_baseNoteModel; QList m_processHandles; - // widgets on the top of a instrument-track-window + // widgets on the top of an instrument-track-window tabWidget * m_generalSettingsWidget; QLineEdit * m_instrumentNameLE; volumeKnob * m_volumeKnob; @@ -218,7 +226,11 @@ private: lcdSpinBox * m_effectChannelNumber; QPushButton * m_saveSettingsBtn; - + floatModel m_volumeModel; + surroundAreaModel m_surroundAreaModel; + lcdSpinBoxModel m_effectChannelModel; + + // tab-widget with all children tabWidget * m_tabWidget; instrument * m_instrument; @@ -245,9 +257,9 @@ private: friend class presetPreviewPlayHandle; friend class flpImport; - // base-tone stuff +/* // base-tone stuff void FASTCALL setBaseTone( tones _new_tone ); - void FASTCALL setBaseOctave( octaves _new_octave ); + void FASTCALL setBaseOctave( octaves _new_octave );*/ } ; diff --git a/include/journalling_object.h b/include/journalling_object.h index 48b1763ec6..7c8d91842c 100644 --- a/include/journalling_object.h +++ b/include/journalling_object.h @@ -147,10 +147,6 @@ public: // to be implemented by actual object virtual QString nodeName( void ) const = 0; - -protected: - void addJournalEntry( const journalEntry & _je ); - inline bool isJournalling( void ) const { return( m_journalling ); @@ -169,6 +165,10 @@ protected: } + +protected: + void addJournalEntry( const journalEntry & _je ); + // to be implemented by sub-objects virtual void FASTCALL saveSettings( QDomDocument & _doc, QDomElement & _this ) diff --git a/include/knob.h b/include/knob.h index f614550eb2..d075698e8d 100644 --- a/include/knob.h +++ b/include/knob.h @@ -32,7 +32,8 @@ #include #include -#include "automatable_object.h" +#include "automatable_model.h" +#include "templates.h" class QPixmap; @@ -46,32 +47,20 @@ enum knobTypes -class knob : public QWidget, public automatableObject +class knob : public QWidget, public floatModelView { Q_OBJECT public: - knob( int _knob_num, QWidget * _parent, const QString & _name, - track * _track ); + knob( int _knob_num, QWidget * _parent, const QString & _name ); virtual ~knob(); - + void setHintText( const QString & _txt_before, const QString & _txt_after ); void setLabel( const QString & _txt ); void setTotalAngle( float _angle ); - inline virtual void setInitValue( const float _val ) - { - m_initValue = _val; - autoObj::setInitValue( _val ); - } - - virtual void setValue( const float _x ); - - virtual void setRange( const float _min, const float _max, - const float _step = 0.0 ); - public slots: void reset( void ); @@ -83,8 +72,8 @@ public slots: signals: - void valueChanged( float value ); - void valueChanged( void ); +// void valueChanged( float value ); +// void valueChanged( void ); void sliderPressed( void ); void sliderReleased( void ); void sliderMoved( float value ); @@ -102,8 +91,6 @@ protected: QString m_hintTextBeforeValue; QString m_hintTextAfterValue; - float m_initValue; - virtual void contextMenuEvent( QContextMenuEvent * _me ); virtual void dragEnterEvent( QDragEnterEvent * _dee ); virtual void dropEvent( QDropEvent * _de ); @@ -112,7 +99,6 @@ protected: virtual void mouseMoveEvent( QMouseEvent * _me ); virtual void mouseDoubleClickEvent( QMouseEvent * _me ); virtual void paintEvent( QPaintEvent * _me ); - virtual void resizeEvent( QResizeEvent * _me ); virtual void wheelEvent( QWheelEvent * _me ); void drawKnob( QPainter * _p ); @@ -122,16 +108,16 @@ protected: private: - void layoutKnob( bool _update = TRUE ); - void recalcAngle( void ); - - void valueChange( void ); - void rangeChange( void ); + inline float pageSize( void ) const + { + return( tMax( ( model()->maxValue() - + model()->minValue() ) / 100.0f, + model()->step() ) ); + } + void valueChange( void ); void buttonReleased( void ); - float m_pageSize; - float m_angle; float m_totalAngle; int m_knobNum; @@ -139,4 +125,7 @@ private: } ; + +typedef knob::autoModel knobModel; + #endif diff --git a/include/ladspa_control.h b/include/ladspa_control.h index 66ce7efe5c..9cafb0a8a6 100644 --- a/include/ladspa_control.h +++ b/include/ladspa_control.h @@ -39,10 +39,10 @@ #endif -#include "journalling_object.h" +#include "automatable_model.h" +#include "knob.h" -class knob; class ledCheckBox; class track; @@ -65,14 +65,14 @@ public: void FASTCALL linkControls( ladspaControl * _control ); void FASTCALL unlinkControls( ladspaControl * _control ); - inline ledCheckBox * getToggle( void ) + inline boolModel * getToggledModel( void ) { - return( m_toggle ); + return( &m_toggledModel ); } - inline knob * getKnob( void ) + inline knobModel * getKnobModel( void ) { - return( m_knob ); + return( &m_knobModel ); } inline port_desc_t * getPort( void ) @@ -89,15 +89,18 @@ public: return( "port" ); } + signals: void changed( Uint16 _port, LADSPA_Data _value ); void linkChanged( Uint16 _port, bool _state ); + protected slots: - void ledChange( bool _state ); - void knobChange( float _value ); - void portLink( bool _state ); - + void ledChanged( void ); + void knobChanged( void ); + void linkStateChanged( void ); + + private: port_desc_t * m_port; track * m_track; @@ -105,6 +108,11 @@ private: ledCheckBox * m_link; ledCheckBox * m_toggle; knob * m_knob; -}; + + boolModel m_linkEnabledModel; + boolModel m_toggledModel; + knobModel m_knobModel; + +} ; #endif diff --git a/include/lcd_spinbox.h b/include/lcd_spinbox.h index 8f788a36c9..6c4c86a1ab 100644 --- a/include/lcd_spinbox.h +++ b/include/lcd_spinbox.h @@ -29,33 +29,38 @@ #include #include -#include "automatable_object.h" +#include "automatable_model.h" class QLabel; -class lcdSpinBox : public QWidget, public automatableObject +class lcdSpinBox : public QWidget, public automatableModelView { Q_OBJECT public: - lcdSpinBox( int _min, int _max, int _num_digits, QWidget * _parent, - const QString & _name, track * _track ); + lcdSpinBox( int _num_digits, QWidget * _parent, const QString & _name = + QString::null ); virtual ~lcdSpinBox(); - virtual void setStep( const int _step ); - void setLabel( const QString & _txt ); inline void addTextForValue( int _val, const QString & _text ) { m_textForValue[_val] = _text; + update(); + } + + virtual void modelChanged( void ) + { + modelView::modelChanged(); + update(); } public slots: - virtual void setValue( const int _value ); virtual void setEnabled( bool _on ); + virtual void update( void ); protected: @@ -76,9 +81,10 @@ private: signals: - void valueChanged( int ); void manualChange( void ); } ; +typedef lcdSpinBox::autoModel lcdSpinBoxModel; + #endif diff --git a/include/led_checkbox.h b/include/led_checkbox.h index 17529c6536..6f09581178 100644 --- a/include/led_checkbox.h +++ b/include/led_checkbox.h @@ -42,8 +42,8 @@ public: } ; ledCheckBox( const QString & _txt, QWidget * _parent, - const QString & _name, track * _track, - ledColors _color = YELLOW ); + const QString & _name = QString::null, + ledColors _color = YELLOW ); virtual ~ledCheckBox(); diff --git a/include/meter_dialog.h b/include/meter_dialog.h index de446843f5..5fdba0d3d9 100644 --- a/include/meter_dialog.h +++ b/include/meter_dialog.h @@ -44,21 +44,26 @@ public: inline int getNumerator( void ) { - return( m_numerator->value() ); + return( m_numeratorModel->value() ); } inline int getDenominator( void ) { - return( m_denominator->value() ); + return( m_denominatorModel->value() ); } - + + private: lcdSpinBox * m_numerator; lcdSpinBox * m_denominator; + lcdSpinBoxModel * m_numeratorModel; + lcdSpinBoxModel * m_denominatorModel; + signals: - void numeratorChanged( int ); - void denominatorChanged( int ); -}; + void numeratorChanged( void ); + void denominatorChanged( void ); + +} ; #endif diff --git a/include/midi_tab_widget.h b/include/midi_tab_widget.h index 775dcd7902..3a042f0975 100644 --- a/include/midi_tab_widget.h +++ b/include/midi_tab_widget.h @@ -29,7 +29,7 @@ #include -#include "journalling_object.h" +#include "automatable_model.h" class QMenu; @@ -61,14 +61,14 @@ public: public slots: - void midiPortModeToggled( bool = FALSE ); + void midiPortModeChanged( void ); protected slots: - void inputChannelChanged( int ); - void outputChannelChanged( int ); - void defaultVelInChanged( bool ); - void defaultVelOutChanged( bool ); + void inputChannelChanged( void ); + void outputChannelChanged( void ); + void defaultVelInChanged( void ); + void defaultVelOutChanged( void ); void readablePortsChanged( void ); void writeablePortsChanged( void ); void activatedReadablePort( QAction * _item ); @@ -85,6 +85,12 @@ private: ledCheckBox * m_sendCheckBox; ledCheckBox * m_defaultVelocityInCheckBox; ledCheckBox * m_defaultVelocityOutCheckBox; + intModel m_inputChannelModel; + intModel m_outputChannelModel; + boolModel m_receiveEnabledModel; + boolModel m_sendEnabledModel; + boolModel m_defaultVelocityInEnabledModel; + boolModel m_defaultVelocityOutEnabledModel; QMenu * m_readablePorts; QMenu * m_writeablePorts; diff --git a/include/mv_base.h b/include/mv_base.h new file mode 100644 index 0000000000..d0c990c5de --- /dev/null +++ b/include/mv_base.h @@ -0,0 +1,107 @@ +/* + * mv_base.h - base for M/V-architecture of LMMS + * + * Copyright (c) 2007 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#ifndef _MV_BASE_H +#define _MV_BASE_H + +#include + + +class model : public QObject +{ + Q_OBJECT +public: + model( model * _parent, bool _default_constructed = FALSE ) : + QObject( _parent ), + m_defaultConstructed( _default_constructed ) + { + } + + virtual ~model() + { + } + + inline bool defaultConstructed( void ) + { + return( m_defaultConstructed ); + } + + +private: + bool m_defaultConstructed; + + +signals: + // emitted if actual data of the model (e.g. values) have changed + void dataChanged( void ); + + // emitted if properties of the model (e.g. ranges) have changed + void propertiesChanged( void ); + +} ; + + + + +class modelView +{ +public: + modelView() : + m_model( NULL ) + { + } + + virtual ~modelView() + { + } + + void setModel( model * _model, bool _old_model_valid = TRUE ); + + // sub-classes can re-implement this to track model-changes + virtual void modelChanged( void ) + { + } + + template + T * castModel( void ) + { + return( dynamic_cast( m_model ) ); + } + + template + const T * castModel( void ) const + { + return( dynamic_cast( m_model ) ); + } + + +private: + model * m_model; + +} ; + + +#endif + diff --git a/include/piano_roll.h b/include/piano_roll.h index 567020ec88..b10d6543b5 100644 --- a/include/piano_roll.h +++ b/include/piano_roll.h @@ -39,6 +39,7 @@ class QPixmap; class QScrollBar; class comboBox; +class comboBoxModel; class notePlayHandle; class pattern; class timeLine; @@ -125,7 +126,7 @@ protected slots: void updatePosition( const midiTime & _t ); - void zoomingChanged( const QString & _zfac ); + void zoomingChanged( void ); private: @@ -196,6 +197,11 @@ private: comboBox * m_quantizeComboBox; comboBox * m_noteLenComboBox; + comboBoxModel * m_zoomingModel; + comboBoxModel * m_quantizeModel; + comboBoxModel * m_noteLenModel; + + pattern * m_pattern; QScrollBar * m_leftRightScroll; diff --git a/include/piano_widget.h b/include/piano_widget.h index a5611979b6..9f6668db2f 100644 --- a/include/piano_widget.h +++ b/include/piano_widget.h @@ -33,6 +33,7 @@ #include "note.h" +#include "automatable_model.h" class instrumentTrack; @@ -56,11 +57,6 @@ public: void setKeyState( int _key, bool _on = FALSE ); - virtual void saveSettings( QDomDocument & _doc, QDomElement & _this, - const QString & _name ); - virtual void loadSettings( const QDomElement & _this, - const QString & _name ); - virtual void keyPressEvent( QKeyEvent * ke ); virtual void keyReleaseEvent( QKeyEvent * ke ); #ifndef BUILD_WIN32 @@ -95,14 +91,12 @@ private: octaves m_startOctave; int m_lastKey; - unsigned int m_keycode; + unsigned int m_keyCode; - knob * m_noteKnob; private slots: void pianoScrolled( int _new_pos ); - void updateBaseNote( void ); } ; diff --git a/include/pixmap_button.h b/include/pixmap_button.h index 4af5a91dda..065c47c6d5 100644 --- a/include/pixmap_button.h +++ b/include/pixmap_button.h @@ -35,8 +35,7 @@ class pixmapButton : public automatableButton { Q_OBJECT public: - pixmapButton( QWidget * _parent, const QString & _name, - track * _track ); + pixmapButton( QWidget * _parent, const QString & _name ); virtual ~pixmapButton(); void setActiveGraphic( const QPixmap & _pm ); diff --git a/include/rack_plugin.h b/include/rack_plugin.h index 5d29809d34..7334a3482d 100644 --- a/include/rack_plugin.h +++ b/include/rack_plugin.h @@ -22,12 +22,13 @@ * Boston, MA 02110-1301 USA. * */ + #ifndef _RACK_PLUGIN_H #define _RACK_PLUGIN_H #include -#include "journalling_object.h" +#include "automatable_model.h" class QGroupBox; @@ -68,10 +69,10 @@ public: public slots: void editControls( void ); - void bypassed( bool _state ); - void setWetDry( float _value ); - void setAutoQuit( float _value ); - void setGate( float _value ); + void updateAutoQuit( void ); +/* void bypassChanged( void ); + void updateWetDry( void ); + void updateGate( void );*/ void moveUp( void ); void moveDown( void ); void deletePlugin( void ); @@ -87,6 +88,8 @@ protected: void contextMenuEvent( QContextMenuEvent * _me ); private: + floatModel m_autoQuitModel; + ledCheckBox * m_bypass; knob * m_wetDry; tempoSyncKnob * m_autoQuit; @@ -95,7 +98,7 @@ private: QGroupBox * m_controls; QLabel * m_label; QPushButton * m_editButton; - QMdiSubWindow *m_subWindow; + QMdiSubWindow * m_subWindow; effect * m_effect; effectControlDialog * m_controlView; track * m_track; diff --git a/include/sample_play_handle.h b/include/sample_play_handle.h index eb409ad1da..03106a2f6a 100644 --- a/include/sample_play_handle.h +++ b/include/sample_play_handle.h @@ -30,6 +30,7 @@ #include "play_handle.h" #include "sample_buffer.h" +#include "automatable_model.h" class bbTrack; class pattern; @@ -38,9 +39,8 @@ class track; class audioPort; -class samplePlayHandle : public QObject, public playHandle +class samplePlayHandle : public playHandle { - Q_OBJECT public: samplePlayHandle( const QString & _sample_file ); samplePlayHandle( sampleBuffer * _sample_buffer ); @@ -68,9 +68,10 @@ public: m_bbTrack = _bb_track; } - -public slots: - void setVolume( float _new_volume ); + void setVolumeModel( floatModel * _model ) + { + m_volumeModel = _model; + } private: @@ -83,7 +84,8 @@ private: audioPort * m_audioPort; const bool m_ownAudioPort; - float m_volume; + floatModel m_defaultVolumeModel; + floatModel * m_volumeModel; track * m_track; bbTrack * m_bbTrack; diff --git a/include/sample_track.h b/include/sample_track.h index b3e3bb10f8..e430f9627d 100644 --- a/include/sample_track.h +++ b/include/sample_track.h @@ -30,12 +30,12 @@ #include #include "track.h" +#include "volume_knob.h" class QLabel; class audioPort; class effectLabel; class sampleBuffer; -class volumeKnob; //class sampleTCOSettingsDialog; @@ -147,6 +147,7 @@ private: audioPort * m_audioPort; volumeKnob * m_volumeKnob; + knobModel m_volumeModel; } ; diff --git a/include/setup_dialog.h b/include/setup_dialog.h index 9e3716b177..0be11647d0 100644 --- a/include/setup_dialog.h +++ b/include/setup_dialog.h @@ -99,7 +99,6 @@ private slots: void toggleDisableChActInd( bool _disabled ); void toggleManualChPiano( bool _enabled ); - void setParallelizingLevel( int _level ); private: @@ -138,7 +137,6 @@ private: bool m_disableChActInd; bool m_manualChPiano; - int m_parLevel; typedef QMap aswMap; typedef QMap mswMap; diff --git a/include/song_editor.h b/include/song_editor.h index 93901e5f4e..592cd82e6c 100644 --- a/include/song_editor.h +++ b/include/song_editor.h @@ -28,14 +28,14 @@ #define _SONG_EDITOR_H #include "track_container.h" +#include "lcd_spinbox.h" +#include "automatable_slider.h" class QLabel; class QScrollBar; -class automatableSlider; class comboBox; -class lcdSpinBox; class pattern; class textFloat; class timeLine; @@ -51,6 +51,8 @@ const Uint16 MAX_SONG_LENGTH = 9999; class songEditor : public trackContainer { Q_OBJECT + mapPropertyFromModel(int,masterPitch,setMasterPitch,m_masterPitchModel); + mapPropertyFromModel(int,masterVolume,setMasterVolume,m_masterVolumeModel); public: enum playModes { @@ -154,8 +156,6 @@ public: return( FALSE ); } - int masterPitch( void ) const; - public slots: void play( void ); @@ -172,10 +172,6 @@ public slots: void startExport( void ); void stopExport( void ); - // set tempo in BPM (beats per minute) - void setTempo( int _new_bpm = DEFAULT_BPM ); - void setMasterVolume( volume _vol ); - void setMasterPitch( int _master_pitch ); void setModified( void ); @@ -198,6 +194,8 @@ protected slots: void scrolled( int _new_pos ); void updateTimeLinePosition( void ); + void setTempo( void ); + void masterVolumeChanged( int _new_val ); void masterVolumePressed( void ); void masterVolumeMoved( int _new_val ); @@ -209,7 +207,7 @@ protected slots: void updatePosition( const midiTime & _t ); - void zoomingChanged( const QString & _zfac ); + void zoomingChanged( void ); void doActions( void ); @@ -235,16 +233,22 @@ private: + track * m_automationTrack; + QScrollBar * m_leftRightScroll; QWidget * m_toolBar; toolButton * m_playButton; toolButton * m_stopButton; - lcdSpinBox * m_bpmSpinBox; + lcdSpinBox * m_tempoSpinBox; + lcdSpinBoxModel m_tempoModel; automatableSlider * m_masterVolumeSlider; automatableSlider * m_masterPitchSlider; + sliderModel m_masterVolumeModel; + sliderModel m_masterPitchModel; + textFloat * m_mvsStatus; textFloat * m_mpsStatus; @@ -275,8 +279,6 @@ private: bool m_scrollBack; - track * m_automation_track; - enum ACTIONS diff --git a/include/surround_area.h b/include/surround_area.h index 2147c9d625..c7b40d1785 100644 --- a/include/surround_area.h +++ b/include/surround_area.h @@ -30,6 +30,7 @@ #include +#include "automatable_model.h" #include "mixer.h" @@ -41,24 +42,70 @@ class track; const int SURROUND_AREA_SIZE = 1024; -class surroundArea : public QWidget +class surroundAreaModel : public model +{ + Q_OBJECT + mapPropertyFromModel(int,x,setX,m_posX); + mapPropertyFromModel(int,y,setY,m_posY); +public: + surroundAreaModel( ::model * _parent, track * _track = NULL, + bool _default_constructed = FALSE ); + + volumeVector getVolumeVector( float _v_scale ) const; + + void saveSettings( QDomDocument & _doc, QDomElement & _this, + const QString & _name = "surpos" ); + void loadSettings( const QDomElement & _this, + const QString & _name = "surpos" ); + + inline void prepareJournalEntryFromOldVal( void ) + { + m_posX.prepareJournalEntryFromOldVal(); + m_posY.prepareJournalEntryFromOldVal(); + } + + inline void addJournalEntryFromOldToCurVal( void ) + { + m_posX.addJournalEntryFromOldToCurVal(); + m_posY.addJournalEntryFromOldToCurVal(); + } + + automationPattern * automationPatternX( void ) + { + return( m_posX.getAutomationPattern() ); + } + + automationPattern * automationPatternY( void ) + { + return( m_posY.getAutomationPattern() ); + } + + +private: + intModel m_posX; + intModel m_posY; + +} ; + + + +class surroundArea : public QWidget, public modelView { Q_OBJECT public: - surroundArea( QWidget * _parent, const QString & _name, - track * _track ); + surroundArea( QWidget * _parent, const QString & _name ); virtual ~surroundArea(); - volumeVector getVolumeVector( float _v_scale ) const; - inline const QPoint & value( void ) const - { - return( m_sndSrcPos ); - } - void FASTCALL setValue( const QPoint & _p ); - void FASTCALL saveSettings( QDomDocument & _doc, QDomElement & _this, - const QString & _name = "surpos" ); - void FASTCALL loadSettings( const QDomElement & _this, - const QString & _name = "surpos" ); + + surroundAreaModel * model( void ) + { + return( castModel() ); + } + + const surroundAreaModel * model( void ) const + { + return( castModel() ); + } protected: @@ -69,23 +116,9 @@ protected: virtual void mouseReleaseEvent( QMouseEvent * _me ); -signals: - void valueChanged( const QPoint & _p ); - - private: - QPoint m_sndSrcPos; - static QPixmap * s_backgroundArtwork; - knob * m_position_x; - knob * m_position_y; - - -private slots: - void updatePositionX( void ); - void updatePositionY( void ); - } ; diff --git a/include/tempo_sync_knob.h b/include/tempo_sync_knob.h index dc3f2bc3c9..af56eb5af2 100644 --- a/include/tempo_sync_knob.h +++ b/include/tempo_sync_knob.h @@ -54,7 +54,7 @@ public: tempoSyncKnob( int _knob_num, QWidget * _parent, const QString & _name, - track * _track, float _scale = 1.0f ); + float _scale = 1.0f ); virtual ~tempoSyncKnob(); virtual void FASTCALL saveSettings( QDomDocument & _doc, @@ -95,7 +95,7 @@ protected: protected slots: void calculateTempoSyncTime( bpm_t _bpm ); - void updateCustom( int ); + void updateCustom( void ); void showCustom( void ); private: @@ -103,7 +103,7 @@ private: float m_scale; QPixmap m_tempoSyncIcon; QString m_tempoSyncDescription; - + tempoSyncMode m_tempoLastSyncMode; QPointer m_custom; diff --git a/include/volume_knob.h b/include/volume_knob.h index dc838e3f25..35204b38a6 100644 --- a/include/volume_knob.h +++ b/include/volume_knob.h @@ -34,8 +34,7 @@ class volumeKnob : public knob { Q_OBJECT public: - volumeKnob( int _knob_num, QWidget * _parent, const QString & _name, - track * _track ); + volumeKnob( int _knob_num, QWidget * _parent, const QString & _name ); virtual ~volumeKnob(); diff --git a/src/audio/audio_alsa.cpp b/src/audio/audio_alsa.cpp index 0189e4199e..4574ae090c 100644 --- a/src/audio/audio_alsa.cpp +++ b/src/audio/audio_alsa.cpp @@ -465,12 +465,15 @@ audioALSA::setupWidget::setupWidget( QWidget * _parent ) : dev_lbl->setFont( pointSize<6>( dev_lbl->font() ) ); dev_lbl->setGeometry( 10, 40, 160, 10 ); - m_channels = new lcdSpinBox( DEFAULT_CHANNELS, SURROUND_CHANNELS, 1, - this, NULL, NULL ); - m_channels->setStep( 2 ); - m_channels->setLabel( tr( "CHANNELS" ) ); - m_channels->setValue( configManager::inst()->value( "audioalsa", + lcdSpinBoxModel * m = new lcdSpinBoxModel( /* this */ ); + m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); + m->setStep( 2 ); + m->setValue( configManager::inst()->value( "audioalsa", "channels" ).toInt() ); + + m_channels = new lcdSpinBox( 1, this ); + m_channels->setModel( m ); + m_channels->setLabel( tr( "CHANNELS" ) ); m_channels->move( 180, 20 ); } diff --git a/src/audio/audio_jack.cpp b/src/audio/audio_jack.cpp index 7012ea8457..5f0b1de4ca 100644 --- a/src/audio/audio_jack.cpp +++ b/src/audio/audio_jack.cpp @@ -424,12 +424,15 @@ audioJACK::setupWidget::setupWidget( QWidget * _parent ) : cn_lbl->setFont( pointSize<6>( cn_lbl->font() ) ); cn_lbl->setGeometry( 10, 40, 160, 10 ); - m_channels = new lcdSpinBox( DEFAULT_CHANNELS, SURROUND_CHANNELS, 1, - this, NULL, NULL ); - m_channels->setStep( 2 ); - m_channels->setLabel( tr( "CHANNELS" ) ); - m_channels->setValue( configManager::inst()->value( "audiojack", + lcdSpinBoxModel * m = new lcdSpinBoxModel( /* this */ ); + m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); + m->setStep( 2 ); + m->setValue( configManager::inst()->value( "audiojack", "channels" ).toInt() ); + + m_channels = new lcdSpinBox( 1, this ); + m_channels->setModel( m ); + m_channels->setLabel( tr( "CHANNELS" ) ); m_channels->move( 180, 20 ); } diff --git a/src/audio/audio_oss.cpp b/src/audio/audio_oss.cpp index 6549265323..5ce44c7065 100644 --- a/src/audio/audio_oss.cpp +++ b/src/audio/audio_oss.cpp @@ -325,12 +325,15 @@ audioOSS::setupWidget::setupWidget( QWidget * _parent ) : dev_lbl->setFont( pointSize<6>( dev_lbl->font() ) ); dev_lbl->setGeometry( 10, 40, 160, 10 ); - m_channels = new lcdSpinBox( DEFAULT_CHANNELS, SURROUND_CHANNELS, 1, - this, NULL, NULL ); - m_channels->setStep( 2 ); - m_channels->setLabel( tr( "CHANNELS" ) ); - m_channels->setValue( configManager::inst()->value( "audiooss", + lcdSpinBoxModel * m = new lcdSpinBoxModel( /* this */ ); + m->setRange( DEFAULT_CHANNELS, SURROUND_CHANNELS ); + m->setStep( 2 ); + m->setValue( configManager::inst()->value( "audiooss", "channels" ).toInt() ); + + m_channels = new lcdSpinBox( 1, this ); + m_channels->setModel( m ); + m_channels->setLabel( tr( "CHANNELS" ) ); m_channels->move( 180, 20 ); } diff --git a/src/core/about_dialog.cpp b/src/core/about_dialog.cpp index 5a069bbf92..684f4fe30b 100644 --- a/src/core/about_dialog.cpp +++ b/src/core/about_dialog.cpp @@ -3,7 +3,7 @@ /* * about_dialog.cpp - implementation of about-dialog * - * Copyright (c) 2004-2007 Tobias Doerffel + * Copyright (c) 2004-2008 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -60,7 +60,7 @@ aboutDialog::aboutDialog() : QLabel * about_lbl = new QLabel( tr( "LMMS - A powerful " "synthesizer-studio\n\n" - "Copyright (c) 2004-2007 " + "Copyright (c) 2004-2008 " "LMMS-Developers\n\n" "http://lmms.sourceforge.net" ) ); diff --git a/src/core/arp_and_chords_tab_widget.cpp b/src/core/arp_and_chords_tab_widget.cpp index 249a5f66df..b4a3fca040 100644 --- a/src/core/arp_and_chords_tab_widget.cpp +++ b/src/core/arp_and_chords_tab_widget.cpp @@ -180,30 +180,48 @@ const int ARP_GROUPBOX_HEIGHT = 240 - ARP_GROUPBOX_Y; arpAndChordsTabWidget::arpAndChordsTabWidget( instrumentTrack * _instrument_track ) : - QWidget( _instrument_track->tabWidgetParent() ) + QWidget( _instrument_track->tabWidgetParent() ), + m_chordsEnabledModel( new boolModel( /* this */ ) ), + m_chordsModel( new comboBoxModel( /* this */ ) ), + m_chordRangeModel( new floatModel( 1.0f, 1.0f, 9.0f, 1.0f + /* this */ ) ), + m_arpEnabledModel( new boolModel( /* this */ ) ), + m_arpModel( new comboBoxModel( /* this */ ) ), + m_arpRangeModel( new floatModel( 1.0f, 1.0f, 9.0f, 1.0f + /* this */ ) ), + m_arpTimeModel( new floatModel( 100.0f, 25.0f, 2000.0f, 1.0f + /* this */ ) ), + m_arpGateModel( new floatModel( 100.0f, 1.0f, 200.0f, 1.0f + /* this */ ) ), + m_arpDirectionModel( new intModel( /* this */ ) ), + m_arpModeModel( new comboBoxModel( /* this */ ) ) { - m_chordsGroupBox = new groupBox( tr( "CHORDS" ), this, - _instrument_track ); + m_chordsEnabledModel->setTrack( _instrument_track ); + m_chordsGroupBox = new groupBox( tr( "CHORDS" ), this ); m_chordsGroupBox->setGeometry( CHORDS_GROUPBOX_X, CHORDS_GROUPBOX_Y, CHORDS_GROUPBOX_WIDTH, CHORDS_GROUPBOX_HEIGHT ); + m_chordsGroupBox->setModel( m_chordsEnabledModel ); - m_chordsComboBox = new comboBox( m_chordsGroupBox, tr( "Chord type" ), - _instrument_track ); + + m_chordsModel->setTrack( _instrument_track ); + m_chordsComboBox = new comboBox( m_chordsGroupBox, tr( "Chord type" ) ); m_chordsComboBox->setGeometry( 10, 25, 140, 22 ); for( int i = 0; s_chords[i].interval[0] != -1; ++i ) { - m_chordsComboBox->addItem( tr( s_chords[i].name - .toAscii().constData() ) ); + m_chordsModel->addItem( tr( s_chords[i].name.toAscii(). + constData() ) ); } + m_chordsComboBox->setModel( m_chordsModel ); + + m_chordRangeModel->setTrack( _instrument_track ); + m_chordRangeModel->setInitValue( 1.0f ); m_chordRangeKnob = new knob( knobBright_26, m_chordsGroupBox, - tr( "Chord range" ), - _instrument_track ); + tr( "Chord range" ) ); + m_chordRangeKnob->setModel( m_chordRangeModel ); m_chordRangeKnob->setLabel( tr( "RANGE" ) ); - m_chordRangeKnob->setRange( 1.0f, 9.0f, 1.0f ); - m_chordRangeKnob->setInitValue( 1.0f ); m_chordRangeKnob->move( 164, 24 ); m_chordRangeKnob->setHintText( tr( "Chord range:" ) + " ", " " + tr( "octave(s)" ) ); @@ -214,9 +232,9 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( - - m_arpGroupBox = new groupBox( tr( "ARPEGGIO" ), this, - _instrument_track ); + m_arpEnabledModel->setTrack( _instrument_track ); + m_arpGroupBox = new groupBox( tr( "ARPEGGIO" ), this ); + m_arpGroupBox->setModel( m_arpEnabledModel ); m_arpGroupBox->setGeometry( ARP_GROUPBOX_X, ARP_GROUPBOX_Y, ARP_GROUPBOX_WIDTH, ARP_GROUPBOX_HEIGHT ); @@ -230,23 +248,26 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( "not played at the same time. Typical arpeggios are " "major or minor triads. But there're a lot of other " "possible chords, you can select." ) ); - m_arpComboBox = new comboBox( m_arpGroupBox, tr( "Arpeggio type" ), - _instrument_track ); + + + m_arpModel->setTrack( _instrument_track ); + m_arpComboBox = new comboBox( m_arpGroupBox, tr( "Arpeggio type" ) ); m_arpComboBox->setGeometry( 10, 25, 140, 22 ); for( int i = 0; s_chords[i].interval[0] != -1; ++i ) { - m_arpComboBox->addItem( tr( s_chords[i].name - .toAscii().constData() ) ); + m_arpModel->addItem( tr( s_chords[i].name.toAscii(). + constData() ) ); } + m_arpComboBox->setModel( m_arpModel ); + m_arpRangeModel->setTrack( _instrument_track ); + m_arpRangeModel->setInitValue( 1.0f ); m_arpRangeKnob = new knob( knobBright_26, m_arpGroupBox, - tr( "Arpeggio range" ), - _instrument_track ); + tr( "Arpeggio range" ) ); + m_arpRangeKnob->setModel( m_arpRangeModel ); m_arpRangeKnob->setLabel( tr( "RANGE" ) ); - m_arpRangeKnob->setRange( 1.0f, 9.0f, 1.0f ); - m_arpRangeKnob->setInitValue( 1.0f ); m_arpRangeKnob->move( 164, 24 ); m_arpRangeKnob->setHintText( tr( "Arpeggio range:" ) + " ", " " + tr( "octave(s)" ) ); @@ -255,12 +276,13 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( "The selected arpeggio will be played within specified " "amount of octaves." ) ); + + m_arpTimeModel->setTrack( _instrument_track ); + m_arpTimeModel->setInitValue( 100.0f ); m_arpTimeKnob = new tempoSyncKnob( knobBright_26, m_arpGroupBox, - tr( "Arpeggio time" ), - _instrument_track ); + tr( "Arpeggio time" ) ); + m_arpTimeKnob->setModel( m_arpTimeModel ); m_arpTimeKnob->setLabel( tr( "TIME" ) ); - m_arpTimeKnob->setRange( 25.0f, 2000.0f, 1.0f ); - m_arpTimeKnob->setInitValue( 100.0f ); m_arpTimeKnob->move( 164, 70 ); m_arpTimeKnob->setHintText( tr( "Arpeggio time:" ) + " ", " " + tr( "ms" ) ); @@ -269,12 +291,13 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( "milliseconds. The arpeggio time specifies how long " "each arpeggio-tone should be played." ) ); + + m_arpGateModel->setTrack( _instrument_track ); + m_arpGateModel->setInitValue( 100.0f ); m_arpGateKnob = new knob( knobBright_26, m_arpGroupBox, - tr( "Arpeggio gate" ), - _instrument_track ); + tr( "Arpeggio gate" ) ); + m_arpGateKnob->setModel( m_arpGateModel ); m_arpGateKnob->setLabel( tr( "GATE" ) ); - m_arpGateKnob->setRange( 1.0f, 200.0f, 1.0f ); - m_arpGateKnob->setInitValue( 100.0f ); m_arpGateKnob->move( 204, 70 ); m_arpGateKnob->setHintText( tr( "Arpeggio gate:" ) + " ", tr( "%" ) ); m_arpGateKnob->setWhatsThis( @@ -289,16 +312,14 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( - pixmapButton * arp_up_btn = new pixmapButton( m_arpGroupBox, NULL, - NULL ); + pixmapButton * arp_up_btn = new pixmapButton( m_arpGroupBox, NULL ); arp_up_btn->move( 10, 74 ); arp_up_btn->setActiveGraphic( embed::getIconPixmap( "arp_up_on" ) ); arp_up_btn->setInactiveGraphic( embed::getIconPixmap( "arp_up_off" ) ); toolTip::add( arp_up_btn, tr( "arpeggio direction = up" ) ); - pixmapButton * arp_down_btn = new pixmapButton( m_arpGroupBox, NULL, - NULL ); + pixmapButton * arp_down_btn = new pixmapButton( m_arpGroupBox, NULL ); arp_down_btn->move( 30, 74 ); arp_down_btn->setActiveGraphic( embed::getIconPixmap( "arp_down_on" ) ); arp_down_btn->setInactiveGraphic( embed::getIconPixmap( @@ -307,7 +328,7 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( pixmapButton * arp_up_and_down_btn = new pixmapButton( m_arpGroupBox, - NULL, NULL ); + NULL ); arp_up_and_down_btn->move( 50, 74 ); arp_up_and_down_btn->setActiveGraphic( embed::getIconPixmap( "arp_up_and_down_on" ) ); @@ -317,8 +338,7 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( tr( "arpeggio direction = up and down" ) ); - pixmapButton * arp_random_btn = new pixmapButton( m_arpGroupBox, NULL, - NULL ); + pixmapButton * arp_random_btn = new pixmapButton( m_arpGroupBox, NULL ); arp_random_btn->move( 70, 74 ); arp_random_btn->setActiveGraphic( embed::getIconPixmap( "arp_random_on" ) ); @@ -327,31 +347,33 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( toolTip::add( arp_random_btn, tr( "arpeggio direction = random" ) ); m_arpDirectionBtnGrp = new automatableButtonGroup( this, - tr( "Arpeggio direction" ), - _instrument_track ); + tr( "Arpeggio direction" ) ); + m_arpDirectionBtnGrp->setModel( m_arpDirectionModel ); m_arpDirectionBtnGrp->addButton( arp_up_btn ); m_arpDirectionBtnGrp->addButton( arp_down_btn ); m_arpDirectionBtnGrp->addButton( arp_up_and_down_btn ); m_arpDirectionBtnGrp->addButton( arp_random_btn ); - m_arpDirectionBtnGrp->setInitValue( UP ); + m_arpDirectionModel->setTrack( _instrument_track ); + m_arpDirectionModel->setInitValue( UP ); QLabel * mode_lbl = new QLabel( tr( "Mode:" ), m_arpGroupBox ); mode_lbl->setGeometry( 10, 104, 64, 10 ); mode_lbl->setFont( pointSize<7>( mode_lbl->font() ) ); - m_arpModeComboBox = new comboBox( m_arpGroupBox, tr( "Arpeggio mode" ), - _instrument_track ); + m_arpModeComboBox = new comboBox( m_arpGroupBox, + tr( "Arpeggio mode" ) ); m_arpModeComboBox->setGeometry( 10, 118, 128, 22 ); - m_arpModeComboBox->addItem( tr( "Free" ), - embed::getIconPixmap( "arp_free" ) ); - m_arpModeComboBox->addItem( tr( "Sort" ), - embed::getIconPixmap( "arp_sort" ) ); - m_arpModeComboBox->addItem( tr( "Sync" ), - embed::getIconPixmap( "arp_sync" ) ); - //m_arpModeComboBox->setValue( 0 ); + m_arpModeModel->setTrack( _instrument_track ); + m_arpModeModel->addItem( tr( "Free" ), new QPixmap( + embed::getIconPixmap( "arp_free" ) ) ); + m_arpModeModel->addItem( tr( "Sort" ), new QPixmap( + embed::getIconPixmap( "arp_sort" ) ) ); + m_arpModeModel->addItem( tr( "Sync" ), new QPixmap( + embed::getIconPixmap( "arp_sync" ) ) ); + m_arpModeComboBox->setModel( m_arpModeModel ); } @@ -372,10 +394,10 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n ) // at the same time we only add sub-notes if nothing of the note was // played yet, because otherwise we would add chord-subnotes every // time an audio-buffer is rendered... - if( ( ( _n->baseNote() && m_arpGroupBox->isActive() == FALSE ) || + if( ( ( _n->baseNote() && m_arpEnabledModel->value() == FALSE ) || _n->arpNote() ) && - _n->totalFramesPlayed() == 0 && - m_chordsGroupBox->isActive() == TRUE ) + _n->totalFramesPlayed() == 0 && + m_chordsEnabledModel->value() == TRUE ) { // then insert sub-notes for chord const int selected_chord = m_chordsComboBox->value(); @@ -426,7 +448,7 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n ) // now follows code for arpeggio if( _n->baseNote() == FALSE || - !m_arpGroupBox->isActive() || + !m_arpEnabledModel->value() || ( _n->released() && _n->releaseFramesDone() >= _n->actualReleaseFramesToDo() ) ) { @@ -593,18 +615,18 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n ) void arpAndChordsTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - m_chordsGroupBox->saveSettings( _doc, _this, "chord-enabled" ); - m_chordsComboBox->saveSettings( _doc, _this, "chord" ); - m_chordRangeKnob->saveSettings( _doc, _this, "chordrange" ); + m_chordsEnabledModel->saveSettings( _doc, _this, "chord-enabled" ); + m_chordsModel->saveSettings( _doc, _this, "chord" ); + m_chordRangeModel->saveSettings( _doc, _this, "chordrange" ); - m_arpGroupBox->saveSettings( _doc, _this, "arp-enabled" ); - m_arpComboBox->saveSettings( _doc, _this, "arp" ); - m_arpRangeKnob->saveSettings( _doc, _this, "arprange" ); - m_arpTimeKnob->saveSettings( _doc, _this, "arptime" ); - m_arpGateKnob->saveSettings( _doc, _this, "arpgate" ); - m_arpDirectionBtnGrp->saveSettings( _doc, _this, "arpdir" ); + m_arpEnabledModel->saveSettings( _doc, _this, "arp-enabled" ); + m_arpModel->saveSettings( _doc, _this, "arp" ); + m_arpRangeModel->saveSettings( _doc, _this, "arprange" ); + m_arpTimeModel->saveSettings( _doc, _this, "arptime" ); + m_arpGateModel->saveSettings( _doc, _this, "arpgate" ); + m_arpDirectionModel->saveSettings( _doc, _this, "arpdir" ); - m_arpModeComboBox->saveSettings( _doc, _this, "arpmode" ); + m_arpModeModel->saveSettings( _doc, _this, "arpmode" ); } @@ -612,16 +634,16 @@ void arpAndChordsTabWidget::saveSettings( QDomDocument & _doc, void arpAndChordsTabWidget::loadSettings( const QDomElement & _this ) { - m_chordsGroupBox->loadSettings( _this, "chord-enabled" ); - m_chordsComboBox->loadSettings( _this, "chord" ); - m_chordRangeKnob->loadSettings( _this, "chordrange" ); + m_chordsEnabledModel->loadSettings( _this, "chord-enabled" ); + m_chordsModel->loadSettings( _this, "chord" ); + m_chordRangeModel->loadSettings( _this, "chordrange" ); - m_arpGroupBox->loadSettings( _this, "arp-enabled" ); - m_arpComboBox->loadSettings( _this, "arp" ); - m_arpRangeKnob->loadSettings( _this, "arprange" ); - m_arpTimeKnob->loadSettings( _this, "arptime" ); - m_arpGateKnob->loadSettings( _this, "arpgate" ); - m_arpDirectionBtnGrp->loadSettings( _this, "arpdir" ); + m_arpEnabledModel->loadSettings( _this, "arp-enabled" ); + m_arpModel->loadSettings( _this, "arp" ); + m_arpRangeModel->loadSettings( _this, "arprange" ); + m_arpTimeModel->loadSettings( _this, "arptime" ); + m_arpGateModel->loadSettings( _this, "arpgate" ); + m_arpDirectionModel->loadSettings( _this, "arpdir" ); // Keep compatibility with version 0.2.1 file format if( _this.hasAttribute( "arpsyncmode" ) ) @@ -631,7 +653,7 @@ void arpAndChordsTabWidget::loadSettings( const QDomElement & _this ) "arpsyncmode" ).toInt() ); } - m_arpModeComboBox->loadSettings( _this, "arpmode" ); + m_arpModeModel->loadSettings( _this, "arpmode" ); } diff --git a/src/core/automation_editor.cpp b/src/core/automation_editor.cpp index c4763753e9..719c6ad855 100644 --- a/src/core/automation_editor.cpp +++ b/src/core/automation_editor.cpp @@ -261,13 +261,18 @@ automationEditor::automationEditor( void ) : QLabel * zoom_x_lbl = new QLabel( m_toolBar ); zoom_x_lbl->setPixmap( embed::getIconPixmap( "zoom_x" ) ); - m_zoomingXComboBox = new comboBox( m_toolBar, NULL, NULL ); + m_zoomingXComboBox = new comboBox( m_toolBar ); m_zoomingXComboBox->setFixedSize( 80, 22 ); + + comboBoxModel * zoom_x_model = new comboBoxModel( /* this */ ); for( int i = 0; i < 6; ++i ) { - m_zoomingXComboBox->addItem( QString::number( 25 << i ) + "%" ); + zoom_x_model->addItem( QString::number( 25 << i ) + "%" ); } - m_zoomingXComboBox->setValue( m_zoomingXComboBox->findText( "100%" ) ); + zoom_x_model->setValue( zoom_x_model->findText( "100%" ) ); + + m_zoomingXComboBox->setModel( zoom_x_model ); + connect( m_zoomingXComboBox, SIGNAL( activated( const QString & ) ), this, SLOT( zoomingXChanged( const QString & ) ) ); @@ -275,14 +280,19 @@ automationEditor::automationEditor( void ) : QLabel * zoom_y_lbl = new QLabel( m_toolBar ); zoom_y_lbl->setPixmap( embed::getIconPixmap( "zoom_y" ) ); - m_zoomingYComboBox = new comboBox( m_toolBar, NULL, NULL ); + m_zoomingYComboBox = new comboBox( m_toolBar ); m_zoomingYComboBox->setFixedSize( 80, 22 ); - m_zoomingYComboBox->addItem( "Auto" ); + + comboBoxModel * zoom_y_model = new comboBoxModel( /* this */ ); + zoom_y_model->addItem( "Auto" ); for( int i = 0; i < 6; ++i ) { - m_zoomingYComboBox->addItem( QString::number( 25 << i ) + "%" ); + zoom_y_model->addItem( QString::number( 25 << i ) + "%" ); } - m_zoomingYComboBox->setValue( m_zoomingYComboBox->findText( "Auto" ) ); + zoom_y_model->setValue( zoom_y_model->findText( "Auto" ) ); + + m_zoomingYComboBox->setModel( zoom_y_model ); + connect( m_zoomingYComboBox, SIGNAL( activated( const QString & ) ), this, SLOT( zoomingYChanged( const QString & ) ) ); @@ -291,14 +301,18 @@ automationEditor::automationEditor( void ) : QLabel * quantize_lbl = new QLabel( m_toolBar ); quantize_lbl->setPixmap( embed::getIconPixmap( "quantize" ) ); - m_quantizeComboBox = new comboBox( m_toolBar, NULL, NULL ); + m_quantizeComboBox = new comboBox( m_toolBar ); m_quantizeComboBox->setFixedSize( 60, 22 ); + + comboBoxModel * quantize_model = new comboBoxModel( /* this */ ); for( int i = 0; i < 7; ++i ) { - m_quantizeComboBox->addItem( "1/" + QString::number( 1 << i ) ); + quantize_model->addItem( "1/" + QString::number( 1 << i ) ); } - m_quantizeComboBox->setValue( m_quantizeComboBox->findText( - "1/16" ) ); + quantize_model->setValue( quantize_model->findText( "1/16" ) ); + + m_quantizeComboBox->setModel( quantize_model ); + tb_layout->addSpacing( 5 ); tb_layout->addWidget( m_playButton ); @@ -1548,8 +1562,8 @@ void automationEditor::wheelEvent( QWheelEvent * _we ) m_ppt /= 2; } // update combobox with zooming-factor - m_zoomingXComboBox->setValue( - m_zoomingXComboBox->findText( QString::number( + m_zoomingXComboBox->model()->setValue( + m_zoomingXComboBox->model()->findText( QString::number( static_cast( m_ppt * 100 / DEFAULT_PPT ) ) +"%" ) ); // update timeline @@ -2015,8 +2029,8 @@ void automationEditor::zoomingYChanged( const QString & _zfac ) int automationEditor::quantization( void ) const { - return( 64 / m_quantizeComboBox->currentText().right( - m_quantizeComboBox->currentText().length() - + return( 64 / m_quantizeComboBox->model()->currentText().right( + m_quantizeComboBox->model()->currentText().length() - 2 ).toInt() ); } diff --git a/src/core/automation_pattern.cpp b/src/core/automation_pattern.cpp index 2b54997ba5..3ec6033e58 100644 --- a/src/core/automation_pattern.cpp +++ b/src/core/automation_pattern.cpp @@ -261,8 +261,8 @@ const QString automationPattern::name( void ) { if( m_track ) { - QString widget_name = dynamic_cast( m_object ) - ->accessibleName(); + QString widget_name = m_object->displayName(); +/* dynamic_cast( m_object )->accessibleName();*/ return( m_track->name() + " - " + widget_name ); } else diff --git a/src/core/bb_editor.cpp b/src/core/bb_editor.cpp index 7958d9f779..9db7425f30 100644 --- a/src/core/bb_editor.cpp +++ b/src/core/bb_editor.cpp @@ -50,7 +50,7 @@ bbEditor::bbEditor( void ) : - m_currentBB( -1 ) + trackContainer() { // create toolbar m_toolBar = new QWidget; @@ -100,10 +100,13 @@ bbEditor::bbEditor( void ) : QLabel * l = new QLabel( m_toolBar ); l->setPixmap( embed::getIconPixmap( "drum" ) ); - m_bbComboBox = new comboBox( m_toolBar, NULL, NULL ); + m_bbComboBox = new comboBox( m_toolBar ); m_bbComboBox->setFixedSize( 200, 22 ); - connect( m_bbComboBox, SIGNAL( valueChanged( int ) ), - this, SLOT( setCurrentBB( int ) ) ); + + m_bbComboBoxModel = new comboBoxModel( /* this */ ); + m_bbComboBox->setModel( m_bbComboBoxModel ); + connect( m_bbComboBoxModel, SIGNAL( dataChanged() ), + this, SLOT( currentBBChanged() ) ); tb_layout->addSpacing( 5 ); tb_layout->addWidget( m_playButton ); @@ -149,17 +152,10 @@ bbEditor::~bbEditor() -void bbEditor::setCurrentBB( int _bb ) +void bbEditor::currentBBChanged( void ) { - m_currentBB = _bb; - - if( m_bbComboBox->value() != _bb ) - { - m_bbComboBox->setValue( _bb ); - } - // first make sure, all channels have a TCO at current BB - createTCOsForBB( _bb ); + createTCOsForBB( currentBB() ); realignTracks(); @@ -240,9 +236,9 @@ void bbEditor::removeBB( int _bb ) tl[i]->removeTCO( _bb ); tl[i]->getTrackContentWidget()->removeTact( _bb * 64 ); } - if( _bb <= m_currentBB ) + if( _bb <= currentBB() ) { - setCurrentBB( tMax( m_currentBB - 1, 0 ) ); + setCurrentBB( tMax( currentBB() - 1, 0 ) ); } } @@ -262,21 +258,17 @@ void bbEditor::updateBBTrack( trackContentObject * _tco ) void bbEditor::updateComboBox( void ) { - disconnect( m_bbComboBox, SIGNAL( valueChanged( int ) ), - this, SLOT( setCurrentBB( int ) ) ); + const int cur_bb = currentBB(); - m_bbComboBox->clear(); + m_bbComboBoxModel->clear(); for( int i = 0; i < numOfBBs(); ++i ) { bbTrack * bbt = bbTrack::findBBTrack( i ); - m_bbComboBox->addItem( bbt->trackLabel()->text(), - bbt->trackLabel()->pixmap() ); + m_bbComboBoxModel->addItem( bbt->trackLabel()->text(), + new QPixmap( bbt->trackLabel()->pixmap() ) ); } - m_bbComboBox->setValue( m_currentBB ); - - connect( m_bbComboBox, SIGNAL( valueChanged( int ) ), - this, SLOT( setCurrentBB( int ) ) ); + setCurrentBB( cur_bb ); } @@ -297,16 +289,16 @@ void bbEditor::keyPressEvent( QKeyEvent * _ke ) } else if ( _ke->key() == Qt::Key_Plus ) { - if( m_currentBB + 1 < numOfBBs() ) + if( currentBB()+ 1 < numOfBBs() ) { - setCurrentBB( m_currentBB + 1 ); + setCurrentBB( currentBB() + 1 ); } } else if ( _ke->key() == Qt::Key_Minus ) { - if( m_currentBB > 0 ) + if( currentBB() > 0 ) { - setCurrentBB( m_currentBB - 1 ); + setCurrentBB( currentBB() - 1 ); } } else diff --git a/src/core/effect.cpp b/src/core/effect.cpp index 1a091b204f..16a1501374 100644 --- a/src/core/effect.cpp +++ b/src/core/effect.cpp @@ -39,11 +39,11 @@ effect::effect( const plugin::descriptor * _desc, m_okay( TRUE ), m_noRun( FALSE ), m_running( FALSE ), - m_bypass( FALSE ), + m_enabledModel( FALSE, FALSE, TRUE ), m_bufferCount( 0 ), m_silenceTimeout( 10 ), - m_wetDry( 1.0f ), - m_gate( 0.0f ) + m_wetDryModel( 1.0f, 0.0f, 1.0f, 0.01f ), + m_gateModel( 0.0f, 0.0f, 1.0f, 0.01f ) { } @@ -65,13 +65,13 @@ bool FASTCALL effect::processAudioBuffer( surroundSampleFrame * _buf, - +/* void FASTCALL effect::setGate( float _level ) { m_gate = _level * _level * m_processors * engine::getMixer()->framesPerPeriod(); } - +*/ effect * effect::instantiate( const QString & _plugin_name, descriptor::subPluginFeatures::key * _key ) diff --git a/src/core/effect_tab_widget.cpp b/src/core/effect_tab_widget.cpp index 776a8911d7..32bd7bc857 100644 --- a/src/core/effect_tab_widget.cpp +++ b/src/core/effect_tab_widget.cpp @@ -42,6 +42,7 @@ #include "rack_view.h" #include "sample_track.h" #include "tooltip.h" +#include "automatable_model_templates.h" @@ -79,8 +80,8 @@ effectTabWidget::~effectTabWidget() void effectTabWidget::setupWidget( void ) { - m_effectsGroupBox = new groupBox( tr( "EFFECTS CHAIN" ), this, - m_track ); + m_effectsGroupBox = new groupBox( tr( "EFFECTS CHAIN" ), this ); + m_effectsGroupBox->model()->setTrack( m_track ); connect( m_effectsGroupBox, SIGNAL( toggled( bool ) ), this, SLOT( setBypass( bool ) ) ); m_effectsGroupBox->setGeometry( 2, 2, 242, 244 ); @@ -100,7 +101,8 @@ void effectTabWidget::setupWidget( void ) void effectTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - _this.setAttribute( "fxdisabled", !m_effectsGroupBox->isActive() ); + _this.setAttribute( "fxdisabled", + !m_effectsGroupBox->model()->value() ); m_rack->saveState( _doc, _this ); } @@ -110,7 +112,7 @@ void effectTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this ) void effectTabWidget::loadSettings( const QDomElement & _this ) { - m_effectsGroupBox->setState( + m_effectsGroupBox->model()->setValue( !_this.attribute( "fxdisabled" ).toInt() ); QDomNode node = _this.firstChild(); diff --git a/src/core/envelope_and_lfo_widget.cpp b/src/core/envelope_and_lfo_widget.cpp index c76972115e..c088aa3d65 100644 --- a/src/core/envelope_and_lfo_widget.cpp +++ b/src/core/envelope_and_lfo_widget.cpp @@ -48,6 +48,7 @@ #include "tempo_sync_knob.h" #include "text_float.h" #include "tooltip.h" +#include "automatable_model_templates.h" @@ -97,13 +98,26 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, track * _track ) : QWidget( _parent ), m_used( FALSE ), + m_predelayModel(), + m_attackModel(), + m_holdModel(), + m_decayModel(), + m_sustainModel(), + m_releaseModel(), + m_amountModel(), + m_lfoPredelayModel(), + m_lfoAttackModel(), + m_lfoSpeedModel(), + m_lfoAmountModel(), + m_lfoWaveModel(), + m_x100Model( FALSE, FALSE, TRUE ), + m_controlEnvAmountModel( FALSE, FALSE, TRUE ), m_valueForZeroAmount( _value_for_zero_amount ), m_pahdEnv( NULL ), m_rEnv( NULL ), m_lfoFrame( 0 ), m_lfoAmountIsZero( FALSE ), - m_lfoShapeData( NULL ), - m_lfoShape( SIN ) + m_lfoShapeData( NULL ) { if( s_envGraph == NULL ) { @@ -117,26 +131,28 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, s_EaLWidgets.push_back( this ); - - m_predelayKnob = new knob( knobBright_26, this, tr( "Predelay-time" ), - _track ); + m_predelayModel.setTrack( _track ); + m_predelayModel.setRange( 0.0, 1.0, 0.001 ); + m_predelayModel.setInitValue( 0.0 ); + m_predelayKnob = new knob( knobBright_26, this, tr( "Predelay-time" ) ); + m_predelayKnob->setModel( &m_predelayModel ); m_predelayKnob->setLabel( tr( "DEL" ) ); - m_predelayKnob->setRange( 0.0, 1.0, 0.001 ); - m_predelayKnob->setInitValue( 0.0 ); m_predelayKnob->move( PREDELAY_KNOB_X, ENV_KNOBS_Y ); m_predelayKnob->setHintText( tr( "Predelay:" ) + " ", "" ); m_predelayKnob->setWhatsThis( tr( "Use this knob for setting predelay of the current " "envelope. The bigger this value the longer the time " "before start of actual envelope." ) ); - connect( m_predelayKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateAfterKnobChange( float ) ) ); + connect( &m_predelayModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); - m_attackKnob = new knob( knobBright_26, this, tr( "Attack-time" ), - _track ); + + m_attackModel.setTrack( _track ); + m_attackModel.setRange( 0.0, 1.0, 0.001 ); + m_attackModel.setInitValue( 0.0 ); + m_attackKnob = new knob( knobBright_26, this, tr( "Attack-time" ) ); + m_attackKnob->setModel( &m_attackModel ); m_attackKnob->setLabel( tr( "ATT" ) ); - m_attackKnob->setRange( 0.0, 1.0, 0.001 ); - m_attackKnob->setInitValue( 0.0 ); m_attackKnob->move( ATTACK_KNOB_X, ENV_KNOBS_Y ); m_attackKnob->setHintText( tr( "Attack:" )+" ", "" ); m_attackKnob->setWhatsThis( @@ -145,13 +161,15 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, "envelope needs to increase to attack-level. " "Choose a small value for instruments like pianos " "and a big value for strings." ) ); - connect( m_attackKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateAfterKnobChange( float ) ) ); + connect( &m_attackModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); - m_holdKnob = new knob( knobBright_26, this, tr( "Hold-time" ), _track ); + m_holdModel.setTrack( _track ); + m_holdModel.setRange( 0.0, 1.0, 0.001 ); + m_holdModel.setInitValue( 0.5 ); + m_holdKnob = new knob( knobBright_26, this, tr( "Hold-time" ) ); + m_holdKnob->setModel( &m_holdModel ); m_holdKnob->setLabel( tr( "HOLD" ) ); - m_holdKnob->setRange( 0.0, 1.0, 0.001 ); - m_holdKnob->setInitValue( 0.5 ); m_holdKnob->move( HOLD_KNOB_X, ENV_KNOBS_Y ); m_holdKnob->setHintText( tr( "Hold:" ) + " ", "" ); m_holdKnob->setWhatsThis( @@ -159,14 +177,16 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, "envelope. The bigger this value the longer the " "envelope holds attack-level before it begins to " "decrease to sustain-level." ) ); - connect( m_holdKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateAfterKnobChange( float ) ) ); + connect( &m_holdModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); - m_decayKnob = new knob( knobBright_26, this, tr( "Decay-time" ), - _track ); + + m_decayModel.setTrack( _track ); + m_decayModel.setRange( 0.0, 1.0, 0.001 ); + m_decayModel.setInitValue( 0.5 ); + m_decayKnob = new knob( knobBright_26, this, tr( "Decay-time" ) ); + m_decayKnob->setModel( &m_decayModel ); m_decayKnob->setLabel( tr( "DEC" ) ); - m_decayKnob->setRange( 0.0, 1.0, 0.001 ); - m_decayKnob->setInitValue( 0.5 ); m_decayKnob->move( DECAY_KNOB_X, ENV_KNOBS_Y ); m_decayKnob->setHintText( tr( "Decay:" ) + " ", "" ); m_decayKnob->setWhatsThis( @@ -175,14 +195,16 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, "envelope needs to decrease from attack-level to " "sustain-level. Choose a small value for instruments " "like pianos." ) ); - connect( m_decayKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateAfterKnobChange( float ) ) ); + connect( &m_decayModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); - m_sustainKnob = new knob( knobBright_26, this, tr( "Sustain-level" ), - _track ); + + m_sustainModel.setTrack( _track ); + m_sustainModel.setRange( 0.0, 1.0, 0.001 ); + m_sustainModel.setInitValue( 0.5 ); + m_sustainKnob = new knob( knobBright_26, this, tr( "Sustain-level" ) ); + m_sustainKnob->setModel( &m_sustainModel ); m_sustainKnob->setLabel( tr( "SUST" ) ); - m_sustainKnob->setRange( 0.0, 1.0, 0.001 ); - m_sustainKnob->setInitValue( 0.5 ); m_sustainKnob->move( SUSTAIN_KNOB_X, ENV_KNOBS_Y ); m_sustainKnob->setHintText( tr( "Sustain:" ) + " ", "" ); m_sustainKnob->setWhatsThis( @@ -190,14 +212,17 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, "envelope. The bigger this value the higher the level " "on which the envelope stays before going down to " "zero." ) ); - connect( m_sustainKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateAfterKnobChange( float ) ) ); + connect( &m_sustainModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); - m_releaseKnob = new knob( knobBright_26, this, tr( "Release-time" ), - _track ); + + + m_releaseModel.setTrack( _track ); + m_releaseModel.setRange( 0.0, 1.0, 0.001 ); + m_releaseModel.setInitValue( 0.1 ); + m_releaseKnob = new knob( knobBright_26, this, tr( "Release-time" ) ); + m_releaseKnob->setModel( &m_releaseModel ); m_releaseKnob->setLabel( tr( "REL" ) ); - m_releaseKnob->setRange( 0.0, 1.0, 0.001 ); - m_releaseKnob->setInitValue( 0.1 ); m_releaseKnob->move( RELEASE_KNOB_X, ENV_KNOBS_Y ); m_releaseKnob->setHintText( tr( "Release:" ) + " ", "" ); m_releaseKnob->setWhatsThis( @@ -206,15 +231,17 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, "envelope needs to decrease from sustain-level to " "zero. Choose a big value for soft instruments like " "strings." ) ); - connect( m_releaseKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateAfterKnobChange( float ) ) ); + connect( &m_releaseModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); + + m_amountModel.setTrack( _track ); + m_amountModel.setRange( -1.0, 1.0, 0.005 ); + m_amountModel.setInitValue( 0.0 ); m_amountKnob = new knob( knobBright_26, this, - tr( "Modulation amount" ), - _track ); + tr( "Modulation amount" ) ); + m_amountKnob->setModel( &m_amountModel ); m_amountKnob->setLabel( tr( "AMT" ) ); - m_amountKnob->setRange( -1.0, 1.0, 0.005 ); - m_amountKnob->setInitValue( 0.0 ); m_amountKnob->move( AMOUNT_KNOB_X, ENV_GRAPH_Y ); m_amountKnob->setHintText( tr( "Modulation amount:" ) + " ", "" ); m_amountKnob->setWhatsThis( @@ -222,62 +249,70 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, "current envelope. The bigger this value the more the " "according size (e.g. volume or cutoff-frequency) " "will be influenced by this envelope." ) ); - connect( m_amountKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateAfterKnobChange( float ) ) ); + connect( &m_amountModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); + + m_lfoPredelayModel.setTrack( _track ); + m_lfoPredelayModel.setRange( 0.0, 1.0, 0.001 ); + m_lfoPredelayModel.setInitValue( 0.0 ); m_lfoPredelayKnob = new knob( knobBright_26, this, - tr( "LFO-predelay-time" ), - _track ); + tr( "LFO-predelay-time" ) ); + m_lfoPredelayKnob->setModel( &m_lfoPredelayModel ); m_lfoPredelayKnob->setLabel( tr( "DEL" ) ); - m_lfoPredelayKnob->setRange( 0.0, 1.0, 0.001 ); - m_lfoPredelayKnob->setInitValue( 0.0 ); m_lfoPredelayKnob->move( LFO_PREDELAY_KNOB_X, LFO_KNOB_Y ); m_lfoPredelayKnob->setHintText( tr( "LFO-predelay:" ) + " ", "" ); m_lfoPredelayKnob->setWhatsThis( tr( "Use this knob for setting predelay-time of the current " "LFO. The bigger this value the the time until the " "LFO starts to oscillate." ) ); - connect( m_lfoPredelayKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateAfterKnobChange( float ) ) ); + connect( &m_lfoPredelayModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); + + m_lfoAttackModel.setTrack( _track ); + m_lfoAttackModel.setRange( 0.0, 1.0, 0.001 ); + m_lfoAttackModel.setInitValue( 0.0 ); m_lfoAttackKnob = new knob( knobBright_26, this, - tr( "LFO-attack-time" ), - _track ); + tr( "LFO-attack-time" ) ); + m_lfoAttackKnob->setModel( &m_lfoAttackModel ); m_lfoAttackKnob->setLabel( tr( "ATT" ) ); - m_lfoAttackKnob->setRange( 0.0, 1.0, 0.001 ); - m_lfoAttackKnob->setInitValue( 0.0 ); m_lfoAttackKnob->move( LFO_ATTACK_KNOB_X, LFO_KNOB_Y ); m_lfoAttackKnob->setHintText( tr( "LFO-attack:" ) + " ", "" ); m_lfoAttackKnob->setWhatsThis( tr( "Use this knob for setting attack-time of the current LFO. " "The bigger this value the longer the LFO needs to " "increase its amplitude to maximum." ) ); - connect( m_lfoAttackKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateAfterKnobChange( float ) ) ); + connect( &m_lfoAttackModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); + + m_lfoSpeedModel.setTrack( _track ); + m_lfoSpeedModel.setRange( 0.01, 1.0, 0.0001 ); + m_lfoSpeedModel.setInitValue( 0.1 ); m_lfoSpeedKnob = new tempoSyncKnob( knobBright_26, this, - tr( "LFO-speed" ), - _track, 20000.0 ); + tr( "LFO-speed" ), 20000.0 ); + m_lfoSpeedKnob->setModel( &m_lfoSpeedModel ); m_lfoSpeedKnob->setLabel( tr( "SPD" ) ); - m_lfoSpeedKnob->setRange( 0.01, 1.0, 0.0001 ); - m_lfoSpeedKnob->setInitValue( 0.1 ); m_lfoSpeedKnob->move( LFO_SPEED_KNOB_X, LFO_KNOB_Y ); m_lfoSpeedKnob->setHintText( tr( "LFO-speed:" ) + " ", "" ); m_lfoSpeedKnob->setWhatsThis( tr( "Use this knob for setting speed of the current LFO. The " "bigger this value the faster the LFO oscillates and " "the faster will be your effect." ) ); - connect( m_lfoSpeedKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateAfterKnobChange( float ) ) ); + connect( &m_lfoSpeedModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); + + m_lfoAmountModel.setTrack( _track ); + m_lfoAmountModel.setRange( -1.0, 1.0, 0.005 ); + m_lfoAmountModel.setInitValue( 0.0 ); m_lfoAmountKnob = new knob( knobBright_26, this, - tr( "LFO-modulation-amount" ), - _track ); + tr( "LFO-modulation-amount" ) ); + m_lfoAmountKnob->setModel( &m_lfoAmountModel ); m_lfoAmountKnob->setLabel( tr( "AMT" ) ); - m_lfoAmountKnob->setRange( -1.0, 1.0, 0.005 ); - m_lfoAmountKnob->setInitValue( 0.0 ); m_lfoAmountKnob->move( LFO_AMOUNT_KNOB_X, LFO_KNOB_Y ); m_lfoAmountKnob->setHintText( tr( "Modulation amount:" ) + " ", "" ); m_lfoAmountKnob->setWhatsThis( @@ -285,11 +320,11 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, "current LFO. The bigger this value the more the " "selected size (e.g. volume or cutoff-frequency) will " "be influenced by this LFO." ) ); - connect( m_lfoAmountKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateAfterKnobChange( float ) ) ); + connect( &m_lfoAmountModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); - pixmapButton * sin_lfo_btn = new pixmapButton( this, NULL, NULL ); + pixmapButton * sin_lfo_btn = new pixmapButton( this, NULL ); sin_lfo_btn->move( LFO_SHAPES_X, LFO_SHAPES_Y ); sin_lfo_btn->setActiveGraphic( embed::getIconPixmap( "sin_wave_active" ) ); @@ -299,7 +334,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, tr( "Click here if you want a sine-wave for current " "oscillator." ) ); - pixmapButton * triangle_lfo_btn = new pixmapButton( this, NULL, NULL ); + pixmapButton * triangle_lfo_btn = new pixmapButton( this, NULL ); triangle_lfo_btn->move( LFO_SHAPES_X+15, LFO_SHAPES_Y ); triangle_lfo_btn->setActiveGraphic( embed::getIconPixmap( "triangle_wave_active" ) ); @@ -309,7 +344,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, tr( "Click here if you want a triangle-wave for current " "oscillator." ) ); - pixmapButton * saw_lfo_btn = new pixmapButton( this, NULL, NULL ); + pixmapButton * saw_lfo_btn = new pixmapButton( this, NULL ); saw_lfo_btn->move( LFO_SHAPES_X+30, LFO_SHAPES_Y ); saw_lfo_btn->setActiveGraphic( embed::getIconPixmap( "saw_wave_active" ) ); @@ -319,7 +354,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, tr( "Click here if you want a saw-wave for current " "oscillator." ) ); - pixmapButton * sqr_lfo_btn = new pixmapButton( this, NULL, NULL ); + pixmapButton * sqr_lfo_btn = new pixmapButton( this, NULL ); sqr_lfo_btn->move( LFO_SHAPES_X+45, LFO_SHAPES_Y ); sqr_lfo_btn->setActiveGraphic( embed::getIconPixmap( "square_wave_active" ) ); @@ -329,7 +364,7 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, tr( "Click here if you want a square-wave for current " "oscillator." ) ); - m_userLfoBtn = new pixmapButton( this, NULL, NULL ); + m_userLfoBtn = new pixmapButton( this, NULL ); m_userLfoBtn->move( LFO_SHAPES_X+60, LFO_SHAPES_Y ); m_userLfoBtn->setActiveGraphic( embed::getIconPixmap( "usr_wave_active" ) ); @@ -340,37 +375,42 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, "oscillator. Afterwards drag an according sample-" "file into LFO-graph." ) ); - connect( m_userLfoBtn, SIGNAL( toggled( bool ) ), this, - SLOT( lfoUserWaveCh( bool ) ) ); + connect( m_userLfoBtn, SIGNAL( toggled( bool ) ), + this, SLOT( lfoUserWaveChanged() ) ); m_lfoWaveBtnGrp = new automatableButtonGroup( this, - tr( "LFO wave shape" ), - _track ); + tr( "LFO wave shape" ) ); + m_lfoWaveBtnGrp->setModel( &m_lfoWaveModel ); m_lfoWaveBtnGrp->addButton( sin_lfo_btn ); m_lfoWaveBtnGrp->addButton( triangle_lfo_btn ); m_lfoWaveBtnGrp->addButton( saw_lfo_btn ); m_lfoWaveBtnGrp->addButton( sqr_lfo_btn ); m_lfoWaveBtnGrp->addButton( m_userLfoBtn ); - m_lfoWaveBtnGrp->setInitValue( SIN ); - connect( m_lfoWaveBtnGrp, SIGNAL( valueChanged( int ) ), - SLOT( lfoWaveCh( int ) ) ); + m_lfoWaveModel.setTrack( _track ); + m_lfoWaveModel.setInitValue( SIN ); + connect( &m_lfoWaveModel, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); + + m_x100Model.setTrack( _track ); m_x100Cb = new ledCheckBox( tr( "FREQ x 100" ), this, - tr( "Freq x 100" ), _track ); + tr( "Freq x 100" ) ); + m_x100Cb->setModel( &m_x100Model ); m_x100Cb->setFont( pointSize<6>( m_x100Cb->font() ) ); m_x100Cb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 36 ); m_x100Cb->setWhatsThis( tr( "Click here if the frequency of this LFO should be " "multiplied with 100." ) ); toolTip::add( m_x100Cb, tr( "multiply LFO-frequency with 100" ) ); - connect( m_x100Cb, SIGNAL( toggled( bool ) ), this, - SLOT( x100Toggled( bool ) ) ); + connect( &m_x100Model, SIGNAL( dataChanged() ), + this, SLOT( updateSampleVars() ) ); + m_controlEnvAmountModel.setTrack( _track ); m_controlEnvAmountCb = new ledCheckBox( tr( "MODULATE ENV-AMOUNT" ), - this, tr( "Modulate Env-Amount" ), - _track ); + this, tr( "Modulate Env-Amount" ) ); + m_controlEnvAmountCb->setModel( &m_controlEnvAmountModel ); m_controlEnvAmountCb->move( LFO_PREDELAY_KNOB_X, LFO_GRAPH_Y + 54 ); m_controlEnvAmountCb->setFont( pointSize<6>( m_controlEnvAmountCb->font() ) ); @@ -396,6 +436,20 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount, envelopeAndLFOWidget::~envelopeAndLFOWidget() { + m_predelayModel.disconnect( this ); + m_attackModel.disconnect( this ); + m_holdModel.disconnect( this ); + m_decayModel.disconnect( this ); + m_sustainModel.disconnect( this ); + m_releaseModel.disconnect( this ); + m_amountModel.disconnect( this ); + m_lfoPredelayModel.disconnect( this ); + m_lfoAttackModel.disconnect( this ); + m_lfoSpeedModel.disconnect( this ); + m_lfoAmountModel.disconnect( this ); + m_lfoWaveModel.disconnect( this ); + m_x100Model.disconnect( this ); + delete[] m_pahdEnv; delete[] m_rEnv; delete[] m_lfoShapeData; @@ -405,6 +459,8 @@ envelopeAndLFOWidget::~envelopeAndLFOWidget() { v.erase( qFind( v.begin(), v.end(), this ) ); } + + delete m_lfoWaveBtnGrp; } @@ -416,7 +472,7 @@ inline sample_t envelopeAndLFOWidget::lfoShapeSample( fpp_t _frame_offset ) const float phase = frame / static_cast( m_lfoOscillationFrames ); sample_t shape_sample; - switch( m_lfoShape ) + switch( m_lfoWaveModel.value() ) { case TRIANGLE: shape_sample = oscillator::triangleSample( phase ); @@ -549,7 +605,7 @@ void FASTCALL envelopeAndLFOWidget::fillLevel( float * _buf, f_cnt_t _frame, } // at this point, *_buf is LFO level - *_buf = m_controlEnvAmountCb->isChecked() ? + *_buf = m_controlEnvAmountModel.value() ? env_level * ( 0.5f + *_buf ) : env_level + *_buf; } @@ -561,20 +617,20 @@ void FASTCALL envelopeAndLFOWidget::fillLevel( float * _buf, f_cnt_t _frame, void envelopeAndLFOWidget::saveSettings( QDomDocument & _doc, QDomElement & _parent ) { - m_predelayKnob->saveSettings( _doc, _parent, "pdel" ); - m_attackKnob->saveSettings( _doc, _parent, "att" ); - m_holdKnob->saveSettings( _doc, _parent, "hold" ); - m_decayKnob->saveSettings( _doc, _parent, "dec" ); - m_sustainKnob->saveSettings( _doc, _parent, "sus" ); - m_releaseKnob->saveSettings( _doc, _parent, "rel" ); - m_amountKnob->saveSettings( _doc, _parent, "amt" ); - m_lfoWaveBtnGrp->saveSettings( _doc, _parent, "lshp" ); - m_lfoPredelayKnob->saveSettings( _doc, _parent, "lpdel" ); - m_lfoAttackKnob->saveSettings( _doc, _parent, "latt" ); - m_lfoSpeedKnob->saveSettings( _doc, _parent, "lspd" ); - m_lfoAmountKnob->saveSettings( _doc, _parent, "lamt" ); - m_x100Cb->saveSettings( _doc, _parent, "x100" ); - m_controlEnvAmountCb->saveSettings( _doc, _parent, "ctlenvamt" ); + m_predelayModel.saveSettings( _doc, _parent, "pdel" ); + m_attackModel.saveSettings( _doc, _parent, "att" ); + m_holdModel.saveSettings( _doc, _parent, "hold" ); + m_decayModel.saveSettings( _doc, _parent, "dec" ); + m_sustainModel.saveSettings( _doc, _parent, "sus" ); + m_releaseModel.saveSettings( _doc, _parent, "rel" ); + m_amountModel.saveSettings( _doc, _parent, "amt" ); + m_lfoWaveModel.saveSettings( _doc, _parent, "lshp" ); + m_lfoPredelayModel.saveSettings( _doc, _parent, "lpdel" ); + m_lfoAttackModel.saveSettings( _doc, _parent, "latt" ); + m_lfoSpeedModel.saveSettings( _doc, _parent, "lspd" ); + m_lfoAmountModel.saveSettings( _doc, _parent, "lamt" ); + m_x100Model.saveSettings( _doc, _parent, "x100" ); + m_controlEnvAmountModel.saveSettings( _doc, _parent, "ctlenvamt" ); _parent.setAttribute( "userwavefile", m_userWave.audioFile() ); } @@ -583,20 +639,20 @@ void envelopeAndLFOWidget::saveSettings( QDomDocument & _doc, void envelopeAndLFOWidget::loadSettings( const QDomElement & _this ) { - m_predelayKnob->loadSettings( _this, "pdel" ); - m_attackKnob->loadSettings( _this, "att" ); - m_holdKnob->loadSettings( _this, "hold" ); - m_decayKnob->loadSettings( _this, "dec" ); - m_sustainKnob->loadSettings( _this, "sus" ); - m_releaseKnob->loadSettings( _this, "rel" ); - m_amountKnob->loadSettings( _this, "amt" ); - m_lfoWaveBtnGrp->loadSettings( _this, "lshp" ); - m_lfoPredelayKnob->loadSettings( _this, "lpdel" ); - m_lfoAttackKnob->loadSettings( _this, "latt" ); - m_lfoSpeedKnob->loadSettings( _this, "lspd" ); - m_lfoAmountKnob->loadSettings( _this, "lamt" ); - m_x100Cb->loadSettings( _this, "x100" ); - m_controlEnvAmountCb->loadSettings( _this, "ctlenvamt" ); + m_predelayModel.loadSettings( _this, "pdel" ); + m_attackModel.loadSettings( _this, "att" ); + m_holdModel.loadSettings( _this, "hold" ); + m_decayModel.loadSettings( _this, "dec" ); + m_sustainModel.loadSettings( _this, "sus" ); + m_releaseModel.loadSettings( _this, "rel" ); + m_amountModel.loadSettings( _this, "amt" ); + m_lfoWaveModel.loadSettings( _this, "lshp" ); + m_lfoPredelayModel.loadSettings( _this, "lpdel" ); + m_lfoAttackModel.loadSettings( _this, "latt" ); + m_lfoSpeedModel.loadSettings( _this, "lspd" ); + m_lfoAmountModel.loadSettings( _this, "lamt" ); + m_x100Model.loadSettings( _this, "x100" ); + m_controlEnvAmountModel.loadSettings( _this, "ctlenvamt" ); // Keep compatibility with version 2.1 file format if( _this.hasAttribute( "lfosyncmode" ) ) @@ -669,8 +725,7 @@ void envelopeAndLFOWidget::dropEvent( QDropEvent * _de ) if( type == "samplefile" ) { m_userWave.setAudioFile( stringPairDrag::decodeValue( _de ) ); - m_userLfoBtn->setChecked( TRUE ); - lfoUserWaveCh( TRUE ); + m_userLfoBtn->model()->setValue( TRUE ); _de->accept(); } else if( type == QString( "tco_%1" ).arg( track::SAMPLE_TRACK ) ) @@ -678,8 +733,7 @@ void envelopeAndLFOWidget::dropEvent( QDropEvent * _de ) multimediaProject mmp( value, FALSE ); m_userWave.setAudioFile( mmp.content().firstChild().toElement(). attribute( "src" ) ); - m_userLfoBtn->setChecked( TRUE ); - lfoUserWaveCh( TRUE ); + m_userLfoBtn->model()->setValue( TRUE ); _de->accept(); } } @@ -778,7 +832,7 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) float osc_frames = m_lfoOscillationFrames; - if( m_x100Cb->isChecked() ) + if( m_x100Model.value() ) { osc_frames *= 100.0f; } @@ -792,7 +846,7 @@ void envelopeAndLFOWidget::paintEvent( QPaintEvent * ) { float phase = ( cur_sample -= m_lfoPredelayFrames ) / osc_frames; - switch( m_lfoShape ) + switch( m_lfoWaveModel.value() ) { case SIN: val = oscillator::sinSample( phase ); @@ -935,7 +989,7 @@ void envelopeAndLFOWidget::updateSampleVars( void ) m_lfoOscillationFrames = static_cast( frames_per_lfo_oscillation * m_lfoSpeedKnob->value() ); - if( m_x100Cb->isChecked() ) + if( m_x100Model.value() ) { m_lfoOscillationFrames /= 100; } @@ -965,35 +1019,9 @@ void envelopeAndLFOWidget::updateSampleVars( void ) -void envelopeAndLFOWidget::x100Toggled( bool ) +void envelopeAndLFOWidget::lfoUserWaveChanged( void ) { - engine::getSongEditor()->setModified(); - updateSampleVars(); -} - - - - -void envelopeAndLFOWidget::updateAfterKnobChange( float ) -{ - updateSampleVars(); -} - - - - -void envelopeAndLFOWidget::lfoWaveCh( int _val ) -{ - m_lfoShape = static_cast( _val ); - updateSampleVars(); -} - - - - -void envelopeAndLFOWidget::lfoUserWaveCh( bool _on ) -{ - if( _on && m_lfoShape != USER ) + if( m_lfoWaveModel.value() == USER ) { if( m_userWave.frames() <= 1 ) { @@ -1002,11 +1030,7 @@ void envelopeAndLFOWidget::lfoUserWaveCh( bool _on ) "it in this window." ), embed::getIconPixmap( "hint" ), 3000 ); } - m_lfoShape = USER; } - engine::getSongEditor()->setModified(); - - updateSampleVars(); } diff --git a/src/core/envelope_tab_widget.cpp b/src/core/envelope_tab_widget.cpp index ba5dc56653..8444baa603 100644 --- a/src/core/envelope_tab_widget.cpp +++ b/src/core/envelope_tab_widget.cpp @@ -73,9 +73,12 @@ static const QString targetNames[envelopeTabWidget::TARGET_COUNT][2] = envelopeTabWidget::envelopeTabWidget( instrumentTrack * _instrument_track ) : QWidget( _instrument_track->tabWidgetParent() ), - m_instrumentTrack( _instrument_track ) + m_instrumentTrack( _instrument_track ), + m_filterEnabledModel( new boolModel( /* this */ ) ), + m_filterModel( new comboBoxModel( /* this */ ) ), + m_filterCutModel( new floatModel( /* this */ ) ), + m_filterResModel( new floatModel( /* this */ ) ) { - m_targetsTabWidget = new tabWidget( tr( "TARGET" ), this ); m_targetsTabWidget->setGeometry( TARGETS_TABWIDGET_X, TARGETS_TABWIDGET_Y, @@ -111,50 +114,54 @@ envelopeTabWidget::envelopeTabWidget( instrumentTrack * _instrument_track ) : tr( targetNames[i][0] .toAscii().constData() ) ); } - - - m_filterGroupBox = new groupBox( tr( "FILTER" ), this, - _instrument_track ); + + + m_filterEnabledModel->setTrack( _instrument_track ); + m_filterGroupBox = new groupBox( tr( "FILTER" ), this ); + m_filterGroupBox->setModel( m_filterEnabledModel ); m_filterGroupBox->setGeometry( FILTER_GROUPBOX_X, FILTER_GROUPBOX_Y, FILTER_GROUPBOX_WIDTH, FILTER_GROUPBOX_HEIGHT ); - m_filterComboBox = new comboBox( m_filterGroupBox, tr( "Filter type" ), - _instrument_track ); + + m_filterModel->addItem( tr( "LowPass" ), new QPixmap( + embed::getIconPixmap( "filter_lp" ) ) ); + m_filterModel->addItem( tr( "HiPass" ), new QPixmap( + embed::getIconPixmap( "filter_hp" ) ) ); + m_filterModel->addItem( tr( "BandPass csg" ), new QPixmap( + embed::getIconPixmap( "filter_bp" ) ) ); + m_filterModel->addItem( tr( "BandPass czpg" ), new QPixmap( + embed::getIconPixmap( "filter_bp" ) ) ); + m_filterModel->addItem( tr( "Notch" ), new QPixmap( + embed::getIconPixmap( "filter_notch" ) ) ); + m_filterModel->addItem( tr( "Allpass" ), new QPixmap( + embed::getIconPixmap( "filter_ap" ) ) ); + m_filterModel->addItem( tr( "Moog" ), new QPixmap( + embed::getIconPixmap( "filter_lp" ) ) ); + m_filterModel->addItem( tr( "2x LowPass" ), new QPixmap( + embed::getIconPixmap( "filter_2lp" ) ) ); + + m_filterModel->setTrack( _instrument_track ); + m_filterComboBox = new comboBox( m_filterGroupBox, tr( "Filter type" ) ); + m_filterComboBox->setModel( m_filterModel ); m_filterComboBox->setGeometry( 14, 22, 120, 22 ); m_filterComboBox->setFont( pointSize<8>( m_filterComboBox->font() ) ); - - m_filterComboBox->addItem( tr( "LowPass" ), - embed::getIconPixmap( "filter_lp" ) ); - m_filterComboBox->addItem( tr( "HiPass" ), - embed::getIconPixmap( "filter_hp" ) ); - m_filterComboBox->addItem( tr( "BandPass csg" ), - embed::getIconPixmap( "filter_bp" ) ); - m_filterComboBox->addItem( tr( "BandPass czpg" ), - embed::getIconPixmap( "filter_bp" ) ); - m_filterComboBox->addItem( tr( "Notch" ), - embed::getIconPixmap( "filter_notch" ) ); - m_filterComboBox->addItem( tr( "Allpass" ), - embed::getIconPixmap( "filter_ap" ) ); - m_filterComboBox->addItem( tr( "Moog" ), - embed::getIconPixmap( "filter_lp" ) ); - m_filterComboBox->addItem( tr( "2x LowPass" ), - embed::getIconPixmap( "filter_2lp" ) ); - m_filterComboBox->setWhatsThis( tr( "Here you can select the built-in filter you want to use " "for this instrument-track. Filters are very important " "for changing the characteristics of a sound." ) ); + m_filterCutModel->setTrack( _instrument_track ); + m_filterCutModel->setRange( 0.0, 14000.0, 1.0 ); + m_filterCutModel->setInitValue( 16000.0 ); + m_filterCutKnob = new knob( knobBright_26, m_filterGroupBox, - tr( "cutoff-frequency" ), - _instrument_track ); + tr( "cutoff-frequency" ) ); + m_filterCutKnob->setModel( m_filterCutModel ); m_filterCutKnob->setLabel( tr( "CUTOFF" ) ); - m_filterCutKnob->setRange( 0.0, 14000.0, 1.0 ); m_filterCutKnob->move( 140, 18 ); - m_filterCutKnob->setInitValue( 16000.0 ); m_filterCutKnob->setHintText( tr( "cutoff-frequency:" ) + " ", " " + tr( "Hz" ) ); m_filterCutKnob->setWhatsThis( @@ -165,13 +172,17 @@ envelopeTabWidget::envelopeTabWidget( instrumentTrack * _instrument_track ) : "the cutoff-frequency. A highpass-filter cuts all " "frequencies below cutoff-frequency and so on..." ) ); + + + m_filterResModel->setTrack( _instrument_track ); + m_filterResModel->setRange( basicFilters<>::minQ(), 10.0, 0.01 ); + m_filterResModel->setInitValue( 0.5 ); + m_filterResKnob = new knob( knobBright_26, m_filterGroupBox, - tr( "Q/Resonance" ), - _instrument_track ); + tr( "Q/Resonance" ) ); + m_filterResKnob->setModel( m_filterResModel ); m_filterResKnob->setLabel( tr( "Q/RESO" ) ); - m_filterResKnob->setRange( basicFilters<>::minQ(), 10.0, 0.01 ); m_filterResKnob->move( 190, 18 ); - m_filterResKnob->setInitValue( 0.5 ); m_filterResKnob->setHintText( tr( "Q/Resonance:" ) + " ", "" ); m_filterResKnob->setWhatsThis( tr( "Use this knob for setting Q/Resonance for the selected " @@ -233,7 +244,7 @@ void envelopeTabWidget::processAudioBuffer( sampleFrame * _ab, // only use filter, if it is really needed - if( m_filterGroupBox->isActive() ) + if( m_filterEnabledModel->value() ) { int old_filter_cut = 0; int old_filter_res = 0; @@ -429,10 +440,10 @@ f_cnt_t envelopeTabWidget::releaseFrames( const bool _only_vol ) void envelopeTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - m_filterComboBox->saveSettings( _doc, _this, "ftype" ); - m_filterCutKnob->saveSettings( _doc, _this, "fcut" ); - m_filterResKnob->saveSettings( _doc, _this, "fres" ); - m_filterGroupBox->saveSettings( _doc, _this, "fwet" ); + m_filterModel->saveSettings( _doc, _this, "ftype" ); + m_filterCutModel->saveSettings( _doc, _this, "fcut" ); + m_filterResModel->saveSettings( _doc, _this, "fres" ); + m_filterEnabledModel->saveSettings( _doc, _this, "fwet" ); for( int i = 0; i < TARGET_COUNT; ++i ) { @@ -447,10 +458,10 @@ void envelopeTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this ) void envelopeTabWidget::loadSettings( const QDomElement & _this ) { - m_filterComboBox->loadSettings( _this, "ftype" ); - m_filterCutKnob->loadSettings( _this, "fcut" ); - m_filterResKnob->loadSettings( _this, "fres" ); - m_filterGroupBox->loadSettings( _this, "fwet" ); + m_filterModel->loadSettings( _this, "ftype" ); + m_filterCutModel->loadSettings( _this, "fcut" ); + m_filterResModel->loadSettings( _this, "fres" ); + m_filterEnabledModel->loadSettings( _this, "fwet" ); QDomNode node = _this.firstChild(); while( !node.isNull() ) diff --git a/src/core/export_project_dialog.cpp b/src/core/export_project_dialog.cpp index f09cfc2b34..02e7f460b0 100644 --- a/src/core/export_project_dialog.cpp +++ b/src/core/export_project_dialog.cpp @@ -117,8 +117,11 @@ Sint16 exportProjectDialog::s_availableBitrates[] = exportProjectDialog::exportProjectDialog( const QString & _file_name, QWidget * _parent ) : QDialog( _parent ), + m_typeModel( new comboBoxModel( /* this */ ) ), + m_kbpsModel( new comboBoxModel( /* this */ ) ), + m_vbrEnabledModel( new boolModel( /* this */ ) ), + m_hqmEnabledModel( new boolModel( /* this */ ) ), m_fileName( _file_name ), - m_hourglassLbl( NULL ), m_deleteFile( FALSE ) { m_fileType = getFileTypeFromExtension( "." + @@ -132,53 +135,57 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name, m_typeLbl->setGeometry( LABEL_X, TYPE_STUFF_Y, LABEL_WIDTH, TYPE_HEIGHT ); - m_typeCombo = new comboBox( this, NULL, NULL ); - m_typeCombo->setGeometry( LABEL_X + LABEL_WIDTH+LABEL_MARGIN, - TYPE_STUFF_Y, TYPE_COMBO_WIDTH, - TYPE_HEIGHT ); - connect( m_typeCombo, SIGNAL( activated( const QString & ) ), this, - SLOT( changedType( const QString & ) ) ); - Uint8 idx = 0; while( fileEncodeDevices[idx].m_fileType != NULL_FILE ) { - m_typeCombo->addItem( + m_typeModel->addItem( tr( fileEncodeDevices[idx].m_description ) ); ++idx; } - m_typeCombo->setValue( m_typeCombo->findText( tr( + m_typeModel->setValue( m_typeModel->findText( tr( fileEncodeDevices[m_fileType].m_description ) ) ); + m_typeCombo = new comboBox( this ); + m_typeCombo->setGeometry( LABEL_X + LABEL_WIDTH+LABEL_MARGIN, + TYPE_STUFF_Y, TYPE_COMBO_WIDTH, + TYPE_HEIGHT ); + m_typeCombo->setModel( m_typeModel ); +/* connect( m_typeCombo, SIGNAL( activated( const QString & ) ), this, + SLOT( changedType( const QString & ) ) );*/ + // kbps-ui-stuff m_kbpsLbl = new QLabel( tr( "kbps:" ), this ); m_kbpsLbl->setGeometry( LABEL_X, KBPS_STUFF_Y, LABEL_WIDTH, KBPS_HEIGHT ); - m_kbpsCombo = new comboBox( this, NULL, NULL ); + idx = 0; + while( s_availableBitrates[idx] != -1 ) + { + m_kbpsModel->addItem( QString::number( + s_availableBitrates[idx] ) ); + ++idx; + } + m_kbpsModel->setValue( m_kbpsModel->findText( + QString::number( 128 ) ) ); + + m_kbpsCombo = new comboBox( this ); + m_kbpsCombo->setModel( m_kbpsModel ); m_kbpsCombo->setGeometry( LABEL_X + LABEL_WIDTH + LABEL_MARGIN, KBPS_STUFF_Y, KBPS_COMBO_WIDTH, KBPS_HEIGHT ); - idx = 0; - while( s_availableBitrates[idx] != -1 ) - { - m_kbpsCombo->addItem( QString::number( - s_availableBitrates[idx] ) ); - ++idx; - } - m_typeCombo->setValue( m_typeCombo->findText( - QString::number( 128 ) ) ); - - m_vbrCb = new ledCheckBox( tr( "variable bitrate" ), this, NULL, NULL ); + m_vbrCb = new ledCheckBox( tr( "variable bitrate" ), this ); + m_vbrCb->setModel( m_vbrEnabledModel ); m_vbrCb->setGeometry( LABEL_X + LABEL_WIDTH + 3 * LABEL_MARGIN + KBPS_COMBO_WIDTH, KBPS_STUFF_Y + 3, 190, 20 ); m_vbrCb->setChecked( TRUE ); m_hqmCb = new ledCheckBox( tr( "use high-quality-mode (recommened)" ), - this, NULL, NULL ); + this ); + m_hqmCb->setModel( m_hqmEnabledModel ); m_hqmCb->setGeometry( LABEL_X, HQ_MODE_CB_Y + 3, HQ_MODE_CB_WIDTH, HQ_MODE_CB_HEIGHT ); m_hqmCb->setChecked( TRUE ); @@ -306,10 +313,10 @@ void exportProjectDialog::exportBtnClicked( void ) DEFAULT_CHANNELS, success_ful, m_fileName, - m_vbrCb->isChecked(), - m_kbpsCombo->currentText().toInt(), - m_kbpsCombo->currentText().toInt() - 64, - m_kbpsCombo->currentText().toInt() + 64, + m_vbrCb->model()->value(), + m_kbpsModel->currentText().toInt(), + m_kbpsModel->currentText().toInt() - 64, + m_kbpsModel->currentText().toInt() + 64, engine::getMixer() ); if( success_ful == FALSE ) { @@ -351,7 +358,7 @@ void exportProjectDialog::exportBtnClicked( void ) - engine::getMixer()->setAudioDevice( dev, m_hqmCb->isChecked() ); + engine::getMixer()->setAudioDevice( dev, m_hqmCb->model()->value() ); engine::getSongEditor()->startExport(); delete m_hqmCb; diff --git a/src/core/instrument.cpp b/src/core/instrument.cpp index 4acce70226..a26cd4c8e1 100644 --- a/src/core/instrument.cpp +++ b/src/core/instrument.cpp @@ -26,6 +26,7 @@ #include "instrument.h" +#include "automatable_model_templates.h" #include "instrument_track.h" #include "dummy_instrument.h" #include "note_play_handle.h" diff --git a/src/core/ladspa_control.cpp b/src/core/ladspa_control.cpp index 70573d08ec..9ba2016af7 100644 --- a/src/core/ladspa_control.cpp +++ b/src/core/ladspa_control.cpp @@ -26,7 +26,7 @@ #include #include "ladspa_control.h" -#include "automatable_object_templates.h" +#include "automatable_model_templates.h" #include "ladspa_base.h" #include "led_checkbox.h" #include "tempo_sync_knob.h" @@ -42,31 +42,41 @@ ladspaControl::ladspaControl( QWidget * _parent, m_track( _track ), m_link( NULL ), m_toggle( NULL ), - m_knob( NULL ) + m_knob( NULL ), + m_linkEnabledModel( FALSE, FALSE, TRUE ), + m_toggledModel( FALSE, FALSE, TRUE ), + m_knobModel() { m_layout = new QHBoxLayout( this ); if( _link ) { - m_link = new ledCheckBox( "", this, NULL, NULL ); - m_link->setChecked( FALSE ); - connect( m_link, SIGNAL( toggled( bool ) ), - this, SLOT( portLink( bool ) ) ); - m_layout->addWidget( m_link ); + m_link = new ledCheckBox( "", this ); toolTip::add( m_link, tr( "Link channels" ) ); + + m_linkEnabledModel.setValue( FALSE ); + m_linkEnabledModel.setTrack( _track ); + m_link->setModel( &m_linkEnabledModel ); + connect( &m_linkEnabledModel, SIGNAL( dataChanged() ), + this, SLOT( linkStateChanged() ) ); + + m_layout->addWidget( m_link ); } switch( m_port->data_type ) { case TOGGLED: - m_toggle = new ledCheckBox( m_port->name, this, "", - m_track, ledCheckBox::GREEN ); - connect( m_toggle, SIGNAL( toggled( bool ) ), - this, SLOT( ledChange( bool ) ) ); + m_toggledModel.setTrack( m_track ); + m_toggle = new ledCheckBox( m_port->name, this, + QString::null, + ledCheckBox::GREEN ); + m_toggle->setModel( &m_toggledModel ); + connect( &m_toggledModel, SIGNAL( dataChanged() ), + this, SLOT( ledChanged() ) ); setFixedSize( m_toggle->width(), m_toggle->height() ); if( m_port->def == 1.0f ) { - m_toggle->setChecked( TRUE ); + m_toggledModel.setValue( TRUE ); } if( _link ) { @@ -77,17 +87,19 @@ ladspaControl::ladspaControl( QWidget * _parent, } break; case INTEGER: - m_knob = new knob( knobBright_26, this, m_port->name, - m_track ); - connect( m_knob, SIGNAL( valueChanged( float ) ), - this, SLOT( knobChange( float ) ) ); - m_knob->setLabel( m_port->name ); - m_knob->setRange( static_cast( m_port->max ), + m_knobModel.setTrack( m_track ); + m_knobModel.setRange( static_cast( m_port->max ), static_cast( m_port->min ), 1 + static_cast( m_port->max - m_port->min ) / 400 ); - m_knob->setInitValue( + m_knobModel.setInitValue( static_cast( m_port->def ) ); + m_knob = new knob( knobBright_26, this, m_port->name ); + m_knob->setModel( &m_knobModel ); + connect( &m_knobModel, SIGNAL( dataChanged() ), + this, SLOT( knobChanged() ) ); + + m_knob->setLabel( m_port->name ); setFixedSize( m_knob->width(), m_knob->height() ); m_knob->setHintText( tr( "Value:" ) + " ", "" ); m_knob->setWhatsThis( @@ -101,17 +113,18 @@ ladspaControl::ladspaControl( QWidget * _parent, } break; case FLOAT: - m_knob = new knob( knobBright_26, this, m_port->name, - m_track ); - connect( m_knob, SIGNAL( valueChanged( float ) ), - this, SLOT( knobChange( float ) ) ); - m_knob->setLabel( m_port->name ); - m_knob->setRange( m_port->min, m_port->max, + m_knobModel.setTrack( m_track ); + m_knobModel.setRange( m_port->min, m_port->max, ( m_port->max - m_port->min ) / ( m_port->name.toUpper() == "GAIN" && m_port->max == 10.0f ? 4000.0f : 400.0f ) ); - m_knob->setInitValue( m_port->def ); + m_knobModel.setInitValue( m_port->def ); + m_knob = new knob( knobBright_26, this, m_port->name ); + m_knob->setModel( &m_knobModel ); + connect( &m_knobModel, SIGNAL( dataChanged() ), + this, SLOT( knobChanged() ) ); + m_knob->setLabel( m_port->name ); m_knob->setHintText( tr( "Value:" ) + " ", "" ); m_knob->setWhatsThis( tr( "Sorry, no help available." ) ); @@ -125,15 +138,17 @@ ladspaControl::ladspaControl( QWidget * _parent, } break; case TIME: - m_knob = new tempoSyncKnob( knobBright_26, this, - m_port->name, m_track ); - connect( m_knob, SIGNAL( valueChanged( float ) ), - this, SLOT( knobChange( float ) ) ); - m_knob->setLabel( m_port->name ); - m_knob->setRange( m_port->min, m_port->max, + m_knobModel.setTrack( m_track ); + m_knobModel.setRange( m_port->min, m_port->max, ( m_port->max - m_port->min ) / 400.0f ); - m_knob->setInitValue( m_port->def ); + m_knobModel.setInitValue( m_port->def ); + m_knob = new tempoSyncKnob( knobBright_26, this, + m_port->name ); + m_knob->setModel( &m_knobModel ); + connect( &m_knobModel, SIGNAL( dataChanged() ), + this, SLOT( knobChanged() ) ); + m_knob->setLabel( m_port->name ); m_knob->setHintText( tr( "Value:" ) + " ", "" ); m_knob->setWhatsThis( tr( "Sorry, no help available." ) ); @@ -169,12 +184,13 @@ LADSPA_Data ladspaControl::getValue( void ) { case TOGGLED: value = static_cast( - m_toggle->isChecked() ); + m_toggledModel.value() ); break; case INTEGER: case FLOAT: case TIME: - value = static_cast( m_knob->value() ); + value = static_cast( + m_knobModel.value() ); break; default: printf( "ladspaControl::getValue BAD BAD BAD\n" ); @@ -192,14 +208,14 @@ void ladspaControl::setValue( LADSPA_Data _value ) switch( m_port->data_type ) { case TOGGLED: - m_toggle->setChecked( static_cast( _value ) ); + m_toggledModel.setValue( static_cast( _value ) ); break; case INTEGER: - m_knob->setValue( static_cast( _value ) ); + m_knobModel.setValue( static_cast( _value ) ); break; case FLOAT: case TIME: - m_knob->setValue( static_cast( _value ) ); + m_knobModel.setValue( static_cast( _value ) ); break; default: printf("ladspaControl::setValue BAD BAD BAD\n"); @@ -216,17 +232,17 @@ void FASTCALL ladspaControl::saveSettings( QDomDocument & _doc, { if( m_link != NULL ) { - m_link->saveSettings( _doc, _this, _name + "link" ); + m_linkEnabledModel.saveSettings( _doc, _this, _name + "link" ); } switch( m_port->data_type ) { case TOGGLED: - m_toggle->saveSettings( _doc, _this, _name ); + m_toggledModel.saveSettings( _doc, _this, _name ); break; case INTEGER: case FLOAT: case TIME: - m_knob->saveSettings( _doc, _this, _name ); + m_knobModel.saveSettings( _doc, _this, _name ); break; default: printf("ladspaControl::saveSettings BAD BAD BAD\n"); @@ -241,17 +257,17 @@ void FASTCALL ladspaControl::loadSettings( const QDomElement & _this, { if( m_link != NULL ) { - m_link->loadSettings( _this, _name + "link" ); + m_linkEnabledModel.loadSettings( _this, _name + "link" ); } switch( m_port->data_type ) { case TOGGLED: - m_toggle->loadSettings( _this, _name ); + m_toggledModel.loadSettings( _this, _name ); break; case INTEGER: case FLOAT: case TIME: - m_knob->loadSettings( _this, _name ); + m_knobModel.loadSettings( _this, _name ); break; default: printf("ladspaControl::loadSettings BAD BAD BAD\n"); @@ -267,12 +283,14 @@ void FASTCALL ladspaControl::linkControls( ladspaControl * _control ) switch( m_port->data_type ) { case TOGGLED: - ledCheckBox::linkObjects( m_toggle, _control->getToggle() ); + boolModel::linkModels( &m_toggledModel, + _control->getToggledModel() ); break; case INTEGER: case FLOAT: case TIME: - knob::linkObjects( m_knob, _control->getKnob() ); + knobModel::linkModels( &m_knobModel, + _control->getKnobModel() ); break; default: break; @@ -282,17 +300,19 @@ void FASTCALL ladspaControl::linkControls( ladspaControl * _control ) -void ladspaControl::ledChange( bool _state ) +void ladspaControl::ledChanged( void ) { - emit( changed( m_port->port_id, static_cast( _state ) ) ); + emit( changed( m_port->port_id, static_cast( + m_toggledModel.value() ) ) ); } -void ladspaControl::knobChange( float _value ) +void ladspaControl::knobChanged( void ) { - emit( changed( m_port->port_id, static_cast( _value ) ) ); + emit( changed( m_port->port_id, static_cast( + m_knobModel.value() ) ) ); } @@ -303,12 +323,14 @@ void FASTCALL ladspaControl::unlinkControls( ladspaControl * _control ) switch( m_port->data_type ) { case TOGGLED: - ledCheckBox::unlinkObjects( m_toggle, _control->getToggle() ); + boolModel::unlinkModels( &m_toggledModel, + _control->getToggledModel() ); break; case INTEGER: case FLOAT: case TIME: - knob::unlinkObjects( m_knob, _control->getKnob() ); + knobModel::unlinkModels( &m_knobModel, + _control->getKnobModel() ); break; default: break; @@ -318,9 +340,9 @@ void FASTCALL ladspaControl::unlinkControls( ladspaControl * _control ) -void ladspaControl::portLink( bool _state ) +void ladspaControl::linkStateChanged( void ) { - emit( linkChanged( m_port->control_id, _state ) ); + emit( linkChanged( m_port->control_id, m_linkEnabledModel.value() ) ); } @@ -328,10 +350,7 @@ void ladspaControl::portLink( bool _state ) void FASTCALL ladspaControl::setLink( bool _state ) { - if( m_link != NULL ) - { - m_link->setChecked( _state ); - } + m_linkEnabledModel.setValue( _state ); } diff --git a/src/core/meter_dialog.cpp b/src/core/meter_dialog.cpp index 8f462d3b00..3a0af7c0af 100644 --- a/src/core/meter_dialog.cpp +++ b/src/core/meter_dialog.cpp @@ -34,47 +34,63 @@ meterDialog::meterDialog( QWidget * _parent, track * _track ): - QWidget( _parent ) + QWidget( _parent ), + m_numeratorModel( new lcdSpinBoxModel( /* this */ ) ), + m_denominatorModel( new lcdSpinBoxModel( /* this */ ) ) { QVBoxLayout * vlayout = new QVBoxLayout( this ); vlayout->setSpacing( 5 ); vlayout->setMargin( 5 ); + QWidget * num = new QWidget( this ); QHBoxLayout * num_layout = new QHBoxLayout( num ); num_layout->setSpacing( 10 ); - m_numerator = new lcdSpinBox( 1, 32, 2, num, tr( "Meter Numerator" ), - _track ); - connect( m_numerator, SIGNAL( valueChanged( int ) ), - this, SIGNAL( numeratorChanged( int ) ) ); - m_numerator->setValue( 4 ); + + + m_numeratorModel->setTrack( _track ); + m_numeratorModel->setRange( 1, 32 ); + m_numeratorModel->setValue( 4 ); + connect( m_numeratorModel, SIGNAL( dataChanged() ), + this, SIGNAL( numeratorChanged() ) ); + + m_numerator = new lcdSpinBox( 2, num, tr( "Meter Numerator" ) ); + m_numerator->setModel( m_numeratorModel ); + num_layout->addWidget( m_numerator ); + QLabel * num_label = new QLabel( num ); num_label->setText( tr( "Meter Numerator" ) ); QFont f = num_label->font(); num_label->setFont( pointSize<7>( f ) ); num_layout->addWidget( num_label ); + - QWidget * dem = new QWidget( this ); - QHBoxLayout * dem_layout = new QHBoxLayout( dem ); - dem_layout->setSpacing( 10 ); - m_denominator = new lcdSpinBox( 1, 32, 2, dem, - tr( "Meter Denominator" ), - _track ); - connect( m_denominator, SIGNAL( valueChanged( int ) ), - this, SIGNAL( denominatorChanged( int ) ) ); - m_denominator->setValue( 4 ); - dem_layout->addWidget( m_denominator ); - QLabel * dem_label = new QLabel( dem ); - f = dem_label->font(); - dem_label->setFont( pointSize<7>( f ) ); - dem_label->setText( tr( "Meter Denominator" ) ); - dem_layout->addWidget( dem_label ); + QWidget * den = new QWidget( this ); + QHBoxLayout * den_layout = new QHBoxLayout( den ); + den_layout->setSpacing( 10 ); + + m_denominatorModel->setTrack( _track ); + m_denominatorModel->setRange( 1, 32 ); + m_denominatorModel->setValue( 4 ); + connect( m_denominatorModel, SIGNAL( dataChanged() ), + this, SIGNAL( denominatorChanged() ) ); + + m_denominator = new lcdSpinBox( 2, den, tr( "Meter Denominator" ) ); + m_denominator->setModel( m_denominatorModel ); + + den_layout->addWidget( m_denominator ); + + QLabel * den_label = new QLabel( den ); + f = den_label->font(); + den_label->setFont( pointSize<7>( f ) ); + den_label->setText( tr( "Meter Denominator" ) ); + den_layout->addWidget( den_label ); vlayout->addWidget( num ); - vlayout->addWidget( dem ); + vlayout->addWidget( den ); - setFixedSize( dem_label->width() + m_denominator->width() + 10, + setFixedSize( den_label->width() + m_denominator->width() + 10, m_numerator->height() + m_denominator->height() + 15 ); } @@ -91,8 +107,8 @@ meterDialog::~meterDialog() void meterDialog::saveSettings( QDomDocument & _doc, QDomElement & _this, const QString & _name ) { - m_numerator->saveSettings( _doc, _this, _name + "_numerator" ); - m_denominator->saveSettings( _doc, _this, _name + "_denominator" ); + m_numeratorModel->saveSettings( _doc, _this, _name + "_numerator" ); + m_denominatorModel->saveSettings( _doc, _this, _name + "_denominator" ); } @@ -101,8 +117,8 @@ void meterDialog::saveSettings( QDomDocument & _doc, QDomElement & _this, void meterDialog::loadSettings( const QDomElement & _this, const QString & _name ) { - m_numerator->loadSettings( _this, _name + "_numerator" ); - m_denominator->loadSettings( _this, _name + "_denominator" ); + m_numeratorModel->loadSettings( _this, _name + "_numerator" ); + m_denominatorModel->loadSettings( _this, _name + "_denominator" ); } diff --git a/src/core/midi_tab_widget.cpp b/src/core/midi_tab_widget.cpp index 66c341684a..c620a08480 100644 --- a/src/core/midi_tab_widget.cpp +++ b/src/core/midi_tab_widget.cpp @@ -43,6 +43,7 @@ #include "song_editor.h" #include "tab_widget.h" #include "tooltip.h" +#include "automatable_model_templates.h" @@ -51,6 +52,12 @@ midiTabWidget::midiTabWidget( instrumentTrack * _instrument_track, QWidget( _instrument_track->tabWidgetParent() ), m_instrumentTrack( _instrument_track ), m_midiPort( _port ), + m_inputChannelModel(), + m_outputChannelModel(), + m_receiveEnabledModel( FALSE, FALSE, TRUE ), + m_sendEnabledModel( FALSE, FALSE, TRUE ), + m_defaultVelocityInEnabledModel( FALSE, FALSE, TRUE ), + m_defaultVelocityOutEnabledModel( FALSE, FALSE, TRUE ), m_readablePorts( NULL ), m_writeablePorts( NULL ) { @@ -58,78 +65,91 @@ midiTabWidget::midiTabWidget( instrumentTrack * _instrument_track, this ); m_setupTabWidget->setGeometry( 4, 5, 238, 200 ); + m_inputChannelModel.setTrack( m_instrumentTrack ); + m_inputChannelModel.setRange( 0, MIDI_CHANNEL_COUNT ); + m_inputChannelModel.setValue( m_midiPort->inputChannel() + 1 ); + connect( &m_inputChannelModel, SIGNAL( dataChanged() ), + this, SLOT( inputChannelChanged() ) ); - m_inputChannelSpinBox = new lcdSpinBox( 0, MIDI_CHANNEL_COUNT, 3, - m_setupTabWidget, - tr( "Input channel" ), - _instrument_track ); + m_inputChannelSpinBox = new lcdSpinBox( 3, m_setupTabWidget, + tr( "Input channel" ) ); + m_inputChannelSpinBox->setModel( &m_inputChannelModel ); m_inputChannelSpinBox->addTextForValue( 0, "---" ); - m_inputChannelSpinBox->setValue( m_midiPort->inputChannel() + 1 ); m_inputChannelSpinBox->setLabel( tr( "CHANNEL" ) ); m_inputChannelSpinBox->move( 28, 52 ); m_inputChannelSpinBox->setEnabled( FALSE ); - connect( m_inputChannelSpinBox, SIGNAL( valueChanged( int ) ), - this, SLOT( inputChannelChanged( int ) ) ); - inputChannelChanged( m_inputChannelSpinBox->value() ); + inputChannelChanged(); - m_outputChannelSpinBox = new lcdSpinBox( 1, MIDI_CHANNEL_COUNT, 3, - m_setupTabWidget, - tr( "Output channel" ), - _instrument_track ); - m_outputChannelSpinBox->setValue( m_midiPort->outputChannel() + 1 ); - //m_outputChannelSpinBox->addTextForValue( 0, "---" ); + + + m_outputChannelModel.setTrack( m_instrumentTrack ); + m_outputChannelModel.setRange( 1, MIDI_CHANNEL_COUNT ); + m_outputChannelModel.setValue( m_midiPort->outputChannel() + 1 ); + connect( &m_outputChannelModel, SIGNAL( dataChanged() ), + this, SLOT( outputChannelChanged() ) ); + + m_outputChannelSpinBox = new lcdSpinBox( 3, m_setupTabWidget, + tr( "Output channel" ) ); m_outputChannelSpinBox->setLabel( tr( "CHANNEL" ) ); m_outputChannelSpinBox->move( 28, 132 ); m_outputChannelSpinBox->setEnabled( FALSE ); - connect( m_outputChannelSpinBox, SIGNAL( valueChanged( int ) ), - this, SLOT( outputChannelChanged( int ) ) ); - outputChannelChanged( m_outputChannelSpinBox->value() ); + outputChannelChanged(); + m_receiveEnabledModel.setTrack( m_instrumentTrack ); m_receiveCheckBox = new ledCheckBox( tr( "Receive MIDI-events" ), m_setupTabWidget, - tr( "Receive MIDI-events" ), - _instrument_track ); + tr( "Receive MIDI-events" ) ); + m_receiveCheckBox->setModel( &m_receiveEnabledModel ); m_receiveCheckBox->move( 10, 34 ); - connect( m_receiveCheckBox, SIGNAL( toggled( bool ) ), - this, SLOT( midiPortModeToggled( bool ) ) ); + // enabling/disabling widgets is UI-stuff thus we do not use model here connect( m_receiveCheckBox, SIGNAL( toggled( bool ) ), m_inputChannelSpinBox, SLOT( setEnabled( bool ) ) ); + connect( &m_receiveEnabledModel, SIGNAL( dataChanged() ), + this, SLOT( midiPortModeChanged() ) ); + + m_defaultVelocityInEnabledModel.setTrack( m_instrumentTrack ); m_defaultVelocityInCheckBox = new ledCheckBox( tr( "Default velocity " "for all input-events" ), m_setupTabWidget, - tr( "Default input velocity" ), - _instrument_track ); + tr( "Default input velocity" ) ); + m_defaultVelocityInCheckBox->setModel( + &m_defaultVelocityInEnabledModel ); m_defaultVelocityInCheckBox->move( 28, 84 ); - connect( m_defaultVelocityInCheckBox, SIGNAL( toggled( bool ) ), - this, SLOT( defaultVelInChanged( bool ) ) ); + connect( &m_defaultVelocityInEnabledModel, SIGNAL( dataChanged() ), + this, SLOT( defaultVelInChanged() ) ); + m_sendEnabledModel.setTrack( m_instrumentTrack ); m_sendCheckBox = new ledCheckBox( tr( "Send MIDI-events" ), m_setupTabWidget, - tr( "Send MIDI-events" ), - _instrument_track ); + tr( "Send MIDI-events" ) ); + m_sendCheckBox->setModel( &m_sendEnabledModel ); m_sendCheckBox->move( 10, 114 ); - connect( m_sendCheckBox, SIGNAL( toggled( bool ) ), - this, SLOT( midiPortModeToggled( bool ) ) ); connect( m_sendCheckBox, SIGNAL( toggled( bool ) ), m_outputChannelSpinBox, SLOT( setEnabled( bool ) ) ); + connect( &m_sendEnabledModel, SIGNAL( dataChanged() ), + this, SLOT( midiPortModeChanged() ) ); + + m_defaultVelocityOutEnabledModel.setTrack( m_instrumentTrack ); m_defaultVelocityOutCheckBox = new ledCheckBox( tr( "Default velocity " "for all output-events" ), m_setupTabWidget, - tr( "Default output velocity" ), - _instrument_track ); + tr( "Default output velocity" ) ); + m_defaultVelocityOutCheckBox->setModel( + &m_defaultVelocityOutEnabledModel ); m_defaultVelocityOutCheckBox->move( 28, 164 ); - connect( m_defaultVelocityOutCheckBox, SIGNAL( toggled( bool ) ), - this, SLOT( defaultVelOutChanged( bool ) ) ); + connect( &m_defaultVelocityOutEnabledModel, SIGNAL( dataChanged() ), + this, SLOT( defaultVelOutChanged() ) ); + const midiPort::modes m = m_midiPort->mode(); - m_receiveCheckBox->setChecked( m == midiPort::INPUT || + m_receiveEnabledModel.setValue( m == midiPort::INPUT || m == midiPort::DUPLEX ); - m_sendCheckBox->setChecked( m == midiPort::OUTPUT || + m_sendEnabledModel.setValue( m == midiPort::OUTPUT || m == midiPort::DUPLEX ); // when using with non-raw-clients we can provide buttons showing @@ -173,7 +193,6 @@ midiTabWidget::midiTabWidget( instrumentTrack * _instrument_track, mc->connectRPChanged( this, SLOT( readablePortsChanged() ) ); mc->connectWPChanged( this, SLOT( writeablePortsChanged() ) ); } - } @@ -188,15 +207,16 @@ midiTabWidget::~midiTabWidget() void midiTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - m_inputChannelSpinBox->saveSettings( _doc, _this, "inputchannel" ); - m_outputChannelSpinBox->saveSettings( _doc, _this, "outputchannel" ); - m_receiveCheckBox->saveSettings( _doc, _this, "receive" ); - m_sendCheckBox->saveSettings( _doc, _this, "send" ); - m_defaultVelocityInCheckBox->saveSettings( _doc, _this, "defvelin" ); - m_defaultVelocityOutCheckBox->saveSettings( _doc, _this, "defvelout" ); + m_inputChannelModel.saveSettings( _doc, _this, "inputchannel" ); + m_outputChannelModel.saveSettings( _doc, _this, "outputchannel" ); + m_receiveEnabledModel.saveSettings( _doc, _this, "receive" ); + m_sendEnabledModel.saveSettings( _doc, _this, "send" ); + m_defaultVelocityInEnabledModel.saveSettings( _doc, _this, "defvelin" ); + m_defaultVelocityOutEnabledModel.saveSettings( _doc, _this, "defvelout" ); - if( m_readablePorts != NULL && m_receiveCheckBox->isChecked() == TRUE ) + if( m_readablePorts != NULL && m_receiveEnabledModel.value() == TRUE ) { + // TODO: M/V-split! QString rp; QList actions = m_readablePorts->actions(); for( QList::iterator it = actions.begin(); @@ -215,8 +235,9 @@ void midiTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this ) _this.setAttribute( "inports", rp ); } - if( m_writeablePorts != NULL && m_sendCheckBox->isChecked() == TRUE ) + if( m_writeablePorts != NULL && m_sendEnabledModel.value() == TRUE ) { + // TODO: M/V-split! QString wp; QList actions = m_writeablePorts->actions(); for( QList::iterator it = actions.begin(); @@ -241,17 +262,18 @@ void midiTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _this ) void midiTabWidget::loadSettings( const QDomElement & _this ) { - m_inputChannelSpinBox->loadSettings( _this, "inputchannel" ); - m_outputChannelSpinBox->loadSettings( _this, "outputchannel" ); - m_receiveCheckBox->loadSettings( _this, "receive" ); - m_sendCheckBox->loadSettings( _this, "send" ); - m_defaultVelocityInCheckBox->loadSettings( _this, "defvelin" ); - m_defaultVelocityOutCheckBox->loadSettings( _this, "defvelout" ); + m_inputChannelModel.loadSettings( _this, "inputchannel" ); + m_outputChannelModel.loadSettings( _this, "outputchannel" ); + m_receiveEnabledModel.loadSettings( _this, "receive" ); + m_sendEnabledModel.loadSettings( _this, "send" ); + m_defaultVelocityInEnabledModel.loadSettings( _this, "defvelin" ); + m_defaultVelocityOutEnabledModel.loadSettings( _this, "defvelout" ); // restore connections - if( m_readablePorts != NULL && m_receiveCheckBox->isChecked() == TRUE ) + if( m_readablePorts != NULL && m_receiveEnabledModel.value() == TRUE ) { + // TODO: M/V-split! QStringList rp = _this.attribute( "inports" ).split( ',' ); QList actions = m_readablePorts->actions(); for( QList::iterator it = actions.begin(); @@ -266,8 +288,9 @@ void midiTabWidget::loadSettings( const QDomElement & _this ) } } - if( m_writeablePorts != NULL && m_sendCheckBox->isChecked() == TRUE ) + if( m_writeablePorts != NULL && m_sendEnabledModel.value() == TRUE ) { + // TODO: M/V-split! QStringList wp = _this.attribute( "outports" ).split( ',' ); QList actions = m_writeablePorts->actions(); for( QList::iterator it = actions.begin(); @@ -286,41 +309,43 @@ void midiTabWidget::loadSettings( const QDomElement & _this ) -void midiTabWidget::inputChannelChanged( int _new_chnl ) +void midiTabWidget::inputChannelChanged( void ) { - m_midiPort->setInputChannel( _new_chnl - 1 ); + m_midiPort->setInputChannel( m_inputChannelModel.value() - 1 ); engine::getSongEditor()->setModified(); } -void midiTabWidget::outputChannelChanged( int _new_chnl ) +void midiTabWidget::outputChannelChanged( void ) { - m_midiPort->setOutputChannel( _new_chnl - 1 ); + m_midiPort->setOutputChannel( m_outputChannelModel.value() - 1 ); engine::getSongEditor()->setModified(); } -void midiTabWidget::defaultVelInChanged( bool _on ) +void midiTabWidget::defaultVelInChanged( void ) { - m_midiPort->enableDefaultVelocityForInEvents( _on ); + m_midiPort->enableDefaultVelocityForInEvents( + m_defaultVelocityInEnabledModel.value() ); } -void midiTabWidget::defaultVelOutChanged( bool _on ) +void midiTabWidget::defaultVelOutChanged( void ) { - m_midiPort->enableDefaultVelocityForOutEvents( _on ); + m_midiPort->enableDefaultVelocityForOutEvents( + m_defaultVelocityOutEnabledModel.value() ); } -void midiTabWidget::midiPortModeToggled( bool ) +void midiTabWidget::midiPortModeChanged( void ) { // this small lookup-table makes everything easier static const midiPort::modes modeTable[2][2] = @@ -328,11 +353,11 @@ void midiTabWidget::midiPortModeToggled( bool ) { midiPort::DUMMY, midiPort::OUTPUT }, { midiPort::INPUT, midiPort::DUPLEX } } ; - m_midiPort->setMode( modeTable[m_receiveCheckBox->isChecked()] - [m_sendCheckBox->isChecked()] ); + m_midiPort->setMode( modeTable[m_receiveEnabledModel.value()] + [m_sendEnabledModel.value()] ); // check whether we have to dis-check items in connection-menu - if( m_readablePorts != NULL && m_receiveCheckBox->isChecked() == FALSE ) + if( m_readablePorts != NULL && m_receiveEnabledModel.value() == FALSE ) { QList actions = m_readablePorts->actions(); for( QList::iterator it = actions.begin(); @@ -345,7 +370,8 @@ void midiTabWidget::midiPortModeToggled( bool ) } } } - if( m_writeablePorts != NULL && m_sendCheckBox->isChecked() == FALSE ) + + if( m_writeablePorts != NULL && m_sendEnabledModel.value() == FALSE ) { QList actions = m_writeablePorts->actions(); for( QList::iterator it = actions.begin(); @@ -435,7 +461,7 @@ void midiTabWidget::activatedReadablePort( QAction * _item ) m_midiPort->mode() != midiPort::INPUT && m_midiPort->mode() != midiPort::DUPLEX ) { - m_receiveCheckBox->setChecked( TRUE ); + m_receiveEnabledModel.setValue( TRUE ); } engine::getMixer()->getMIDIClient()->subscribeReadablePort( m_midiPort, _item->text(), !_item->isChecked() ); @@ -451,7 +477,7 @@ void midiTabWidget::activatedWriteablePort( QAction * _item ) m_midiPort->mode() != midiPort::OUTPUT && m_midiPort->mode() != midiPort::DUPLEX ) { - m_sendCheckBox->setChecked( TRUE ); + m_sendEnabledModel.setValue( TRUE ); } engine::getMixer()->getMIDIClient()->subscribeWriteablePort( m_midiPort, _item->text(), !_item->isChecked() ); diff --git a/src/core/mv_base.cpp b/src/core/mv_base.cpp new file mode 100644 index 0000000000..3eb7ded89e --- /dev/null +++ b/src/core/mv_base.cpp @@ -0,0 +1,64 @@ +/* + * mv_base.cpp - base for M/V-architecture of LMMS + * + * Copyright (c) 2007 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include + +#include + + +#include "mv_base.h" + + +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() ) + { + delete m_model; + } + else + { + m_model->disconnect( w ); + } + } + + m_model = _model; + QObject::connect( _model, SIGNAL( dataChanged() ), + w, SLOT( update() ) ); + QObject::connect( _model, SIGNAL( propertiesChanged() ), + w, SLOT( update() ) ); + + w->update(); + + modelChanged(); +} + + + +#include "mv_base.moc" + diff --git a/src/core/note.cpp b/src/core/note.cpp index 84dea4cc2a..a2bdd9e6c0 100644 --- a/src/core/note.cpp +++ b/src/core/note.cpp @@ -30,7 +30,7 @@ #include #include "note.h" -#include "automatable_object_templates.h" +#include "automatable_model_templates.h" #include "detuning_helper.h" #include "templates.h" diff --git a/src/core/note_play_handle.cpp b/src/core/note_play_handle.cpp index 0aaed5906e..c8af5a3cbb 100644 --- a/src/core/note_play_handle.cpp +++ b/src/core/note_play_handle.cpp @@ -27,7 +27,7 @@ #include "note_play_handle.h" -#include "automatable_object_templates.h" +#include "automatable_model_templates.h" #include "config_mgr.h" #include "detuning_helper.h" #include "envelope_tab_widget.h" @@ -436,10 +436,14 @@ bool notePlayHandle::operator==( const notePlayHandle & _nph ) const void notePlayHandle::updateFrequency( void ) { - float pitch = (float)( tone() - m_instrumentTrack->baseTone() + + const int base_tone = m_instrumentTrack->baseNoteModel()->value() % + NOTES_PER_OCTAVE; + const int base_octave = m_instrumentTrack->baseNoteModel()->value() / + NOTES_PER_OCTAVE; + const float pitch = (float)( tone() - base_tone + engine::getSongEditor()->masterPitch() ) / 12.0f + - (float)( octave() - m_instrumentTrack->baseOctave() ) - + m_base_detuning->value() / 12.0f; + (float)( octave() - base_octave ) + + m_base_detuning->value() / 12.0f; m_frequency = BASE_FREQ * powf( 2.0f, pitch ); for( notePlayHandleVector::iterator it = m_subNotes.begin(); diff --git a/src/core/piano_roll.cpp b/src/core/piano_roll.cpp index 19c73fe781..da0e136d6a 100644 --- a/src/core/piano_roll.cpp +++ b/src/core/piano_roll.cpp @@ -48,7 +48,6 @@ #include -#include "automatable_object_templates.h" #include "clipboard.h" #include "combobox.h" #include "debug.h" @@ -127,6 +126,9 @@ const int DEFAULT_PR_PPT = KEY_LINE_HEIGHT * DEFAULT_STEPS_PER_TACT; pianoRoll::pianoRoll( void ) : + m_zoomingModel( new comboBoxModel( /* this */ ) ), + m_quantizeModel( new comboBoxModel( /* this */ ) ), + m_noteLenModel( new comboBoxModel( /* this */ ) ), m_pattern( NULL ), m_currentPosition(), m_recording( FALSE ), @@ -344,49 +346,51 @@ pianoRoll::pianoRoll( void ) : zoom_lbl->setPixmap( embed::getIconPixmap( "zoom" ) ); // setup zooming-stuff - m_zoomingComboBox = new comboBox( m_toolBar, NULL, NULL ); - m_zoomingComboBox->setFixedSize( 80, 22 ); for( int i = 0; i < 6; ++i ) { - m_zoomingComboBox->addItem( QString::number( 25 << i ) + "%" ); + m_zoomingModel->addItem( QString::number( 25 << i ) + "%" ); } - m_zoomingComboBox->setValue( m_zoomingComboBox->findText( - "100%" ) ); - connect( m_zoomingComboBox, SIGNAL( activated( const QString & ) ), - this, SLOT( zoomingChanged( const QString & ) ) ); + m_zoomingModel->setValue( m_zoomingModel->findText( "100%" ) ); + connect( m_zoomingModel, SIGNAL( dataChanged() ), + this, SLOT( zoomingChanged() ) ); + m_zoomingComboBox = new comboBox( m_toolBar ); + m_zoomingComboBox->setModel( m_zoomingModel ); + m_zoomingComboBox->setFixedSize( 80, 22 ); // setup quantize-stuff QLabel * quantize_lbl = new QLabel( m_toolBar ); quantize_lbl->setPixmap( embed::getIconPixmap( "quantize" ) ); - m_quantizeComboBox = new comboBox( m_toolBar, NULL, NULL ); - m_quantizeComboBox->setFixedSize( 60, 22 ); for( int i = 0; i < 7; ++i ) { - m_quantizeComboBox->addItem( "1/" + QString::number( 1 << i ) ); + m_quantizeModel->addItem( "1/" + QString::number( 1 << i ) ); } - m_quantizeComboBox->setValue( m_quantizeComboBox->findText( - "1/16" ) ); + m_quantizeModel->setValue( m_quantizeModel->findText( "1/16" ) ); + m_quantizeComboBox = new comboBox( m_toolBar ); + m_quantizeComboBox->setModel( m_quantizeModel ); + m_quantizeComboBox->setFixedSize( 60, 22 ); + // setup note-len-stuff QLabel * note_len_lbl = new QLabel( m_toolBar ); note_len_lbl->setPixmap( embed::getIconPixmap( "note" ) ); - m_noteLenComboBox = new comboBox( m_toolBar, NULL, NULL ); - m_noteLenComboBox->setFixedSize( 120, 22 ); - m_noteLenComboBox->addItem( tr( "Last note" ), - embed::getIconPixmap( "edit_draw" ) ); + m_noteLenModel->addItem( tr( "Last note" ), new QPixmap( + embed::getIconPixmap( "edit_draw" ) ) ); const QString pixmaps[] = { "whole", "half", "quarter", "eighth", "sixteenth", "thirtysecond" } ; for( int i = 0; i < 6; ++i ) { - m_noteLenComboBox->addItem( "1/" + QString::number( 1 << i ), - embed::getIconPixmap( + m_noteLenModel->addItem( "1/" + QString::number( 1 << i ), + new QPixmap( embed::getIconPixmap( QString( "note_" + pixmaps[i] ). - toAscii().constData() ) ); + toAscii().constData() ) ) ); } - m_noteLenComboBox->setValue( 0 ); + m_noteLenModel->setValue( 0 ); + m_noteLenComboBox = new comboBox( m_toolBar ); + m_noteLenComboBox->setModel( m_noteLenModel ); + m_noteLenComboBox->setFixedSize( 120, 22 ); tb_layout->addSpacing( 5 ); @@ -1994,8 +1998,8 @@ void pianoRoll::wheelEvent( QWheelEvent * _we ) m_ppt /= 2; } // update combobox with zooming-factor - m_zoomingComboBox->setValue( - m_zoomingComboBox->findText( QString::number( + m_zoomingModel->setValue( + m_zoomingModel->findText( QString::number( static_cast( m_ppt * 100 / DEFAULT_PR_PPT ) ) +"%" ) ); // update timeline @@ -2459,9 +2463,10 @@ void pianoRoll::updatePosition( const midiTime & _t ) -void pianoRoll::zoomingChanged( const QString & _zfac ) +void pianoRoll::zoomingChanged( void ) { - m_ppt = _zfac.left( _zfac.length() - 1 ).toInt() * DEFAULT_PR_PPT / 100; + const QString & zfac = m_zoomingModel->currentText(); + m_ppt = zfac.left( zfac.length() - 1 ).toInt() * DEFAULT_PR_PPT / 100; #ifdef LMMS_DEBUG assert( m_ppt > 0 ); #endif @@ -2475,8 +2480,8 @@ void pianoRoll::zoomingChanged( const QString & _zfac ) int pianoRoll::quantization( void ) const { - return( 64 / m_quantizeComboBox->currentText().right( - m_quantizeComboBox->currentText().length() - + return( 64 / m_quantizeModel->currentText().right( + m_quantizeModel->currentText().length() - 2 ).toInt() ); } @@ -2485,12 +2490,12 @@ int pianoRoll::quantization( void ) const midiTime pianoRoll::newNoteLen( void ) const { - if( m_noteLenComboBox->value() == 0 ) + if( m_noteLenModel->value() == 0 ) { return( m_lenOfNewNotes ); } - return( 64 / m_noteLenComboBox->currentText().right( - m_noteLenComboBox->currentText().length() - + return( 64 / m_noteLenModel->currentText().right( + m_noteLenModel->currentText().length() - 2 ).toInt() ); } diff --git a/src/core/piano_widget.cpp b/src/core/piano_widget.cpp index 683e8dd133..0511c0f277 100644 --- a/src/core/piano_widget.cpp +++ b/src/core/piano_widget.cpp @@ -35,8 +35,8 @@ #include -#include "automatable_object_templates.h" #include "caption_menu.h" +#include "automatable_model_templates.h" #include "embed.h" #include "gui_templates.h" #include "instrument_track.h" @@ -86,8 +86,13 @@ pianoWidget::pianoWidget( instrumentTrack * _parent ) : m_instrumentTrack( _parent ), m_startTone( C ), m_startOctave( OCTAVE_3 ), - m_lastKey( -1 ) + m_lastKey( -1 ), + m_keyCode( 0 ) { + connect( m_instrumentTrack->baseNoteModel(), SIGNAL( dataChanged() ), + this, SLOT( update( void ) ) ); + + setFocusPolicy( Qt::StrongFocus ); if( s_whiteKeyPm == NULL ) @@ -128,13 +133,6 @@ pianoWidget::pianoWidget( instrumentTrack * _parent ) : connect( m_pianoScroll, SIGNAL( valueChanged( int ) ), this, SLOT( pianoScrolled( int ) ) ); - - m_noteKnob = new knob( knobDark_28, NULL, tr( "Base note" ), _parent ); - m_noteKnob->setRange( 0, NOTES_PER_OCTAVE * OCTAVES - 1, 1.0f ); - m_noteKnob->setInitValue( DEFAULT_OCTAVE * NOTES_PER_OCTAVE + A ); - - connect( m_noteKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateBaseNote( void ) ) ); } @@ -142,7 +140,6 @@ pianoWidget::pianoWidget( instrumentTrack * _parent ) : pianoWidget::~pianoWidget() { - delete m_noteKnob; } @@ -218,10 +215,10 @@ void pianoWidget::contextMenuEvent( QContextMenuEvent * _me ) return; } - captionMenu contextMenu( m_noteKnob->accessibleName() ); + captionMenu contextMenu( tr( "Base note" ) ); contextMenu.addAction( embed::getIconPixmap( "automation" ), tr( "&Open in automation editor" ), - m_noteKnob->getAutomationPattern(), + m_instrumentTrack->baseNoteModel()->getAutomationPattern(), SLOT( openInAutomationEditor() ) ); contextMenu.exec( QCursor::pos() ); } @@ -265,8 +262,8 @@ void pianoWidget::mousePressEvent( QMouseEvent * _me ) } else { - m_noteKnob->setInitValue( key_num ); - m_instrumentTrack->setBaseNote( key_num ); + m_instrumentTrack->baseNoteModel()-> + setInitValue( key_num ); } // and let the user see that he pressed a key... :) @@ -343,8 +340,8 @@ void pianoWidget::mouseMoveEvent( QMouseEvent * _me ) } else { - m_noteKnob->setInitValue( key_num ); - m_instrumentTrack->setBaseNote( key_num ); + m_instrumentTrack->baseNoteModel()-> + setInitValue( key_num ); } } // and let the user see that he pressed a key... :) @@ -364,7 +361,7 @@ void pianoWidget::mouseMoveEvent( QMouseEvent * _me ) int pianoWidget::getKeyFromKeyboard( int _k ) const { - switch( m_keycode ) + switch( m_keyCode ) { case 52: return( 0 ); // Y case 39: return( 1 ); // S @@ -547,8 +544,7 @@ void pianoWidget::paintEvent( QPaintEvent * ) p.setPen( QColor ( 0xFF, 0xFF, 0xFF ) ); - int base_key = m_instrumentTrack->baseTone() + - m_instrumentTrack->baseOctave() * NOTES_PER_OCTAVE; + int base_key = m_instrumentTrack->baseNoteModel()->value(); if( KEY_ORDER[base_key % NOTES_PER_OCTAVE] == WHITE_KEY ) { p.fillRect( QRect( getKeyX( base_key ), 1, PW_WHITE_KEY_WIDTH-1, @@ -656,44 +652,6 @@ void pianoWidget::paintEvent( QPaintEvent * ) -void pianoWidget::updateBaseNote( void ) -{ - m_instrumentTrack->setBaseNote( (int)roundf( m_noteKnob->value() ), - FALSE ); - update(); -} - - - - -void pianoWidget::saveSettings( QDomDocument & _doc, QDomElement & _this, - const QString & _name ) -{ - m_noteKnob->saveSettings( _doc, _this, _name ); -} - - - - -void pianoWidget::loadSettings( const QDomElement & _this, - const QString & _name ) -{ - if( _this.hasAttribute( "baseoct" ) ) - { - m_noteKnob->setInitValue( _this.attribute( "baseoct" ).toInt() - * NOTES_PER_OCTAVE - + _this.attribute( "basetone" ).toInt() ); - } - else - { - m_noteKnob->loadSettings( _this, _name ); - } - updateBaseNote(); -} - - - - #ifdef BUILD_LINUX bool pianoWidget::x11Event( XEvent * _xe ) { @@ -701,7 +659,7 @@ bool pianoWidget::x11Event( XEvent * _xe ) { case KeyPress: case KeyRelease: - m_keycode = _xe->xkey.keycode; + m_keyCode = _xe->xkey.keycode; } return( FALSE ); } diff --git a/src/core/preset_preview_play_handle.cpp b/src/core/preset_preview_play_handle.cpp index a03a88105e..0c07224cdc 100644 --- a/src/core/preset_preview_play_handle.cpp +++ b/src/core/preset_preview_play_handle.cpp @@ -30,6 +30,7 @@ #include #include "preset_preview_play_handle.h" +#include "automatable_model_templates.h" #include "debug.h" #include "engine.h" #include "instrument_track.h" diff --git a/src/core/sample_play_handle.cpp b/src/core/sample_play_handle.cpp index fa1a4eb8db..a1b3aa8201 100644 --- a/src/core/sample_play_handle.cpp +++ b/src/core/sample_play_handle.cpp @@ -26,6 +26,7 @@ #include "sample_play_handle.h" +#include "automatable_model_templates.h" #include "audio_port.h" #include "bb_track.h" #include "engine.h" @@ -43,7 +44,8 @@ samplePlayHandle::samplePlayHandle( const QString & _sample_file ) : m_frame( 0 ), m_audioPort( new audioPort( "samplePlayHandle" ) ), m_ownAudioPort( TRUE ), - m_volume( 1.0f ), + m_defaultVolumeModel( 1.0f, 0.0f, 4.0f, 0.001f/* this*/ ), + m_volumeModel( &m_defaultVolumeModel ), m_track( NULL ), m_bbTrack( NULL ) { @@ -59,7 +61,8 @@ samplePlayHandle::samplePlayHandle( sampleBuffer * _sample_buffer ) : m_frame( 0 ), m_audioPort( new audioPort( "samplePlayHandle" ) ), m_ownAudioPort( TRUE ), - m_volume( 1.0f ), + m_defaultVolumeModel( 1.0f, 0.0f, 4.0f, 0.001f/* this*/ ), + m_volumeModel( &m_defaultVolumeModel ), m_track( NULL ), m_bbTrack( NULL ) { @@ -75,7 +78,8 @@ samplePlayHandle::samplePlayHandle( sampleTCO * _tco ) : m_frame( 0 ), m_audioPort( ( (sampleTrack *)_tco->getTrack() )->getAudioPort() ), m_ownAudioPort( FALSE ), - m_volume( 1.0f ), + m_defaultVolumeModel( 1.0f, 0.0f, 4.0f, 0.001f/* this*/ ), + m_volumeModel( &m_defaultVolumeModel ), m_track( _tco->getTrack() ), m_bbTrack( NULL ) { @@ -91,7 +95,8 @@ samplePlayHandle::samplePlayHandle( pattern * _pattern ) : m_frame( 0 ), m_audioPort( _pattern->getInstrumentTrack()->getAudioPort() ), m_ownAudioPort( FALSE ), - m_volume( 1.0f ), + m_defaultVolumeModel( 1.0f, 0.0f, 4.0f, 0.001f/* this*/ ), + m_volumeModel( &m_defaultVolumeModel ), m_track( _pattern->getInstrumentTrack() ), m_bbTrack( NULL ) { @@ -125,9 +130,11 @@ void samplePlayHandle::play( bool /* _try_parallelizing */ ) && !( m_bbTrack && m_bbTrack->muted() ) ) { sampleFrame * buf = new sampleFrame[frames]; - volumeVector v = { { m_volume, m_volume + volumeVector v = { { m_volumeModel->value(), + m_volumeModel->value() #ifndef DISABLE_SURROUND - , m_volume, m_volume + , m_volumeModel->value(), + m_volumeModel->value() #endif } } ; m_sampleBuffer->play( buf, &m_state, frames ); @@ -169,18 +176,4 @@ f_cnt_t samplePlayHandle::totalFrames( void ) const -void samplePlayHandle::setVolume( float _new_volume ) -{ - if( _new_volume <= MAX_VOLUME ) - { - m_volume = _new_volume / 100.0f; - } -} - - - - -#include "sample_play_handle.moc" - - #endif diff --git a/src/core/setup_dialog.cpp b/src/core/setup_dialog.cpp index 776f38e480..271070c4b3 100644 --- a/src/core/setup_dialog.cpp +++ b/src/core/setup_dialog.cpp @@ -109,10 +109,7 @@ setupDialog::setupDialog( configTabs _tab_to_open ) : m_disableChActInd( configManager::inst()->value( "ui", "disablechannelactivityindicators" ).toInt() ), m_manualChPiano( configManager::inst()->value( "ui", - "manualchannelpiano" ).toInt() ), - m_parLevel( configManager::inst()->value( "mixer", - "parallelizinglevel" ).toInt() ) - + "manualchannelpiano" ).toInt() ) { setWindowIcon( embed::getIconPixmap( "setup_general" ) ); setWindowTitle( tr( "Setup LMMS" ) ); @@ -182,7 +179,7 @@ setupDialog::setupDialog( configTabs _tab_to_open ) : ledCheckBox * enable_tooltips = new ledCheckBox( tr( "Enable tooltips" ), - misc_tw, NULL, NULL ); + misc_tw ); enable_tooltips->move( 10, 18 ); enable_tooltips->setChecked( m_toolTips ); connect( enable_tooltips, SIGNAL( toggled( bool ) ), @@ -192,8 +189,7 @@ setupDialog::setupDialog( configTabs _tab_to_open ) : ledCheckBox * classical_knob_usability = new ledCheckBox( tr( "Classical knob usability (move " "cursor around knob to change " - "value)" ), - misc_tw, NULL, NULL ); + "value)" ), misc_tw ); classical_knob_usability->move( 10, 36 ); classical_knob_usability->setChecked( m_classicalKnobUsability ); connect( classical_knob_usability, SIGNAL( toggled( bool ) ), @@ -202,7 +198,7 @@ setupDialog::setupDialog( configTabs _tab_to_open ) : ledCheckBox * mdi_windows = new ledCheckBox( tr( "Multiple Document Interface" ), - misc_tw, NULL, NULL ); + misc_tw ); mdi_windows->move( 10, 54 ); mdi_windows->setChecked( m_MDI ); connect( mdi_windows, SIGNAL( toggled( bool ) ), @@ -211,7 +207,7 @@ setupDialog::setupDialog( configTabs _tab_to_open ) : ledCheckBox * wizard = new ledCheckBox( tr( "Show wizard after up-/downgrade" ), - misc_tw, NULL, NULL ); + misc_tw ); wizard->move( 10, 72 ); wizard->setChecked( m_wizard ); connect( wizard, SIGNAL( toggled( bool ) ), @@ -220,7 +216,7 @@ setupDialog::setupDialog( configTabs _tab_to_open ) : ledCheckBox * restart_msg = new ledCheckBox( tr( "Show restart warning after changing settings" ), - misc_tw, NULL, NULL ); + misc_tw ); restart_msg->move( 10, 90 ); restart_msg->setChecked( m_warnAfterSetup ); connect( restart_msg, SIGNAL( toggled( bool ) ), @@ -228,7 +224,7 @@ setupDialog::setupDialog( configTabs _tab_to_open ) : ledCheckBox * dbv = new ledCheckBox( tr( "Display volume as dBV " ), - misc_tw, NULL, NULL ); + misc_tw ); dbv->move( 10, 108 ); dbv->setChecked( m_displaydBV ); connect( dbv, SIGNAL( toggled( bool ) ), @@ -237,7 +233,7 @@ setupDialog::setupDialog( configTabs _tab_to_open ) : ledCheckBox * mmpz = new ledCheckBox( tr( "Compress project files per default" ), - misc_tw, NULL, NULL ); + misc_tw ); mmpz->move( 10, 126 ); mmpz->setChecked( m_MMPZ ); connect( mmpz, SIGNAL( toggled( bool ) ), @@ -411,7 +407,7 @@ setupDialog::setupDialog( configTabs _tab_to_open ) : ledCheckBox * disable_ch_act_ind = new ledCheckBox( tr( "Disable channel activity indicators" ), - ui_fx_tw, NULL, NULL ); + ui_fx_tw ); disable_ch_act_ind->move( 10, 20 ); disable_ch_act_ind->setChecked( m_disableChActInd ); connect( disable_ch_act_ind, SIGNAL( toggled( bool ) ), @@ -420,7 +416,7 @@ setupDialog::setupDialog( configTabs _tab_to_open ) : ledCheckBox * manual_ch_piano = new ledCheckBox( tr( "Only press keys on channel-piano manually" ), - ui_fx_tw, NULL, NULL ); + ui_fx_tw ); manual_ch_piano->move( 10, 40 ); manual_ch_piano->setChecked( m_manualChPiano ); connect( manual_ch_piano, SIGNAL( toggled( bool ) ), @@ -432,34 +428,6 @@ setupDialog::setupDialog( configTabs _tab_to_open ) : performance ); smp_supp_tw->setFixedHeight( 200 ); - QLabel * par_level_lbl = new QLabel( tr( "Parallelizing level" ), - smp_supp_tw ); - par_level_lbl->move( 10, 15 ); - par_level_lbl->setFixedSize( 120, 16 ); - lcdSpinBox * par_level = new lcdSpinBox( 1, 16, 2, smp_supp_tw, NULL, - NULL ); - par_level->setValue( m_parLevel ); - connect( par_level, SIGNAL( valueChanged( int ) ), - this, SLOT( setParallelizingLevel( int ) ) ); - - par_level->move( 140, 20 ); - - QLabel * smp_help = new QLabel( - tr( "If you have a machine with more then one processor " - "(e.g. dual-core systems) you should use a " - "parallelizing-level above 1 which means that LMMS " - "will try to split up sound-processing into several " - "threads which should should be run on several cores " - "by the underlaying operating-system.\n" - "Please note that in some cases parallelizing won't " - "work with small buffer-sizes. If you experience " - "problems (i.e. lot of xruns), try to increase buffer-" - "size." ), smp_supp_tw ); - smp_help->setFixedSize( performance->width() - 20, 140 ); - smp_help->setWordWrap( TRUE ); - smp_help->move( 10, 55 ); - - perf_layout->addWidget( ui_fx_tw ); perf_layout->addSpacing( 15 ); perf_layout->addWidget( smp_supp_tw ); @@ -715,8 +683,6 @@ void setupDialog::accept( void ) QString::number( m_disableChActInd ) ); configManager::inst()->setValue( "ui", "manualchannelpiano", QString::number( m_manualChPiano ) ); - configManager::inst()->setValue( "mixer", "parallelizinglevel", - QString::number( m_parLevel ) ); configManager::inst()->setWorkingDir( m_workingDir ); configManager::inst()->setVSTDir( m_vstDir ); @@ -883,12 +849,6 @@ void setupDialog::toggleManualChPiano( bool _enabled ) -void setupDialog::setParallelizingLevel( int _level ) -{ - m_parLevel = _level; -} - - void setupDialog::openWorkingDir( void ) diff --git a/src/core/song_editor.cpp b/src/core/song_editor.cpp index 4b5561b2e7..5b359348e9 100644 --- a/src/core/song_editor.cpp +++ b/src/core/song_editor.cpp @@ -49,7 +49,6 @@ #include -#include "automatable_object_templates.h" #include "automatable_slider.h" #include "bb_editor.h" #include "bb_track.h" @@ -82,6 +81,10 @@ songEditor::songEditor( void ) : + m_automationTrack( track::create( track::AUTOMATION_TRACK, this ) ), + m_tempoModel( DEFAULT_BPM, MIN_BPM, MAX_BPM ), + m_masterVolumeModel( 100, 0, 200, 1 ), + m_masterPitchModel( 0, -12, 12, 1 ), m_fileName( "" ), m_oldFileName( "" ), m_exporting( FALSE ), @@ -111,23 +114,24 @@ songEditor::songEditor( void ) : connect( tl, SIGNAL( positionChanged( const midiTime & ) ), this, SLOT( updatePosition( const midiTime & ) ) ); - m_automation_track = track::create( track::AUTOMATION_TRACK, this ); // add some essential widgets to global tool-bar QWidget * tb = engine::getMainWindow()->toolBar(); engine::getMainWindow()->addSpacingToToolBar( 10 ); - m_bpmSpinBox = new lcdSpinBox( MIN_BPM, MAX_BPM, 3, tb, tr( "Tempo" ), - m_automation_track ); - m_bpmSpinBox->setLabel( tr( "TEMPO/BPM" ) ); - connect( m_bpmSpinBox, SIGNAL( valueChanged( int ) ), this, - SLOT( setTempo( int ) ) ); - connect( m_bpmSpinBox, SIGNAL( manualChange() ), this, - SLOT( setModified() ) ); - toolTip::add( m_bpmSpinBox, tr( "tempo of song" ) ); + m_tempoModel.setTrack( m_automationTrack ); + m_tempoSpinBox = new lcdSpinBox( 3, tb, tr( "Tempo" ) ); + m_tempoSpinBox->setModel( &m_tempoModel ); + m_tempoSpinBox->setLabel( tr( "TEMPO/BPM" ) ); + toolTip::add( m_tempoSpinBox, tr( "tempo of song" ) ); - m_bpmSpinBox->setWhatsThis( + connect( &m_tempoModel, SIGNAL( dataChanged() ), + this, SLOT( setTempo() ) ); + connect( m_tempoSpinBox, SIGNAL( manualChange() ), this, + SLOT( setModified() ) ); + + m_tempoSpinBox->setWhatsThis( tr( "The tempo of a song is specified in beats per minute " "(BPM). If you want to change the tempo of your " "song, change this value. Every tact has four beats, " @@ -135,7 +139,7 @@ songEditor::songEditor( void ) : "should be played within a minute (or how many tacts " "should be played within four minutes)." ) ); - int col = engine::getMainWindow()->addWidgetToToolBar( m_bpmSpinBox, + int col = engine::getMainWindow()->addWidgetToToolBar( m_tempoSpinBox, 0 ); @@ -169,12 +173,11 @@ songEditor::songEditor( void ) : QLabel * master_vol_lbl = new QLabel( tb ); master_vol_lbl->setPixmap( embed::getIconPixmap( "master_volume" ) ); - m_masterVolumeSlider = new automatableSlider( tb, tr( "Master volume" ), - m_automation_track ); + m_masterVolumeModel.setTrack( m_automationTrack ); + m_masterVolumeSlider = new automatableSlider( tb, tr( "Master volume" ) ); + m_masterVolumeSlider->setModel( &m_masterVolumeModel ); m_masterVolumeSlider->setOrientation( Qt::Vertical ); - m_masterVolumeSlider->setRange( 0, 200 ); m_masterVolumeSlider->setPageStep( 1 ); - m_masterVolumeSlider->setInitValue( 100 ); m_masterVolumeSlider->setTickPosition( QSlider::TicksLeft ); m_masterVolumeSlider->setFixedSize( 26, 60 ); m_masterVolumeSlider->setTickInterval( 50 ); @@ -199,16 +202,16 @@ songEditor::songEditor( void ) : engine::getMainWindow()->addSpacingToToolBar( 10 ); + QLabel * master_pitch_lbl = new QLabel( tb ); master_pitch_lbl->setPixmap( embed::getIconPixmap( "master_pitch" ) ); master_pitch_lbl->setFixedHeight( 64 ); - m_masterPitchSlider = new automatableSlider( tb, tr( "Master pitch" ), - m_automation_track ); + m_masterPitchModel.setTrack( m_automationTrack ); + m_masterPitchSlider = new automatableSlider( tb, tr( "Master pitch" ) ); + m_masterPitchSlider->setModel( &m_masterPitchModel ); m_masterPitchSlider->setOrientation( Qt::Vertical ); - m_masterPitchSlider->setRange( -12, 12 ); m_masterPitchSlider->setPageStep( 1 ); - m_masterPitchSlider->setInitValue( 0 ); m_masterPitchSlider->setTickPosition( QSlider::TicksLeft ); m_masterPitchSlider->setFixedSize( 26, 60 ); m_masterPitchSlider->setTickInterval( 12 ); @@ -330,17 +333,18 @@ songEditor::songEditor( void ) : zoom_lbl->setPixmap( embed::getIconPixmap( "zoom" ) ); // setup zooming-stuff - m_zoomingComboBox = new comboBox( m_toolBar, NULL, NULL ); + m_zoomingComboBox = new comboBox( m_toolBar ); m_zoomingComboBox->setFixedSize( 80, 22 ); m_zoomingComboBox->move( 580, 4 ); for( int i = 0; i < 7; ++i ) { - m_zoomingComboBox->addItem( QString::number( 25 << i ) + "%" ); + m_zoomingComboBox->model()->addItem( + QString::number( 25 << i ) + "%" ); } - m_zoomingComboBox->setInitValue( m_zoomingComboBox->findText( - "100%" ) ); - connect( m_zoomingComboBox, SIGNAL( activated( const QString & ) ), - this, SLOT( zoomingChanged( const QString & ) ) ); + m_zoomingComboBox->model()->setInitValue( + m_zoomingComboBox->model()->findText( "100%" ) ); + connect( m_zoomingComboBox->model(), SIGNAL( dataChanged() ), + this, SLOT( zoomingChanged( void ) ) ); tb_layout->addSpacing( 5 ); @@ -399,7 +403,7 @@ songEditor::songEditor( void ) : songEditor::~songEditor() { m_playing = FALSE; - delete m_automation_track; + delete m_automationTrack; } @@ -496,10 +500,12 @@ void songEditor::wheelEvent( QWheelEvent * _we ) setPixelsPerTact( (int) pixelsPerTact() / 2 ); } // update combobox with zooming-factor - m_zoomingComboBox->setValue( - m_zoomingComboBox->findText( QString::number( + m_zoomingComboBox->model()->setValue( + m_zoomingComboBox->model()->findText( + QString::number( static_cast( pixelsPerTact() * - 100 / DEFAULT_PIXELS_PER_TACT ) ) + "%" ) ); + 100 / DEFAULT_PIXELS_PER_TACT ) ) + + "%" ) ); // update timeline m_playPos[PLAY_SONG].m_timeLine->setPixelsPerTact( pixelsPerTact() ); @@ -549,7 +555,7 @@ void songEditor::masterVolumePressed( void ) QPoint( 0, 0 ) ) + QPoint( m_masterVolumeSlider->width() + 2, -2 ) ); m_mvsStatus->show(); - masterVolumeMoved( m_masterVolumeSlider->logicValue() ); + masterVolumeMoved( m_masterVolumeModel.value() ); } @@ -597,7 +603,7 @@ void songEditor::masterPitchPressed( void ) QPoint( 0, 0 ) ) + QPoint( m_masterPitchSlider->width() + 2, -2 ) ); m_mpsStatus->show(); - masterPitchMoved( m_masterPitchSlider->logicValue() ); + masterPitchMoved( m_masterPitchModel.value() ); } @@ -644,9 +650,10 @@ void songEditor::updatePosition( const midiTime & _t ) -void songEditor::zoomingChanged( const QString & _zfac ) +void songEditor::zoomingChanged( void ) { - setPixelsPerTact( _zfac.left( _zfac.length() - 1 ).toInt() * + const QString & zfac = m_zoomingComboBox->model()->currentText(); + setPixelsPerTact( zfac.left( zfac.length() - 1 ).toInt() * DEFAULT_PIXELS_PER_TACT / 100 ); m_playPos[PLAY_SONG].m_timeLine->setPixelsPerTact( pixelsPerTact() ); realignTracks(); @@ -655,8 +662,9 @@ void songEditor::zoomingChanged( const QString & _zfac ) -void songEditor::setTempo( int _new_bpm ) +void songEditor::setTempo( void ) { + const bpm_t tempo = m_tempoModel.value(); playHandleVector & phv = engine::getMixer()->playHandles(); for( playHandleVector::iterator it = phv.begin(); it != phv.end(); ++it ) @@ -664,37 +672,13 @@ void songEditor::setTempo( int _new_bpm ) notePlayHandle * nph = dynamic_cast( *it ); if( nph && !nph->released() ) { - nph->resize( _new_bpm ); + nph->resize( tempo ); } } - m_bpmSpinBox->setInitValue( _new_bpm ); +// m_bpmSpinBox->setInitValue( _new_bpm ); engine::updateFramesPerTact64th(); - emit tempoChanged( _new_bpm ); -} - - - - -void songEditor::setMasterVolume( volume _vol ) -{ - m_masterVolumeSlider->setInitValue( _vol ); -} - - - - -void songEditor::setMasterPitch( int _master_pitch ) -{ - m_masterPitchSlider->setInitValue( _master_pitch ); -} - - - - -int songEditor::masterPitch( void ) const -{ - return( m_masterPitchSlider->logicValue() ); + emit tempoChanged( tempo ); } @@ -985,7 +969,7 @@ void songEditor::processNextBuffer( void ) { if( m_playMode == PLAY_SONG ) { - m_automation_track->play( m_playPos[m_playMode], + m_automationTrack->play( m_playPos[m_playMode], played_frames, total_frames_played, tco_num ); } @@ -1236,7 +1220,7 @@ void songEditor::addSampleTrack( void ) bpm_t songEditor::getTempo( void ) { - return( m_bpmSpinBox->value() ); + return( m_tempoModel.value() ); } @@ -1244,7 +1228,7 @@ bpm_t songEditor::getTempo( void ) automationPattern * songEditor::tempoAutomationPattern( void ) { - return( m_bpmSpinBox->getAutomationPattern() ); + return( m_tempoModel.getAutomationPattern() ); } @@ -1263,9 +1247,9 @@ void songEditor::clearProject( void ) clearAllTracks(); engine::getAutomationEditor()->setCurrentPattern( NULL ); - m_bpmSpinBox->getAutomationPattern()->clear(); - m_masterVolumeSlider->clearAutomationValues(); - m_masterPitchSlider->clearAutomationValues(); + m_tempoModel.getAutomationPattern()->clear(); + m_masterVolumeModel.getAutomationPattern()->clear(); + m_masterPitchModel.getAutomationPattern()->clear(); engine::getBBEditor()->clearAllTracks(); engine::getMixer()->unlock(); @@ -1321,9 +1305,9 @@ void songEditor::createNewProject( void ) "tripleoscillator" ); track::create( track::BB_TRACK, this ); - m_bpmSpinBox->setInitValue( DEFAULT_BPM ); - m_masterVolumeSlider->setInitValue( 100 ); - m_masterPitchSlider->setInitValue( 0 ); + m_tempoModel.setInitValue( DEFAULT_BPM ); + m_masterVolumeModel.setInitValue( 100 ); + m_masterPitchModel.setInitValue( 0 ); engine::getProjectJournal()->setJournalling( TRUE ); @@ -1369,9 +1353,9 @@ void FASTCALL songEditor::loadProject( const QString & _file_name ) engine::getMainWindow()->resetWindowTitle(); // get the header information from the DOM - m_bpmSpinBox->loadSettings( mmp.head(), "bpm" ); - m_masterVolumeSlider->loadSettings( mmp.head(), "mastervol" ); - m_masterPitchSlider->loadSettings( mmp.head(), "masterpitch" ); + m_tempoModel.loadSettings( mmp.head(), "bpm" ); + m_masterVolumeModel.loadSettings( mmp.head(), "mastervol" ); + m_masterPitchModel.loadSettings( mmp.head(), "masterpitch" ); // reset loop-point-state m_playPos[PLAY_SONG].m_timeLine->toggleLoopPoints( 0 ); @@ -1432,9 +1416,9 @@ bool songEditor::saveProject( void ) { multimediaProject mmp( multimediaProject::SONG_PROJECT ); - m_bpmSpinBox->saveSettings( mmp, mmp.head(), "bpm" ); - m_masterVolumeSlider->saveSettings( mmp, mmp.head(), "mastervol" ); - m_masterPitchSlider->saveSettings( mmp, mmp.head(), "masterpitch" ); + m_tempoModel.saveSettings( mmp, mmp.head(), "bpm" ); + m_masterVolumeModel.saveSettings( mmp, mmp.head(), "mastervol" ); + m_masterPitchModel.saveSettings( mmp, mmp.head(), "masterpitch" ); ( (journallingObject *)( this ) )->saveState( mmp, mmp.content() ); diff --git a/src/core/surround_area.cpp b/src/core/surround_area.cpp index 2314821e3d..b44ae48c56 100644 --- a/src/core/surround_area.cpp +++ b/src/core/surround_area.cpp @@ -34,10 +34,9 @@ #include -#include "automatable_object_templates.h" +#include "automatable_model_templates.h" #include "caption_menu.h" #include "embed.h" -#include "knob.h" #include "templates.h" #include "tooltip.h" @@ -49,25 +48,11 @@ QPixmap * surroundArea::s_backgroundArtwork = NULL; -surroundArea::surroundArea( QWidget * _parent, const QString & _name, - track * _track ) : +surroundArea::surroundArea( QWidget * _parent, const QString & _name ) : QWidget( _parent ), - m_sndSrcPos( QPoint() ) + modelView() { - m_position_x = new knob( knobDark_28, NULL, tr ( "Surround area X" ), - _track ); - m_position_x->setRange( -SURROUND_AREA_SIZE, SURROUND_AREA_SIZE, 1.0f ); - m_position_x->setInitValue( 0.0f ); - - m_position_y = new knob( knobDark_28, NULL, tr ( "Surround area Y" ), - _track ); - m_position_y->setRange( -SURROUND_AREA_SIZE, SURROUND_AREA_SIZE, 1.0f ); - m_position_y->setInitValue( 0.0f ); - - connect( m_position_x, SIGNAL( valueChanged( float ) ), this, - SLOT( updatePositionX( void ) ) ); - connect( m_position_y, SIGNAL( valueChanged( float ) ), this, - SLOT( updatePositionY( void ) ) ); + setModel( new surroundAreaModel( NULL, NULL, TRUE ) ); if( s_backgroundArtwork == NULL ) { @@ -87,71 +72,11 @@ surroundArea::surroundArea( QWidget * _parent, const QString & _name, surroundArea::~surroundArea() { - delete m_position_x; - delete m_position_y; } -volumeVector surroundArea::getVolumeVector( float _v_scale ) const -{ - volumeVector v = { { _v_scale, _v_scale -#ifndef DISABLE_SURROUND - , _v_scale, _v_scale -#endif - } } ; - - if( m_sndSrcPos.x() >= 0 ) - { - v.vol[0] *= 1.0f - m_sndSrcPos.x() / (float)SURROUND_AREA_SIZE; -#ifndef DISABLE_SURROUND - v.vol[2] *= 1.0f - m_sndSrcPos.x() / (float)SURROUND_AREA_SIZE; -#endif - } - else - { - v.vol[1] *= 1.0f + m_sndSrcPos.x() / (float)SURROUND_AREA_SIZE; -#ifndef DISABLE_SURROUND - v.vol[3] *= 1.0f + m_sndSrcPos.x() / (float)SURROUND_AREA_SIZE; -#endif - } - - if( m_sndSrcPos.y() >= 0 ) - { - v.vol[0] *= 1.0f - m_sndSrcPos.y() / (float)SURROUND_AREA_SIZE; - v.vol[1] *= 1.0f - m_sndSrcPos.y() / (float)SURROUND_AREA_SIZE; - } -#ifndef DISABLE_SURROUND - else - { - v.vol[2] *= 1.0f + m_sndSrcPos.y() / (float)SURROUND_AREA_SIZE; - v.vol[3] *= 1.0f + m_sndSrcPos.y() / (float)SURROUND_AREA_SIZE; - } -#endif - - return( v ); -} - - - - -void surroundArea::setValue( const QPoint & _p ) -{ - if( tLimit( _p.x(), -SURROUND_AREA_SIZE, SURROUND_AREA_SIZE ) != - _p.x() || - tLimit( _p.y(), -SURROUND_AREA_SIZE, SURROUND_AREA_SIZE ) != _p.y() ) - { - m_sndSrcPos = QPoint( 0, 0 ); - } - else - { - m_sndSrcPos = _p; - } - update(); -} - - void surroundArea::contextMenuEvent( QContextMenuEvent * ) @@ -165,11 +90,11 @@ void surroundArea::contextMenuEvent( QContextMenuEvent * ) captionMenu contextMenu( accessibleName() ); contextMenu.addAction( embed::getIconPixmap( "automation" ), tr( "Open &X in automation editor" ), - m_position_x->getAutomationPattern(), + model()->automationPatternX(), SLOT( openInAutomationEditor() ) ); contextMenu.addAction( embed::getIconPixmap( "automation" ), tr( "Open &Y in automation editor" ), - m_position_y->getAutomationPattern(), + model()->automationPatternY(), SLOT( openInAutomationEditor() ) ); contextMenu.exec( QCursor::pos() ); } @@ -191,9 +116,9 @@ void surroundArea::paintEvent( QPaintEvent * ) Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) ); } - const int x = ( width() + m_sndSrcPos.x() * ( width() - 4 ) / + const int x = ( width() + model()->x() * ( width() - 4 ) / SURROUND_AREA_SIZE ) / 2; - const int y = ( height() + m_sndSrcPos.y() * ( height() - 4 ) / + const int y = ( height() + model()->y() * ( height() - 4 ) / SURROUND_AREA_SIZE ) / 2; p.setPen( QColor( 64, 255, 64 ) ); p.drawPoint( x, y - 1 ); @@ -213,15 +138,17 @@ void surroundArea::mousePressEvent( QMouseEvent * _me ) return; } + model()->prepareJournalEntryFromOldVal(); + const int w = width();//s_backgroundArtwork->width(); const int h = height();//s_backgroundArtwork->height(); if( _me->x() > 1 && _me->x() < w-1 && _me->y() > 1 && _me->y() < h-1 ) { - m_sndSrcPos.setX( ( _me->x() * 2 - w ) * SURROUND_AREA_SIZE / + model()->setX( ( _me->x() * 2 - w ) * SURROUND_AREA_SIZE / ( w - 4 ) ); - m_sndSrcPos.setY( ( _me->y() * 2 - h ) * SURROUND_AREA_SIZE / + model()->setY( ( _me->y() * 2 - h ) * SURROUND_AREA_SIZE / ( h - 4 ) ); - update(); + //update(); if( _me->button() != Qt::NoButton ) { QApplication::setOverrideCursor( Qt::BlankCursor ); @@ -233,11 +160,6 @@ void surroundArea::mousePressEvent( QMouseEvent * _me ) int y = tLimit( _me->y(), 2, h - 2 ); QCursor::setPos( mapToGlobal( QPoint( x, y ) ) ); } - - m_position_x->setValue( m_sndSrcPos.x() ); - m_position_y->setValue( m_sndSrcPos.y() ); - - emit valueChanged( m_sndSrcPos ); } @@ -253,62 +175,108 @@ void surroundArea::mouseMoveEvent( QMouseEvent * _me ) void surroundArea::mouseReleaseEvent( QMouseEvent * ) { + model()->addJournalEntryFromOldToCurVal(); QApplication::restoreOverrideCursor(); } -void surroundArea::updatePositionX( void ) + + + + +surroundAreaModel::surroundAreaModel( ::model * _parent, track * _track, + bool _default_constructed ) : + model( _parent, _default_constructed ), + m_posX( 0, -SURROUND_AREA_SIZE, SURROUND_AREA_SIZE, 1, _parent ), + m_posY( 0, -SURROUND_AREA_SIZE, SURROUND_AREA_SIZE, 1, _parent ) { - m_sndSrcPos.setX( (int)roundf( m_position_x->value() ) ); - update(); + m_posX.setTrack( _track ); + m_posY.setTrack( _track ); + connect( &m_posX, SIGNAL( dataChanged() ), + this, SIGNAL( dataChanged() ) ); + connect( &m_posY, SIGNAL( dataChanged() ), + this, SIGNAL( dataChanged() ) ); } -void surroundArea::updatePositionY( void ) +volumeVector surroundAreaModel::getVolumeVector( float _v_scale ) const { - m_sndSrcPos.setY( (int)roundf( m_position_y->value() ) ); - update(); + volumeVector v = { { _v_scale, _v_scale +#ifndef DISABLE_SURROUND + , _v_scale, _v_scale +#endif + } } ; + + if( x() >= 0 ) + { + v.vol[0] *= 1.0f - x() / (float)SURROUND_AREA_SIZE; +#ifndef DISABLE_SURROUND + v.vol[2] *= 1.0f - x() / (float)SURROUND_AREA_SIZE; +#endif + } + else + { + v.vol[1] *= 1.0f + x() / (float)SURROUND_AREA_SIZE; +#ifndef DISABLE_SURROUND + v.vol[3] *= 1.0f + x() / (float)SURROUND_AREA_SIZE; +#endif + } + + if( y() >= 0 ) + { + v.vol[0] *= 1.0f - y() / (float)SURROUND_AREA_SIZE; + v.vol[1] *= 1.0f - y() / (float)SURROUND_AREA_SIZE; + } +#ifndef DISABLE_SURROUND + else + { + v.vol[2] *= 1.0f + y() / (float)SURROUND_AREA_SIZE; + v.vol[3] *= 1.0f + y() / (float)SURROUND_AREA_SIZE; + } +#endif + + return( v ); } - -void FASTCALL surroundArea::saveSettings( QDomDocument & _doc, +void surroundAreaModel::saveSettings( QDomDocument & _doc, QDomElement & _this, const QString & _name ) { - m_position_x->saveSettings( _doc, _this, _name + "-x" ); - m_position_y->saveSettings( _doc, _this, _name + "-y" ); + m_posX.saveSettings( _doc, _this, _name + "-x" ); + m_posY.saveSettings( _doc, _this, _name + "-y" ); } -void FASTCALL surroundArea::loadSettings( const QDomElement & _this, +void surroundAreaModel::loadSettings( const QDomElement & _this, const QString & _name ) { if( _this.hasAttribute( _name ) ) { - int i = _this.attribute( _name ).toInt(); - setValue( QPoint( ( i & 0xFFFF ) - 2 * SURROUND_AREA_SIZE, - ( i >> 16 ) - 2 * SURROUND_AREA_SIZE) ); - m_position_x->setValue( m_sndSrcPos.x() ); - m_position_y->setValue( m_sndSrcPos.y() ); + const int i = _this.attribute( _name ).toInt(); + m_posX.setValue( ( i & 0xFFFF ) - 2 * SURROUND_AREA_SIZE ); + m_posY.setValue( ( i >> 16 ) - 2 * SURROUND_AREA_SIZE ); } else { - m_position_x->loadSettings( _this, _name + "-x" ); - m_position_y->loadSettings( _this, _name + "-y" ); + m_posX.loadSettings( _this, _name + "-x" ); + m_posY.loadSettings( _this, _name + "-y" ); } } + + + #include "surround_area.moc" diff --git a/src/core/track.cpp b/src/core/track.cpp index 0f8a19c78a..7d4d916167 100644 --- a/src/core/track.cpp +++ b/src/core/track.cpp @@ -966,8 +966,8 @@ trackOperationsWidget::trackOperationsWidget( trackWidget * _parent ) : toolTip::add( m_trackOps, tr( "Actions for this track" ) ); - m_muteBtn = new pixmapButton( this, tr( "Mute" ), - m_trackWidget->getTrack() ); + m_muteBtn = new pixmapButton( this, tr( "Mute" ) ); + m_muteBtn->model()->setTrack( m_trackWidget->getTrack() ); m_muteBtn->setActiveGraphic( *s_muteOnEnabled ); m_muteBtn->setInactiveGraphic( *s_muteOffEnabled ); m_muteBtn->setCheckable( TRUE ); @@ -1009,7 +1009,7 @@ trackOperationsWidget::~trackOperationsWidget() bool trackOperationsWidget::muted( void ) const { - return( m_muteBtn->isChecked() ); + return( m_muteBtn->model()->value() ); } diff --git a/src/core/track_container.cpp b/src/core/track_container.cpp index 6e8ca2ef45..e55177f8f1 100644 --- a/src/core/track_container.cpp +++ b/src/core/track_container.cpp @@ -36,6 +36,7 @@ #include +#include "automatable_model_templates.h" #include "bb_track.h" #include "config_mgr.h" #include "debug.h" @@ -87,7 +88,7 @@ trackContainer::~trackContainer() { while( !m_tracks.empty() ) { - delete m_tracks.takeFirst(); + delete m_tracks.takeLast(); } } @@ -281,7 +282,7 @@ void trackContainer::clearAllTracks( void ) { while( !m_tracks.empty() ) { - removeTrack( m_tracks.front() ); + removeTrack( m_tracks.last() ); } } diff --git a/src/tracks/instrument_track.cpp b/src/tracks/instrument_track.cpp index bc96368302..f9296a4c2e 100644 --- a/src/tracks/instrument_track.cpp +++ b/src/tracks/instrument_track.cpp @@ -44,6 +44,7 @@ #include "arp_and_chords_tab_widget.h" #include "audio_port.h" +#include "automatable_model_templates.h" #include "automation_pattern.h" #include "config_mgr.h" #include "debug.h" @@ -56,7 +57,6 @@ #include "fade_button.h" #include "gui_templates.h" #include "instrument.h" -#include "lcd_spinbox.h" #include "led_checkbox.h" #include "main_window.h" #include "midi_client.h" @@ -69,7 +69,6 @@ #include "sample_play_handle.h" #include "song_editor.h" #include "string_pair_drag.h" -#include "surround_area.h" #include "tab_widget.h" #include "tooltip.h" #include "volume_knob.h" @@ -103,12 +102,26 @@ instrumentTrack::instrumentTrack( trackContainer * _tc ) : tr( "unnamed_channel" ) ) ), m_audioPort( new audioPort( tr( "unnamed_channel" ) ) ), m_notes(), - m_baseTone( A ), - m_baseOctave( OCTAVE_4 ), + m_baseNoteModel( 0, 0, NOTES_PER_OCTAVE * OCTAVES - 1, 1/* this */ ), + m_volumeModel( DEFAULT_VOLUME, MIN_VOLUME, MAX_VOLUME, + 1.0f /* this */ ), + m_surroundAreaModel( NULL /* this */, this ), + m_effectChannelModel( DEFAULT_EFFECT_CHANNEL, + MIN_EFFECT_CHANNEL, MAX_EFFECT_CHANNEL + /* this */ ), m_instrument( NULL ), m_midiInputAction( NULL ), m_midiOutputAction( NULL ) { + m_baseNoteModel.setTrack( this ); + m_baseNoteModel.setInitValue( DEFAULT_OCTAVE * NOTES_PER_OCTAVE + A ); + connect( &m_baseNoteModel, SIGNAL( dataChanged() ), + this, SLOT( updateBaseNote() ) ); + + m_volumeModel.setTrack( this ); + m_effectChannelModel.setTrack( this ); + + for( int i = 0; i < NOTES; ++i ) { m_notes[i] = NULL; @@ -122,15 +135,12 @@ instrumentTrack::instrumentTrack( trackContainer * _tc ) : // creation of widgets for track-settings-widget m_tswVolumeKnob = new volumeKnob( knobSmall_17, getTrackSettingsWidget(), - tr( "Channel volume" ), this ); - m_tswVolumeKnob->setRange( MIN_VOLUME, MAX_VOLUME, 1.0f ); - m_tswVolumeKnob->setInitValue( DEFAULT_VOLUME ); + tr( "Channel volume" ) ); + m_tswVolumeKnob->setModel( &m_volumeModel ); m_tswVolumeKnob->setHintText( tr( "Channel volume:" ) + " ", "%" ); m_tswVolumeKnob->move( 4, 4 ); m_tswVolumeKnob->setLabel( tr( "VOL" ) ); m_tswVolumeKnob->show(); -/* connect( m_tswVolumeKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( volValueChanged( float ) ) );*/ m_tswVolumeKnob->setWhatsThis( tr( volume_help ) ); QPushButton * tsw_midi = new QPushButton( @@ -184,39 +194,28 @@ instrumentTrack::instrumentTrack( trackContainer * _tc ) : // setup volume-knob m_volumeKnob = new volumeKnob( knobBright_26, m_generalSettingsWidget, - tr( "Channel volume" ), this ); + tr( "Channel volume" ) ); + m_volumeKnob->setModel( &m_volumeModel ); m_volumeKnob->move( 10, 44 ); - m_volumeKnob->setRange( MIN_VOLUME, MAX_VOLUME, 1.0f ); - m_volumeKnob->setInitValue( DEFAULT_VOLUME ); m_volumeKnob->setHintText( tr( "Channel volume:" ) + " ", "%" ); m_volumeKnob->setLabel( tr( "VOLUME" ) ); m_volumeKnob->setWhatsThis( tr( volume_help ) ); -/* connect( m_volumeKnob, SIGNAL( valueChanged( float ) ), this, - SLOT( volValueChanged( float ) ) );*/ - volumeKnob::linkObjects( m_tswVolumeKnob, m_volumeKnob ); + //volumeKnob::linkObjects( m_tswVolumeKnob, m_volumeKnob ); // setup surround-area m_surroundArea = new surroundArea( m_generalSettingsWidget, - tr( "Surround area" ), this ); + tr( "Surround area" ) ); + m_surroundArea->setModel( &m_surroundAreaModel ); m_surroundArea->move( 20 + m_volumeKnob->width(), 38 ); m_surroundArea->show(); m_surroundArea->setWhatsThis( tr( surroundarea_help ) ); - connect( m_surroundArea, SIGNAL( valueChanged( const QPoint & ) ), - this, - SLOT( surroundAreaPosChanged( const QPoint & ) ) ); - - // setup spinbox for selecting FX-channel - m_effectChannelNumber = new lcdSpinBox( MIN_EFFECT_CHANNEL, - MAX_EFFECT_CHANNEL, 2, - m_generalSettingsWidget, - tr( "FX channel" ), - this ); - m_effectChannelNumber->setInitValue( DEFAULT_EFFECT_CHANNEL ); + m_effectChannelNumber = new lcdSpinBox( 2, m_generalSettingsWidget, + tr( "FX channel" ) ); m_effectChannelNumber->setLabel( tr( "FX CHNL" ) ); m_effectChannelNumber->move( m_surroundArea->x() + m_surroundArea->width() + 16, 40 ); @@ -238,8 +237,6 @@ instrumentTrack::instrumentTrack( trackContainer * _tc ) : "double-clicking it in the preset-browser." ) ); - setVolume( DEFAULT_VOLUME ); - setSurroundAreaPos( QPoint() ); setName( tr( "Default" ) ); @@ -416,9 +413,9 @@ void instrumentTrack::midiOutSelected( void ) void instrumentTrack::midiConfigChanged( bool ) { m_midiInputAction->setChecked( - m_midiWidget->m_receiveCheckBox->isChecked() ); + m_midiWidget->m_receiveCheckBox->model()->value() ); m_midiOutputAction->setChecked( - m_midiWidget->m_sendCheckBox->isChecked() ); + m_midiWidget->m_sendCheckBox->model()->value() ); } @@ -462,44 +459,12 @@ void instrumentTrack::processAudioBuffer( sampleFrame * _buf, { m_envWidget->processAudioBuffer( _buf, _frames, _n ); v_scale *= ( (float) _n->getVolume() / DEFAULT_VOLUME ); -/* const fpp_t ENV_FRAMES = 10; - if( _n->totalFramesPlayed() == 0 ) - { - // very basic envelope for not having clicks at the - // beginning - const fpp_t frames = tMin( _frames, - ENV_FRAMES ); - for( fpp_t i = 0; i < frames; ++i ) - { - for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; - ++ch ) - { - _buf[i][ch] *= (float) i / frames; - } - } - } - - // last time we're called for current note? - if( _n->willFinishThisPeriod() ) - { - // then do a soft fade-out at the end to avoid clicks - for( fpp_t i = ( _frames >= ENV_FRAMES ) ? - _frames - ENV_FRAMES : 0; - i < _frames; ++i ) - { - for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; - ++ch ) - { - _buf[i][ch] *= (float) ( _frames-i-1 ) / - ENV_FRAMES; - } - } - }*/ } - volumeVector v = m_surroundArea->getVolumeVector( v_scale ); + volumeVector v = m_surroundArea->model()->getVolumeVector( v_scale ); engine::getMixer()->bufferToPort( _buf, - ( _n != NULL ) ? tMin( _n->framesLeftForCurrentPeriod(), _frames ) : _frames, + ( _n != NULL ) ? tMin( _n->framesLeftForCurrentPeriod(), _frames ) : + _frames, ( _n != NULL ) ? _n->offset() : 0, v, m_audioPort ); } @@ -683,8 +648,6 @@ void instrumentTrack::playNote( notePlayHandle * _n, bool _try_parallelizing ) { processInEvent( midiEvent( NOTE_OFF, 0, _n->key(), 0 ), midiTime() ); - //printf("%d\n",( *youngest_note )->offset()+m_instrument->desiredTransitionFrames()); - //_n->noteOff( ( *youngest_note )->offset()+m_instrument->desiredTransitionFrames() ); if( ( *youngest_note )->offset() > _n->offset() ) { @@ -792,80 +755,22 @@ void instrumentTrack::setName( const QString & _new_name ) -void instrumentTrack::setVolume( volume _new_volume ) -{ - if( _new_volume <= MAX_VOLUME ) - { - m_volumeKnob->setValue( _new_volume ); - //m_tswVolumeKnob->setValue( _new_volume ); - } -} - - -volume instrumentTrack::getVolume( void ) const -{ - return( static_cast( m_volumeKnob->value() ) ); -} - - - - -void instrumentTrack::setSurroundAreaPos( const QPoint & _p ) -{ - if( m_surroundArea->value() != _p ) - { - m_surroundArea->setValue( _p ); - } -/* if( m_tswSurroundArea->value() != _p ) - { - m_tswSurroundArea->setValue( _p ); - }*/ -} - - - - -void instrumentTrack::setBaseNote( Uint32 _new_note, bool _modified ) +void instrumentTrack::updateBaseNote( /* bool _modified*/ void ) { engine::getMixer()->lock(); - setBaseTone( (tones)( _new_note % NOTES_PER_OCTAVE ) ); - setBaseOctave( (octaves)( _new_note / NOTES_PER_OCTAVE ) ); - for( QList::iterator it = m_processHandles.begin(); it != m_processHandles.end(); ++it ) { ( *it )->updateFrequency(); } engine::getMixer()->unlock(); - +/* if( _modified ) { engine::getSongEditor()->setModified(); - } -} - - - - -void instrumentTrack::setBaseTone( tones _new_tone ) -{ - if( _new_tone >= C && _new_tone <= H ) - { - m_baseTone = _new_tone; - } -} - - - - -void instrumentTrack::setBaseOctave( octaves _new_octave ) -{ - if( _new_octave >= MIN_OCTAVE && _new_octave <= MAX_OCTAVE ) - { - m_baseOctave = _new_octave; - } + }*/ } @@ -873,7 +778,7 @@ void instrumentTrack::setBaseOctave( octaves _new_octave ) int instrumentTrack::masterKey( notePlayHandle * _n ) const { - int key = baseTone() + baseOctave() * NOTES_PER_OCTAVE + + int key = m_baseNoteModel.value() + engine::getSongEditor()->masterPitch(); return( tLimit( _n->key() - ( key - A - DEFAULT_OCTAVE * NOTES_PER_OCTAVE ), 0, NOTES ) ); @@ -1047,12 +952,12 @@ void instrumentTrack::saveTrackSpecificSettings( QDomDocument & _doc, QDomElement & _this ) { _this.setAttribute( "name", name() ); - m_volumeKnob->saveSettings( _doc, _this, "vol" ); + m_volumeModel.saveSettings( _doc, _this, "vol" ); - m_surroundArea->saveSettings( _doc, _this, "surpos" ); + m_surroundAreaModel.saveSettings( _doc, _this, "surpos" ); - m_effectChannelNumber->saveSettings( _doc, _this, "fxch" ); - m_pianoWidget->saveSettings( _doc, _this, "basenote" ); + m_effectChannelModel.saveSettings( _doc, _this, "fxch" ); + m_baseNoteModel.saveSettings( _doc, _this, "basenote" ); _this.setAttribute( "tab", m_tabWidget->activeTab() ); mainWindow::saveWidgetState( this, _this ); @@ -1076,12 +981,24 @@ void instrumentTrack::loadTrackSpecificSettings( const QDomElement & _this ) engine::getMixer()->lock(); setName( _this.attribute( "name" ) ); - m_volumeKnob->loadSettings( _this, "vol" ); + m_volumeModel.loadSettings( _this, "vol" ); - m_surroundArea->loadSettings( _this, "surpos" ); + m_surroundAreaModel.loadSettings( _this, "surpos" ); + + m_effectChannelModel.loadSettings( _this, "fxch" ); + + if( _this.hasAttribute( "baseoct" ) ) + { + // TODO: move this compat code to mmp.cpp -> upgrade() + m_baseNoteModel.setInitValue( _this.attribute( "baseoct" ).toInt() + * NOTES_PER_OCTAVE + + _this.attribute( "basetone" ).toInt() ); + } + else + { + m_baseNoteModel.loadSettings( _this, "basenote" ); + } - m_effectChannelNumber->loadSettings( _this, "fxch" ); - m_pianoWidget->loadSettings( _this, "basenote" ); int tab = _this.attribute( "tab" ).toInt(); bool had_fx = FALSE; @@ -1169,23 +1086,6 @@ instrument * instrumentTrack::loadInstrument( const QString & _plugin_name ) -/*void instrumentTrack::volValueChanged( float _new_value ) -{ - setVolume( (volume) _new_value ); -}*/ - - - - -void instrumentTrack::surroundAreaPosChanged( const QPoint & _p ) -{ - setSurroundAreaPos( _p ); - engine::getSongEditor()->setModified(); -} - - - - void instrumentTrack::textChanged( const QString & _new_name ) { setName( _new_name ); diff --git a/src/tracks/sample_track.cpp b/src/tracks/sample_track.cpp index c138005b5e..41f2606e64 100644 --- a/src/tracks/sample_track.cpp +++ b/src/tracks/sample_track.cpp @@ -330,8 +330,11 @@ void sampleTCOSettingsDialog::setSampleFile( const QString & _f ) sampleTrack::sampleTrack( trackContainer * _tc ) : track( _tc ), - m_audioPort( new audioPort( tr( "Sample track" ) ) ) + m_audioPort( new audioPort( tr( "Sample track" ) ) ), + m_volumeModel( DEFAULT_VOLUME, MIN_VOLUME, MAX_VOLUME, 1/*, this*/ ) { + m_volumeModel.setTrack( this ); + getTrackWidget()->setFixedHeight( 32 ); m_trackLabel = new effectLabel( tr( "Sample track" ), @@ -345,9 +348,8 @@ sampleTrack::sampleTrack( trackContainer * _tc ) : m_trackLabel->show(); m_volumeKnob = new volumeKnob( knobSmall_17, getTrackSettingsWidget(), - tr( "Channel volume" ), this ); - m_volumeKnob->setRange( MIN_VOLUME, MAX_VOLUME, 1.0f ); - m_volumeKnob->setInitValue( DEFAULT_VOLUME ); + tr( "Channel volume" ) ); + m_volumeKnob->setModel( &m_volumeModel ); m_volumeKnob->setHintText( tr( "Channel volume:" ) + " ", "%" ); m_volumeKnob->move( 4, 4 ); m_volumeKnob->setLabel( tr( "VOL" ) ); @@ -405,11 +407,9 @@ bool FASTCALL sampleTrack::play( const midiTime & _start, if( !st->muted() ) { samplePlayHandle * handle = new samplePlayHandle( st ); - connect( m_volumeKnob, SIGNAL( valueChanged( float ) ), - handle, SLOT( setVolume( float ) ) ); - handle->setVolume( m_volumeKnob->value() ); -//TODO: do we need sample tracks in BB editor? -// handle->setBBTrack( bb_track ); + handle->setVolumeModel( &m_volumeModel ); +//TODO: check whether this works +// handle->setBBTrack( _tco_num ); handle->setOffset( _offset ); // send it to the mixer engine::getMixer()->addPlayHandle( handle ); @@ -440,7 +440,7 @@ void sampleTrack::saveTrackSpecificSettings( QDomDocument & _doc, #if 0 _this.setAttribute( "icon", m_trackLabel->pixmapFile() ); #endif - m_volumeKnob->saveSettings( _doc, _this, "vol" ); + m_volumeModel.saveSettings( _doc, _this, "vol" ); } @@ -467,7 +467,7 @@ void sampleTrack::loadTrackSpecificSettings( const QDomElement & _this ) m_trackLabel->setPixmapFile( _this.attribute( "icon" ) ); } #endif - m_volumeKnob->loadSettings( _this, "vol" ); + m_volumeModel.loadSettings( _this, "vol" ); } diff --git a/src/widgets/automatable_button.cpp b/src/widgets/automatable_button.cpp index a8181ae511..98c77816cb 100644 --- a/src/widgets/automatable_button.cpp +++ b/src/widgets/automatable_button.cpp @@ -31,24 +31,20 @@ #include #include -#include "automatable_object_templates.h" +#include "automatable_model_templates.h" #include "caption_menu.h" #include "embed.h" -automatableButton::automatableButton( QWidget * _parent, const QString & _name, - track * _track ) : +automatableButton::automatableButton( QWidget * _parent, + const QString & _name ) : QPushButton( _parent ), - autoObj( _track, FALSE, FALSE, TRUE ), + autoModelView(), m_group( NULL ) { - if( _track != NULL ) - { - getAutomationPattern(); - } - setInitValue( FALSE ); + setModel( new autoModel( FALSE, FALSE, TRUE, 1, NULL, TRUE ) ); setAccessibleName( _name ); } @@ -66,9 +62,22 @@ automatableButton::~automatableButton() +void automatableButton::update( void ) +{ + if( QPushButton::isChecked() != model()->value() ) + { + QPushButton::setChecked( model()->value() ); + } + QPushButton::update(); +} + + + + void automatableButton::contextMenuEvent( QContextMenuEvent * _me ) { - if( nullTrack() && ( m_group == NULL || m_group->nullTrack() ) ) + if( model()->nullTrack() && + ( m_group == NULL || m_group->model()->nullTrack() ) ) { QPushButton::contextMenuEvent( _me ); return; @@ -85,12 +94,12 @@ void automatableButton::contextMenuEvent( QContextMenuEvent * _me ) if ( m_group != NULL ) { target = m_group; - pattern = m_group->getAutomationPattern(); + pattern = m_group->model()->getAutomationPattern(); } else { target = this; - pattern = getAutomationPattern(); + pattern = model()->getAutomationPattern(); } captionMenu contextMenu( target->accessibleName() ); @@ -135,30 +144,14 @@ void automatableButton::toggle( void ) { if( isCheckable() && m_group != NULL ) { - if( value() == FALSE ) + if( model()->value() == FALSE ) { m_group->activateButton( this ); } } else { - setValue( !value() ); - update(); - } -} - - - - -void automatableButton::setValue( const bool _on ) -{ - if( _on != value() ) - { - autoObj::setValue( _on ); - setFirstValue(); - QPushButton::setChecked( _on ); - update(); - emit( toggled( value() ) ); + model()->setValue( !model()->value() ); } } @@ -170,17 +163,12 @@ void automatableButton::setValue( const bool _on ) automatableButtonGroup::automatableButtonGroup( QWidget * _parent, - const QString & _name, - track * _track ) : + const QString & _name ) : QWidget( _parent ), - automatableObject( _track ) + autoModelView() { + setModel( new autoModel( 0, 0, 0, 1, NULL, TRUE ) ); hide(); - if( _track != NULL ) - { - getAutomationPattern(); - } - setInitValue( 0 ); setAccessibleName( _name ); } @@ -202,13 +190,14 @@ void automatableButtonGroup::addButton( automatableButton * _btn ) { _btn->m_group = this; _btn->setCheckable( TRUE ); - _btn->setChecked( FALSE ); - // disable step-recording as we're recording changes of states of + _btn->model()->setValue( FALSE ); + // disable journalling as we're recording changes of states of // button-group members on our own - _btn->setJournalling( FALSE ); + _btn->model()->setJournalling( FALSE ); m_buttons.push_back( _btn ); - setRange( 0, m_buttons.size() - 1 ); + model()->setRange( 0, m_buttons.size() - 1 ); + updateButtons(); } @@ -219,7 +208,7 @@ void automatableButtonGroup::removeButton( automatableButton * _btn ) m_buttons.erase( qFind( m_buttons.begin(), m_buttons.end(), _btn ) ); _btn->m_group = NULL; - setRange( 0, m_buttons.size() - 1 ); + model()->setRange( 0, m_buttons.size() - 1 ); } @@ -227,30 +216,34 @@ void automatableButtonGroup::removeButton( automatableButton * _btn ) void automatableButtonGroup::activateButton( automatableButton * _btn ) { - if( _btn != m_buttons[value()] && m_buttons.indexOf( _btn ) != -1 ) + if( _btn != m_buttons[model()->value()] && + m_buttons.indexOf( _btn ) != -1 ) { - setValue( m_buttons.indexOf( _btn ) ); + model()->setValue( m_buttons.indexOf( _btn ) ); } } -void automatableButtonGroup::setValue( const int _value ) +void automatableButtonGroup::modelChanged( void ) { - if( m_buttons.empty() == FALSE ) - { - // range not updated yet? - if( value() == fittedValue( value() ) ) - { - m_buttons[value()]->setChecked( FALSE ); - } - automatableObject::setValue( _value ); - setFirstValue(); - m_buttons[value()]->setChecked( TRUE ); - } + connect( model(), SIGNAL( dataChanged() ), + this, SLOT( updateButtons() ) ); + autoModelView::modelChanged(); +} - emit valueChanged( value() ); + + + +void automatableButtonGroup::updateButtons( void ) +{ + int i = 0; + foreach( automatableButton * btn, m_buttons ) + { + btn->setValue( i == value() ); + ++i; + } } diff --git a/src/widgets/automatable_slider.cpp b/src/widgets/automatable_slider.cpp index 660b9ee6d3..e17bcb0721 100644 --- a/src/widgets/automatable_slider.cpp +++ b/src/widgets/automatable_slider.cpp @@ -4,6 +4,7 @@ * automatable_slider.cpp - implementation of class automatableSlider * * Copyright (c) 2006-2007 Javier Serrano Polo + * Copyright (c) 2007 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -30,7 +31,7 @@ #include #include -#include "automatable_object_templates.h" +#include "automatable_model_templates.h" #include "caption_menu.h" #include "embed.h" #include "knob.h" @@ -38,21 +39,18 @@ -automatableSlider::automatableSlider( QWidget * _parent, const QString & _name, - class track * _track ) : +automatableSlider::automatableSlider( QWidget * _parent, const QString & _name ) : QSlider( _parent ), - m_show_status( FALSE ) + autoModelView(), + m_showStatus( FALSE ) { - m_knob = new knob( knobDark_28, NULL, _name, _track ); - + setModel( new autoModel( 0, 0, 0, 1, NULL, TRUE ) ); setAccessibleName( _name ); - connect( m_knob, SIGNAL( valueChanged( float ) ), this, - SLOT( updateSlider( void ) ) ); - connect( this, SIGNAL( valueChanged( int ) ), this, - SLOT( changeValue( int ) ) ); - connect( this, SIGNAL( sliderMoved( int ) ), this, - SLOT( moveSlider( int ) ) ); + connect( this, SIGNAL( valueChanged( int ) ), + this, SLOT( changeValue( int ) ) ); + connect( this, SIGNAL( sliderMoved( int ) ), + this, SLOT( moveSlider( int ) ) ); } @@ -60,34 +58,6 @@ automatableSlider::automatableSlider( QWidget * _parent, const QString & _name, automatableSlider::~automatableSlider() { - delete m_knob; -} - - - - -void automatableSlider::setRange( int _min, int _max ) -{ - QSlider::setRange( _min, _max ); - m_knob->setRange( _min, _max, 1.0f ); -} - - - - -void automatableSlider::setValue( int _value ) -{ - QSlider::setValue( _value ); - m_knob->setValue( _value ); -} - - - - -void automatableSlider::setInitValue( int _value ) -{ - m_knob->setInitValue( _value ); - QSlider::setValue( _value ); } @@ -98,7 +68,7 @@ void automatableSlider::contextMenuEvent( QContextMenuEvent * _me ) captionMenu contextMenu( accessibleName() ); contextMenu.addAction( embed::getIconPixmap( "automation" ), tr( "&Open in automation editor" ), - m_knob->getAutomationPattern(), + model()->getAutomationPattern(), SLOT( openInAutomationEditor() ) ); contextMenu.exec( QCursor::pos() ); } @@ -108,7 +78,7 @@ void automatableSlider::contextMenuEvent( QContextMenuEvent * _me ) void automatableSlider::mousePressEvent( QMouseEvent * _me ) { - m_show_status = TRUE; + m_showStatus = TRUE; QSlider::mousePressEvent( _me ); } @@ -117,7 +87,7 @@ void automatableSlider::mousePressEvent( QMouseEvent * _me ) void automatableSlider::mouseReleaseEvent( QMouseEvent * _me ) { - m_show_status = FALSE; + m_showStatus = FALSE; QSlider::mouseReleaseEvent( _me ); } @@ -126,10 +96,21 @@ void automatableSlider::mouseReleaseEvent( QMouseEvent * _me ) void automatableSlider::wheelEvent( QWheelEvent * _me ) { - bool old_status = m_show_status; - m_show_status = TRUE; + bool old_status = m_showStatus; + m_showStatus = TRUE; QSlider::wheelEvent( _me ); - m_show_status = old_status; + m_showStatus = old_status; +} + + + + +void automatableSlider::modelChanged( void ) +{ + QSlider::setRange( model()->minValue(), model()->maxValue() ); + updateSlider(); + connect( model(), SIGNAL( dataChanged() ), + this, SLOT( updateSlider() ) ); } @@ -137,8 +118,8 @@ void automatableSlider::wheelEvent( QWheelEvent * _me ) void automatableSlider::changeValue( int _value ) { - setValue( _value ); - emit logicValueChanged( logicValue() ); + model()->setValue( _value ); + emit logicValueChanged( model()->value() ); } @@ -146,8 +127,8 @@ void automatableSlider::changeValue( int _value ) void automatableSlider::moveSlider( int _value ) { - setValue( _value ); - emit logicSliderMoved( logicValue() ); + model()->setValue( _value ); + emit logicSliderMoved( model()->value() ); } @@ -155,41 +136,7 @@ void automatableSlider::moveSlider( int _value ) void automatableSlider::updateSlider( void ) { - QSlider::setValue( logicValue() ); -} - - - - -void automatableSlider::saveSettings( QDomDocument & _doc, QDomElement & _this, - const QString & _name ) -{ - m_knob->saveSettings( _doc, _this, _name ); -} - - - - -void automatableSlider::loadSettings( const QDomElement & _this, - const QString & _name ) -{ - m_knob->loadSettings( _this, _name ); -} - - - - -int automatableSlider::logicValue( void ) -{ - return( (int)roundf( m_knob->value() ) ); -} - - - - -void automatableSlider::clearAutomationValues( void ) -{ - m_knob->getAutomationPattern()->clear(); + QSlider::setValue( model()->value() ); } diff --git a/src/widgets/combobox.cpp b/src/widgets/combobox.cpp index edfb51ffda..3400d36410 100644 --- a/src/widgets/combobox.cpp +++ b/src/widgets/combobox.cpp @@ -34,7 +34,6 @@ #include #include -#include "automatable_object_templates.h" #include "caption_menu.h" #include "embed.h" #include "gui_templates.h" @@ -46,12 +45,13 @@ QPixmap * comboBox::s_arrow = NULL; const int CB_ARROW_BTN_WIDTH = 20; -comboBox::comboBox( QWidget * _parent, const QString & _name, track * _track ) : +comboBox::comboBox( QWidget * _parent, const QString & _name ) : QWidget( _parent ), - automatableObject( _track ), + autoModelView(), m_menu( this ), m_pressed( FALSE ) { + setModel( new comboBoxModel ); if( s_background == NULL ) { s_background = new QPixmap( embed::getIconPixmap( @@ -70,11 +70,6 @@ comboBox::comboBox( QWidget * _parent, const QString & _name, track * _track ) : connect( &m_menu, SIGNAL( triggered( QAction * ) ), this, SLOT( setItem( QAction * ) ) ); - if( _track != NULL ) - { - getAutomationPattern(); - } - setInitValue( 0 ); setAccessibleName( _name ); } @@ -88,59 +83,9 @@ comboBox::~comboBox() -void comboBox::addItem( const QString & _item, const QPixmap & _pixmap ) -{ - QPixmap pm = _pixmap; - if( pm.height() > 16 ) - { - pm = pm.scaledToHeight( 16, Qt::SmoothTransformation ); - } - m_items.push_back( qMakePair( _item, pm ) ); - m_menu.clear(); - for( QVector::iterator it = m_items.begin(); - it != m_items.end(); ++it ) - { - m_menu.addAction( ( *it ).second, ( *it ).first ); - } - setRange( 0, m_items.size() - 1 ); -} - - - - -int comboBox::findText( const QString & _txt ) const -{ - for( QVector::const_iterator it = m_items.begin(); - it != m_items.end(); ++it ) - { - if( ( *it ).first == _txt ) - { - return( it - m_items.begin() ); - } - } - return( -1 ); -} - - - - -void comboBox::setValue( const int _idx ) -{ - automatableObject::setValue( _idx ); -/* m_value = tLimit( _idx, 0, ( m_items.size() > 0 ) ? - m_items.size() - 1 : 0 );*/ - emit( valueChanged( value() ) ); - emit( activated( ( m_items.size() > 0 ) ? - m_items[value()].first : "" ) ); - update(); -} - - - - void comboBox::contextMenuEvent( QContextMenuEvent * _me ) { - if( nullTrack() || _me->x() <= width() - CB_ARROW_BTN_WIDTH ) + if( model()->nullTrack() || _me->x() <= width() - CB_ARROW_BTN_WIDTH ) { QWidget::contextMenuEvent( _me ); return; @@ -149,7 +94,7 @@ void comboBox::contextMenuEvent( QContextMenuEvent * _me ) captionMenu contextMenu( accessibleName() ); contextMenu.addAction( embed::getIconPixmap( "automation" ), tr( "&Open in automation editor" ), - getAutomationPattern(), + model()->getAutomationPattern(), SLOT( openInAutomationEditor() ) ); contextMenu.exec( QCursor::pos() ); } @@ -169,6 +114,15 @@ void comboBox::mousePressEvent( QMouseEvent * _me ) m_pressed = TRUE; update(); + m_menu.clear(); + for( int i = 0; i < model()->size(); ++i ) + { + m_menu.addAction( model()->itemPixmap( i ) ? + *model()->itemPixmap( i ) : + QPixmap(), + model()->itemText( i ) ); + } + QPoint gpos = mapToGlobal( QPoint( 0, height() ) ); if( gpos.y() + m_menu.sizeHint().height() < qApp->desktop()->height() ) @@ -184,11 +138,11 @@ void comboBox::mousePressEvent( QMouseEvent * _me ) } else if( _me->button() == Qt::LeftButton ) { - setInitValue( value() + 1 ); + model()->setInitValue( model()->value() + 1 ); } else if( _me->button() == Qt::RightButton ) { - setInitValue( value() - 1 ); + model()->setInitValue( model()->value() - 1 ); } } @@ -230,24 +184,30 @@ void comboBox::paintEvent( QPaintEvent * _pe ) p.drawPixmap( width() - CB_ARROW_BTN_WIDTH + 4 + dxy, 4 + dxy, *s_arrow ); - if( m_items.size() > 0 ) + if( model()->size() > 0 ) { p.setFont( font() ); p.setClipRect( QRect( 5, 2, width() - CB_ARROW_BTN_WIDTH - 8, height() - 2 ) ); - const QPixmap & item_pm = m_items[value()].second; + const QPixmap * item_pm = model()->currentData(); int tx = 4; - if( item_pm.isNull() == FALSE ) + if( item_pm != NULL ) { - p.drawPixmap( tx, 3, item_pm ); - tx += item_pm.width() + 2; + QPixmap pm = *item_pm; + if( pm.height() > 16 ) + { + pm = pm.scaledToHeight( 16, + Qt::SmoothTransformation ); + } + p.drawPixmap( tx, 3, pm ); + tx += pm.width() + 2; } p.setPen( QColor( 64, 64, 64 ) ); p.drawText( tx+1, p.fontMetrics().height()-1, - m_items[value()].first ); + model()->currentText() ); p.setPen( QColor( 224, 224, 224 ) ); p.drawText( tx, p.fontMetrics().height()-2, - m_items[value()].first ); + model()->currentText() ); } } @@ -256,15 +216,69 @@ void comboBox::paintEvent( QPaintEvent * _pe ) void comboBox::wheelEvent( QWheelEvent * _we ) { - setInitValue( value() + ( ( _we->delta() < 0 ) ? 1 : -1 ) ); + model()->setInitValue( model()->value() + + ( ( _we->delta() < 0 ) ? 1 : -1 ) ); _we->accept(); } + +void comboBox::deletePixmap( QPixmap * _pixmap ) +{ + delete _pixmap; +} + + + + void comboBox::setItem( QAction * _item ) { - setInitValue( findText( _item->text() ) ); + model()->setInitValue( model()->findText( _item->text() ) ); +} + + + + + + + + + +void comboBoxModel::addItem( const QString & _item, QPixmap * _pixmap ) +{ + m_items.push_back( qMakePair( _item, _pixmap ) ); + setRange( 0, m_items.size() - 1 ); +} + + + + +void comboBoxModel::clear( void ) +{ + setRange( 0, 0 ); + foreach( const item & _i, m_items ) + { + emit itemPixmapRemoved( _i.second ); + } + m_items.clear(); + emit propertiesChanged(); +} + + + + +int comboBoxModel::findText( const QString & _txt ) const +{ + for( QVector::const_iterator it = m_items.begin(); + it != m_items.end(); ++it ) + { + if( ( *it ).first == _txt ) + { + return( it - m_items.begin() ); + } + } + return( -1 ); } diff --git a/src/widgets/group_box.cpp b/src/widgets/group_box.cpp index fbec802676..472849d1bd 100644 --- a/src/widgets/group_box.cpp +++ b/src/widgets/group_box.cpp @@ -47,15 +47,13 @@ QPixmap * groupBox::s_ledBg = NULL; -groupBox::groupBox( const QString & _caption, QWidget * _parent, - track * _track ) : +groupBox::groupBox( const QString & _caption, QWidget * _parent ) : QWidget( _parent ), + autoModelView(), m_caption( _caption ), m_origHeight( height() ), m_animating( FALSE ) { - setAutoFillBackground( TRUE ); - if( s_ledBg == NULL ) { s_ledBg = new QPixmap( embed::getIconPixmap( @@ -64,13 +62,15 @@ groupBox::groupBox( const QString & _caption, QWidget * _parent, updatePixmap(); - m_led = new pixmapButton( this, _caption, _track ); + m_led = new pixmapButton( this, _caption ); m_led->setCheckable( TRUE ); m_led->move( 2, 3 ); m_led->setActiveGraphic( embed::getIconPixmap( "led_green" ) ); m_led->setInactiveGraphic( embed::getIconPixmap( "led_off" ) ); - connect( m_led, SIGNAL( toggled( bool ) ), - this, SLOT( setState( bool ) ) ); + + setModel( new autoModel( FALSE, FALSE, TRUE, 1, NULL, FALSE ) ); + setAutoFillBackground( TRUE ); + } @@ -83,6 +83,13 @@ groupBox::~groupBox() +void groupBox::modelChanged( void ) +{ + m_led->setModel( model(), FALSE ); +} + + + void groupBox::resizeEvent( QResizeEvent * ) { updatePixmap(); @@ -99,25 +106,25 @@ void groupBox::mousePressEvent( QMouseEvent * _me ) { if( _me->y() > 1 && _me->y() < 13 ) { - setState( !isActive(), TRUE ); + //setState( !isActive(), TRUE ); + if( ( model()->value() == TRUE && height() < m_origHeight ) && + m_animating == FALSE ) + { + m_animating = TRUE; + animate(); + } } } - +/* void groupBox::setState( bool _on, bool _anim ) { m_led->setChecked( _on ); - if( ( _anim == TRUE || ( _on == TRUE && height() < m_origHeight ) ) && - m_animating == FALSE ) - { - m_animating = TRUE; - animate(); - } emit( toggled( _on ) ); } - +*/ @@ -126,10 +133,10 @@ void groupBox::animate( void ) float state = (float)( m_origHeight - height() ) / (float)( m_origHeight - 19 ); int dy = static_cast( 3 - 2 * cosf( state * 2 * M_PI ) ); - if( isActive() && height() < m_origHeight ) + if( model()->value() && height() < m_origHeight ) { } - else if( !isActive() && height() > 19 ) + else if( !model()->value() && height() > 19 ) { dy = -dy; } @@ -219,23 +226,6 @@ void groupBox::updatePixmap( void ) -void groupBox::saveSettings( QDomDocument & _doc, QDomElement & _this, - const QString & _name ) -{ - m_led->saveSettings( _doc, _this, _name ); -} - - - - -void groupBox::loadSettings( const QDomElement & _this, const QString & _name ) -{ - m_led->loadSettings( _this, _name ); -} - - - - #include "group_box.moc" diff --git a/src/widgets/knob.cpp b/src/widgets/knob.cpp index 1f319690f7..88b6046a1a 100644 --- a/src/widgets/knob.cpp +++ b/src/widgets/knob.cpp @@ -44,7 +44,7 @@ #endif #include -#include "automatable_object_templates.h" +#include "automatable_model_templates.h" #include "caption_menu.h" #include "config_mgr.h" #include "embed.h" @@ -63,19 +63,18 @@ textFloat * knob::s_textFloat = NULL; -knob::knob( int _knob_num, QWidget * _parent, const QString & _name, - track * _track ) : +knob::knob( int _knob_num, QWidget * _parent, const QString & _name ) : QWidget( _parent ), - autoObj( _track ), + autoModelView(), m_mouseOffset( 0.0f ), m_buttonPressed( FALSE ), m_hintTextBeforeValue( "" ), m_hintTextAfterValue( "" ), - m_initValue( 0.0f ), - m_angle( 0.0f ), m_knobNum( _knob_num ), m_label( "" ) { + setModel( new autoModel( 0, 0, 0, 1, NULL, TRUE ) ); + if( s_textFloat == NULL ) { s_textFloat = new textFloat( this ); @@ -87,31 +86,18 @@ knob::knob( int _knob_num, QWidget * _parent, const QString & _name, m_knobPixmap = new QPixmap( embed::getIconPixmap( QString( "knob0" + QString::number( m_knobNum + 1 ) ).toAscii().constData() ) ); - if( _track != NULL ) - { - getAutomationPattern(); - } - - setRange( 0.0f, 100.0f, 1.0f ); + //setRange( 0.0f, 100.0f, 1.0f ); setFixedSize( m_knobPixmap->width(), m_knobPixmap->height() ); setTotalAngle( 270.0f ); - recalcAngle(); } -// Destructor knob::~knob() { delete m_knobPixmap; -/* // make sure pointer to this knob isn't used anymore in active - // midi-device-class - if( engine::getMixer()->getMIDIClient()->pitchBendKnob() == this ) - { - engine::getMixer()->getMIDIClient()->setPitchBendKnob( NULL ); - }*/ } @@ -151,7 +137,7 @@ void knob::setTotalAngle( float _angle ) m_totalAngle = _angle; } - layoutKnob(); + update(); } @@ -159,11 +145,21 @@ void knob::setTotalAngle( float _angle ) void knob::drawKnob( QPainter * _p ) { + float angle = 0.0f; + if( model()->maxValue() != model()->minValue() ) + { + angle = ( model()->value() - 0.5 * ( model()->minValue() + + model()->maxValue() ) ) / + ( model()->maxValue() - model()->minValue() ) * + m_totalAngle; + angle = static_cast( angle ) % 360; + } + const float radius = m_knobPixmap->width() / 2.0f - 1; const float xm = m_knobPixmap->width() / 2.0f;//radius + 1; const float ym = m_knobPixmap->height() / 2.0f;//radius+1; - const float rarc = m_angle * M_PI / 180.0; + const float rarc = angle * M_PI / 180.0; const float ca = cos( rarc ); const float sa = -sin( rarc ); @@ -214,17 +210,6 @@ void knob::drawKnob( QPainter * _p ) -void knob::valueChange( void ) -{ - recalcAngle(); - update(); - emit valueChanged( value() ); - emit valueChanged(); -} - - - - float knob::getValue( const QPoint & _p ) { if( configManager::inst()->value( "knobs", "classicalusability" @@ -237,13 +222,16 @@ float knob::getValue( const QPoint & _p ) const float arc = atan2( -dx, dy ) * 180.0 / M_PI; - float new_value = 0.5 * ( minValue() + maxValue() ) + - arc * ( maxValue() - minValue() ) / + float new_value = 0.5 * ( model()->minValue() + + model()->maxValue() ) + + arc * ( model()->maxValue() - + model()->minValue() ) / m_totalAngle; - const float oneTurn = tAbs( maxValue() - minValue() ) * + const float oneTurn = tAbs( model()->maxValue() - + model()->minValue() ) * 360.0 / m_totalAngle; - const float eqValue = value() + m_mouseOffset; + const float eqValue = model()->value() + m_mouseOffset; if( tAbs( new_value - eqValue ) > 0.5 * oneTurn ) { @@ -260,52 +248,9 @@ float knob::getValue( const QPoint & _p ) } if( engine::getMainWindow()->isShiftPressed() ) { - return( ( _p.y() - m_origMousePos.y() ) * step() ); - } - return( ( _p.y() - m_origMousePos.y() ) * m_pageSize ); -} - - - - -void knob::rangeChange() -{ - layoutKnob(); - recalcAngle(); -} - - - - -// Recalculate the slider's geometry and layout based on -// the current rect and fonts. -void knob::layoutKnob( bool _update_geometry ) -{ - if( _update_geometry ) - { - updateGeometry(); - update(); - } -} - - - - -void knob::recalcAngle( void ) -{ - // - // calculate the angle corresponding to the value - // - if( maxValue() == minValue() ) - { - m_angle = 0; - } - else - { - m_angle = ( value() - 0.5 * ( minValue() + maxValue() ) ) / - ( maxValue() - minValue() ) * m_totalAngle; - m_angle = static_cast( m_angle ) % 360; + return( ( _p.y() - m_origMousePos.y() ) * model()->step() ); } + return( ( _p.y() - m_origMousePos.y() ) * pageSize() ); } @@ -321,13 +266,15 @@ void knob::contextMenuEvent( QContextMenuEvent * ) captionMenu contextMenu( accessibleName() ); contextMenu.addAction( embed::getIconPixmap( "reload" ), - tr( "&Reset (%1%2)" ).arg( m_initValue ).arg( - m_hintTextAfterValue ), + tr( "&Reset (%1%2)" ). + arg( model()->initValue() ). + arg( m_hintTextAfterValue ), this, SLOT( reset() ) ); contextMenu.addSeparator(); contextMenu.addAction( embed::getIconPixmap( "edit_copy" ), - tr( "&Copy value (%1%2)" ).arg( value() ).arg( - m_hintTextAfterValue ), + tr( "&Copy value (%1%2)" ). + arg( model()->value() ). + arg( m_hintTextAfterValue ), this, SLOT( copyValue() ) ); contextMenu.addAction( embed::getIconPixmap( "edit_paste" ), tr( "&Paste value (%1%2)" @@ -335,16 +282,16 @@ void knob::contextMenuEvent( QContextMenuEvent * ) m_hintTextAfterValue ), this, SLOT( pasteValue() ) ); contextMenu.addSeparator(); - if( !nullTrack() ) + if( !model()->nullTrack() ) { contextMenu.addAction( embed::getIconPixmap( "automation" ), tr( "&Open in automation editor" ), - getAutomationPattern(), + model()->getAutomationPattern(), SLOT( openInAutomationEditor() ) ); contextMenu.addSeparator(); } - contextMenu.addAction( tr( "Connect to MIDI-device" ), this, - SLOT( connectToMidiDevice() ) ); +/* contextMenu.addAction( tr( "Connect to MIDI-device" ), this, + SLOT( connectToMidiDevice() ) );*/ contextMenu.addSeparator(); contextMenu.addAction( embed::getIconPixmap( "help" ), tr( "&Help" ), this, SLOT( displayHelp() ) ); @@ -369,30 +316,27 @@ void knob::dropEvent( QDropEvent * _de ) QString val = stringPairDrag::decodeValue( _de ); if( type == "float_value" ) { - //printf("set val\n"); - setValue( val.toFloat() ); + model()->setValue( val.toFloat() ); _de->accept(); } else if( type == "link_object" ) { - //printf("link!\n"); - knob * obj = (knob *)( val.toULong() ); - linkObjects( this, obj ); - obj->setValue( value() ); + knobModel * mod = (knobModel *)( val.toULong() ); + autoModel::linkModels( model(), mod ); + mod->setValue( model()->value() ); } } -//! Mouse press event handler void knob::mousePressEvent( QMouseEvent * _me ) { if( _me->button() == Qt::LeftButton && engine::getMainWindow()->isCtrlPressed() == FALSE && engine::getMainWindow()->isShiftPressed() == FALSE ) { - prepareJournalEntryFromOldVal(); + model()->prepareJournalEntryFromOldVal(); const QPoint & p = _me->pos(); m_origMousePos = p; @@ -400,7 +344,7 @@ void knob::mousePressEvent( QMouseEvent * _me ) if( configManager::inst()->value( "knobs", "classicalusability").toInt() ) { - m_mouseOffset = getValue( p ) - value(); + m_mouseOffset = getValue( p ) - model()->value(); } emit sliderPressed(); @@ -411,7 +355,8 @@ void knob::mousePressEvent( QMouseEvent * _me ) } s_textFloat->reparent( this ); s_textFloat->setText( m_hintTextBeforeValue + - QString::number( value() ) + + QString::number( + model()->value() ) + m_hintTextAfterValue ); s_textFloat->move( mapTo( topLevelWidget(), QPoint( 0, 0 ) ) + QPoint( m_knobPixmap->width() + 2, 0 ) ); @@ -422,7 +367,8 @@ void knob::mousePressEvent( QMouseEvent * _me ) engine::getMainWindow()->isCtrlPressed() == TRUE/* && engine::getMainWindow()->isShiftPressed() == FALSE*/ ) { - new stringPairDrag( "float_value", QString::number( value() ), + new stringPairDrag( "float_value", + QString::number( model()->value() ), QPixmap(), this ); } else if( _me->button() == Qt::LeftButton && @@ -432,7 +378,7 @@ void knob::mousePressEvent( QMouseEvent * _me ) /* this pointer was casted to uint, * compile time error on 64 bit systems */ new stringPairDrag( "link_object", - QString::number( (ulong) this ), + QString::number( (ulong) model() ), QPixmap(), this ); } else if( _me->button() == Qt::MidButton ) @@ -444,14 +390,13 @@ void knob::mousePressEvent( QMouseEvent * _me ) -//! Mouse Move Event handler void knob::mouseMoveEvent( QMouseEvent * _me ) { if( m_buttonPressed == TRUE ) { setPosition( _me->pos() ); - emit sliderMoved( value() ); - emit valueChanged(); + emit sliderMoved( model()->value() ); +// emit valueChanged(); if( !configManager::inst()->value( "knobs", "classicalusability").toInt() ) { @@ -460,17 +405,16 @@ void knob::mouseMoveEvent( QMouseEvent * _me ) } s_textFloat->setText( m_hintTextBeforeValue + - QString::number( value() ) + - m_hintTextAfterValue ); + QString::number( model()->value() ) + + m_hintTextAfterValue ); } -//! Mouse Release Event handler void knob::mouseReleaseEvent( QMouseEvent * /* _me*/ ) { - addJournalEntryFromOldToCurVal(); + model()->addJournalEntryFromOldToCurVal(); if( m_buttonPressed ) { @@ -526,32 +470,23 @@ void knob::paintEvent( QPaintEvent * _me ) -void knob::resizeEvent( QResizeEvent * ) -{ - layoutKnob( FALSE ); -} - - - - -//! Qt wheel event void knob::wheelEvent( QWheelEvent * _we ) { _we->accept(); const int inc = ( _we->delta() > 0 ) ? 1 : -1; - incValue( inc ); + model()->incValue( inc ); s_textFloat->reparent( this ); s_textFloat->setText( m_hintTextBeforeValue + - QString::number( value() ) + + QString::number( model()->value() ) + m_hintTextAfterValue ); s_textFloat->move( mapTo( topLevelWidget(), QPoint( 0, 0 ) ) + QPoint( m_knobPixmap->width() + 2, 0 ) ); s_textFloat->setVisibilityTimeOut( 1000 ); - emit sliderMoved( value() ); - emit valueChanged(); + emit sliderMoved( model()->value() ); +// emit valueChanged(); } @@ -559,8 +494,8 @@ void knob::wheelEvent( QWheelEvent * _we ) void knob::buttonReleased( void ) { - emit valueChanged( value() ); - emit valueChanged(); +// emit valueChanged( model()->value() ); +// emit valueChanged(); } @@ -571,56 +506,27 @@ void knob::setPosition( const QPoint & _p ) if( configManager::inst()->value( "knobs", "classicalusability" ).toInt() ) { - setValue( getValue( _p ) - m_mouseOffset ); + model()->setValue( getValue( _p ) - m_mouseOffset ); } else { - setValue( value() - getValue( _p ) ); + model()->setValue( model()->value() - getValue( _p ) ); } } -void knob::setValue( const float _x ) -{ - const float prev_value = value(); - autoObj::setValue( _x ); - setFirstValue(); - if( prev_value != value() ) - { - valueChange(); - } -} - - - - -void knob::setRange( const float _min, const float _max, const float _step ) -{ - bool rchg = ( ( maxValue() != _max ) || ( minValue() != _min ) ); - autoObj::setRange( _min, _max, _step ); - - m_pageSize = tMax( ( maxValue() - minValue() ) / 100.0f, - step() ); - - // call notifier after the step width has been adjusted. - if( rchg ) - { - rangeChange(); - } -} - void knob::reset( void ) { - setValue( m_initValue ); + model()->setValue( model()->initValue() ); s_textFloat->reparent( this ); s_textFloat->setText( m_hintTextBeforeValue + - QString::number( value() ) + - m_hintTextAfterValue ); + QString::number( model()->value() ) + + m_hintTextAfterValue ); s_textFloat->move( mapTo( topLevelWidget(), QPoint( 0, 0 ) ) + QPoint( m_knobPixmap->width() + 2, 0 ) ); s_textFloat->setVisibilityTimeOut( 1000 ); @@ -631,7 +537,7 @@ void knob::reset( void ) void knob::copyValue( void ) { - s_copiedValue = value(); + s_copiedValue = model()->value(); } @@ -639,11 +545,11 @@ void knob::copyValue( void ) void knob::pasteValue( void ) { - setValue( s_copiedValue ); + model()->setValue( s_copiedValue ); s_textFloat->reparent( this ); s_textFloat->setText( m_hintTextBeforeValue + - QString::number( value() ) + - m_hintTextAfterValue ); + QString::number( model()->value() ) + + m_hintTextAfterValue ); s_textFloat->move( mapTo( topLevelWidget(), QPoint( 0, 0 ) ) + QPoint( m_knobPixmap->width() + 2, 0 ) ); s_textFloat->setVisibilityTimeOut( 1000 ); @@ -659,13 +565,16 @@ void knob::enterValue( void ) this, accessibleName(), tr( "Please enter a new value between " - "%1 and %2:" ).arg( - minValue() ).arg( maxValue() ), - value(), minValue(), maxValue(), + "%1 and %2:" ). + arg( model()->minValue() ). + arg( model()->maxValue() ), + model()->value(), + model()->minValue(), + model()->maxValue(), 4, &ok ); if( ok ) { - setValue( new_val ); + model()->setValue( new_val ); } } diff --git a/src/widgets/lcd_spinbox.cpp b/src/widgets/lcd_spinbox.cpp index 0167469fc8..1fbd434461 100644 --- a/src/widgets/lcd_spinbox.cpp +++ b/src/widgets/lcd_spinbox.cpp @@ -31,26 +31,27 @@ #include #include -#include "automatable_object_templates.h" +#include "automatable_model_templates.h" #include "caption_menu.h" #include "embed.h" #include "gui_templates.h" #include "templates.h" -lcdSpinBox::lcdSpinBox( int _min, int _max, int _num_digits, QWidget * _parent, - const QString & _name, - track * _track ) : +lcdSpinBox::lcdSpinBox( int _num_digits, QWidget * _parent, + const QString & _name ) : QWidget( _parent ), - autoObj( _track, 0, _min, _max ), + autoModelView(), + m_number( new QLCDNumber( _num_digits, this ) ), m_label( NULL ), m_origMousePos() { - m_number = new QLCDNumber( _num_digits, this ); m_number->setFrameShape( QFrame::Panel ); m_number->setFrameShadow( QFrame::Sunken ); m_number->setSegmentStyle( QLCDNumber::Flat ); + setModel( new autoModel( 0, 0, 0, 1, NULL, TRUE ) ); + QPalette pal; pal.setColor( QPalette::Light, Qt::gray ); pal.setColor( QPalette::Mid, Qt::darkGray ); @@ -61,14 +62,6 @@ lcdSpinBox::lcdSpinBox( int _min, int _max, int _num_digits, QWidget * _parent, setEnabled( TRUE ); - if( _track != NULL ) - { - getAutomationPattern(); - } - - // value is automatically limited to given range - setInitValue( 0 ); - setAccessibleName( _name ); m_number->setFixedSize( m_number->sizeHint() * 0.9 ); @@ -85,33 +78,19 @@ lcdSpinBox::~lcdSpinBox() -void lcdSpinBox::setStep( const int _step ) +void lcdSpinBox::update( void ) { - autoObj::setStep( tMax( _step, 1 ) ); -} - - - - -void lcdSpinBox::setValue( const int _value ) -{ - const int prev_value = value(); - autoObj::setValue( _value ); - QString s = m_textForValue[value()]; + QString s = m_textForValue[model()->value()]; if( s == "" ) { - s = QString::number( value() ); + s = QString::number( model()->value() ); while( (int) s.length() < m_number->numDigits() ) { s = "0" + s; } } m_number->display( s ); - - if( prev_value != value() ) - { - emit valueChanged( value() ); - } + QWidget::update(); } @@ -159,7 +138,7 @@ void lcdSpinBox::contextMenuEvent( QContextMenuEvent * _me ) { m_origMousePos = _me->globalPos(); - if( nullTrack() ) + if( model()->nullTrack() ) { QWidget::contextMenuEvent( _me ); return; @@ -174,7 +153,7 @@ void lcdSpinBox::contextMenuEvent( QContextMenuEvent * _me ) captionMenu contextMenu( accessibleName() ); contextMenu.addAction( embed::getIconPixmap( "automation" ), tr( "&Open in automation editor" ), - getAutomationPattern(), + model()->getAutomationPattern(), SLOT( openInAutomationEditor() ) ); contextMenu.exec( QCursor::pos() ); } @@ -188,7 +167,7 @@ void lcdSpinBox::mousePressEvent( QMouseEvent * _me ) { m_origMousePos = _me->globalPos(); QApplication::setOverrideCursor( Qt::BlankCursor ); - prepareJournalEntryFromOldVal(); + model()->prepareJournalEntryFromOldVal(); } } @@ -202,7 +181,8 @@ void lcdSpinBox::mouseMoveEvent( QMouseEvent * _me ) int dy = _me->globalY() - m_origMousePos.y(); if( dy > 1 || dy < -1 ) { - setInitValue( value() - dy / 2 * step() ); + model()->setInitValue( model()->value() - + dy / 2 * model()->step() ); emit manualChange(); QCursor::setPos( m_origMousePos ); } @@ -214,7 +194,7 @@ void lcdSpinBox::mouseMoveEvent( QMouseEvent * _me ) void lcdSpinBox::mouseReleaseEvent( QMouseEvent * _me ) { - addJournalEntryFromOldToCurVal(); + model()->addJournalEntryFromOldToCurVal(); QCursor::setPos( m_origMousePos ); QApplication::restoreOverrideCursor(); @@ -226,7 +206,8 @@ void lcdSpinBox::mouseReleaseEvent( QMouseEvent * _me ) void lcdSpinBox::wheelEvent( QWheelEvent * _we ) { _we->accept(); - setInitValue( value() + ( ( _we->delta() > 0 ) ? 1 : -1 ) * step() ); + model()->setInitValue( model()->value() + + ( ( _we->delta() > 0 ) ? 1 : -1 ) * model()->step() ); emit manualChange(); } diff --git a/src/widgets/led_checkbox.cpp b/src/widgets/led_checkbox.cpp index 07f42a61ce..320273c9e3 100644 --- a/src/widgets/led_checkbox.cpp +++ b/src/widgets/led_checkbox.cpp @@ -31,7 +31,6 @@ #include #include -#include "automatable_object_templates.h" #include "embed.h" #include "gui_templates.h" @@ -44,9 +43,8 @@ static const QString names[ledCheckBox::TOTAL_COLORS] = ledCheckBox::ledCheckBox( const QString & _text, QWidget * _parent, - const QString & _name, track * _track, - ledColors _color ) : - automatableButton( _parent, _name, _track ), + const QString & _name, ledColors _color ) : + automatableButton( _parent, _name ), m_text( _text ) { setCheckable( TRUE ); @@ -82,7 +80,7 @@ void ledCheckBox::paintEvent( QPaintEvent * ) QPainter p( this ); p.setFont( pointSize<7>( font() ) ); - if( isChecked() == TRUE ) + if( model()->value() == TRUE ) { p.drawPixmap( 0, 0, *m_ledOnPixmap ); } diff --git a/src/widgets/pixmap_button.cpp b/src/widgets/pixmap_button.cpp index 17ee9b5347..980a875349 100644 --- a/src/widgets/pixmap_button.cpp +++ b/src/widgets/pixmap_button.cpp @@ -30,14 +30,12 @@ #include #include "pixmap_button.h" -#include "automatable_object_templates.h" #include "embed.h" -pixmapButton::pixmapButton( QWidget * _parent, const QString & _name, - track * _track ) : - automatableButton( _parent, _name, _track ), +pixmapButton::pixmapButton( QWidget * _parent, const QString & _name ) : + automatableButton( _parent, _name ), m_activePixmap(), m_inactivePixmap() { @@ -59,7 +57,7 @@ void pixmapButton::paintEvent( QPaintEvent * ) { QPainter p( this ); - if( isChecked() ) + if( model()->value() ) { if( !m_activePixmap.isNull() ) { diff --git a/src/widgets/rack_plugin.cpp b/src/widgets/rack_plugin.cpp index 315c54fbbc..ab7ad8c4f8 100644 --- a/src/widgets/rack_plugin.cpp +++ b/src/widgets/rack_plugin.cpp @@ -51,6 +51,7 @@ rackPlugin::rackPlugin( QWidget * _parent, track * _track, audioPort * _port ) : QWidget( _parent ), + m_autoQuitModel( 1.0f, 1.0f, 8000.0f, 100.0f /* this */ ), m_effect( _eff ), m_track( _track ), m_port( _port ), @@ -65,35 +66,33 @@ rackPlugin::rackPlugin( QWidget * _parent, pal.setBrush( backgroundRole(), bg ); setPalette( pal ); - m_bypass = new ledCheckBox( "", this, tr( "Turn the effect off" ), - m_track ); - connect( m_bypass, SIGNAL( toggled( bool ) ), - this, SLOT( bypassed( bool ) ) ); - toolTip::add( m_bypass, tr( "On/Off" ) ); - m_bypass->setChecked( TRUE ); + m_effect->m_enabledModel.setTrack( m_track ); + m_effect->m_enabledModel.setValue( TRUE ); + m_bypass = new ledCheckBox( "", this, tr( "Turn the effect off" ) ); + m_bypass->setModel( &m_effect->m_enabledModel ); m_bypass->move( 3, 3 ); m_bypass->setWhatsThis( tr( "Toggles the effect on or off." ) ); + toolTip::add( m_bypass, tr( "On/Off" ) ); - m_wetDry = new knob( knobBright_26, this, tr( "Wet/Dry mix" ), - m_track ); - connect( m_wetDry, SIGNAL( valueChanged( float ) ), - this, SLOT( setWetDry( float ) ) ); + + m_effect->m_wetDryModel.setTrack( m_track ); + m_wetDry = new knob( knobBright_26, this, tr( "Wet/Dry mix" ) ); + m_wetDry->setModel( &m_effect->m_wetDryModel ); m_wetDry->setLabel( tr( "W/D" ) ); - m_wetDry->setRange( 0.0f, 1.0f, 0.01f ); - m_wetDry->setInitValue( 1.0f ); m_wetDry->move( 27, 5 ); m_wetDry->setHintText( tr( "Wet Level:" ) + " ", "" ); m_wetDry->setWhatsThis( tr( "The Wet/Dry knob sets the ratio between " "the input signal and the effect that " "shows up in the output." ) ); - m_autoQuit = new tempoSyncKnob( knobBright_26, this, tr( "Decay" ), - m_track ); - connect( m_autoQuit, SIGNAL( valueChanged( float ) ), - this, SLOT( setAutoQuit( float ) ) ); + + m_autoQuitModel.setTrack( m_track ); + m_autoQuitModel.setInitValue( 1.0f ); + connect( &m_autoQuitModel, SIGNAL( dataChanged( void ) ), + this, SLOT( updateAutoQuit( void ) ) ); + m_autoQuit = new tempoSyncKnob( knobBright_26, this, tr( "Decay" ) ); + m_autoQuit->setModel( &m_autoQuitModel ); m_autoQuit->setLabel( tr( "Decay" ) ); - m_autoQuit->setRange( 1.0f, 8000.0f, 100.0f ); - m_autoQuit->setInitValue( 1 ); m_autoQuit->move( 60, 5 ); m_autoQuit->setHintText( tr( "Time:" ) + " ", "ms" ); m_autoQuit->setWhatsThis( tr( @@ -101,18 +100,18 @@ rackPlugin::rackPlugin( QWidget * _parent, "plugin stops processing. Smaller values will reduce the CPU overhead but " "run the risk of clipping the tail on delay effects." ) ); - m_gate = new knob( knobBright_26, this, tr( "Gate" ), m_track ); - connect( m_wetDry, SIGNAL( valueChanged( float ) ), - this, SLOT( setGate( float ) ) ); + + m_effect->m_gateModel.setTrack( m_track ); + m_gate = new knob( knobBright_26, this, tr( "Gate" ) ); + m_gate->setModel( &m_effect->m_gateModel ); m_gate->setLabel( tr( "Gate" ) ); - m_gate->setRange( 0.0f, 1.0f, 0.01f ); - m_gate->setInitValue( 0.0f ); m_gate->move( 93, 5 ); m_gate->setHintText( tr( "Gate:" ) + " ", "" ); m_gate->setWhatsThis( tr( "The Gate knob controls the signal level that is considered to be 'silence' " "while deciding when to stop processing signals." ) ); + m_editButton = new QPushButton( tr( "Controls" ), this ); QFont f = m_editButton->font(); m_editButton->setFont( pointSize<7>( f ) ); @@ -133,17 +132,18 @@ rackPlugin::rackPlugin( QWidget * _parent, m_label->setPalette( pal ); m_controlView = m_effect->createControlDialog( m_track ); - m_subWindow = engine::getMainWindow()->workspace()->addSubWindow( m_controlView ); + m_subWindow = engine::getMainWindow()->workspace()->addSubWindow( + m_controlView ); connect( m_controlView, SIGNAL( closed() ), this, SLOT( closeEffects() ) ); - m_subWindow->hide(); - + m_subWindow->hide(); + if( m_controlView->getControlCount() == 0 ) { m_editButton->hide(); } - + setWhatsThis( tr( "Effect plugins function as a chained series of effects where the signal will " "be processed from top to bottom.\n\n" @@ -178,6 +178,7 @@ rackPlugin::rackPlugin( QWidget * _parent, + rackPlugin::~rackPlugin() { m_port->getEffects()->removeEffect( m_effect ); @@ -187,6 +188,7 @@ rackPlugin::~rackPlugin() + void rackPlugin::editControls( void ) { if( m_show ) @@ -205,24 +207,10 @@ void rackPlugin::editControls( void ) -void rackPlugin::bypassed( bool _state ) +void rackPlugin::updateAutoQuit( void ) { - m_effect->setBypass( !_state ); -} - - - - -void rackPlugin::setWetDry( float _value ) -{ - m_effect->setWetLevel( _value ); -} - - - -void rackPlugin::setAutoQuit( float _value ) -{ - float samples = engine::getMixer()->sampleRate() * _value / 1000.0f; + float samples = engine::getMixer()->sampleRate() * + m_autoQuitModel.value() / 1000.0f; Uint32 buffers = 1 + ( static_cast( samples ) / engine::getMixer()->framesPerPeriod() ); m_effect->setTimeout( buffers ); @@ -230,13 +218,6 @@ void rackPlugin::setAutoQuit( float _value ) -void rackPlugin::setGate( float _value ) -{ - m_effect->setGate( _value ); -} - - - void rackPlugin::contextMenuEvent( QContextMenuEvent * ) { @@ -298,10 +279,10 @@ void rackPlugin::displayHelp( void ) void FASTCALL rackPlugin::saveSettings( QDomDocument & _doc, QDomElement & _this ) { - _this.setAttribute( "on", m_bypass->isChecked() ); - _this.setAttribute( "wet", m_wetDry->value() ); - _this.setAttribute( "autoquit", m_autoQuit->value() ); - _this.setAttribute( "gate", m_gate->value() ); + _this.setAttribute( "on", m_effect->m_enabledModel.value() ); + _this.setAttribute( "wet", m_effect->m_wetDryModel.value() ); + _this.setAttribute( "autoquit", m_autoQuitModel.value() ); + _this.setAttribute( "gate", m_effect->m_gateModel.value() ); m_controlView->saveState( _doc, _this ); } @@ -310,10 +291,10 @@ void FASTCALL rackPlugin::saveSettings( QDomDocument & _doc, void FASTCALL rackPlugin::loadSettings( const QDomElement & _this ) { - m_bypass->setChecked( _this.attribute( "on" ).toInt() ); - m_wetDry->setValue( _this.attribute( "wet" ).toFloat() ); - m_autoQuit->setValue( _this.attribute( "autoquit" ).toFloat() ); - m_gate->setValue( _this.attribute( "gate" ).toFloat() ); + m_effect->m_enabledModel.setValue( _this.attribute( "on" ).toInt() ); + m_effect->m_wetDryModel.setValue( _this.attribute( "wet" ).toFloat() ); + m_autoQuitModel.setValue( _this.attribute( "autoquit" ).toFloat() ); + m_effect->m_gateModel.setValue( _this.attribute( "gate" ).toFloat() ); QDomNode node = _this.firstChild(); while( !node.isNull() ) diff --git a/src/widgets/tempo_sync_knob.cpp b/src/widgets/tempo_sync_knob.cpp index 2c3ab665db..2173b68d99 100644 --- a/src/widgets/tempo_sync_knob.cpp +++ b/src/widgets/tempo_sync_knob.cpp @@ -31,7 +31,8 @@ #include #include -#include "automatable_object_templates.h" +#include "automatable_model_templates.h" +#include "engine.h" #include "caption_menu.h" #include "embed.h" #include "main_window.h" @@ -41,9 +42,8 @@ tempoSyncKnob::tempoSyncKnob( int _knob_num, QWidget * _parent, const QString & _name, - track * _track, float _scale ) : - knob( _knob_num, _parent, _name, _track ), + knob( _knob_num, _parent, _name ), m_tempoSyncMode( NO_SYNC ), m_scale( _scale ), m_tempoSyncIcon( embed::getIconPixmap( "tempo_sync" ) ), @@ -53,7 +53,7 @@ tempoSyncKnob::tempoSyncKnob( int _knob_num, QWidget * _parent, connect( engine::getSongEditor(), SIGNAL( tempoChanged( bpm_t ) ), this, SLOT( calculateTempoSyncTime( bpm_t ) ) ); m_custom = new meterDialog( engine::getMainWindow()->workspace(), - _track ); + NULL ); m_custom->hide(); m_custom->setWindowTitle( "Meter" ); } @@ -76,19 +76,21 @@ void tempoSyncKnob::contextMenuEvent( QContextMenuEvent * ) { captionMenu contextMenu( accessibleName() ); contextMenu.addAction( embed::getIconPixmap( "reload" ), - tr( "&Reset (%1%2)" ).arg( m_initValue ).arg( - m_hintTextAfterValue ), - this, SLOT( reset() ) ); + tr( "&Reset (%1%2)" ). + arg( model()->initValue() ). + arg( m_hintTextAfterValue ), + this, SLOT( reset() ) ); contextMenu.addSeparator(); contextMenu.addAction( embed::getIconPixmap( "edit_copy" ), - tr( "&Copy value (%1%2)" ).arg( value() ).arg( - m_hintTextAfterValue ), - this, SLOT( copyValue() ) ); + tr( "&Copy value (%1%2)" ). + arg( value() ). + arg( m_hintTextAfterValue ), + this, SLOT( copyValue() ) ); contextMenu.addAction( embed::getIconPixmap( "edit_paste" ), - tr( "&Paste value (%1%2)" - ).arg( s_copiedValue ).arg( - m_hintTextAfterValue ), - this, SLOT( pasteValue() ) ); + tr( "&Paste value (%1%2)" ). + arg( s_copiedValue ). + arg( m_hintTextAfterValue ), + this, SLOT( pasteValue() ) ); contextMenu.addSeparator(); float limit = 60000.0f / ( engine::getSongEditor()->getTempo() * @@ -96,43 +98,44 @@ void tempoSyncKnob::contextMenuEvent( QContextMenuEvent * ) QMenu * syncMenu = contextMenu.addMenu( m_tempoSyncIcon, m_tempoSyncDescription ); - if( limit / 8.0f <= maxValue() ) + if( limit / 8.0f <= model()->maxValue() ) { + connect( syncMenu, SIGNAL( triggered( QAction * ) ), this, SLOT( setTempoSync( QAction * ) ) ); syncMenu->addAction( embed::getIconPixmap( "note_none" ), tr( "No Sync" ) )->setData( (int) NO_SYNC ); - if( limit / 0.125f <= maxValue() ) + if( limit / 0.125f <= model()->maxValue() ) { syncMenu->addAction( embed::getIconPixmap( "note_double_whole" ), tr( "Eight beats" ) )->setData( (int) DOUBLE_WHOLE_NOTE ); } - if( limit / 0.25f <= maxValue() ) + if( limit / 0.25f <= model()->maxValue() ) { syncMenu->addAction( embed::getIconPixmap( "note_whole" ), tr( "Whole note" ) )->setData( (int) WHOLE_NOTE ); } - if( limit / 0.5f <= maxValue() ) + if( limit / 0.5f <= model()->maxValue() ) { syncMenu->addAction( embed::getIconPixmap( "note_half" ), tr( "Half note" ) )->setData( (int) HALF_NOTE ); } - if( limit <= maxValue() ) + if( limit <= model()->maxValue() ) { syncMenu->addAction( embed::getIconPixmap( "note_quarter" ), tr( "Quarter note" ) )->setData( (int) QUARTER_NOTE ); } - if( limit / 2.0f <= maxValue() ) + if( limit / 2.0f <= model()->maxValue() ) { syncMenu->addAction( embed::getIconPixmap( "note_eighth" ), tr( "8th note" ) )->setData( (int) EIGHTH_NOTE ); } - if( limit / 4.0f <= maxValue() ) + if( limit / 4.0f <= model()->maxValue() ) { syncMenu->addAction( embed::getIconPixmap( "note_sixteenth" ), tr( "16th note" ) )->setData( @@ -146,11 +149,12 @@ void tempoSyncKnob::contextMenuEvent( QContextMenuEvent * ) this, SLOT( showCustom( void ) ) )->setData( (int) CUSTOM ); contextMenu.addSeparator(); + } - + contextMenu.addAction( embed::getIconPixmap( "automation" ), tr( "&Open in automation editor" ), - getAutomationPattern(), + model()->getAutomationPattern(), SLOT( openInAutomationEditor() ) ); contextMenu.addSeparator(); contextMenu.addAction( tr( "Connect to MIDI-device" ), this, @@ -193,6 +197,7 @@ void tempoSyncKnob::setTempoSync( QAction * _item ) + void tempoSyncKnob::setTempoSync( int _note_type ) { setSyncMode( ( tempoSyncMode ) _note_type ); @@ -258,9 +263,10 @@ void tempoSyncKnob::calculateTempoSyncTime( bpm_t _bpm ) break; default: ; } - bool journalling = testAndSetJournalling( FALSE ); - setValue( 60000.0 / ( _bpm * conversionFactor * m_scale ) ); - setJournalling( journalling ); + bool journalling = model()->testAndSetJournalling( FALSE ); + model()->setValue( 60000.0 / + ( _bpm * conversionFactor * m_scale ) ); + model()->setJournalling( journalling ); } else { @@ -328,7 +334,7 @@ void tempoSyncKnob::saveSettings( QDomDocument & _doc, QDomElement & _this, const QString & _name ) { _this.setAttribute( "syncmode", ( int ) getSyncMode() ); - automatableObject::saveSettings( _doc, _this, _name ); + model()->saveSettings( _doc, _this, _name ); m_custom->saveSettings( _doc, _this, _name ); } @@ -340,7 +346,7 @@ void tempoSyncKnob::loadSettings( const QDomElement & _this, { setSyncMode( ( tempoSyncMode ) _this.attribute( "syncmode" ).toInt() ); - automatableObject::loadSettings( _this, _name ); + model()->loadSettings( _this, _name ); m_custom->loadSettings( _this, _name ); } @@ -362,16 +368,16 @@ void tempoSyncKnob::setSyncMode( tempoSyncMode _new_mode ) m_tempoSyncMode = _new_mode; if( _new_mode == CUSTOM ) { - connect( m_custom, SIGNAL( numeratorChanged( int ) ), - this, SLOT( updateCustom( int ) ) ); - connect( m_custom, SIGNAL( denominatorChanged( int ) ), - this, SLOT( updateCustom( int ) ) ); + connect( m_custom, SIGNAL( numeratorChanged() ), + this, SLOT( updateCustom() ) ); + connect( m_custom, SIGNAL( denominatorChanged() ), + this, SLOT( updateCustom() ) ); } else { m_custom->hide(); disconnect( m_custom, 0, - this, SLOT( updateCustom( int ) ) ); + this, SLOT( updateCustom() ) ); } } calculateTempoSyncTime( engine::getSongEditor()->getTempo() ); @@ -432,7 +438,7 @@ void tempoSyncKnob::setSyncIcon( const QPixmap & _new_icon ) -void tempoSyncKnob::updateCustom( int ) +void tempoSyncKnob::updateCustom( void ) { setSyncMode( CUSTOM ); } diff --git a/src/widgets/volume_knob.cpp b/src/widgets/volume_knob.cpp index af8dd1420d..2e35f0555b 100644 --- a/src/widgets/volume_knob.cpp +++ b/src/widgets/volume_knob.cpp @@ -33,7 +33,7 @@ #include #include "volume_knob.h" -#include "automatable_object_templates.h" +#include "automatable_model_templates.h" #include "main_window.h" #include "config_mgr.h" #include "engine.h" @@ -42,9 +42,9 @@ -volumeKnob::volumeKnob( int _knob_num, QWidget * _parent, const QString & _name, - track * _track ) : - knob( _knob_num, _parent, _name, _track ) +volumeKnob::volumeKnob( int _knob_num, QWidget * _parent, + const QString & _name ) : + knob( _knob_num, _parent, _name ) { } @@ -64,7 +64,7 @@ void volumeKnob::mousePressEvent( QMouseEvent * _me ) if( _me->button() == Qt::LeftButton && engine::getMainWindow()->isCtrlPressed() == FALSE ) { - prepareJournalEntryFromOldVal(); + model()->prepareJournalEntryFromOldVal(); const QPoint & p = _me->pos(); m_origMousePos = p; @@ -116,14 +116,14 @@ void volumeKnob::mousePressEvent( QMouseEvent * _me ) -//! Mouse Move Event handler void volumeKnob::mouseMoveEvent( QMouseEvent * _me ) { + // TODO: merge code with knob::mouseMoveEvent if( m_buttonPressed == TRUE ) { setPosition( _me->pos() ); - emit sliderMoved( value() ); - emit valueChanged(); + emit sliderMoved( model()->value() ); +// emit valueChanged(); if( !configManager::inst()->value( "knobs", "classicalusability").toInt() ) { @@ -135,12 +135,12 @@ void volumeKnob::mouseMoveEvent( QMouseEvent * _me ) if( configManager::inst()->value( "app", "displaydbv" ).toInt() ) { val = QString( " %1 dBV" ).arg( - 20.0 * log10( value() / 100.0 ), + 20.0 * log10( model()->value() / 100.0 ), 3, 'f', 2 ); } else { - val = QString( " %1%" ).arg( value(), 3, 'f', 0 ); + val = QString( " %1%" ).arg( model()->value(), 3, 'f', 0 ); } s_textFloat->setText( m_hintTextBeforeValue + val ); } @@ -150,9 +150,10 @@ void volumeKnob::mouseMoveEvent( QMouseEvent * _me ) void volumeKnob::wheelEvent( QWheelEvent * _we ) { + // TODO: merge code with knob::mouseMoveEvent _we->accept(); const int inc = ( _we->delta() > 0 ) ? 1 : -1; - incValue( inc ); + model()->incValue( inc ); s_textFloat->reparent( this ); @@ -161,12 +162,12 @@ void volumeKnob::wheelEvent( QWheelEvent * _we ) if( configManager::inst()->value( "app", "displaydbv" ).toInt() ) { val = QString( " %1 dBV" ).arg( - 20.0 * log10( value() / 100.0 ), + 20.0 * log10( model()->value() / 100.0 ), 3, 'f', 2 ); } else { - val = QString( " %1%" ).arg( value(), 3, 'f', 0 ); + val = QString( " %1%" ).arg( model()->value(), 3, 'f', 0 ); } s_textFloat->setText( m_hintTextBeforeValue + val ); @@ -174,8 +175,8 @@ void volumeKnob::wheelEvent( QWheelEvent * _we ) QPoint( m_knobPixmap->width() + 2, 0 ) ); s_textFloat->setVisibilityTimeOut( 1000 ); - emit sliderMoved( value() ); - emit valueChanged(); + emit sliderMoved( model()->value() ); +// emit valueChanged(); } @@ -191,7 +192,7 @@ void volumeKnob::enterValue( void ) this, accessibleName(), tr( "Please enter a new value between " "-96.0 dBV and 6.0 dBV:" ), - 20.0 * log10( value() / 100.0 ), + 20.0 * log10( model()->value() / 100.0 ), -96.0, 6.0, 4, &ok ); if( new_val <= -96.0 ) { @@ -207,15 +208,17 @@ void volumeKnob::enterValue( void ) new_val = QInputDialog::getDouble( this, accessibleName(), tr( "Please enter a new value between " - "%1 and %2:" ).arg( - minValue() ).arg( maxValue() ), - value(), minValue(), maxValue(), - 4, &ok ); + "%1 and %2:" ). + arg( model()->minValue() ). + arg( model()->maxValue() ), + model()->value(), + model()->minValue(), + model()->maxValue(), 4, &ok ); } - + if( ok ) { - setValue( new_val ); + model()->setValue( new_val ); } }