diff --git a/README.md b/README.md index 7b0254a61..7090a6a15 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Features --------- * Song-Editor for composing songs -* A Beat+Bassline-Editor for creating beats and basslines +* Pattern-Editor for creating beats and patterns * An easy-to-use Piano-Roll for editing patterns and melodies * A Mixer with unlimited mixer channels and arbitrary number of effects * Many powerful instrument and effect-plugins out of the box diff --git a/data/projects/templates/CR8000.mpt b/data/projects/templates/CR8000.mpt index f3f0f62b2..7d7314b65 100644 --- a/data/projects/templates/CR8000.mpt +++ b/data/projects/templates/CR8000.mpt @@ -20,7 +20,7 @@ - + diff --git a/data/projects/templates/TR808.mpt b/data/projects/templates/TR808.mpt index 69c313bd1..08ad876ca 100644 --- a/data/projects/templates/TR808.mpt +++ b/data/projects/templates/TR808.mpt @@ -20,7 +20,7 @@ - + diff --git a/data/projects/templates/default.mpt b/data/projects/templates/default.mpt index 70e6d0aeb..299aaff2d 100644 --- a/data/projects/templates/default.mpt +++ b/data/projects/templates/default.mpt @@ -25,7 +25,7 @@ - + diff --git a/data/themes/classic/add_bb_track.png b/data/themes/classic/add_pattern_track.png similarity index 100% rename from data/themes/classic/add_bb_track.png rename to data/themes/classic/add_pattern_track.png diff --git a/data/themes/classic/clone_bb_track_clip.png b/data/themes/classic/clone_pattern_track_clip.png similarity index 100% rename from data/themes/classic/clone_bb_track_clip.png rename to data/themes/classic/clone_pattern_track_clip.png diff --git a/data/themes/classic/bb_track.png b/data/themes/classic/pattern_track.png similarity index 100% rename from data/themes/classic/bb_track.png rename to data/themes/classic/pattern_track.png diff --git a/data/themes/classic/bb_track_btn.png b/data/themes/classic/pattern_track_btn.png similarity index 100% rename from data/themes/classic/bb_track_btn.png rename to data/themes/classic/pattern_track_btn.png diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css index fc2c28e5f..4e38d2afe 100644 --- a/data/themes/classic/style.css +++ b/data/themes/classic/style.css @@ -333,7 +333,7 @@ QScrollBar::right-arrow:horizontal:disabled { background-image: url(resources:sb QScrollBar::up-arrow:vertical:disabled { background-image: url(resources:sbarrow_up_d.png);} QScrollBar::down-arrow:vertical:disabled { background-image: url(resources:sbarrow_down_d.png);} -/* background for song editor and bb-editor */ +/* background for song editor and pattern editor */ TrackContainerView QFrame{ background-color: #49515b; @@ -670,7 +670,7 @@ ClipView { qproperty-mutedColor: rgb( 128, 128, 128 ); qproperty-mutedBackgroundColor: rgb( 80, 80, 80 ); qproperty-selectedColor: rgb( 0, 125, 255 ); - qproperty-BBClipBackground: rgb( 80, 80, 80 ); + qproperty-patternClipBackground: rgb( 80, 80, 80 ); qproperty-textColor: rgb( 255, 255, 255 ); qproperty-textBackgroundColor: rgba(0, 0, 0, 75); qproperty-textShadowColor: rgb( 0, 0, 0 ); @@ -705,9 +705,9 @@ AutomationClipView { color: rgb( 204, 215, 255 ); } -/* bb-clip */ -BBClipView { - background-color: rgb( 128, 182, 175 ); /* default colour for bb-tracks */ +/* pattern clip */ +PatternClipView { + background-color: rgb( 128, 182, 175 ); /* default colour for pattern tracks */ } /* Subwindows in MDI-Area */ diff --git a/data/themes/default/add_bb_track.png b/data/themes/default/add_pattern_track.png similarity index 100% rename from data/themes/default/add_bb_track.png rename to data/themes/default/add_pattern_track.png diff --git a/data/themes/default/clone_bb_track_clip.png b/data/themes/default/clone_pattern_track_clip.png similarity index 100% rename from data/themes/default/clone_bb_track_clip.png rename to data/themes/default/clone_pattern_track_clip.png diff --git a/data/themes/default/bb_track.png b/data/themes/default/pattern_track.png similarity index 100% rename from data/themes/default/bb_track.png rename to data/themes/default/pattern_track.png diff --git a/data/themes/default/bb_track_btn.png b/data/themes/default/pattern_track_btn.png similarity index 100% rename from data/themes/default/bb_track_btn.png rename to data/themes/default/pattern_track_btn.png diff --git a/data/themes/default/style.css b/data/themes/default/style.css index 87be1242f..743ab01bf 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -369,7 +369,7 @@ QScrollBar::down-arrow:vertical:disabled { background-image: url(resources:sbarr EffectRackView QScrollBar::up-arrow:vertical:disabled { background-image: url(resources:sbarrow_up.png);} EffectRackView QScrollBar::down-arrow:vertical:disabled { background-image: url(resources:sbarrow_down.png);} -/* background for song editor and bb-editor */ +/* background for song editor and pattern editor */ TrackContainerView QFrame { background-color: #262b30; @@ -716,7 +716,7 @@ ClipView { qproperty-mutedColor: rgba(255,255,255,100); qproperty-mutedBackgroundColor: #373d48; qproperty-selectedColor: #006B65; - qproperty-BBClipBackground: #373d48; + qproperty-patternClipBackground: #373d48; qproperty-textColor: #fff; qproperty-textBackgroundColor: rgba(0, 0, 0, 75); qproperty-textShadowColor: rgba(0,0,0,200); @@ -751,9 +751,9 @@ AutomationClipView { color: rgba(255,255,255,90); } -/* bb-clip */ -BBClipView { - background-color: #20BDB2; /* default colour for bb-tracks */ +/* pattern clip */ +PatternClipView { + background-color: #20BDB2; /* default colour for pattern tracks */ } /* Subwindows in MDI-Area */ diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h index 4be2756aa..dea531043 100644 --- a/include/AutomationEditor.h +++ b/include/AutomationEditor.h @@ -218,7 +218,7 @@ private: void drawCross(QPainter & p ); void drawAutomationPoint( QPainter & p, timeMap::iterator it ); - bool inBBEditor(); + bool inPatternEditor(); QColor m_barLineColor; QColor m_beatLineColor; diff --git a/include/BBTrackContainer.h b/include/BBTrackContainer.h deleted file mode 100644 index dac67a39d..000000000 --- a/include/BBTrackContainer.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * BBTrackContainer.h - model-component of BB-Editor - * - * Copyright (c) 2004-2014 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * 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 BB_TRACK_CONTAINER_H -#define BB_TRACK_CONTAINER_H - -#include "TrackContainer.h" -#include "ComboBoxModel.h" - - -class LMMS_EXPORT BBTrackContainer : public TrackContainer -{ - Q_OBJECT - mapPropertyFromModel(int,currentBB,setCurrentBB,m_bbComboBoxModel); -public: - BBTrackContainer(); - virtual ~BBTrackContainer(); - - virtual bool play(TimePos start, const fpp_t frames, const f_cnt_t frameBase, int clipNum = -1); - - void updateAfterTrackAdd() override; - - inline QString nodeName() const override - { - return "bbtrackcontainer"; - } - - bar_t lengthOfBB(int bb) const; - inline bar_t lengthOfCurrentBB() - { - return lengthOfBB(currentBB()); - } - int numOfBBs() const; - void removeBB(int bb); - - void swapBB(int bb1, int bb2); - - void updateBBTrack(Clip * clip); - void fixIncorrectPositions(); - void createClipsForBB(int bb); - - AutomatedValueMap automatedValuesAt(TimePos time, int clipNum) const override; - -public slots: - void play(); - void stop(); - void updateComboBox(); - void currentBBChanged(); - - -private: - ComboBoxModel m_bbComboBoxModel; - - - friend class BBEditor; - -} ; - - -#endif diff --git a/include/ClipView.h b/include/ClipView.h index d9fb520c8..149774c0a 100644 --- a/include/ClipView.h +++ b/include/ClipView.h @@ -53,7 +53,7 @@ class ClipView : public selectableObject, public ModelView Q_PROPERTY( QColor textColor READ textColor WRITE setTextColor ) Q_PROPERTY( QColor textBackgroundColor READ textBackgroundColor WRITE setTextBackgroundColor ) Q_PROPERTY( QColor textShadowColor READ textShadowColor WRITE setTextShadowColor ) - Q_PROPERTY( QColor BBClipBackground READ BBClipBackground WRITE setBBClipBackground ) + Q_PROPERTY( QColor patternClipBackground READ patternClipBackground WRITE setPatternClipBackground ) Q_PROPERTY( bool gradient READ gradient WRITE setGradient ) // We have to use a QSize here because using QPoint isn't supported. // width -> x, height -> y @@ -83,7 +83,7 @@ public: QColor textColor() const; QColor textBackgroundColor() const; QColor textShadowColor() const; - QColor BBClipBackground() const; + QColor patternClipBackground() const; bool gradient() const; void setMutedColor( const QColor & c ); void setMutedBackgroundColor( const QColor & c ); @@ -91,7 +91,7 @@ public: void setTextColor( const QColor & c ); void setTextBackgroundColor( const QColor & c ); void setTextShadowColor( const QColor & c ); - void setBBClipBackground( const QColor & c ); + void setPatternClipBackground(const QColor& c); void setGradient( const bool & b ); // access needsUpdate member variable @@ -211,7 +211,7 @@ private: QColor m_textColor; QColor m_textBackgroundColor; QColor m_textShadowColor; - QColor m_BBClipBackground; + QColor m_patternClipBackground; bool m_gradient; QSize m_mouseHotspotHand; // QSize must be used because QPoint QSize m_mouseHotspotKnife; // isn't supported by property system diff --git a/include/Engine.h b/include/Engine.h index f11d3b19a..32b1ee419 100644 --- a/include/Engine.h +++ b/include/Engine.h @@ -35,8 +35,8 @@ #include "lmms_basics.h" class AudioEngine; -class BBTrackContainer; class Mixer; +class PatternStore; class ProjectJournal; class Song; class Ladspa2LMMS; @@ -77,9 +77,9 @@ public: return s_song; } - static BBTrackContainer * getBBTrackContainer() + static PatternStore * patternStore() { - return s_bbTrackContainer; + return s_patternStore; } static ProjectJournal * projectJournal() @@ -143,7 +143,7 @@ private: static AudioEngine *s_audioEngine; static Mixer * s_mixer; static Song * s_song; - static BBTrackContainer * s_bbTrackContainer; + static PatternStore * s_patternStore; static ProjectJournal * s_projectJournal; #ifdef LMMS_HAVE_LV2 diff --git a/include/ExportFilter.h b/include/ExportFilter.h index dc33c2aa2..91c1bcc7e 100644 --- a/include/ExportFilter.h +++ b/include/ExportFilter.h @@ -40,7 +40,7 @@ public: virtual bool tryExport(const TrackContainer::TrackList &tracks, - const TrackContainer::TrackList &tracksBB, + const TrackContainer::TrackList &patternTracks, int tempo, int masterPitch, const QString &filename ) = 0; protected: diff --git a/include/GuiApplication.h b/include/GuiApplication.h index d26655d46..6c48c5bc6 100644 --- a/include/GuiApplication.h +++ b/include/GuiApplication.h @@ -33,11 +33,11 @@ class QLabel; class AutomationEditorWindow; -class BBEditor; class ControllerRackView; class MixerView; class MainWindow; class MicrotunerConfig; +class PatternEditorWindow; class PianoRollWindow; class ProjectNotes; class SongEditorWindow; @@ -57,7 +57,7 @@ public: MainWindow* mainWindow() { return m_mainWindow; } MixerView* mixerView() { return m_mixerView; } SongEditorWindow* songEditor() { return m_songEditor; } - BBEditor* getBBEditor() { return m_bbEditor; } + PatternEditorWindow* patternEditor() { return m_patternEditor; } PianoRollWindow* pianoRoll() { return m_pianoRoll; } ProjectNotes* getProjectNotes() { return m_projectNotes; } MicrotunerConfig* getMicrotunerConfig() { return m_microtunerConfig; } @@ -77,7 +77,7 @@ private: MixerView* m_mixerView; SongEditorWindow* m_songEditor; AutomationEditorWindow* m_automationEditor; - BBEditor* m_bbEditor; + PatternEditorWindow* m_patternEditor; PianoRollWindow* m_pianoRoll; ProjectNotes* m_projectNotes; MicrotunerConfig* m_microtunerConfig; diff --git a/include/MainWindow.h b/include/MainWindow.h index a23c3516a..3af16e7f5 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -149,7 +149,7 @@ public slots: void aboutLMMS(); void help(); void toggleAutomationEditorWin(); - void toggleBBEditorWin( bool forceShow = false ); + void togglePatternEditorWin(bool forceShow = false); void toggleSongEditorWin(); void toggleProjectNotesWin(); void toggleMicrotunerWin(); diff --git a/include/MidiClip.h b/include/MidiClip.h index b39e366f5..8ecaa9c1f 100644 --- a/include/MidiClip.h +++ b/include/MidiClip.h @@ -108,16 +108,16 @@ public: using Model::dataChanged; - -protected: - void updateBBTrack(); - - -protected slots: +public slots: void addSteps(); void cloneSteps(); void removeSteps(); void clear(); + +protected: + void updatePatternTrack(); + +protected slots: void changeTimeSignature(); @@ -140,7 +140,6 @@ private: MidiClip * adjacentMidiClipByOffset(int offset) const; friend class MidiClipView; - friend class BBTrackContainerView; signals: diff --git a/include/MidiClipView.h b/include/MidiClipView.h index 179486bf0..e18b8d2b0 100644 --- a/include/MidiClipView.h +++ b/include/MidiClipView.h @@ -93,7 +93,7 @@ private: QStaticText m_staticTextName; - bool m_legacySEBB; + bool m_legacySEPattern; } ; diff --git a/include/NotePlayHandle.h b/include/NotePlayHandle.h index 1ba07b33f..778acd46e 100644 --- a/include/NotePlayHandle.h +++ b/include/NotePlayHandle.h @@ -231,16 +231,16 @@ public: /*! Returns whether given NotePlayHandle instance is equal to *this */ bool operator==( const NotePlayHandle & _nph ) const; - /*! Returns whether NotePlayHandle belongs to BB track and BB track is muted */ - bool isBbTrackMuted() + /*! Returns whether NotePlayHandle belongs to pattern track and pattern track is muted */ + bool isPatternTrackMuted() { - return m_bbTrack && m_bbTrack->isMuted(); + return m_patternTrack && m_patternTrack->isMuted(); } - /*! Sets attached BB track */ - void setBBTrack( Track* t ) + /*! Sets attached pattern track */ + void setPatternTrack(Track* t) { - m_bbTrack = t; + m_patternTrack = t; } /*! Process note detuning automation */ @@ -311,7 +311,7 @@ private: NotePlayHandle * m_parent; // parent note bool m_hadChildren; bool m_muted; // indicates whether note is muted - Track* m_bbTrack; // related BB track + Track* m_patternTrack; // related pattern track // tempo reaction bpm_t m_origTempo; // original tempo diff --git a/include/BBClip.h b/include/PatternClip.h similarity index 75% rename from include/BBClip.h rename to include/PatternClip.h index f073fca49..15c3c8d02 100644 --- a/include/BBClip.h +++ b/include/PatternClip.h @@ -1,5 +1,5 @@ /* - * BBClip.h + * PatternClip.h * * Copyright (c) 2004-2014 Tobias Doerffel * @@ -23,33 +23,37 @@ */ -#ifndef BB_CLIP_H -#define BB_CLIP_H +#ifndef PATTERN_CLIP_H +#define PATTERN_CLIP_H #include "ClipView.h" -class BBClip : public Clip +/*! \brief Dummy clip for PatternTracks + * + * Only used in the Song (Editor). See PatternStore.h for more info. +*/ +class PatternClip : public Clip { public: - BBClip( Track * _track ); - virtual ~BBClip() = default; + PatternClip(Track* track); + virtual ~PatternClip() = default; void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override; void loadSettings( const QDomElement & _this ) override; inline QString nodeName() const override { - return( "bbtco" ); + return( "bbtco" ); // TODO rename to patternclip } - int bbTrackIndex(); + int patternIndex(); ClipView * createView( TrackView * _tv ) override; private: - friend class BBClipView; + friend class PatternClipView; } ; -#endif \ No newline at end of file +#endif diff --git a/include/BBClipView.h b/include/PatternClipView.h similarity index 81% rename from include/BBClipView.h rename to include/PatternClipView.h index a779ca680..c23715a12 100644 --- a/include/BBClipView.h +++ b/include/PatternClipView.h @@ -1,5 +1,5 @@ /* - * BBClipView.h + * PatternClipView.h * * Copyright (c) 2004-2014 Tobias Doerffel * @@ -23,27 +23,27 @@ */ -#ifndef BB_CLIP_VIEW_H -#define BB_CLIP_VIEW_H +#ifndef PATTERN_CLIP_VIEW_H +#define PATTERN_CLIP_VIEW_H -#include "BBClip.h" +#include "PatternClip.h" #include -class BBClipView : public ClipView +class PatternClipView : public ClipView { Q_OBJECT public: - BBClipView( Clip * _clip, TrackView * _tv ); - virtual ~BBClipView() = default; + PatternClipView(Clip* clip, TrackView* tv); + virtual ~PatternClipView() = default; public slots: void update() override; protected slots: - void openInBBEditor(); + void openInPatternEditor(); void resetName(); void changeName(); @@ -55,7 +55,7 @@ protected: private: - BBClip * m_bbClip; + PatternClip* m_patternClip; QPixmap m_paintPixmap; QStaticText m_staticTextName; @@ -63,4 +63,4 @@ private: -#endif \ No newline at end of file +#endif diff --git a/include/BBEditor.h b/include/PatternEditor.h similarity index 70% rename from include/BBEditor.h rename to include/PatternEditor.h index e13097e59..03861c1b0 100644 --- a/include/BBEditor.h +++ b/include/PatternEditor.h @@ -1,5 +1,5 @@ /* - * BBEditor.h - view-component of BB-Editor + * PatternEditor.h - basic main-window for editing patterns * * Copyright (c) 2004-2014 Tobias Doerffel * @@ -23,60 +23,30 @@ */ -#ifndef BB_EDITOR_H -#define BB_EDITOR_H +#ifndef PATTERN_EDITOR_H +#define PATTERN_EDITOR_H #include "Editor.h" #include "TrackContainerView.h" -class BBTrackContainer; +class PatternStore; class ComboBox; -class BBTrackContainerView; -class BBEditor : public Editor +class PatternEditor : public TrackContainerView { Q_OBJECT public: - BBEditor( BBTrackContainer * _tc ); - ~BBEditor(); - - QSize sizeHint() const override; - - const BBTrackContainerView* trackContainerView() const { - return m_trackContainerView; - } - BBTrackContainerView* trackContainerView() { - return m_trackContainerView; - } - - void removeBBView( int bb ); - -public slots: - void play() override; - void stop() override; - -private: - BBTrackContainerView* m_trackContainerView; - ComboBox * m_bbComboBox; -} ; - - - -class BBTrackContainerView : public TrackContainerView -{ - Q_OBJECT -public: - BBTrackContainerView(BBTrackContainer* tc); + PatternEditor(PatternStore* ps); bool fixedClips() const override { return true; } - void removeBBView(int bb); + void removeViewsForPattern(int pattern); void saveSettings(QDomDocument& doc, QDomElement& element) override; void loadSettings(const QDomElement& element) override; @@ -94,9 +64,30 @@ protected slots: void updatePosition(); private: - BBTrackContainer * m_bbtc; + PatternStore* m_ps; void makeSteps( bool clone ); }; + + +class PatternEditorWindow : public Editor +{ + Q_OBJECT +public: + PatternEditorWindow(PatternStore* ps); + ~PatternEditorWindow(); + + QSize sizeHint() const override; + + PatternEditor* m_editor; + +public slots: + void play() override; + void stop() override; + +private: + ComboBox* m_patternComboBox; +}; + #endif diff --git a/include/PatternStore.h b/include/PatternStore.h new file mode 100644 index 000000000..c088095e0 --- /dev/null +++ b/include/PatternStore.h @@ -0,0 +1,108 @@ +/* + * PatternStore.h - model-component of Pattern Editor + * + * Copyright (c) 2004-2014 Tobias Doerffel + * + * This file is part of LMMS - https://lmms.io + * + * 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 PATTERN_STORE_H +#define PATTERN_STORE_H + +#include "TrackContainer.h" +#include "ComboBoxModel.h" + + +/* + * PatternStore is the backend of Pattern Editor: + * + * +----------------------------------+ + * | PatternStore (TrackContainer) | + * | | + * | +------------------------------+ | + * | | Track 1 [Clip A] [Clip B] | | + * | +------------------------------+ | + * | | + * | +------------------------------+ | + * | | Track 2 [Clip C] [Clip D] | | + * | +------------------------------+ | + * +----------------------------------+ + * + * There is only one PatternStore which holds all patterns, and it's very similar to the Song Editor. + * Think of it as a table - tracks are rows, bars are columns and clips are cells. + * With this logic a "pattern" is a column, i.e. all clips on the same bar. + * In the Pattern Editor you can select which pattern (column) you want to see, using the combo box at the top. + * In the illustration above, Clip A and Clip C start on bar 1, thus they are "Pattern 1". + * + * Do not confuse tracks and clips in the PatternStore with PatternTracks and PatternClips. + * - PatternTracks are used in the Song Editor. Each one reference a "pattern" in the PatternStore. + * - PatternClips are stored inside PatternTracks. They are just empty placeholders. + */ +class LMMS_EXPORT PatternStore : public TrackContainer +{ + Q_OBJECT + mapPropertyFromModel(int, currentPattern, setCurrentPattern, m_patternComboBoxModel); +public: + PatternStore(); + virtual ~PatternStore(); + + virtual bool play(TimePos start, const fpp_t frames, const f_cnt_t frameBase, int clipNum = -1); + + void updateAfterTrackAdd() override; + + inline QString nodeName() const override + { + return "bbtrackcontainer"; // TODO rename to patternstore + } + + bar_t lengthOfPattern(int pattern) const; + inline bar_t lengthOfCurrentPattern() + { + return lengthOfPattern(currentPattern()); + } + int numOfPatterns() const; + void removePattern(int pattern); + + void swapPattern(int p1, int p2); + + void updatePatternTrack(Clip* clip); + void fixIncorrectPositions(); + void createClipsForPattern(int pattern); + + AutomatedValueMap automatedValuesAt(TimePos time, int clipNum) const override; + +public slots: + void play(); + void stop(); + void updateComboBox(); + void currentPatternChanged(); + + +private: + ComboBoxModel m_patternComboBoxModel; + + + // Where the pattern selection combo box is + friend class PatternEditorWindow; + +} ; + + +#endif diff --git a/include/BBTrack.h b/include/PatternTrack.h similarity index 75% rename from include/BBTrack.h rename to include/PatternTrack.h index c07c8a90e..6529baf8d 100644 --- a/include/BBTrack.h +++ b/include/PatternTrack.h @@ -1,6 +1,5 @@ /* - * BBTrack.h - class BBTrack, a wrapper for using bbEditor - * (which is a singleton-class) as track + * PatternTrack.h - a track representing a pattern in the PatternStore * * Copyright (c) 2004-2014 Tobias Doerffel * @@ -24,25 +23,26 @@ */ -#ifndef BB_TRACK_H -#define BB_TRACK_H +#ifndef PATTERN_TRACK_H +#define PATTERN_TRACK_H #include -#include "BBClipView.h" +#include "PatternClipView.h" #include "Track.h" class TrackLabelButton; class TrackContainer; -class LMMS_EXPORT BBTrack : public Track +/*! Track type used in the Song (Editor) to reference a pattern in the PatternStore */ +class LMMS_EXPORT PatternTrack : public Track { Q_OBJECT public: - BBTrack( TrackContainer* tc ); - virtual ~BBTrack(); + PatternTrack(TrackContainer* tc); + virtual ~PatternTrack(); virtual bool play( const TimePos & _start, const fpp_t _frames, const f_cnt_t _frame_base, int _clip_num = -1 ) override; @@ -53,10 +53,10 @@ public: QDomElement & _parent ) override; void loadTrackSpecificSettings( const QDomElement & _this ) override; - static BBTrack * findBBTrack( int _bb_num ); - static void swapBBTracks( Track * _track1, Track * _track2 ); + static PatternTrack* findPatternTrack(int pattern_num); + static void swapPatternTracks(Track* track1, Track* track2); - int index() + int patternIndex() { return s_infoMap[this]; } @@ -77,17 +77,17 @@ public: protected: inline QString nodeName() const override { - return( "bbtrack" ); + return( "bbtrack" ); //TODO rename to patterntrack } private: QList m_disabledTracks; - typedef QMap infoMap; + typedef QMap infoMap; static infoMap s_infoMap; - friend class BBTrackView; + friend class PatternTrackView; } ; diff --git a/include/BBTrackView.h b/include/PatternTrackView.h similarity index 75% rename from include/BBTrackView.h rename to include/PatternTrackView.h index 86c10cd30..3009aa02a 100644 --- a/include/BBTrackView.h +++ b/include/PatternTrackView.h @@ -1,5 +1,5 @@ /* - * BBTrackView.h + * PatternTrackView.h * * Copyright (c) 2004-2014 Tobias Doerffel * @@ -23,27 +23,27 @@ */ -#ifndef BB_TRACK_VIEW_H -#define BB_TRACK_VIEW_H +#ifndef PATTERN_TRACK_VIEW_H +#define PATTERN_TRACK_VIEW_H #include -#include "BBTrack.h" +#include "PatternTrack.h" #include "TrackView.h" -class BBTrackView : public TrackView +class PatternTrackView : public TrackView { Q_OBJECT public: - BBTrackView( BBTrack* bbt, TrackContainerView* tcv ); - virtual ~BBTrackView(); + PatternTrackView(PatternTrack* pt, TrackContainerView* tcv); + virtual ~PatternTrackView(); bool close() override; - const BBTrack * getBBTrack() const + const PatternTrack* getPatternTrack() const { - return( m_bbTrack ); + return (m_patternTrack); } @@ -52,10 +52,10 @@ public slots: private: - BBTrack * m_bbTrack; + PatternTrack* m_patternTrack; TrackLabelButton * m_trackLabel; } ; -#endif \ No newline at end of file +#endif diff --git a/include/SamplePlayHandle.h b/include/SamplePlayHandle.h index 367a9a25a..04360a26e 100644 --- a/include/SamplePlayHandle.h +++ b/include/SamplePlayHandle.h @@ -30,7 +30,7 @@ #include "AutomatableModel.h" #include "PlayHandle.h" -class BBTrack; +class PatternTrack; class SampleClip; class Track; class AudioPort; @@ -65,9 +65,9 @@ public: m_doneMayReturnTrue = _enable; } - void setBBTrack( BBTrack * _bb_track ) + void setPatternTrack(PatternTrack* pt) { - m_bbTrack = _bb_track; + m_patternTrack = pt; } void setVolumeModel( FloatModel * _model ) @@ -89,7 +89,7 @@ private: FloatModel * m_volumeModel; Track * m_track; - BBTrack * m_bbTrack; + PatternTrack* m_patternTrack; } ; diff --git a/include/SampleRecordHandle.h b/include/SampleRecordHandle.h index 3921b1976..9cb6bb8a7 100644 --- a/include/SampleRecordHandle.h +++ b/include/SampleRecordHandle.h @@ -32,7 +32,7 @@ #include "PlayHandle.h" #include "TimePos.h" -class BBTrack; +class PatternTrack; class SampleBuffer; class SampleClip; class Track; @@ -63,7 +63,7 @@ private: TimePos m_minLength; Track * m_track; - BBTrack * m_bbTrack; + PatternTrack* m_patternTrack; SampleClip * m_clip; } ; diff --git a/include/Song.h b/include/Song.h index 94c816423..d7fcf4720 100644 --- a/include/Song.h +++ b/include/Song.h @@ -65,7 +65,7 @@ public: { Mode_None, Mode_PlaySong, - Mode_PlayBB, + Mode_PlayPattern, Mode_PlayMidiClip, Mode_PlayAutomationClip, Mode_Count @@ -363,7 +363,7 @@ public slots: void playSong(); void record(); void playAndRecord(); - void playBB(); + void playPattern(); void playMidiClip( const MidiClip * midiClipToPlay, bool loop = true ); void togglePause(); void stop(); @@ -376,7 +376,7 @@ public slots: void clearProject(); - void addBBTrack(); + void addPatternTrack(); private slots: diff --git a/include/SongEditor.h b/include/SongEditor.h index 41b732ddd..35eae2b7d 100644 --- a/include/SongEditor.h +++ b/include/SongEditor.h @@ -198,7 +198,7 @@ signals: void resized(); private: - QAction* m_addBBTrackAction; + QAction* m_addPatternTrackAction; QAction* m_addSampleTrackAction; QAction* m_addAutomationTrackAction; QAction* m_setProportionalSnapAction; diff --git a/include/Track.h b/include/Track.h index 9c68808b8..73295459c 100644 --- a/include/Track.h +++ b/include/Track.h @@ -65,7 +65,7 @@ public: enum TrackTypes { InstrumentTrack, - BBTrack, + PatternTrack, SampleTrack, EventTrack, VideoTrack, @@ -127,7 +127,7 @@ public: const TimePos & end ); void swapPositionOfClips( int clipNum1, int clipNum2 ); - void createClipsForBB( int bb ); + void createClipsForPattern(int pattern); void insertBar( const TimePos & pos ); diff --git a/include/TrackContainer.h b/include/TrackContainer.h index 67cd90f85..a07f9c9ef 100644 --- a/include/TrackContainer.h +++ b/include/TrackContainer.h @@ -1,6 +1,6 @@ /* * TrackContainer.h - base-class for all track-containers like Song-Editor, - * BB-Editor... + * Pattern Editor... * * Copyright (c) 2004-2009 Tobias Doerffel * @@ -44,7 +44,7 @@ public: typedef QVector TrackList; enum TrackContainerTypes { - BBContainer, + PatternContainer, SongContainer } ; diff --git a/plugins/HydrogenImport/HydrogenImport.cpp b/plugins/HydrogenImport/HydrogenImport.cpp index 906c94f0b..201eab497 100644 --- a/plugins/HydrogenImport/HydrogenImport.cpp +++ b/plugins/HydrogenImport/HydrogenImport.cpp @@ -14,9 +14,9 @@ #include "InstrumentTrack.h" #include "Note.h" #include "MidiClip.h" +#include "PatternStore.h" +#include "PatternTrack.h" #include "Track.h" -#include "BBTrack.h" -#include "BBTrackContainer.h" #include "Instrument.h" #include "plugin_export.h" @@ -223,7 +223,9 @@ bool HydrogenImport::readSong() if ( nLayer == 0 ) { - drum_track[sId] = ( InstrumentTrack * ) Track::create( Track::InstrumentTrack,Engine::getBBTrackContainer() ); + drum_track[sId] = static_cast( + Track::create(Track::InstrumentTrack, Engine::patternStore()) + ); drum_track[sId]->volumeModel()->setValue( fVolume * 100 ); drum_track[sId]->panningModel()->setValue( ( fPan_R - fPan_L ) * 100 ); ins = drum_track[sId]->loadInstrument( "audiofileprocessor" ); @@ -247,7 +249,7 @@ bool HydrogenImport::readSong() } QDomNode patterns = songNode.firstChildElement( "patternList" ); int pattern_count = 0; - int nbb = Engine::getBBTrackContainer()->numOfBBs(); + int existing_patterns = Engine::patternStore()->numOfPatterns(); QDomNode patternNode = patterns.firstChildElement( "pattern" ); int pn = 1; while ( !patternNode.isNull() ) @@ -255,7 +257,7 @@ bool HydrogenImport::readSong() if ( pn > 0 ) { pattern_count++; - s->addBBTrack(); + s->addPatternTrack(); pn = 0; } QString sName; // name @@ -278,7 +280,7 @@ bool HydrogenImport::readSong() QString nNoteOff = LocalFileMng::readXmlString( noteNode, "note_off", "false", false, false ); QString instrId = LocalFileMng::readXmlString( noteNode, "instrument", 0,false, false ); - int i = pattern_count - 1 + nbb; + int i = pattern_count - 1 + existing_patterns; pattern_id[sName] = pattern_count - 1; MidiClip*p = dynamic_cast( drum_track[instrId]->getClip( i ) ); Note n; @@ -315,7 +317,7 @@ bool HydrogenImport::readSong() patternId = ( QDomNode ) patternId.nextSiblingElement( "patternID" ); int i = pattern_id[patId]+song_num_tracks; - Track *t = ( BBTrack * ) s->tracks().at( i ); + Track* t = s->tracks().at(i); t->createClip(pos); if ( pattern_length[patId] > best_length ) diff --git a/plugins/MidiExport/MidiExport.cpp b/plugins/MidiExport/MidiExport.cpp index cee588db9..cbce5c0d8 100644 --- a/plugins/MidiExport/MidiExport.cpp +++ b/plugins/MidiExport/MidiExport.cpp @@ -34,10 +34,10 @@ #include "lmms_math.h" #include "TrackContainer.h" -#include "BBTrack.h" #include "DataFile.h" #include "InstrumentTrack.h" #include "LocaleHelper.h" +#include "PatternTrack.h" #include "plugin_export.h" @@ -76,7 +76,7 @@ MidiExport::~MidiExport() bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, - const TrackContainer::TrackList &tracks_BB, + const TrackContainer::TrackList &patternStoreTracks, int tempo, int masterPitch, const QString &filename) { QFile f(filename); @@ -84,7 +84,7 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, QDataStream midiout(&f); InstrumentTrack* instTrack; - BBTrack* bbTrack; + PatternTrack* patternTrack; QDomElement element; @@ -93,7 +93,7 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, uint32_t size; for (const Track* track : tracks) if (track->type() == Track::InstrumentTrack) nTracks++; - for (const Track* track : tracks_BB) if (track->type() == Track::InstrumentTrack) nTracks++; + for (const Track* track : patternStoreTracks) if (track->type() == Track::InstrumentTrack) nTracks++; // midi header MidiFile::MIDIHeader header(nTracks); @@ -145,22 +145,22 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, } } - ProcessBBNotes(midiClip, INT_MAX); + processPatternNotes(midiClip, INT_MAX); writeMidiClipToTrack(mtrack, midiClip); size = mtrack.writeToBuffer(buffer); midiout.writeRawData((char *)buffer, size); } - if (track->type() == Track::BBTrack) + if (track->type() == Track::PatternTrack) { - bbTrack = dynamic_cast(track); - element = bbTrack->saveState(dataFile, dataFile.content()); + patternTrack = dynamic_cast(track); + element = patternTrack->saveState(dataFile, dataFile.content()); std::vector> plist; for (QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling()) { - if (n.nodeName() == "bbclip") + if (n.nodeName() == "bbclip") // TODO rename to patternclip { QDomElement it = n.toElement(); int pos = it.attribute("pos", "0").toInt(); @@ -174,13 +174,15 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, } } // for each track - // midi tracks in BB tracks - for (Track* track : tracks_BB) + // for each instrument in the pattern editor + for (Track* track : patternStoreTracks) { DataFile dataFile(DataFile::SongProject); MTrack mtrack; + // begin at the first pattern track (first pattern) auto itr = plists.begin(); + std::vector> st; if (track->type() != Track::InstrumentTrack) continue; @@ -195,6 +197,7 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, int base_pitch = 0; double base_volume = 1.0; + // for each pattern in the pattern editor for (QDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling()) { if (n.nodeName() == "instrumenttrack") @@ -215,21 +218,24 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, MidiNoteVector nv, midiClip; writeMidiClip(midiClip, n, base_pitch, base_volume, 0); - // workaround for nested BBClips + + // FIXME better variable names and comments int pos = 0; int len = n.toElement().attribute("steps", "1").toInt() * 12; + + // for each pattern clip of the current pattern track (in song editor) for (auto it = plist.begin(); it != plist.end(); ++it) { while (!st.empty() && st.back().second <= it->first) { - writeBBClip(midiClip, nv, len, st.back().first, pos, st.back().second); + writePatternClip(midiClip, nv, len, st.back().first, pos, st.back().second); pos = st.back().second; st.pop_back(); } if (!st.empty() && st.back().second <= it->second) { - writeBBClip(midiClip, nv, len, st.back().first, pos, it->first); + writePatternClip(midiClip, nv, len, st.back().first, pos, it->first); pos = it->first; while (!st.empty() && st.back().second <= it->second) { @@ -243,13 +249,15 @@ bool MidiExport::tryExport(const TrackContainer::TrackList &tracks, while (!st.empty()) { - writeBBClip(midiClip, nv, len, st.back().first, pos, st.back().second); + writePatternClip(midiClip, nv, len, st.back().first, pos, st.back().second); pos = st.back().second; st.pop_back(); } - ProcessBBNotes(nv, pos); + processPatternNotes(nv, pos); writeMidiClipToTrack(mtrack, nv); + + // next pattern track ++itr; } } @@ -294,7 +302,7 @@ void MidiExport::writeMidiClipToTrack(MTrack &mtrack, MidiNoteVector &nv) -void MidiExport::writeBBClip(MidiNoteVector &src, MidiNoteVector &dst, +void MidiExport::writePatternClip(MidiNoteVector& src, MidiNoteVector& dst, int len, int base, int start, int end) { if (start >= end) { return; } @@ -318,7 +326,7 @@ void MidiExport::writeBBClip(MidiNoteVector &src, MidiNoteVector &dst, -void MidiExport::ProcessBBNotes(MidiNoteVector &nv, int cutPos) +void MidiExport::processPatternNotes(MidiNoteVector& nv, int cutPos) { std::sort(nv.begin(), nv.end()); int cur = INT_MAX, next = INT_MAX; diff --git a/plugins/MidiExport/MidiExport.h b/plugins/MidiExport/MidiExport.h index 2520b97bf..e65d5a870 100644 --- a/plugins/MidiExport/MidiExport.h +++ b/plugins/MidiExport/MidiExport.h @@ -66,16 +66,16 @@ public: } virtual bool tryExport(const TrackContainer::TrackList &tracks, - const TrackContainer::TrackList &tracks_BB, + const TrackContainer::TrackList &patternTracks, int tempo, int masterPitch, const QString &filename); private: void writeMidiClip(MidiNoteVector &midiClip, QDomNode n, int base_pitch, double base_volume, int base_time); void writeMidiClipToTrack(MTrack &mtrack, MidiNoteVector &nv); - void writeBBClip(MidiNoteVector &src, MidiNoteVector &dst, + void writePatternClip(MidiNoteVector &src, MidiNoteVector &dst, int len, int base, int start, int end); - void ProcessBBNotes(MidiNoteVector &nv, int cutPos); + void processPatternNotes(MidiNoteVector &nv, int cutPos); void error(); diff --git a/src/core/AudioEngine.cpp b/src/core/AudioEngine.cpp index 722cd3792..eae7c6f20 100644 --- a/src/core/AudioEngine.cpp +++ b/src/core/AudioEngine.cpp @@ -465,7 +465,7 @@ void AudioEngine::handleMetronome() bool metronomeSupported = currentPlayMode == Song::Mode_PlayMidiClip || currentPlayMode == Song::Mode_PlaySong - || currentPlayMode == Song::Mode_PlayBB; + || currentPlayMode == Song::Mode_PlayPattern; if (!metronomeSupported || !m_metronomeActive || song->isExporting()) { diff --git a/src/core/AutomationClip.cpp b/src/core/AutomationClip.cpp index f132fec40..419c74536 100644 --- a/src/core/AutomationClip.cpp +++ b/src/core/AutomationClip.cpp @@ -29,8 +29,8 @@ #include "AutomationNode.h" #include "AutomationClipView.h" #include "AutomationTrack.h" -#include "BBTrackContainer.h" #include "LocaleHelper.h" +#include "PatternStore.h" #include "ProjectJournal.h" #include "Song.h" @@ -57,7 +57,7 @@ AutomationClip::AutomationClip( AutomationTrack * _auto_track ) : { switch( getTrack()->trackContainer()->type() ) { - case TrackContainer::BBContainer: + case TrackContainer::PatternContainer: setAutoResize( true ); break; @@ -96,7 +96,7 @@ AutomationClip::AutomationClip( const AutomationClip & _clip_to_copy ) : if (!getTrack()){ return; } switch( getTrack()->trackContainer()->type() ) { - case TrackContainer::BBContainer: + case TrackContainer::PatternContainer: setAutoResize( true ); break; @@ -884,7 +884,7 @@ bool AutomationClip::isAutomated( const AutomatableModel * _m ) { TrackContainer::TrackList l; l += Engine::getSong()->tracks(); - l += Engine::getBBTrackContainer()->tracks(); + l += Engine::patternStore()->tracks(); l += Engine::getSong()->globalAutomationTrack(); for( TrackContainer::TrackList::ConstIterator it = l.begin(); it != l.end(); ++it ) @@ -922,7 +922,7 @@ QVector AutomationClip::clipsForModel( const AutomatableModel QVector clips; TrackContainer::TrackList l; l += Engine::getSong()->tracks(); - l += Engine::getBBTrackContainer()->tracks(); + l += Engine::patternStore()->tracks(); l += Engine::getSong()->globalAutomationTrack(); // go through all tracks... @@ -994,7 +994,7 @@ AutomationClip * AutomationClip::globalAutomationClip( void AutomationClip::resolveAllIDs() { TrackContainer::TrackList l = Engine::getSong()->tracks() + - Engine::getBBTrackContainer()->tracks(); + Engine::patternStore()->tracks(); l += Engine::getSong()->globalAutomationTrack(); for( TrackContainer::TrackList::iterator it = l.begin(); it != l.end(); ++it ) diff --git a/src/core/BBTrackContainer.cpp b/src/core/BBTrackContainer.cpp deleted file mode 100644 index 152f34a25..000000000 --- a/src/core/BBTrackContainer.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* - * BBTrackContainer.cpp - model-component of BB-Editor - * - * Copyright (c) 2004-2014 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * 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 "BBTrackContainer.h" -#include "BBTrack.h" -#include "Engine.h" -#include "Song.h" - - - -BBTrackContainer::BBTrackContainer() : - TrackContainer(), - m_bbComboBoxModel(this) -{ - connect(&m_bbComboBoxModel, SIGNAL(dataChanged()), - this, SLOT(currentBBChanged())); - // we *always* want to receive updates even in case BB actually did - // not change upon setCurrentBB()-call - connect(&m_bbComboBoxModel, SIGNAL(dataUnchanged()), - this, SLOT(currentBBChanged())); - setType(BBContainer); -} - - - - -BBTrackContainer::~BBTrackContainer() -{ -} - - - - -bool BBTrackContainer::play(TimePos start, fpp_t frames, f_cnt_t offset, int clipNum) -{ - bool notePlayed = false; - - if (lengthOfBB(clipNum) <= 0) - { - return false; - } - - start = start % (lengthOfBB(clipNum) * TimePos::ticksPerBar()); - - TrackList tl = tracks(); - for (Track * t : tl) - { - if (t->play(start, frames, offset, clipNum)) - { - notePlayed = true; - } - } - - return notePlayed; -} - - - - -void BBTrackContainer::updateAfterTrackAdd() -{ - if (numOfBBs() == 0 && !Engine::getSong()->isLoadingProject()) - { - Engine::getSong()->addBBTrack(); - } -} - - - - -bar_t BBTrackContainer::lengthOfBB(int bb) const -{ - TimePos maxLength = TimePos::ticksPerBar(); - - const TrackList & tl = tracks(); - for (Track * t : tl) - { - // Don't create Clips here if they don't exist - if (bb < t->numOfClips()) - { - maxLength = qMax(maxLength, t->getClip(bb)->length()); - } - } - - return maxLength.nextFullBar(); -} - - - - -int BBTrackContainer::numOfBBs() const -{ - return Engine::getSong()->countTracks(Track::BBTrack); -} - - - - -void BBTrackContainer::removeBB(int bb) -{ - TrackList tl = tracks(); - for (Track * t : tl) - { - delete t->getClip(bb); - t->removeBar(bb * DefaultTicksPerBar); - } - if (bb <= currentBB()) - { - setCurrentBB(qMax(currentBB() - 1, 0)); - } -} - - - - -void BBTrackContainer::swapBB(int bb1, int bb2) -{ - TrackList tl = tracks(); - for (Track * t : tl) - { - t->swapPositionOfClips(bb1, bb2); - } - updateComboBox(); -} - - - - -void BBTrackContainer::updateBBTrack(Clip * clip) -{ - BBTrack * t = BBTrack::findBBTrack(clip->startPosition() / DefaultTicksPerBar); - if (t != nullptr) - { - t->dataChanged(); - } -} - - - - -void BBTrackContainer::fixIncorrectPositions() -{ - TrackList tl = tracks(); - for (Track * t : tl) - { - for (int i = 0; i < numOfBBs(); ++i) - { - t->getClip(i)->movePosition(TimePos(i, 0)); - } - } -} - - - - -void BBTrackContainer::play() -{ - if (Engine::getSong()->playMode() != Song::Mode_PlayBB) - { - Engine::getSong()->playBB(); - } - else - { - Engine::getSong()->togglePause(); - } -} - - - - -void BBTrackContainer::stop() -{ - Engine::getSong()->stop(); -} - - - - -void BBTrackContainer::updateComboBox() -{ - const int curBB = currentBB(); - - m_bbComboBoxModel.clear(); - - for (int i = 0; i < numOfBBs(); ++i) - { - BBTrack * bbt = BBTrack::findBBTrack(i); - m_bbComboBoxModel.addItem(bbt->name()); - } - setCurrentBB(curBB); -} - - - - -void BBTrackContainer::currentBBChanged() -{ - // now update all track-labels (the current one has to become white, the others gray) - TrackList tl = Engine::getSong()->tracks(); - for (Track * t : tl) - { - if (t->type() == Track::BBTrack) - { - t->dataChanged(); - } - } -} - - - - -void BBTrackContainer::createClipsForBB(int bb) -{ - TrackList tl = tracks(); - for (Track * t : tl) - { - t->createClipsForBB(bb); - } -} - -AutomatedValueMap BBTrackContainer::automatedValuesAt(TimePos time, int clipNum) const -{ - Q_ASSERT(clipNum >= 0); - Q_ASSERT(time.getTicks() >= 0); - - auto lengthBars = lengthOfBB(clipNum); - auto lengthTicks = lengthBars * TimePos::ticksPerBar(); - if (time > lengthTicks) - { - time = lengthTicks; - } - - return TrackContainer::automatedValuesAt(time + (TimePos::ticksPerBar() * clipNum), clipNum); -} - diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 79890e112..b8809ed78 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -9,8 +9,6 @@ set(LMMS_SRCS core/AutomationNode.cpp core/BandLimitedWave.cpp core/base64.cpp - core/BBClip.cpp - core/BBTrackContainer.cpp core/BufferManager.cpp core/Clipboard.cpp core/ComboBoxModel.cpp @@ -51,6 +49,8 @@ set(LMMS_SRCS core/NotePlayHandle.cpp core/Oscillator.cpp core/PathUtil.cpp + core/PatternClip.cpp + core/PatternStore.cpp core/PeakController.cpp core/PerfLog.cpp core/Piano.cpp diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index 4d5d303b3..a46590188 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -25,11 +25,11 @@ #include "Engine.h" #include "AudioEngine.h" -#include "BBTrackContainer.h" #include "ConfigManager.h" #include "Mixer.h" #include "Ladspa2LMMS.h" #include "Lv2Manager.h" +#include "PatternStore.h" #include "Plugin.h" #include "PresetPreviewPlayHandle.h" #include "ProjectJournal.h" @@ -40,7 +40,7 @@ float LmmsCore::s_framesPerTick; AudioEngine* LmmsCore::s_audioEngine = nullptr; Mixer * LmmsCore::s_mixer = nullptr; -BBTrackContainer * LmmsCore::s_bbTrackContainer = nullptr; +PatternStore * LmmsCore::s_patternStore = nullptr; Song * LmmsCore::s_song = nullptr; ProjectJournal * LmmsCore::s_projectJournal = nullptr; #ifdef LMMS_HAVE_LV2 @@ -67,7 +67,7 @@ void LmmsCore::init( bool renderOnly ) s_audioEngine = new AudioEngine( renderOnly ); s_song = new Song; s_mixer = new Mixer; - s_bbTrackContainer = new BBTrackContainer; + s_patternStore = new PatternStore; #ifdef LMMS_HAVE_LV2 s_lv2Manager = new Lv2Manager; @@ -98,7 +98,7 @@ void LmmsCore::destroy() s_song->clearProject(); - deleteHelper( &s_bbTrackContainer ); + deleteHelper( &s_patternStore ); deleteHelper( &s_mixer ); deleteHelper( &s_audioEngine ); diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp index 2a2448274..bf72c42a4 100644 --- a/src/core/Mixer.cpp +++ b/src/core/Mixer.cpp @@ -32,8 +32,8 @@ #include "Song.h" #include "InstrumentTrack.h" +#include "PatternStore.h" #include "SampleTrack.h" -#include "BBTrackContainer.h" #include "TrackContainer.h" // For TrackContainer::TrackList typedef MixerRoute::MixerRoute( MixerChannel * from, MixerChannel * to, float amount ) : @@ -288,7 +288,7 @@ void Mixer::deleteChannel( int index ) // go through every instrument and adjust for the channel index change TrackContainer::TrackList tracks; tracks += Engine::getSong()->tracks(); - tracks += Engine::getBBTrackContainer()->tracks(); + tracks += Engine::patternStore()->tracks(); for( Track* t : tracks ) { @@ -386,9 +386,9 @@ void Mixer::moveChannelLeft( int index ) // go through every instrument and adjust for the channel index change TrackContainer::TrackList songTrackList = Engine::getSong()->tracks(); - TrackContainer::TrackList bbTrackList = Engine::getBBTrackContainer()->tracks(); + TrackContainer::TrackList patternTrackList = Engine::patternStore()->tracks(); - TrackContainer::TrackList trackLists[] = {songTrackList, bbTrackList}; + TrackContainer::TrackList trackLists[] = {songTrackList, patternTrackList}; for(int tl=0; tl<2; ++tl) { TrackContainer::TrackList trackList = trackLists[tl]; diff --git a/src/core/NotePlayHandle.cpp b/src/core/NotePlayHandle.cpp index 45b9013af..c58522bb7 100644 --- a/src/core/NotePlayHandle.cpp +++ b/src/core/NotePlayHandle.cpp @@ -68,7 +68,7 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack, m_parent( parent ), m_hadChildren( false ), m_muted( false ), - m_bbTrack( nullptr ), + m_patternTrack( nullptr ), m_origTempo( Engine::getSong()->getTempo() ), m_origBaseNote( instrumentTrack->baseNote() ), m_frequency( 0 ), @@ -92,7 +92,7 @@ NotePlayHandle::NotePlayHandle( InstrumentTrack* instrumentTrack, parent->m_subNotes.push_back( this ); parent->m_hadChildren = true; - m_bbTrack = parent->m_bbTrack; + m_patternTrack = parent->m_patternTrack; parent->setUsesBuffer( false ); } @@ -358,7 +358,7 @@ fpp_t NotePlayHandle::framesLeftForCurrentPeriod() const bool NotePlayHandle::isFromTrack( const Track * _track ) const { - return m_instrumentTrack == _track || m_bbTrack == _track; + return m_instrumentTrack == _track || m_patternTrack == _track; } diff --git a/src/core/BBClip.cpp b/src/core/PatternClip.cpp similarity index 78% rename from src/core/BBClip.cpp rename to src/core/PatternClip.cpp index 8e19cb50f..1d3586e74 100644 --- a/src/core/BBClip.cpp +++ b/src/core/PatternClip.cpp @@ -1,5 +1,5 @@ /* - * BBClip.cpp - implementation of class bbClip + * PatternClip.cpp - implementation of class PatternClip * * Copyright (c) 2004-2014 Tobias Doerffel * @@ -22,19 +22,19 @@ * */ - #include "BBClip.h" + #include "PatternClip.h" #include - #include "BBTrack.h" - #include "BBTrackContainer.h" #include "Engine.h" - + #include "PatternStore.h" + #include "PatternTrack.h" -BBClip::BBClip( Track * _track ) : - Clip( _track ) + +PatternClip::PatternClip(Track* track) : + Clip(track) { - bar_t t = Engine::getBBTrackContainer()->lengthOfBB( bbTrackIndex() ); + bar_t t = Engine::patternStore()->lengthOfPattern(patternIndex()); if( t > 0 ) { saveJournallingState( false ); @@ -44,7 +44,7 @@ BBClip::BBClip( Track * _track ) : setAutoResize( false ); } -void BBClip::saveSettings( QDomDocument & doc, QDomElement & element ) +void PatternClip::saveSettings(QDomDocument& doc, QDomElement& element) { element.setAttribute( "name", name() ); if( element.parentNode().nodeName() == "clipboard" ) @@ -66,7 +66,7 @@ void BBClip::saveSettings( QDomDocument & doc, QDomElement & element ) -void BBClip::loadSettings( const QDomElement & element ) +void PatternClip::loadSettings(const QDomElement& element) { setName( element.attribute( "name" ) ); if( element.attribute( "pos" ).toInt() >= 0 ) @@ -101,14 +101,14 @@ void BBClip::loadSettings( const QDomElement & element ) -int BBClip::bbTrackIndex() +int PatternClip::patternIndex() { - return dynamic_cast( getTrack() )->index(); + return dynamic_cast(getTrack())->patternIndex(); } -ClipView * BBClip::createView( TrackView * _tv ) +ClipView* PatternClip::createView(TrackView* tv) { - return new BBClipView( this, _tv ); -} \ No newline at end of file + return new PatternClipView(this, tv); +} diff --git a/src/core/PatternStore.cpp b/src/core/PatternStore.cpp new file mode 100644 index 000000000..a075a6edf --- /dev/null +++ b/src/core/PatternStore.cpp @@ -0,0 +1,258 @@ +/* + * PatternStore.cpp - model-component of Pattern Editor + * + * Copyright (c) 2004-2014 Tobias Doerffel + * + * This file is part of LMMS - https://lmms.io + * + * 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 "PatternStore.h" + +#include "Engine.h" +#include "PatternTrack.h" +#include "Song.h" + + + +PatternStore::PatternStore() : + TrackContainer(), + m_patternComboBoxModel(this) +{ + connect(&m_patternComboBoxModel, SIGNAL(dataChanged()), + this, SLOT(currentPatternChanged())); + // we *always* want to receive updates even in case pattern actually did + // not change upon setCurrentPattern()-call + connect(&m_patternComboBoxModel, SIGNAL(dataUnchanged()), + this, SLOT(currentPatternChanged())); + setType(PatternContainer); +} + + + + +PatternStore::~PatternStore() +{ +} + + + + +bool PatternStore::play(TimePos start, fpp_t frames, f_cnt_t offset, int clipNum) +{ + bool notePlayed = false; + + if (lengthOfPattern(clipNum) <= 0) + { + return false; + } + + start = start % (lengthOfPattern(clipNum) * TimePos::ticksPerBar()); + + TrackList tl = tracks(); + for (Track * t : tl) + { + if (t->play(start, frames, offset, clipNum)) + { + notePlayed = true; + } + } + + return notePlayed; +} + + + + +void PatternStore::updateAfterTrackAdd() +{ + if (numOfPatterns() == 0 && !Engine::getSong()->isLoadingProject()) + { + Engine::getSong()->addPatternTrack(); + } +} + + + + +bar_t PatternStore::lengthOfPattern(int pattern) const +{ + TimePos maxLength = TimePos::ticksPerBar(); + + const TrackList & tl = tracks(); + for (Track * t : tl) + { + // Don't create Clips here if they don't exist + if (pattern < t->numOfClips()) + { + maxLength = qMax(maxLength, t->getClip(pattern)->length()); + } + } + + return maxLength.nextFullBar(); +} + + + + +int PatternStore::numOfPatterns() const +{ + return Engine::getSong()->countTracks(Track::PatternTrack); +} + + + + +void PatternStore::removePattern(int pattern) +{ + TrackList tl = tracks(); + for (Track * t : tl) + { + delete t->getClip(pattern); + t->removeBar(pattern * DefaultTicksPerBar); + } + if (pattern <= currentPattern()) + { + setCurrentPattern(qMax(currentPattern() - 1, 0)); + } +} + + + + +void PatternStore::swapPattern(int pattern1, int pattern2) +{ + TrackList tl = tracks(); + for (Track * t : tl) + { + t->swapPositionOfClips(pattern1, pattern2); + } + updateComboBox(); +} + + + + +void PatternStore::updatePatternTrack(Clip* clip) +{ + PatternTrack * t = PatternTrack::findPatternTrack(clip->startPosition() / DefaultTicksPerBar); + if (t != nullptr) + { + t->dataChanged(); + } +} + + + + +void PatternStore::fixIncorrectPositions() +{ + TrackList tl = tracks(); + for (Track * t : tl) + { + for (int i = 0; i < numOfPatterns(); ++i) + { + t->getClip(i)->movePosition(TimePos(i, 0)); + } + } +} + + + + +void PatternStore::play() +{ + if (Engine::getSong()->playMode() != Song::Mode_PlayPattern) + { + Engine::getSong()->playPattern(); + } + else + { + Engine::getSong()->togglePause(); + } +} + + + + +void PatternStore::stop() +{ + Engine::getSong()->stop(); +} + + + + +void PatternStore::updateComboBox() +{ + const int curPattern = currentPattern(); + + m_patternComboBoxModel.clear(); + + for (int i = 0; i < numOfPatterns(); ++i) + { + PatternTrack* pt = PatternTrack::findPatternTrack(i); + m_patternComboBoxModel.addItem(pt->name()); + } + setCurrentPattern(curPattern); +} + + + + +void PatternStore::currentPatternChanged() +{ + // now update all track-labels (the current one has to become white, the others gray) + TrackList tl = Engine::getSong()->tracks(); + for (Track * t : tl) + { + if (t->type() == Track::PatternTrack) + { + t->dataChanged(); + } + } +} + + + + +void PatternStore::createClipsForPattern(int pattern) +{ + TrackList tl = tracks(); + for (Track * t : tl) + { + t->createClipsForPattern(pattern); + } +} + +AutomatedValueMap PatternStore::automatedValuesAt(TimePos time, int clipNum) const +{ + Q_ASSERT(clipNum >= 0); + Q_ASSERT(time.getTicks() >= 0); + + auto lengthBars = lengthOfPattern(clipNum); + auto lengthTicks = lengthBars * TimePos::ticksPerBar(); + if (time > lengthTicks) + { + time = lengthTicks; + } + + return TrackContainer::automatedValuesAt(time + (TimePos::ticksPerBar() * clipNum), clipNum); +} + diff --git a/src/core/RenderManager.cpp b/src/core/RenderManager.cpp index 4d64f3a14..69b053983 100644 --- a/src/core/RenderManager.cpp +++ b/src/core/RenderManager.cpp @@ -26,9 +26,10 @@ #include #include "RenderManager.h" + +#include "PatternStore.h" +#include "PatternTrack.h" #include "Song.h" -#include "BBTrackContainer.h" -#include "BBTrack.h" RenderManager::RenderManager( @@ -110,7 +111,7 @@ void RenderManager::renderTracks() } } - const TrackContainer::TrackList t2 = Engine::getBBTrackContainer()->tracks(); + const TrackContainer::TrackList t2 = Engine::patternStore()->tracks(); for( auto it = t2.begin(); it != t2.end(); ++it ) { Track* tk = (*it); diff --git a/src/core/SampleClip.cpp b/src/core/SampleClip.cpp index d848c6b57..a949a8078 100644 --- a/src/core/SampleClip.cpp +++ b/src/core/SampleClip.cpp @@ -67,7 +67,7 @@ SampleClip::SampleClip( Track * _track ) : switch( getTrack()->trackContainer()->type() ) { - case TrackContainer::BBContainer: + case TrackContainer::PatternContainer: setAutoResize( true ); break; diff --git a/src/core/SamplePlayHandle.cpp b/src/core/SamplePlayHandle.cpp index a904e3d34..2d5a40c6a 100644 --- a/src/core/SamplePlayHandle.cpp +++ b/src/core/SamplePlayHandle.cpp @@ -25,10 +25,10 @@ #include "SamplePlayHandle.h" #include "AudioEngine.h" #include "AudioPort.h" -#include "BBTrack.h" #include "Engine.h" #include "InstrumentTrack.h" #include "lmms_constants.h" +#include "PatternTrack.h" #include "SampleClip.h" @@ -42,7 +42,7 @@ SamplePlayHandle::SamplePlayHandle( SampleBuffer* sampleBuffer , bool ownAudioPo m_defaultVolumeModel( DefaultVolume, MinVolume, MaxVolume, 1 ), m_volumeModel( &m_defaultVolumeModel ), m_track( nullptr ), - m_bbTrack( nullptr ) + m_patternTrack( nullptr ) { if (ownAudioPort) { @@ -106,7 +106,7 @@ void SamplePlayHandle::play( sampleFrame * buffer ) } if( !( m_track && m_track->isMuted() ) - && !( m_bbTrack && m_bbTrack->isMuted() ) ) + && !(m_patternTrack && m_patternTrack->isMuted())) { /* stereoVolumeVector v = { { m_volumeModel->value() / DefaultVolume, @@ -135,7 +135,7 @@ bool SamplePlayHandle::isFinished() const bool SamplePlayHandle::isFromTrack( const Track * _track ) const { - return m_track == _track || m_bbTrack == _track; + return m_track == _track || m_patternTrack == _track; } diff --git a/src/core/SampleRecordHandle.cpp b/src/core/SampleRecordHandle.cpp index ba1d0b016..783bc8dbb 100644 --- a/src/core/SampleRecordHandle.cpp +++ b/src/core/SampleRecordHandle.cpp @@ -25,9 +25,9 @@ #include "SampleRecordHandle.h" #include "AudioEngine.h" -#include "BBTrack.h" #include "Engine.h" #include "InstrumentTrack.h" +#include "PatternTrack.h" #include "SampleBuffer.h" #include "SampleTrack.h" #include "debug.h" @@ -38,7 +38,7 @@ SampleRecordHandle::SampleRecordHandle( SampleClip* clip ) : m_framesRecorded( 0 ), m_minLength( clip->length() ), m_track( clip->getTrack() ), - m_bbTrack( nullptr ), + m_patternTrack( nullptr ), m_clip( clip ) { } @@ -94,7 +94,7 @@ bool SampleRecordHandle::isFinished() const bool SampleRecordHandle::isFromTrack( const Track * _track ) const { - return( m_track == _track || m_bbTrack == _track ); + return (m_track == _track || m_patternTrack == _track); } diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 0d48f718b..c3362a245 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -36,9 +36,6 @@ #include "AutomationTrack.h" #include "AutomationEditor.h" -#include "BBEditor.h" -#include "BBTrack.h" -#include "BBTrackContainer.h" #include "ConfigManager.h" #include "ControllerRackView.h" #include "ControllerConnection.h" @@ -51,6 +48,9 @@ #include "InstrumentTrack.h" #include "NotePlayHandle.h" #include "MidiClip.h" +#include "PatternEditor.h" +#include "PatternStore.h" +#include "PatternTrack.h" #include "PianoRoll.h" #include "ProjectJournal.h" #include "ProjectNotes.h" @@ -219,11 +219,11 @@ void Song::processNextBuffer() trackList = tracks(); break; - case Mode_PlayBB: - if (Engine::getBBTrackContainer()->numOfBBs() > 0) + case Mode_PlayPattern: + if (Engine::patternStore()->numOfPatterns() > 0) { - clipNum = Engine::getBBTrackContainer()->currentBB(); - trackList.push_back(BBTrack::findBBTrack(clipNum)); + clipNum = Engine::patternStore()->currentPattern(); + trackList.push_back(PatternTrack::findPatternTrack(clipNum)); } break; @@ -288,11 +288,11 @@ void Song::processNextBuffer() frameOffsetInTick -= elapsedTicks * framesPerTick; getPlayPos().setCurrentFrame(frameOffsetInTick); - // If we are playing a BB track, or a MIDI clip with no loop enabled, + // If we are playing a pattern track, or a MIDI clip with no loop enabled, // loop back to the beginning when we reach the end - if (m_playMode == Mode_PlayBB) + if (m_playMode == Mode_PlayPattern) { - enforceLoop(TimePos{0}, TimePos{Engine::getBBTrackContainer()->lengthOfCurrentBB(), 0}); + enforceLoop(TimePos{0}, TimePos{Engine::patternStore()->lengthOfCurrentPattern(), 0}); } else if (m_playMode == Mode_PlayMidiClip && m_loopMidiClip && !loopEnabled) { @@ -368,14 +368,13 @@ void Song::processAutomations(const TrackList &tracklist, TimePos timeStart, fpp { case Mode_PlaySong: break; - case Mode_PlayBB: + case Mode_PlayPattern: { Q_ASSERT(tracklist.size() == 1); - Q_ASSERT(tracklist.at(0)->type() == Track::BBTrack); - auto bbTrack = dynamic_cast(tracklist.at(0)); - auto bbContainer = Engine::getBBTrackContainer(); - container = bbContainer; - clipNum = bbTrack->index(); + Q_ASSERT(tracklist.at(0)->type() == Track::PatternTrack); + auto patternTrack = dynamic_cast(tracklist.at(0)); + container = Engine::patternStore(); + clipNum = patternTrack->patternIndex(); } break; default: @@ -518,14 +517,14 @@ void Song::playAndRecord() -void Song::playBB() +void Song::playPattern() { if( isStopped() == false ) { stop(); } - m_playMode = Mode_PlayBB; + m_playMode = Mode_PlayPattern; m_playing = true; m_paused = false; @@ -802,10 +801,10 @@ void Song::removeBar() -void Song::addBBTrack() +void Song::addPatternTrack() { - Track * t = Track::create( Track::BBTrack, this ); - Engine::getBBTrackContainer()->setCurrentBB( dynamic_cast( t )->index() ); + Track * t = Track::create(Track::PatternTrack, this); + Engine::patternStore()->setCurrentPattern(dynamic_cast(t)->patternIndex()); } @@ -866,9 +865,9 @@ void Song::clearProject() Engine::audioEngine()->requestChangeInModel(); - if( getGUI() != nullptr && getGUI()->getBBEditor() ) + if( getGUI() != nullptr && getGUI()->patternEditor() ) { - getGUI()->getBBEditor()->trackContainerView()->clearAllTracks(); + getGUI()->patternEditor()->m_editor->clearAllTracks(); } if( getGUI() != nullptr && getGUI()->songEditor() ) { @@ -879,7 +878,7 @@ void Song::clearProject() getGUI()->mixerView()->clear(); } QCoreApplication::sendPostedEvents(); - Engine::getBBTrackContainer()->clearAllTracks(); + Engine::patternStore()->clearAllTracks(); clearAllTracks(); Engine::mixer()->clear(); @@ -962,12 +961,11 @@ void Song::createNewProject() t = Track::create( Track::InstrumentTrack, this ); dynamic_cast( t )->loadInstrument( "tripleoscillator" ); - t = Track::create( Track::InstrumentTrack, - Engine::getBBTrackContainer() ); + t = Track::create(Track::InstrumentTrack, Engine::patternStore()); dynamic_cast( t )->loadInstrument( "kicker" ); Track::create( Track::SampleTrack, this ); - Track::create( Track::BBTrack, this ); + Track::create( Track::PatternTrack, this ); Track::create( Track::AutomationTrack, this ); m_tempoModel.setInitValue( DefaultTempo ); @@ -979,7 +977,7 @@ void Song::createNewProject() m_loadingProject = false; - Engine::getBBTrackContainer()->updateAfterTrackAdd(); + Engine::patternStore()->updateAfterTrackAdd(); Engine::projectJournal()->setJournalling( true ); @@ -1112,9 +1110,9 @@ void Song::loadProject( const QString & fileName ) if( nd.isElement() && nd.nodeName() == "track" ) { ++m_nLoadingTrack; - if( nd.toElement().attribute("type").toInt() == Track::BBTrack ) + if (nd.toElement().attribute("type").toInt() == Track::PatternTrack) { - n += nd.toElement().elementsByTagName("bbtrack").at(0) + n += nd.toElement().elementsByTagName("bbtrack").at(0) // TODO rename to patterntrack .toElement().firstChildElement().childNodes().count(); } nd=nd.nextSibling(); @@ -1169,9 +1167,8 @@ void Song::loadProject( const QString & fileName ) node = node.nextSibling(); } - // quirk for fixing projects with broken positions of Clips inside - // BB-tracks - Engine::getBBTrackContainer()->fixIncorrectPositions(); + // quirk for fixing projects with broken positions of Clips inside pattern tracks + Engine::patternStore()->fixIncorrectPositions(); // Connect controller links to their controllers // now that everything is loaded @@ -1396,12 +1393,12 @@ void Song::exportProjectMidi(QString const & exportFileName) const { // instantiate midi export plugin TrackContainer::TrackList const & tracks = this->tracks(); - TrackContainer::TrackList const & tracks_BB = Engine::getBBTrackContainer()->tracks(); + TrackContainer::TrackList const & patternStoreTracks = Engine::patternStore()->tracks(); ExportFilter *exf = dynamic_cast (Plugin::instantiate("midiexport", nullptr, nullptr)); if (exf) { - exf->tryExport(tracks, tracks_BB, getTempo(), m_masterPitchModel.value(), exportFileName); + exf->tryExport(tracks, patternStoreTracks, getTempo(), m_masterPitchModel.value(), exportFileName); } else { diff --git a/src/core/Track.cpp b/src/core/Track.cpp index 800662256..58cbd8ccb 100644 --- a/src/core/Track.cpp +++ b/src/core/Track.cpp @@ -33,11 +33,11 @@ #include "AutomationClip.h" #include "AutomationTrack.h" -#include "BBTrack.h" -#include "BBTrackContainer.h" #include "ConfigManager.h" #include "Engine.h" #include "InstrumentTrack.h" +#include "PatternStore.h" +#include "PatternTrack.h" #include "SampleTrack.h" #include "Song.h" @@ -47,7 +47,7 @@ * The track object is the whole track, linking its contents, its * automation, name, type, and so forth. * - * \param type The type of track (Song Editor or Beat+Bassline Editor) + * \param type The type of track (Song Editor or Pattern Editor) * \param tc The track Container object to encapsulate in this track. * * \todo check the definitions of all the properties - are they OK? @@ -73,13 +73,7 @@ Track::Track( TrackTypes type, TrackContainer * tc ) : /*! \brief Destroy this track * - * If the track container is a Beat+Bassline container, step through - * its list of tracks and remove us. - * - * Then delete the Clip's contents, remove this track from - * the track container. - * - * Finally step through this track's automation and forget all of them. + * Delete the clips and remove this track from the track container. */ Track::~Track() { @@ -112,7 +106,7 @@ Track * Track::create( TrackTypes tt, TrackContainer * tc ) switch( tt ) { case InstrumentTrack: t = new ::InstrumentTrack( tc ); break; - case BBTrack: t = new ::BBTrack( tc ); break; + case PatternTrack: t = new ::PatternTrack( tc ); break; case SampleTrack: t = new ::SampleTrack( tc ); break; // case EVENT_TRACK: // case VIDEO_TRACK: @@ -122,10 +116,9 @@ Track * Track::create( TrackTypes tt, TrackContainer * tc ) default: break; } - if( tc == Engine::getBBTrackContainer() && t ) + if (tc == Engine::patternStore() && t) { - t->createClipsForBB( Engine::getBBTrackContainer()->numOfBBs() - - 1 ); + t->createClipsForPattern(Engine::patternStore()->numOfPatterns() - 1); } tc->updateAfterTrackAdd(); @@ -217,8 +210,7 @@ void Track::saveSettings( QDomDocument & doc, QDomElement & element ) } QDomElement tsDe = doc.createElement( nodeName() ); - // let actual track (InstrumentTrack, bbTrack, sampleTrack etc.) save - // its settings + // let actual track (InstrumentTrack, PatternTrack, SampleTrack etc.) save its settings element.appendChild( tsDe ); saveTrackSpecificSettings( doc, tsDe ); @@ -491,9 +483,9 @@ void Track::swapPositionOfClips( int clipNum1, int clipNum2 ) -void Track::createClipsForBB( int bb ) +void Track::createClipsForPattern(int pattern) { - while( numOfClips() < bb + 1 ) + while( numOfClips() < pattern + 1 ) { TimePos position = TimePos( numOfClips(), 0 ); Clip * clip = createClip( position ); diff --git a/src/core/TrackContainer.cpp b/src/core/TrackContainer.cpp index 881e76d9f..36e744725 100644 --- a/src/core/TrackContainer.cpp +++ b/src/core/TrackContainer.cpp @@ -1,6 +1,6 @@ /* * TrackContainer.cpp - implementation of base class for all trackcontainers - * like Song-Editor, BB-Editor... + * like Song-Editor, Pattern Editor... * * Copyright (c) 2004-2014 Tobias Doerffel * @@ -31,11 +31,11 @@ #include "AutomationClip.h" #include "AutomationTrack.h" -#include "BBTrack.h" -#include "BBTrackContainer.h" #include "embed.h" #include "TrackContainer.h" #include "InstrumentTrack.h" +#include "PatternStore.h" +#include "PatternTrack.h" #include "Song.h" #include "GuiApplication.h" @@ -268,7 +268,7 @@ AutomatedValueMap TrackContainer::automatedValuesFromTracks(const TrackList &tra { case Track::AutomationTrack: case Track::HiddenAutomationTrack: - case Track::BBTrack: + case Track::PatternTrack: if (clipNum < 0) { track->getClipsInRange(clips, 0, time); } else { @@ -306,19 +306,19 @@ AutomatedValueMap TrackContainer::automatedValuesFromTracks(const TrackList &tra valueMap[model] = value; } } - else if (auto* bb = dynamic_cast(clip)) + else if (auto* pattern = dynamic_cast(clip)) { - auto bbIndex = dynamic_cast(bb->getTrack())->index(); - auto bbContainer = Engine::getBBTrackContainer(); + auto patIndex = dynamic_cast(pattern->getTrack())->patternIndex(); + auto patStore = Engine::patternStore(); - TimePos bbTime = time - clip->startPosition(); - bbTime = std::min(bbTime, clip->length()); - bbTime = bbTime % (bbContainer->lengthOfBB(bbIndex) * TimePos::ticksPerBar()); + TimePos patTime = time - clip->startPosition(); + patTime = std::min(patTime, clip->length()); + patTime = patTime % (patStore->lengthOfPattern(patIndex) * TimePos::ticksPerBar()); - auto bbValues = bbContainer->automatedValuesAt(bbTime, bbIndex); - for (auto it=bbValues.begin(); it != bbValues.end(); it++) + auto patValues = patStore->automatedValuesAt(patTime, patIndex); + for (auto it=patValues.begin(); it != patValues.end(); it++) { - // override old values, bb track with the highest index takes precedence + // override old values, pattern track with the highest index takes precedence valueMap[it.key()] = it.value(); } } diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 757eb1c9c..d657a682d 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -9,8 +9,6 @@ SET(LMMS_SRCS gui/AutomationTrackView.cpp gui/ControllerConnectionDialog.cpp gui/ControllerDialog.cpp - gui/BBClipView.cpp - gui/BBTrackView.cpp gui/EffectControlDialog.cpp gui/EffectSelectDialog.cpp gui/embed.cpp @@ -31,6 +29,8 @@ SET(LMMS_SRCS gui/MidiClipView.cpp gui/MidiSetupWidget.cpp gui/ModelView.cpp + gui/PatternClipView.cpp + gui/PatternTrackView.cpp gui/PeakControllerDialog.cpp gui/PianoView.cpp gui/PluginBrowser.cpp @@ -52,8 +52,8 @@ SET(LMMS_SRCS gui/dialogs/ColorChooser.cpp gui/editors/AutomationEditor.cpp - gui/editors/BBEditor.cpp gui/editors/Editor.cpp + gui/editors/PatternEditor.cpp gui/editors/PianoRoll.cpp gui/editors/SongEditor.cpp diff --git a/src/gui/ClipView.cpp b/src/gui/ClipView.cpp index e77ebd67d..3a7eda4f9 100644 --- a/src/gui/ClipView.cpp +++ b/src/gui/ClipView.cpp @@ -91,7 +91,7 @@ ClipView::ClipView( Clip * clip, m_selectedColor( 0, 0, 0 ), m_textColor( 0, 0, 0 ), m_textShadowColor( 0, 0, 0 ), - m_BBClipBackground( 0, 0, 0 ), + m_patternClipBackground( 0, 0, 0 ), m_gradient( true ), m_mouseHotspotHand( 0, 0 ), m_mouseHotspotKnife( 0, 0 ), @@ -219,8 +219,8 @@ QColor ClipView::textBackgroundColor() const QColor ClipView::textShadowColor() const { return m_textShadowColor; } -QColor ClipView::BBClipBackground() const -{ return m_BBClipBackground; } +QColor ClipView::patternClipBackground() const +{ return m_patternClipBackground; } bool ClipView::gradient() const { return m_gradient; } @@ -246,8 +246,8 @@ void ClipView::setTextBackgroundColor( const QColor & c ) void ClipView::setTextShadowColor( const QColor & c ) { m_textShadowColor = QColor( c ); } -void ClipView::setBBClipBackground( const QColor & c ) -{ m_BBClipBackground = QColor( c ); } +void ClipView::setPatternClipBackground( const QColor & c ) +{ m_patternClipBackground = QColor( c ); } void ClipView::setGradient( const bool & b ) { m_gradient = b; } diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 4a37aac91..77a298aa5 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -38,7 +38,6 @@ #include "FileBrowser.h" #include "AudioEngine.h" -#include "BBTrackContainer.h" #include "ConfigManager.h" #include "DataFile.h" #include "embed.h" @@ -50,6 +49,7 @@ #include "InstrumentTrack.h" #include "InstrumentTrackWindow.h" #include "MainWindow.h" +#include "PatternStore.h" #include "PluginFactory.h" #include "PresetPreviewPlayHandle.h" #include "SamplePlayHandle.h" @@ -450,7 +450,7 @@ void FileBrowserTreeWidget::keyPressEvent(QKeyEvent * ke ) // When enter is pressed, add the selected item... if (insert) { - // ...to the song editor by default, or to the BB editor if ctrl is held + // ...to the song editor by default, or to the pattern editor if ctrl is held bool songEditor = !(ke->modifiers() & Qt::ControlModifier); // If shift is held, we send the item to a new sample track... bool sampleTrack = ke->modifiers() & Qt::ShiftModifier; @@ -521,9 +521,9 @@ void FileBrowserTreeWidget::contextMenuEvent(QContextMenuEvent * e ) contextMenu.addAction( songEditorHeader ); contextMenu.addActions( getContextActions(file, true) ); - QAction* bbEditorHeader = new QAction( tr("BB Editor"), nullptr ); - bbEditorHeader->setDisabled(true); - contextMenu.addAction( bbEditorHeader ); + QAction* patternEditorHeader = new QAction(tr("Pattern Editor"), nullptr); + patternEditorHeader->setDisabled(true); + contextMenu.addAction(patternEditorHeader); contextMenu.addActions( getContextActions(file, false) ); // We should only show the menu if it contains items @@ -815,8 +815,8 @@ void FileBrowserTreeWidget::activateListItem(QTreeWidgetItem * item, else if( f->handling() != FileItem::NotSupported ) { InstrumentTrack * it = dynamic_cast( - Track::create( Track::InstrumentTrack, - Engine::getBBTrackContainer() ) ); + Track::create(Track::InstrumentTrack, Engine::patternStore()) + ); handleFile( f, it ); } } @@ -841,7 +841,7 @@ void FileBrowserTreeWidget::openInNewInstrumentTrack(FileItem* item, bool songEd { // Get the correct TrackContainer. Ternary doesn't compile here TrackContainer* tc = Engine::getSong(); - if (!songEditor) { tc = Engine::getBBTrackContainer(); } + if (!songEditor) { tc = Engine::patternStore(); } openInNewInstrumentTrack(tc, item); } diff --git a/src/gui/GuiApplication.cpp b/src/gui/GuiApplication.cpp index 90c9c95f7..15c44fb82 100644 --- a/src/gui/GuiApplication.cpp +++ b/src/gui/GuiApplication.cpp @@ -30,13 +30,13 @@ #include "LmmsPalette.h" #include "AutomationEditor.h" -#include "BBEditor.h" #include "ConfigManager.h" #include "ControllerRackView.h" #include "MixerView.h" #include "InstrumentTrack.h" #include "MainWindow.h" #include "MicrotunerConfig.h" +#include "PatternEditor.h" #include "PianoRoll.h" #include "ProjectNotes.h" #include "SongEditor.h" @@ -153,9 +153,9 @@ GuiApplication::GuiApplication() m_microtunerConfig = new MicrotunerConfig; connect(m_microtunerConfig, SIGNAL(destroyed(QObject*)), this, SLOT(childDestroyed(QObject*))); - displayInitProgress(tr("Preparing beat/bassline editor")); - m_bbEditor = new BBEditor(Engine::getBBTrackContainer()); - connect(m_bbEditor, SIGNAL(destroyed(QObject*)), this, SLOT(childDestroyed(QObject*))); + displayInitProgress(tr("Preparing pattern editor")); + m_patternEditor = new PatternEditorWindow(Engine::patternStore()); + connect(m_patternEditor, SIGNAL(destroyed(QObject*)), this, SLOT(childDestroyed(QObject*))); displayInitProgress(tr("Preparing piano roll")); m_pianoRoll = new PianoRollWindow(); @@ -207,9 +207,9 @@ void GuiApplication::childDestroyed(QObject *obj) { m_automationEditor = nullptr; } - else if (obj == m_bbEditor) + else if (obj == m_patternEditor) { - m_bbEditor = nullptr; + m_patternEditor = nullptr; } else if (obj == m_pianoRoll) { diff --git a/src/gui/InstrumentTrackWindow.cpp b/src/gui/InstrumentTrackWindow.cpp index eb6f7c410..d59ec940f 100644 --- a/src/gui/InstrumentTrackWindow.cpp +++ b/src/gui/InstrumentTrackWindow.cpp @@ -650,7 +650,7 @@ void InstrumentTrackWindow::viewInstrumentInDirection(int d) newView->m_tlb->setChecked(true); newView->getInstrumentTrackWindow()->parentWidget()->move(curPos); - // scroll the SongEditor/BB-editor to make sure the new trackview label is visible + // scroll the SongEditor/PatternEditor to make sure the new trackview label is visible bringToFront->trackContainerView()->scrollToTrackView(bringToFront); // get the instrument window to refresh diff --git a/src/gui/LmmsStyle.cpp b/src/gui/LmmsStyle.cpp index 5d1b29945..c5a08220b 100644 --- a/src/gui/LmmsStyle.cpp +++ b/src/gui/LmmsStyle.cpp @@ -115,7 +115,7 @@ void drawPath( QPainter *p, const QPainterPath &path, p->setOpacity(0.5); - // highlight (bb) + // highlight (pattern) if (dark) p->strokePath(path, QPen(borderCol.lighter(133), 2)); else diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index f3ac68aae..5bc30947a 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -41,7 +41,6 @@ #include "AboutDialog.h" #include "AudioDummy.h" #include "AutomationEditor.h" -#include "BBEditor.h" #include "ControllerRackView.h" #include "embed.h" #include "Engine.h" @@ -54,6 +53,7 @@ #include "InstrumentTrackView.h" #include "InstrumentTrackWindow.h" #include "MicrotunerConfig.h" +#include "PatternEditor.h" #include "PianoRoll.h" #include "PianoView.h" #include "PluginBrowser.h" @@ -500,13 +500,12 @@ void MainWindow::finalize() song_editor_window->setShortcut( Qt::CTRL + Qt::Key_1 ); - ToolButton * bb_editor_window = new ToolButton( - embed::getIconPixmap( "bb_track_btn" ), - tr( "Beat+Bassline Editor" ) + - " (Ctrl+2)", - this, SLOT( toggleBBEditorWin() ), - m_toolBar ); - bb_editor_window->setShortcut( Qt::CTRL + Qt::Key_2 ); + ToolButton* pattern_editor_window = new ToolButton( + embed::getIconPixmap("pattern_track_btn"), + tr("Pattern Editor") + " (Ctrl+2)", + this, SLOT(togglePatternEditorWin()), + m_toolBar); + pattern_editor_window->setShortcut(Qt::CTRL + Qt::Key_2); ToolButton * piano_roll_window = new ToolButton( @@ -558,7 +557,7 @@ void MainWindow::finalize() microtuner_window->setShortcut( Qt::CTRL + Qt::Key_8 ); m_toolBarLayout->addWidget( song_editor_window, 1, 1 ); - m_toolBarLayout->addWidget( bb_editor_window, 1, 2 ); + m_toolBarLayout->addWidget( pattern_editor_window, 1, 2 ); m_toolBarLayout->addWidget( piano_roll_window, 1, 3 ); m_toolBarLayout->addWidget( automation_editor_window, 1, 4 ); m_toolBarLayout->addWidget( mixer_window, 1, 5 ); @@ -589,7 +588,7 @@ void MainWindow::finalize() // Add editor subwindows for (QWidget* widget : std::list{ getGUI()->automationEditor(), - getGUI()->getBBEditor(), + getGUI()->patternEditor(), getGUI()->pianoRoll(), getGUI()->songEditor() }) @@ -601,8 +600,8 @@ void MainWindow::finalize() } getGUI()->automationEditor()->parentWidget()->hide(); - getGUI()->getBBEditor()->parentWidget()->move( 610, 5 ); - getGUI()->getBBEditor()->parentWidget()->hide(); + getGUI()->patternEditor()->parentWidget()->move(610, 5); + getGUI()->patternEditor()->parentWidget()->hide(); getGUI()->pianoRoll()->parentWidget()->move(5, 5); getGUI()->pianoRoll()->parentWidget()->hide(); getGUI()->songEditor()->parentWidget()->move(5, 5); @@ -1056,7 +1055,7 @@ void MainWindow::refocus() QList editors; editors << getGUI()->songEditor()->parentWidget() - << getGUI()->getBBEditor()->parentWidget() + << getGUI()->patternEditor()->parentWidget() << getGUI()->pianoRoll()->parentWidget() << getGUI()->automationEditor()->parentWidget(); @@ -1078,9 +1077,9 @@ void MainWindow::refocus() -void MainWindow::toggleBBEditorWin( bool forceShow ) +void MainWindow::togglePatternEditorWin( bool forceShow ) { - toggleWindow( getGUI()->getBBEditor(), forceShow ); + toggleWindow( getGUI()->patternEditor(), forceShow ); } @@ -1143,9 +1142,9 @@ void MainWindow::updateViewMenu() tr( "Song Editor" ) + "\tCtrl+1", this, SLOT( toggleSongEditorWin() ) ); - m_viewMenu->addAction(embed::getIconPixmap( "bb_track" ), - tr( "Beat+Bassline Editor" ) + "\tCtrl+2", - this, SLOT( toggleBBEditorWin() ) + m_viewMenu->addAction(embed::getIconPixmap("pattern_track"), + tr("Pattern Editor") + "\tCtrl+2", + this, SLOT(togglePatternEditorWin()) ); m_viewMenu->addAction(embed::getIconPixmap( "piano" ), tr( "Piano Roll" ) + "\tCtrl+3", @@ -1279,7 +1278,7 @@ void MainWindow::updatePlayPauseIcons() { getGUI()->songEditor()->setPauseIcon( false ); getGUI()->automationEditor()->setPauseIcon( false ); - getGUI()->getBBEditor()->setPauseIcon( false ); + getGUI()->patternEditor()->setPauseIcon( false ); getGUI()->pianoRoll()->setPauseIcon( false ); if( Engine::getSong()->isPlaying() ) @@ -1294,8 +1293,8 @@ void MainWindow::updatePlayPauseIcons() getGUI()->automationEditor()->setPauseIcon( true ); break; - case Song::Mode_PlayBB: - getGUI()->getBBEditor()->setPauseIcon( true ); + case Song::Mode_PlayPattern: + getGUI()->patternEditor()->setPauseIcon( true ); break; case Song::Mode_PlayMidiClip: diff --git a/src/gui/MidiClipView.cpp b/src/gui/MidiClipView.cpp index 913c8df67..354b77adf 100644 --- a/src/gui/MidiClipView.cpp +++ b/src/gui/MidiClipView.cpp @@ -43,7 +43,8 @@ MidiClipView::MidiClipView( MidiClip* clip, TrackView* parent ) : m_noteBorderColor(255, 255, 255, 220), m_mutedNoteFillColor(100, 100, 100, 220), m_mutedNoteBorderColor(100, 100, 100, 220), - m_legacySEBB(ConfigManager::inst()->value("ui","legacysebb","0").toInt()) + // TODO if this option is ever added to the GUI, rename it to legacysepattern + m_legacySEPattern(ConfigManager::inst()->value("ui", "legacysebb", "0").toInt()) { connect( getGUI()->pianoRoll(), SIGNAL( currentMidiClipChanged() ), this, SLOT( update() ) ); @@ -182,12 +183,12 @@ void MidiClipView::constructContextMenu( QMenu * _cm ) void MidiClipView::mousePressEvent( QMouseEvent * _me ) { - bool displayBB = fixedClips() || (pixelsPerBar() >= 96 && m_legacySEBB); + bool displayPattern = fixedClips() || (pixelsPerBar() >= 96 && m_legacySEPattern); if( _me->button() == Qt::LeftButton && m_clip->m_clipType == MidiClip::BeatClip && - displayBB && _me->y() > height() - s_stepBtnOff->height() ) + displayPattern && _me->y() > height() - s_stepBtnOff->height() ) - // when mouse button is pressed in beat/bassline -mode + // when mouse button is pressed in pattern mode { // get the step number that was clicked on and @@ -228,7 +229,7 @@ void MidiClipView::mousePressEvent( QMouseEvent * _me ) } else - // if not in beat/bassline -mode, let parent class handle the event + // if not in pattern mode, let parent class handle the event { ClipView::mousePressEvent( _me ); @@ -335,8 +336,8 @@ void MidiClipView::paintEvent( QPaintEvent * ) if( beatClip ) { - // Do not paint BBClips how we paint MidiClips - c = BBClipBackground(); + // Do not paint PatternClips how we paint MidiClips + c = patternClipBackground(); } else { @@ -388,7 +389,7 @@ void MidiClipView::paintEvent( QPaintEvent * ) const int x_base = CLIP_BORDER_WIDTH; - bool displayBB = fixedClips() || (pixelsPerBar >= 96 && m_legacySEBB); + bool displayPattern = fixedClips() || (pixelsPerBar >= 96 && m_legacySEPattern); // melody clip paint event NoteVector const & noteCollection = m_clip->m_notes; if( m_clip->m_clipType == MidiClip::MelodyClip && !noteCollection.empty() ) @@ -505,7 +506,7 @@ void MidiClipView::paintEvent( QPaintEvent * ) p.restore(); } // beat clip paint event - else if( beatClip && displayBB ) + else if (beatClip && displayPattern) { QPixmap stepon0; QPixmap stepon200; diff --git a/src/gui/MixerView.cpp b/src/gui/MixerView.cpp index 2cae9ad6f..368206bb5 100644 --- a/src/gui/MixerView.cpp +++ b/src/gui/MixerView.cpp @@ -47,9 +47,9 @@ #include "AudioEngine.h" #include "gui_templates.h" #include "InstrumentTrack.h" +#include "PatternStore.h" #include "SampleTrack.h" #include "Song.h" -#include "BBTrackContainer.h" #include "TrackContainer.h" // For TrackContainer::TrackList typedef MixerView::MixerView() : @@ -238,10 +238,10 @@ void MixerView::refreshDisplay() // update the and max. channel number for every instrument void MixerView::updateMaxChannelSelector() { - TrackContainer::TrackList songTrackList = Engine::getSong()->tracks(); - TrackContainer::TrackList bbTrackList = Engine::getBBTrackContainer()->tracks(); + TrackContainer::TrackList songTracks = Engine::getSong()->tracks(); + TrackContainer::TrackList patternStoreTracks = Engine::patternStore()->tracks(); - TrackContainer::TrackList trackLists[] = {songTrackList, bbTrackList}; + TrackContainer::TrackList trackLists[] = {songTracks, patternStoreTracks}; for(int tl=0; tl<2; ++tl) { TrackContainer::TrackList trackList = trackLists[tl]; @@ -435,7 +435,7 @@ void MixerView::deleteUnusedChannels() { TrackContainer::TrackList tracks; tracks += Engine::getSong()->tracks(); - tracks += Engine::getBBTrackContainer()->tracks(); + tracks += Engine::patternStore()->tracks(); std::vector inUse(m_mixerChannelViews.size(), false); diff --git a/src/gui/BBClipView.cpp b/src/gui/PatternClipView.cpp similarity index 74% rename from src/gui/BBClipView.cpp rename to src/gui/PatternClipView.cpp index d0e832526..6389e6cb0 100644 --- a/src/gui/BBClipView.cpp +++ b/src/gui/PatternClipView.cpp @@ -1,5 +1,5 @@ /* - * BBClipView.cpp + * PatternClipView.cpp * * Copyright (c) 2004-2014 Tobias Doerffel * @@ -22,23 +22,23 @@ * */ -#include "BBClipView.h" +#include "PatternClipView.h" #include #include -#include "BBEditor.h" -#include "BBTrackContainer.h" #include "gui_templates.h" #include "GuiApplication.h" #include "MainWindow.h" +#include "PatternEditor.h" +#include "PatternStore.h" #include "RenameDialog.h" #include "Song.h" #include "ToolTip.h" -BBClipView::BBClipView( Clip * _clip, TrackView * _tv ) : +PatternClipView::PatternClipView(Clip* _clip, TrackView* _tv) : ClipView( _clip, _tv ), - m_bbClip( dynamic_cast( _clip ) ), + m_patternClip(dynamic_cast(_clip)), m_paintPixmap() { connect( _clip->getTrack(), SIGNAL( dataChanged() ), @@ -47,14 +47,14 @@ BBClipView::BBClipView( Clip * _clip, TrackView * _tv ) : setStyle( QApplication::style() ); } -void BBClipView::constructContextMenu( QMenu * _cm ) +void PatternClipView::constructContextMenu(QMenu* _cm) { - QAction * a = new QAction( embed::getIconPixmap( "bb_track" ), - tr( "Open in Beat+Bassline-Editor" ), + QAction* a = new QAction(embed::getIconPixmap("pattern_track"), + tr("Open in Pattern Editor"), _cm ); _cm->insertAction( _cm->actions()[0], a ); connect( a, SIGNAL( triggered( bool ) ), - this, SLOT( openInBBEditor() ) ); + this, SLOT( openInPatternEditor() ) ); _cm->insertSeparator( _cm->actions()[1] ); _cm->addSeparator(); _cm->addAction( embed::getIconPixmap( "reload" ), tr( "Reset name" ), @@ -67,15 +67,15 @@ void BBClipView::constructContextMenu( QMenu * _cm ) -void BBClipView::mouseDoubleClickEvent( QMouseEvent * ) +void PatternClipView::mouseDoubleClickEvent(QMouseEvent*) { - openInBBEditor(); + openInPatternEditor(); } -void BBClipView::paintEvent( QPaintEvent * ) +void PatternClipView::paintEvent(QPaintEvent*) { QPainter painter( this ); @@ -116,8 +116,8 @@ void BBClipView::paintEvent( QPaintEvent * ) const int lineSize = 3; p.setPen( c.darker( 200 ) ); - bar_t t = Engine::getBBTrackContainer()->lengthOfBB( m_bbClip->bbTrackIndex() ); - if( m_bbClip->length() > TimePos::ticksPerBar() && t > 0 ) + bar_t t = Engine::patternStore()->lengthOfPattern(m_patternClip->patternIndex()); + if (m_patternClip->length() > TimePos::ticksPerBar() && t > 0) { for( int x = static_cast( t * pixelsPerBar() ); x < width() - 2; @@ -130,7 +130,7 @@ void BBClipView::paintEvent( QPaintEvent * ) } // clip name - paintTextLabel(m_bbClip->name(), p); + paintTextLabel(m_patternClip->name(), p); // inner border p.setPen( c.lighter( 130 ) ); @@ -142,7 +142,7 @@ void BBClipView::paintEvent( QPaintEvent * ) p.drawRect( 0, 0, rect().right(), rect().bottom() ); // draw the 'muted' pixmap only if the clip was manualy muted - if( m_bbClip->isMuted() ) + if (m_patternClip->isMuted()) { const int spacing = CLIP_BORDER_WIDTH; const int size = 14; @@ -158,34 +158,34 @@ void BBClipView::paintEvent( QPaintEvent * ) -void BBClipView::openInBBEditor() +void PatternClipView::openInPatternEditor() { - Engine::getBBTrackContainer()->setCurrentBB( m_bbClip->bbTrackIndex() ); + Engine::patternStore()->setCurrentPattern(m_patternClip->patternIndex()); - getGUI()->mainWindow()->toggleBBEditorWin( true ); + getGUI()->mainWindow()->togglePatternEditorWin(true); } -void BBClipView::resetName() { m_bbClip->setName(""); } +void PatternClipView::resetName() { m_patternClip->setName(""); } -void BBClipView::changeName() +void PatternClipView::changeName() { - QString s = m_bbClip->name(); + QString s = m_patternClip->name(); RenameDialog rename_dlg( s ); rename_dlg.exec(); - m_bbClip->setName( s ); + m_patternClip->setName(s); } -void BBClipView::update() +void PatternClipView::update() { - ToolTip::add(this, m_bbClip->name()); + ToolTip::add(this, m_patternClip->name()); ClipView::update(); -} \ No newline at end of file +} diff --git a/src/gui/BBTrackView.cpp b/src/gui/PatternTrackView.cpp similarity index 58% rename from src/gui/BBTrackView.cpp rename to src/gui/PatternTrackView.cpp index 8bec7e8ef..9d8607571 100644 --- a/src/gui/BBTrackView.cpp +++ b/src/gui/PatternTrackView.cpp @@ -1,5 +1,5 @@ /* - * BBTrackView.cpp + * PatternTrackView.cpp * * Copyright (c) 2004-2014 Tobias Doerffel * @@ -22,55 +22,54 @@ * */ -#include "BBTrackView.h" +#include "PatternTrackView.h" -#include "BBEditor.h" -#include "BBTrackContainer.h" #include "Engine.h" #include "GuiApplication.h" +#include "PatternEditor.h" +#include "PatternStore.h" #include "TrackLabelButton.h" -BBTrackView::BBTrackView( BBTrack * _bbt, TrackContainerView* tcv ) : - TrackView( _bbt, tcv ), - m_bbTrack( _bbt ) +PatternTrackView::PatternTrackView(PatternTrack* pt, TrackContainerView* tcv) : + TrackView(pt, tcv), + m_patternTrack(pt) { setFixedHeight( 32 ); - // drag'n'drop with bb-tracks only causes troubles (and makes no sense - // too), so disable it + // drag'n'drop with pattern tracks only causes troubles (and makes no sense too), so disable it setAcceptDrops( false ); m_trackLabel = new TrackLabelButton( this, getTrackSettingsWidget() ); - m_trackLabel->setIcon( embed::getIconPixmap( "bb_track" ) ); + m_trackLabel->setIcon( embed::getIconPixmap("pattern_track")); m_trackLabel->move( 3, 1 ); m_trackLabel->show(); connect( m_trackLabel, SIGNAL( clicked( bool ) ), this, SLOT( clickedTrackLabel() ) ); - setModel( _bbt ); + setModel(pt); } -BBTrackView::~BBTrackView() +PatternTrackView::~PatternTrackView() { - getGUI()->getBBEditor()->removeBBView( BBTrack::s_infoMap[m_bbTrack] ); + getGUI()->patternEditor()->m_editor->removeViewsForPattern(PatternTrack::s_infoMap[m_patternTrack]); } -bool BBTrackView::close() +bool PatternTrackView::close() { - getGUI()->getBBEditor()->removeBBView( BBTrack::s_infoMap[m_bbTrack] ); + getGUI()->patternEditor()->m_editor->removeViewsForPattern(PatternTrack::s_infoMap[m_patternTrack]); return TrackView::close(); } -void BBTrackView::clickedTrackLabel() +void PatternTrackView::clickedTrackLabel() { - Engine::getBBTrackContainer()->setCurrentBB( m_bbTrack->index() ); - getGUI()->getBBEditor()->parentWidget()->show(); - getGUI()->getBBEditor()->setFocus( Qt::ActiveWindowFocusReason ); -} \ No newline at end of file + Engine::patternStore()->setCurrentPattern(m_patternTrack->patternIndex()); + getGUI()->patternEditor()->parentWidget()->show(); + getGUI()->patternEditor()->setFocus(Qt::ActiveWindowFocusReason); +} diff --git a/src/gui/PluginBrowser.cpp b/src/gui/PluginBrowser.cpp index 0f8a07f78..b677638a1 100644 --- a/src/gui/PluginBrowser.cpp +++ b/src/gui/PluginBrowser.cpp @@ -55,8 +55,8 @@ PluginBrowser::PluginBrowser( QWidget * _parent ) : auto hint = new QLabel( tr( "Drag an instrument " - "into either the Song-Editor, the " - "Beat+Bassline Editor or into an " + "into either the Song Editor, the " + "Pattern Editor or into an " "existing instrument track." ), m_view ); hint->setWordWrap( true ); diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp index 7201427be..9a5968723 100644 --- a/src/gui/TrackContainerView.cpp +++ b/src/gui/TrackContainerView.cpp @@ -34,13 +34,13 @@ #include "TrackContainer.h" #include "AudioEngine.h" -#include "BBTrack.h" #include "DataFile.h" #include "MainWindow.h" #include "FileBrowser.h" #include "ImportFilter.h" #include "Instrument.h" #include "InstrumentTrack.h" +#include "PatternTrack.h" #include "Song.h" #include "StringPairDrag.h" #include "GuiApplication.h" @@ -165,7 +165,7 @@ void TrackContainerView::moveTrackView( TrackView * trackView, int indexTo ) int indexFrom = m_trackViews.indexOf( trackView ); if ( indexFrom == indexTo ) { return; } - BBTrack::swapBBTracks( trackView->getTrack(), + PatternTrack::swapPatternTracks( trackView->getTrack(), m_trackViews[indexTo]->getTrack() ); m_scrollLayout->removeWidget( trackView ); @@ -471,7 +471,7 @@ TrackContainerView::scrollArea::~scrollArea() void TrackContainerView::scrollArea::wheelEvent( QWheelEvent * _we ) { // always pass wheel-event to parent-widget (song-editor - // bb-editor etc.) because they might want to use it for zooming + // pattern-editor etc.) because they might want to use it for zooming // or scrolling left/right if a modifier-key is pressed, otherwise // they do not accept it and we pass it up to QScrollArea m_trackContainerView->wheelEvent( _we ); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index ce32d6b25..77121e7b9 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -46,7 +46,6 @@ #include "ActionGroup.h" #include "AutomationNode.h" -#include "BBTrackContainer.h" #include "ComboBox.h" #include "debug.h" #include "DeprecationHelper.h" @@ -55,6 +54,7 @@ #include "GuiApplication.h" #include "gui_templates.h" #include "MainWindow.h" +#include "PatternStore.h" #include "PianoRoll.h" #include "ProjectJournal.h" #include "SongEditor.h" @@ -1508,10 +1508,9 @@ float AutomationEditor::getLevel(int y ) -inline bool AutomationEditor::inBBEditor() +inline bool AutomationEditor::inPatternEditor() { - return( validClip() && - m_clip->getTrack()->trackContainer() == Engine::getBBTrackContainer() ); + return (validClip() && m_clip->getTrack()->trackContainer() == Engine::patternStore()); } @@ -1540,9 +1539,9 @@ void AutomationEditor::play() Engine::getSong()->playMidiClip( getGUI()->pianoRoll()->currentMidiClip() ); } } - else if( inBBEditor() ) + else if (inPatternEditor()) { - Engine::getBBTrackContainer()->play(); + Engine::patternStore()->play(); } else { @@ -1566,9 +1565,9 @@ void AutomationEditor::stop() { return; } - if( m_clip->getTrack() && inBBEditor() ) + if (m_clip->getTrack() && inPatternEditor()) { - Engine::getBBTrackContainer()->stop(); + Engine::patternStore()->stop(); } else { diff --git a/src/gui/editors/BBEditor.cpp b/src/gui/editors/BBEditor.cpp deleted file mode 100644 index 361917b5f..000000000 --- a/src/gui/editors/BBEditor.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/* - * BBEditor.cpp - basic main-window for editing of beats and basslines - * - * Copyright (c) 2004-2008 Tobias Doerffel - * - * This file is part of LMMS - https://lmms.io - * - * 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 "BBEditor.h" - -#include -#include -#include - -#include "ComboBox.h" -#include "BBTrack.h" -#include "BBTrackContainer.h" -#include "DataFile.h" -#include "embed.h" -#include "MainWindow.h" -#include "Song.h" -#include "StringPairDrag.h" - -#include "MidiClip.h" - - - -BBEditor::BBEditor( BBTrackContainer* tc ) : - Editor(false), - m_trackContainerView( new BBTrackContainerView(tc) ) -{ - setWindowIcon( embed::getIconPixmap( "bb_track_btn" ) ); - setWindowTitle( tr( "Beat+Bassline Editor" ) ); - setCentralWidget(m_trackContainerView); - - setAcceptDrops(true); - m_toolBar->setAcceptDrops(true); - connect(m_toolBar, SIGNAL(dragEntered(QDragEnterEvent*)), m_trackContainerView, SLOT(dragEnterEvent(QDragEnterEvent*))); - connect(m_toolBar, SIGNAL(dropped(QDropEvent*)), m_trackContainerView, SLOT(dropEvent(QDropEvent*))); - - // TODO: Use style sheet - if( ConfigManager::inst()->value( "ui", - "compacttrackbuttons" ).toInt() ) - { - setMinimumWidth( TRACK_OP_WIDTH_COMPACT + DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT - + 2 * CLIP_BORDER_WIDTH + 384 ); - } - else - { - setMinimumWidth( TRACK_OP_WIDTH + DEFAULT_SETTINGS_WIDGET_WIDTH - + 2 * CLIP_BORDER_WIDTH + 384 ); - } - - - m_playAction->setToolTip(tr( "Play/pause current beat/bassline (Space)" )); - m_stopAction->setToolTip(tr( "Stop playback of current beat/bassline (Space)" )); - - - // Beat selector - DropToolBar *beatSelectionToolBar = addDropToolBarToTop(tr("Beat selector")); - - m_bbComboBox = new ComboBox( m_toolBar ); - m_bbComboBox->setFixedSize( 200, ComboBox::DEFAULT_HEIGHT ); - m_bbComboBox->setModel( &tc->m_bbComboBoxModel ); - - beatSelectionToolBar->addWidget( m_bbComboBox ); - - - // Track actions - DropToolBar *trackAndStepActionsToolBar = addDropToolBarToTop(tr("Track and step actions")); - - - trackAndStepActionsToolBar->addAction(embed::getIconPixmap("add_bb_track"), tr("Add beat/bassline"), - Engine::getSong(), SLOT(addBBTrack())); - trackAndStepActionsToolBar->addAction(embed::getIconPixmap("clone_bb_track_clip"), tr("Clone beat/bassline clip"), - m_trackContainerView, SLOT(cloneClip())); - trackAndStepActionsToolBar->addAction( - embed::getIconPixmap("add_sample_track"), - tr("Add sample-track"), m_trackContainerView, - SLOT(addSampleTrack())); - trackAndStepActionsToolBar->addAction(embed::getIconPixmap("add_automation"), tr("Add automation-track"), - m_trackContainerView, SLOT(addAutomationTrack())); - - QWidget* stretch = new QWidget(m_toolBar); - stretch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - trackAndStepActionsToolBar->addWidget(stretch); - - - // Step actions - trackAndStepActionsToolBar->addAction(embed::getIconPixmap("step_btn_remove"), tr("Remove steps"), - m_trackContainerView, SLOT(removeSteps())); - trackAndStepActionsToolBar->addAction(embed::getIconPixmap("step_btn_add"), tr("Add steps"), - m_trackContainerView, SLOT( addSteps())); - trackAndStepActionsToolBar->addAction( embed::getIconPixmap( "step_btn_duplicate" ), tr( "Clone Steps" ), - m_trackContainerView, SLOT( cloneSteps() ) ); - - connect( &tc->m_bbComboBoxModel, SIGNAL( dataChanged() ), - m_trackContainerView, SLOT( updatePosition() ) ); - - - QAction* viewNext = new QAction(this); - connect(viewNext, SIGNAL(triggered()), m_bbComboBox, SLOT(selectNext())); - viewNext->setShortcut(Qt::Key_Plus); - addAction(viewNext); - - QAction* viewPrevious = new QAction(this); - connect(viewPrevious, SIGNAL(triggered()), m_bbComboBox, SLOT(selectPrevious())); - viewPrevious->setShortcut(Qt::Key_Minus); - addAction(viewPrevious); -} - - -BBEditor::~BBEditor() -{ -} - - -QSize BBEditor::sizeHint() const -{ - return {minimumWidth()+10, 300}; -} - - -void BBEditor::removeBBView( int bb ) -{ - m_trackContainerView->removeBBView(bb); -} - - -void BBEditor::play() -{ - if( Engine::getSong()->playMode() != Song::Mode_PlayBB ) - { - Engine::getSong()->playBB(); - } - else - { - Engine::getSong()->togglePause(); - } -} - - -void BBEditor::stop() -{ - Engine::getSong()->stop(); -} - - - - -BBTrackContainerView::BBTrackContainerView(BBTrackContainer* tc) : - TrackContainerView(tc), - m_bbtc(tc) -{ - setModel( tc ); -} - - - - -void BBTrackContainerView::addSteps() -{ - makeSteps( false ); -} - -void BBTrackContainerView::cloneSteps() -{ - makeSteps( true ); -} - - - - -void BBTrackContainerView::removeSteps() -{ - TrackContainer::TrackList tl = model()->tracks(); - - for( TrackContainer::TrackList::iterator it = tl.begin(); - it != tl.end(); ++it ) - { - if( ( *it )->type() == Track::InstrumentTrack ) - { - MidiClip* p = static_cast( ( *it )->getClip( m_bbtc->currentBB() ) ); - p->removeSteps(); - } - } -} - - - - -void BBTrackContainerView::addSampleTrack() -{ - (void) Track::create( Track::SampleTrack, model() ); -} - - - - -void BBTrackContainerView::addAutomationTrack() -{ - (void) Track::create( Track::AutomationTrack, model() ); -} - - - - -void BBTrackContainerView::removeBBView(int bb) -{ - for( TrackView* view : trackViews() ) - { - view->getTrackContentWidget()->removeClipView( bb ); - } -} - - - -void BBTrackContainerView::saveSettings(QDomDocument& doc, QDomElement& element) -{ - MainWindow::saveWidgetState( parentWidget(), element ); -} - -void BBTrackContainerView::loadSettings(const QDomElement& element) -{ - MainWindow::restoreWidgetState(parentWidget(), element); -} - - - - -void BBTrackContainerView::dropEvent(QDropEvent* de) -{ - QString type = StringPairDrag::decodeKey( de ); - QString value = StringPairDrag::decodeValue( de ); - - if( type.left( 6 ) == "track_" ) - { - DataFile dataFile( value.toUtf8() ); - Track * t = Track::create( dataFile.content().firstChild().toElement(), model() ); - - // Ensure BB Clips exist - bool hasValidBBClips = false; - if (t->getClips().size() == m_bbtc->numOfBBs()) - { - hasValidBBClips = true; - for (int i = 0; i < t->getClips().size(); ++i) - { - if (t->getClips()[i]->startPosition() != TimePos(i, 0)) - { - hasValidBBClips = false; - break; - } - } - } - if (!hasValidBBClips) - { - t->deleteClips(); - t->createClipsForBB(m_bbtc->numOfBBs() - 1); - } - m_bbtc->updateAfterTrackAdd(); - - de->accept(); - } - else - { - TrackContainerView::dropEvent( de ); - } -} - - - - -void BBTrackContainerView::updatePosition() -{ - //realignTracks(); - emit positionChanged( m_currentPosition ); -} - - - - -void BBTrackContainerView::makeSteps( bool clone ) -{ - TrackContainer::TrackList tl = model()->tracks(); - - for( TrackContainer::TrackList::iterator it = tl.begin(); - it != tl.end(); ++it ) - { - if( ( *it )->type() == Track::InstrumentTrack ) - { - MidiClip* p = static_cast( ( *it )->getClip( m_bbtc->currentBB() ) ); - if( clone ) - { - p->cloneSteps(); - } else - { - p->addSteps(); - } - } - } -} - -// Creates a clone of the current BB track with the same clip, but no Clips in the song editor -// TODO: Avoid repeated code from cloneTrack and clearTrack in TrackOperationsWidget somehow -void BBTrackContainerView::cloneClip() -{ - // Get the current BBTrack id - BBTrackContainer *bbtc = static_cast(model()); - const int cur_bb = bbtc->currentBB(); - - BBTrack *bbt = BBTrack::findBBTrack(cur_bb); - - if( bbt ) - { - // Clone the track - Track *newTrack = bbt->clone(); - bbtc->setCurrentBB( static_cast( newTrack )->index() ); - - // Track still have the clips which is undesirable in this case, clear the track - newTrack->lock(); - newTrack->deleteClips(); - newTrack->unlock(); - } -} diff --git a/src/gui/editors/PatternEditor.cpp b/src/gui/editors/PatternEditor.cpp new file mode 100644 index 000000000..6197373eb --- /dev/null +++ b/src/gui/editors/PatternEditor.cpp @@ -0,0 +1,329 @@ +/* + * PatternEditor.cpp - basic main-window for editing patterns + * + * Copyright (c) 2004-2008 Tobias Doerffel + * + * This file is part of LMMS - https://lmms.io + * + * 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 "PatternEditor.h" + +#include +#include +#include + +#include "ComboBox.h" +#include "DataFile.h" +#include "embed.h" +#include "MainWindow.h" +#include "PatternStore.h" +#include "PatternTrack.h" +#include "Song.h" +#include "StringPairDrag.h" + +#include "MidiClip.h" + + + + +PatternEditor::PatternEditor(PatternStore* ps) : + TrackContainerView(ps), + m_ps(ps) +{ + setModel(ps); +} + + + + +void PatternEditor::addSteps() +{ + makeSteps( false ); +} + +void PatternEditor::cloneSteps() +{ + makeSteps( true ); +} + + + + +void PatternEditor::removeSteps() +{ + TrackContainer::TrackList tl = model()->tracks(); + + for( TrackContainer::TrackList::iterator it = tl.begin(); + it != tl.end(); ++it ) + { + if( ( *it )->type() == Track::InstrumentTrack ) + { + MidiClip* p = static_cast((*it)->getClip(m_ps->currentPattern())); + p->removeSteps(); + } + } +} + + + + +void PatternEditor::addSampleTrack() +{ + (void) Track::create( Track::SampleTrack, model() ); +} + + + + +void PatternEditor::addAutomationTrack() +{ + (void) Track::create( Track::AutomationTrack, model() ); +} + + + + +void PatternEditor::removeViewsForPattern(int pattern) +{ + for( TrackView* view : trackViews() ) + { + view->getTrackContentWidget()->removeClipView(pattern); + } +} + + + +void PatternEditor::saveSettings(QDomDocument& doc, QDomElement& element) +{ + MainWindow::saveWidgetState( parentWidget(), element ); +} + +void PatternEditor::loadSettings(const QDomElement& element) +{ + MainWindow::restoreWidgetState(parentWidget(), element); +} + + + + +void PatternEditor::dropEvent(QDropEvent* de) +{ + QString type = StringPairDrag::decodeKey( de ); + QString value = StringPairDrag::decodeValue( de ); + + if( type.left( 6 ) == "track_" ) + { + DataFile dataFile( value.toUtf8() ); + Track * t = Track::create( dataFile.content().firstChild().toElement(), model() ); + + // Ensure pattern clips exist + bool hasValidPatternClips = false; + if (t->getClips().size() == m_ps->numOfPatterns()) + { + hasValidPatternClips = true; + for (int i = 0; i < t->getClips().size(); ++i) + { + if (t->getClips()[i]->startPosition() != TimePos(i, 0)) + { + hasValidPatternClips = false; + break; + } + } + } + if (!hasValidPatternClips) + { + t->deleteClips(); + t->createClipsForPattern(m_ps->numOfPatterns() - 1); + } + m_ps->updateAfterTrackAdd(); + + de->accept(); + } + else + { + TrackContainerView::dropEvent( de ); + } +} + + + + +void PatternEditor::updatePosition() +{ + //realignTracks(); + emit positionChanged( m_currentPosition ); +} + + + + +void PatternEditor::makeSteps( bool clone ) +{ + TrackContainer::TrackList tl = model()->tracks(); + + for( TrackContainer::TrackList::iterator it = tl.begin(); + it != tl.end(); ++it ) + { + if( ( *it )->type() == Track::InstrumentTrack ) + { + MidiClip* p = static_cast((*it)->getClip(m_ps->currentPattern())); + if( clone ) + { + p->cloneSteps(); + } else + { + p->addSteps(); + } + } + } +} + +// Creates a clone of the current pattern track with the same content, but no clips in the song editor +// TODO: Avoid repeated code from cloneTrack and clearTrack in TrackOperationsWidget somehow +void PatternEditor::cloneClip() +{ + // Get the current PatternTrack id + PatternStore* ps = static_cast(model()); + const int currentPattern = ps->currentPattern(); + + PatternTrack* pt = PatternTrack::findPatternTrack(currentPattern); + + if (pt) + { + // Clone the track + Track* newTrack = pt->clone(); + ps->setCurrentPattern(static_cast(newTrack)->patternIndex()); + + // Track still have the clips which is undesirable in this case, clear the track + newTrack->lock(); + newTrack->deleteClips(); + newTrack->unlock(); + } +} + + + + +PatternEditorWindow::PatternEditorWindow(PatternStore* ps) : + Editor(false), + m_editor(new PatternEditor(ps)) +{ + setWindowIcon(embed::getIconPixmap("pattern_track_btn")); + setWindowTitle(tr("Pattern Editor")); + setCentralWidget(m_editor); + + setAcceptDrops(true); + m_toolBar->setAcceptDrops(true); + connect(m_toolBar, SIGNAL(dragEntered(QDragEnterEvent*)), m_editor, SLOT(dragEnterEvent(QDragEnterEvent*))); + connect(m_toolBar, SIGNAL(dropped(QDropEvent*)), m_editor, SLOT(dropEvent(QDropEvent*))); + + // TODO: Use style sheet + if (ConfigManager::inst()->value("ui", "compacttrackbuttons").toInt()) + { + setMinimumWidth(TRACK_OP_WIDTH_COMPACT + DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + 2 * CLIP_BORDER_WIDTH + 384); + } + else + { + setMinimumWidth(TRACK_OP_WIDTH + DEFAULT_SETTINGS_WIDGET_WIDTH + 2 * CLIP_BORDER_WIDTH + 384); + } + + m_playAction->setToolTip(tr("Play/pause current pattern (Space)")); + m_stopAction->setToolTip(tr("Stop playback of current pattern (Space)")); + + + // Pattern selector + DropToolBar* patternSelectionToolBar = addDropToolBarToTop(tr("Pattern selector")); + + m_patternComboBox = new ComboBox(m_toolBar); + m_patternComboBox->setFixedSize(200, ComboBox::DEFAULT_HEIGHT); + m_patternComboBox->setModel(&ps->m_patternComboBoxModel); + + patternSelectionToolBar->addWidget(m_patternComboBox); + + + // Track actions + DropToolBar *trackAndStepActionsToolBar = addDropToolBarToTop(tr("Track and step actions")); + + + trackAndStepActionsToolBar->addAction(embed::getIconPixmap("add_pattern_track"), tr("New pattern"), + Engine::getSong(), SLOT(addPatternTrack())); + trackAndStepActionsToolBar->addAction(embed::getIconPixmap("clone_pattern_track_clip"), tr("Clone pattern"), + m_editor, SLOT(cloneClip())); + trackAndStepActionsToolBar->addAction(embed::getIconPixmap("add_sample_track"), tr("Add sample-track"), + m_editor, SLOT(addSampleTrack())); + trackAndStepActionsToolBar->addAction(embed::getIconPixmap("add_automation"), tr("Add automation-track"), + m_editor, SLOT(addAutomationTrack())); + + QWidget* stretch = new QWidget(m_toolBar); + stretch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + trackAndStepActionsToolBar->addWidget(stretch); + + + // Step actions + trackAndStepActionsToolBar->addAction(embed::getIconPixmap("step_btn_remove"), tr("Remove steps"), + m_editor, SLOT(removeSteps())); + trackAndStepActionsToolBar->addAction(embed::getIconPixmap("step_btn_add"), tr("Add steps"), + m_editor, SLOT(addSteps())); + trackAndStepActionsToolBar->addAction( embed::getIconPixmap("step_btn_duplicate"), tr("Clone Steps"), + m_editor, SLOT(cloneSteps())); + + connect(&ps->m_patternComboBoxModel, SIGNAL(dataChanged()), + m_editor, SLOT(updatePosition())); + + + QAction* viewNext = new QAction(this); + connect(viewNext, SIGNAL(triggered()), m_patternComboBox, SLOT(selectNext())); + viewNext->setShortcut(Qt::Key_Plus); + addAction(viewNext); + + QAction* viewPrevious = new QAction(this); + connect(viewPrevious, SIGNAL(triggered()), m_patternComboBox, SLOT(selectPrevious())); + viewPrevious->setShortcut(Qt::Key_Minus); + addAction(viewPrevious); +} + + +PatternEditorWindow::~PatternEditorWindow() +{ +} + + +QSize PatternEditorWindow::sizeHint() const +{ + return {minimumWidth() + 10, 300}; +} + + +void PatternEditorWindow::play() +{ + if (Engine::getSong()->playMode() != Song::Mode_PlayPattern) + { + Engine::getSong()->playPattern(); + } + else + { + Engine::getSong()->togglePause(); + } +} + + +void PatternEditorWindow::stop() +{ + Engine::getSong()->stop(); +} diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index 05192e31e..fc12c1b63 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -50,7 +50,6 @@ #include "AutomationEditor.h" #include "ActionGroup.h" -#include "BBTrackContainer.h" #include "Clipboard.h" #include "ComboBox.h" #include "ConfigManager.h" @@ -64,6 +63,7 @@ #include "InstrumentTrack.h" #include "MainWindow.h" #include "MidiClip.h" +#include "PatternStore.h" #include "PianoView.h" #include "SongEditor.h" #include "StepRecorderWidget.h" @@ -313,7 +313,7 @@ PianoRoll::PianoRoll() : this, SLOT( updatePositionAccompany( const TimePos & ) ) ); // TODO -/* connect( engine::getSong()->getPlayPos( Song::Mode_PlayBB ).m_timeLine, +/* connect( engine::getSong()->getPlayPos( Song::Mode_PlayPattern ).m_timeLine, SIGNAL( positionChanged( const TimePos & ) ), this, SLOT( updatePositionAccompany( const TimePos & ) ) );*/ @@ -1857,7 +1857,7 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) m_minResizeLen = quantization(); for (Note *note : selectedNotes) { - //Notes from the BB editor can have a negative length, so + //Notes from the pattern editor can have a negative length, so //change their length to the displayed one before resizing if (note->oldLength() <= 0) { note->setOldLength(4); } //Let the note be sized down by quantized increments, stopping @@ -3948,10 +3948,9 @@ QList PianoRoll::getAllOctavesForKey( int keyToMirror ) const Song::PlayModes PianoRoll::desiredPlayModeForAccompany() const { - if( m_midiClip->getTrack()->trackContainer() == - Engine::getBBTrackContainer() ) + if (m_midiClip->getTrack()->trackContainer() == Engine::patternStore()) { - return Song::Mode_PlayBB; + return Song::Mode_PlayPattern; } return Song::Mode_PlaySong; } @@ -4019,7 +4018,7 @@ void PianoRoll::recordAccompany() } else { - Engine::getSong()->playBB(); + Engine::getSong()->playPattern(); } } @@ -4514,7 +4513,7 @@ void PianoRoll::updatePositionAccompany( const TimePos & t ) s->playMode() != Song::Mode_PlayMidiClip ) { TimePos pos = t; - if( s->playMode() != Song::Mode_PlayBB ) + if (s->playMode() != Song::Mode_PlayPattern) { pos -= m_midiClip->startPosition(); } @@ -4731,7 +4730,7 @@ PianoRollWindow::PianoRollWindow() : m_playAction->setToolTip(tr( "Play/pause current clip (Space)" ) ); m_recordAction->setToolTip(tr( "Record notes from MIDI-device/channel-piano" ) ); - m_recordAccompanyAction->setToolTip( tr( "Record notes from MIDI-device/channel-piano while playing song or BB track" ) ); + m_recordAccompanyAction->setToolTip( tr( "Record notes from MIDI-device/channel-piano while playing song or pattern track" ) ); m_toggleStepRecordingAction->setToolTip( tr( "Record notes from MIDI-device/channel-piano, one step at the time" ) ); m_stopAction->setToolTip( tr( "Stop playing of current clip (Space)" ) ); diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index 55d22cf62..8a2eda92f 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -927,15 +927,15 @@ SongEditorWindow::SongEditorWindow(Song* song) : // Set up buttons m_playAction->setToolTip(tr("Play song (Space)")); m_recordAction->setToolTip(tr("Record samples from Audio-device")); - m_recordAccompanyAction->setToolTip(tr( "Record samples from Audio-device while playing song or BB track")); + m_recordAccompanyAction->setToolTip(tr("Record samples from Audio-device while playing song or pattern track")); m_stopAction->setToolTip(tr( "Stop song (Space)" )); // Track actions DropToolBar *trackActionsToolBar = addDropToolBarToTop(tr("Track actions")); - m_addBBTrackAction = new QAction(embed::getIconPixmap("add_bb_track"), - tr("Add beat/bassline"), this); + m_addPatternTrackAction = new QAction(embed::getIconPixmap("add_pattern_track"), + tr("Add pattern-track"), this); m_addSampleTrackAction = new QAction(embed::getIconPixmap("add_sample_track"), tr("Add sample-track"), this); @@ -943,11 +943,11 @@ SongEditorWindow::SongEditorWindow(Song* song) : m_addAutomationTrackAction = new QAction(embed::getIconPixmap("add_automation"), tr("Add automation-track"), this); - connect(m_addBBTrackAction, SIGNAL(triggered()), m_editor->m_song, SLOT(addBBTrack())); + connect(m_addPatternTrackAction, SIGNAL(triggered()), m_editor->m_song, SLOT(addPatternTrack())); connect(m_addSampleTrackAction, SIGNAL(triggered()), m_editor->m_song, SLOT(addSampleTrack())); connect(m_addAutomationTrackAction, SIGNAL(triggered()), m_editor->m_song, SLOT(addAutomationTrack())); - trackActionsToolBar->addAction( m_addBBTrackAction ); + trackActionsToolBar->addAction( m_addPatternTrackAction ); trackActionsToolBar->addAction( m_addSampleTrackAction ); trackActionsToolBar->addAction( m_addAutomationTrackAction ); diff --git a/src/gui/widgets/TrackContentWidget.cpp b/src/gui/widgets/TrackContentWidget.cpp index 2dd9c1f9b..36bbd4096 100644 --- a/src/gui/widgets/TrackContentWidget.cpp +++ b/src/gui/widgets/TrackContentWidget.cpp @@ -30,12 +30,12 @@ #include #include "AutomationClip.h" -#include "BBEditor.h" -#include "BBTrackContainer.h" #include "Clipboard.h" #include "DataFile.h" #include "Engine.h" #include "GuiApplication.h" +#include "PatternEditor.h" +#include "PatternStore.h" #include "Song.h" #include "SongEditor.h" #include "StringPairDrag.h" @@ -199,17 +199,16 @@ void TrackContentWidget::update() */ void TrackContentWidget::changePosition( const TimePos & newPos ) { - if( m_trackView->trackContainerView() == getGUI()->getBBEditor()->trackContainerView() ) + if (m_trackView->trackContainerView() == getGUI()->patternEditor()->m_editor) { - const int curBB = Engine::getBBTrackContainer()->currentBB(); + const int curPattern = Engine::patternStore()->currentPattern(); setUpdatesEnabled( false ); - // first show Clip for current BB... + // first show clip for current pattern... for( clipViewVector::iterator it = m_clipViews.begin(); it != m_clipViews.end(); ++it ) { - if( ( *it )->getClip()-> - startPosition().getBar() == curBB ) + if ((*it)->getClip()->startPosition().getBar() == curPattern) { ( *it )->move( 0, ( *it )->y() ); ( *it )->raise(); @@ -224,8 +223,7 @@ void TrackContentWidget::changePosition( const TimePos & newPos ) for( clipViewVector::iterator it = m_clipViews.begin(); it != m_clipViews.end(); ++it ) { - if( ( *it )->getClip()-> - startPosition().getBar() != curBB ) + if ((*it)->getClip()->startPosition().getBar() != curPattern) { ( *it )->hide(); } @@ -600,8 +598,8 @@ void TrackContentWidget::paintEvent( QPaintEvent * pe ) const TrackContainerView * tcv = m_trackView->trackContainerView(); int ppb = static_cast( tcv->pixelsPerBar() ); QPainter p( this ); - // Don't draw background on BB-Editor - if( m_trackView->trackContainerView() != getGUI()->getBBEditor()->trackContainerView() ) + // Don't draw background on Pattern Editor + if (m_trackView->trackContainerView() != getGUI()->patternEditor()->m_editor) { p.drawTiledPixmap( rect(), m_background, QPoint( tcv->currentPosition().getBar() * ppb, 0 ) ); diff --git a/src/gui/widgets/TrackOperationsWidget.cpp b/src/gui/widgets/TrackOperationsWidget.cpp index 8d192eafd..0b85dd9c5 100644 --- a/src/gui/widgets/TrackOperationsWidget.cpp +++ b/src/gui/widgets/TrackOperationsWidget.cpp @@ -131,7 +131,7 @@ TrackOperationsWidget::~TrackOperationsWidget() /*! \brief Respond to trackOperationsWidget mouse events * * If it's the left mouse button, and Ctrl is held down, and we're - * not a Beat+Bassline Editor track, then start a new drag event to + * not a Pattern Editor track, then start a new drag event to * copy this track. * * Otherwise, ignore all other events. @@ -142,7 +142,7 @@ void TrackOperationsWidget::mousePressEvent( QMouseEvent * me ) { if( me->button() == Qt::LeftButton && me->modifiers() & Qt::ControlModifier && - m_trackView->getTrack()->type() != Track::BBTrack ) + m_trackView->getTrack()->type() != Track::PatternTrack) { DataFile dataFile( DataFile::DragNDropData ); m_trackView->getTrack()->saveState( dataFile, dataFile.content() ); @@ -163,7 +163,7 @@ void TrackOperationsWidget::mousePressEvent( QMouseEvent * me ) /*! \brief Repaint the trackOperationsWidget * - * If we're not moving, and in the Beat+Bassline Editor, then turn + * If we're not moving, and in the Pattern Editor, then turn * automation on or off depending on its previous state and show * ourselves. * diff --git a/src/tracks/CMakeLists.txt b/src/tracks/CMakeLists.txt index a9fd83e90..75704b007 100644 --- a/src/tracks/CMakeLists.txt +++ b/src/tracks/CMakeLists.txt @@ -1,9 +1,9 @@ set(LMMS_SRCS ${LMMS_SRCS} tracks/AutomationTrack.cpp - tracks/BBTrack.cpp tracks/InstrumentTrack.cpp tracks/MidiClip.cpp + tracks/PatternTrack.cpp tracks/SampleTrack.cpp PARENT_SCOPE diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 1891f9a4f..0932404d8 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -25,7 +25,6 @@ #include "AudioEngine.h" #include "AutomationClip.h" -#include "BBTrack.h" #include "ConfigManager.h" #include "ControllerConnection.h" #include "DataFile.h" @@ -35,6 +34,8 @@ #include "MidiClient.h" #include "MidiClip.h" #include "MixHelpers.h" +#include "PatternStore.h" +#include "PatternTrack.h" #include "Song.h" @@ -215,7 +216,7 @@ void InstrumentTrack::processAudioBuffer( sampleFrame* buf, const fpp_t frames, { // we must not play the sound if this InstrumentTrack is muted... if( isMuted() || ( Engine::getSong()->playMode() != Song::Mode_PlayMidiClip && - n && n->isBbTrackMuted() ) || ! m_instrument ) + n && n->isPatternTrackMuted() ) || ! m_instrument ) { return; } @@ -688,14 +689,14 @@ bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames, const float frames_per_tick = Engine::framesPerTick(); clipVector clips; - ::BBTrack * bb_track = nullptr; + ::PatternTrack * pattern_track = nullptr; if( _clip_num >= 0 ) { Clip * clip = getClip( _clip_num ); clips.push_back( clip ); - if (trackContainer() == (TrackContainer*)Engine::getBBTrackContainer()) + if (trackContainer() == Engine::patternStore()) { - bb_track = BBTrack::findBBTrack( _clip_num ); + pattern_track = PatternTrack::findPatternTrack(_clip_num); } } else @@ -762,7 +763,7 @@ bool InstrumentTrack::play( const TimePos & _start, const fpp_t _frames, cur_note->length().frames( frames_per_tick ); NotePlayHandle* notePlayHandle = NotePlayHandleManager::acquire( this, _offset, note_frames, *cur_note ); - notePlayHandle->setBBTrack( bb_track ); + notePlayHandle->setPatternTrack(pattern_track); // are we playing global song? if( _clip_num < 0 ) { diff --git a/src/tracks/MidiClip.cpp b/src/tracks/MidiClip.cpp index 307e62198..70c78e9a8 100644 --- a/src/tracks/MidiClip.cpp +++ b/src/tracks/MidiClip.cpp @@ -25,9 +25,9 @@ #include "MidiClip.h" -#include "BBTrackContainer.h" #include "GuiApplication.h" #include "InstrumentTrack.h" +#include "PatternStore.h" #include "PianoRoll.h" #include @@ -46,8 +46,7 @@ MidiClip::MidiClip( InstrumentTrack * _instrument_track ) : m_clipType( BeatClip ), m_steps( TimePos::stepsPerBar() ) { - if( _instrument_track->trackContainer() - == Engine::getBBTrackContainer() ) + if (_instrument_track->trackContainer() == Engine::patternStore()) { resizeToFirstTrack(); } @@ -72,7 +71,7 @@ MidiClip::MidiClip( const MidiClip& other ) : init(); switch( getTrack()->trackContainer()->type() ) { - case TrackContainer::BBContainer: + case TrackContainer::PatternContainer: setAutoResize( true ); break; @@ -103,7 +102,7 @@ MidiClip::~MidiClip() void MidiClip::resizeToFirstTrack() { - // Resize this track to be the same as existing tracks in the BB + // Resize this track to be the same as existing tracks in the pattern const TrackContainer::TrackList & tracks = m_instrumentTrack->trackContainer()->tracks(); for(unsigned int trackID = 0; trackID < tracks.size(); ++trackID) @@ -144,7 +143,7 @@ void MidiClip::updateLength() if( m_clipType == BeatClip ) { changeLength( beatClipLength() ); - updateBBTrack(); + updatePatternTrack(); return; } @@ -161,7 +160,7 @@ void MidiClip::updateLength() } changeLength( TimePos( max_length ).nextFullBar() * TimePos::ticksPerBar() ); - updateBBTrack(); + updatePatternTrack(); } @@ -558,11 +557,11 @@ ClipView * MidiClip::createView( TrackView * _tv ) -void MidiClip::updateBBTrack() +void MidiClip::updatePatternTrack() { - if( getTrack()->trackContainer() == Engine::getBBTrackContainer() ) + if (getTrack()->trackContainer() == Engine::patternStore()) { - Engine::getBBTrackContainer()->updateBBTrack( this ); + Engine::patternStore()->updatePatternTrack(this); } if( getGUI() != nullptr diff --git a/src/tracks/BBTrack.cpp b/src/tracks/PatternTrack.cpp similarity index 54% rename from src/tracks/BBTrack.cpp rename to src/tracks/PatternTrack.cpp index 4c833f4c8..58cbcd8ce 100644 --- a/src/tracks/BBTrack.cpp +++ b/src/tracks/PatternTrack.cpp @@ -1,5 +1,5 @@ /* - * BBTrack.cpp - implementation of class BBTrack + * PatternTrack.cpp - a track representing a pattern in the PatternStore * * Copyright (c) 2004-2014 Tobias Doerffel * @@ -21,69 +21,68 @@ * Boston, MA 02110-1301 USA. * */ -#include "BBTrack.h" +#include "PatternTrack.h" #include #include #include -#include "BBTrackContainer.h" -#include "BBTrackView.h" +#include "PatternStore.h" +#include "PatternTrackView.h" #include "Song.h" -BBTrack::infoMap BBTrack::s_infoMap; +PatternTrack::infoMap PatternTrack::s_infoMap; -BBTrack::BBTrack( TrackContainer* tc ) : - Track( Track::BBTrack, tc ) +PatternTrack::PatternTrack(TrackContainer* tc) : + Track(Track::PatternTrack, tc) { - int bbNum = s_infoMap.size(); - s_infoMap[this] = bbNum; + int patternNum = s_infoMap.size(); + s_infoMap[this] = patternNum; - setName( tr( "Beat/Bassline %1" ).arg( bbNum ) ); - Engine::getBBTrackContainer()->createClipsForBB( bbNum ); - Engine::getBBTrackContainer()->setCurrentBB( bbNum ); - Engine::getBBTrackContainer()->updateComboBox(); + setName(tr("Pattern %1").arg(patternNum)); + Engine::patternStore()->createClipsForPattern(patternNum); + Engine::patternStore()->setCurrentPattern(patternNum); + Engine::patternStore()->updateComboBox(); connect( this, SIGNAL( nameChanged() ), - Engine::getBBTrackContainer(), SLOT( updateComboBox() ) ); + Engine::patternStore(), SLOT(updateComboBox())); } -BBTrack::~BBTrack() +PatternTrack::~PatternTrack() { Engine::audioEngine()->removePlayHandlesOfTypes( this, PlayHandle::TypeNotePlayHandle | PlayHandle::TypeInstrumentPlayHandle | PlayHandle::TypeSamplePlayHandle ); - const int bb = s_infoMap[this]; - Engine::getBBTrackContainer()->removeBB( bb ); + const int pattern = s_infoMap[this]; + Engine::patternStore()->removePattern(pattern); for( infoMap::iterator it = s_infoMap.begin(); it != s_infoMap.end(); ++it ) { - if( it.value() > bb ) + if (it.value() > pattern) { --it.value(); } } s_infoMap.remove( this ); - // remove us from TC so bbTrackContainer::numOfBBs() returns a smaller - // value and thus combobox-updating in bbTrackContainer works well + // remove us from the Song and update the pattern selection combobox to reflect the change trackContainer()->removeTrack( this ); - Engine::getBBTrackContainer()->updateComboBox(); + Engine::patternStore()->updateComboBox(); } // play _frames frames of given Clip within starting with _start -bool BBTrack::play( const TimePos & _start, const fpp_t _frames, +bool PatternTrack::play( const TimePos & _start, const fpp_t _frames, const f_cnt_t _offset, int _clip_num ) { if( isMuted() ) @@ -93,7 +92,7 @@ bool BBTrack::play( const TimePos & _start, const fpp_t _frames, if( _clip_num >= 0 ) { - return Engine::getBBTrackContainer()->play( _start, _frames, _offset, s_infoMap[this] ); + return Engine::patternStore()->play(_start, _frames, _offset, s_infoMap[this]); } clipVector clips; @@ -118,7 +117,7 @@ bool BBTrack::play( const TimePos & _start, const fpp_t _frames, if( _start - lastPosition < lastLen ) { - return Engine::getBBTrackContainer()->play( _start - lastPosition, _frames, _offset, s_infoMap[this] ); + return Engine::patternStore()->play(_start - lastPosition, _frames, _offset, s_infoMap[this]); } return false; } @@ -126,61 +125,59 @@ bool BBTrack::play( const TimePos & _start, const fpp_t _frames, -TrackView * BBTrack::createView( TrackContainerView* tcv ) +TrackView* PatternTrack::createView(TrackContainerView* tcv) { - return new BBTrackView( this, tcv ); + return new PatternTrackView(this, tcv); } -Clip* BBTrack::createClip(const TimePos & pos) +Clip* PatternTrack::createClip(const TimePos & pos) { - BBClip* bbclip = new BBClip(this); - bbclip->movePosition(pos); - return bbclip; + PatternClip* pc = new PatternClip(this); + pc->movePosition(pos); + return pc; } -void BBTrack::saveTrackSpecificSettings( QDomDocument & _doc, - QDomElement & _this ) +void PatternTrack::saveTrackSpecificSettings(QDomDocument& doc, QDomElement& _this) { // _this.setAttribute( "icon", m_trackLabel->pixmapFile() ); /* _this.setAttribute( "current", s_infoMap[this] == - engine::getBBEditor()->currentBB() );*/ + engine::getPatternEditor()->currentPattern() );*/ if( s_infoMap[this] == 0 && _this.parentNode().parentNode().nodeName() != "clone" && _this.parentNode().parentNode().nodeName() != "journaldata" ) { - ( (JournallingObject *)( Engine::getBBTrackContainer() ) )-> - saveState( _doc, _this ); + Engine::patternStore()->saveState(doc, _this); } if( _this.parentNode().parentNode().nodeName() == "clone" ) { - _this.setAttribute( "clonebbt", s_infoMap[this] ); + _this.setAttribute( "clonebbt", s_infoMap[this] ); // TODO rename bb to pattern } } -void BBTrack::loadTrackSpecificSettings( const QDomElement & _this ) +void PatternTrack::loadTrackSpecificSettings(const QDomElement& _this) { /* if( _this.attribute( "icon" ) != "" ) { m_trackLabel->setPixmapFile( _this.attribute( "icon" ) ); }*/ - if( _this.hasAttribute( "clonebbt" ) ) + if( _this.hasAttribute( "clonebbt" ) ) // TODO rename bb to pattern { - const int src = _this.attribute( "clonebbt" ).toInt(); + const int src = _this.attribute( "clonebbt" ).toInt(); // TODO rename bb to pattern const int dst = s_infoMap[this]; TrackContainer::TrackList tl = - Engine::getBBTrackContainer()->tracks(); - // copy Clips of all tracks from source BB (at bar "src") to destination - // Clips (which are created if they do not exist yet) + Engine::patternStore()->tracks(); + // copy clips of all tracks from source pattern (at bar "src") to destination + // clips (which are created if they do not exist yet) for( TrackContainer::TrackList::iterator it = tl.begin(); it != tl.end(); ++it ) { @@ -196,29 +193,28 @@ void BBTrack::loadTrackSpecificSettings( const QDomElement & _this ) TrackContainer::classNodeName() ); if( node.isElement() ) { - ( (JournallingObject *)Engine::getBBTrackContainer() )-> - restoreState( node.toElement() ); + Engine::patternStore()->restoreState(node.toElement()); } } -/* doesn't work yet because BBTrack-ctor also sets current bb so if - bb-tracks are created after this function is called, this doesn't +/* doesn't work yet because PatternTrack-ctor also sets current pattern so if + pattern tracks are created after this function is called, this doesn't help at all.... if( _this.attribute( "current" ).toInt() ) { - engine::getBBEditor()->setCurrentBB( s_infoMap[this] ); + engine::getPatternEditor()->setCurrentPattern( s_infoMap[this] ); }*/ } -// return pointer to BBTrack specified by _bb_num -BBTrack * BBTrack::findBBTrack( int _bb_num ) +// return pointer to PatternTrack specified by pattern_num +PatternTrack* PatternTrack::findPatternTrack(int pattern_num) { for( infoMap::iterator it = s_infoMap.begin(); it != s_infoMap.end(); ++it ) { - if( it.value() == _bb_num ) + if (it.value() == pattern_num) { return it.key(); } @@ -229,15 +225,14 @@ BBTrack * BBTrack::findBBTrack( int _bb_num ) -void BBTrack::swapBBTracks( Track * _track1, Track * _track2 ) +void PatternTrack::swapPatternTracks(Track* track1, Track* track2) { - BBTrack * t1 = dynamic_cast( _track1 ); - BBTrack * t2 = dynamic_cast( _track2 ); + PatternTrack* t1 = dynamic_cast(track1); + PatternTrack* t2 = dynamic_cast(track2); if( t1 != nullptr && t2 != nullptr ) { qSwap( s_infoMap[t1], s_infoMap[t2] ); - Engine::getBBTrackContainer()->swapBB( s_infoMap[t1], - s_infoMap[t2] ); - Engine::getBBTrackContainer()->setCurrentBB( s_infoMap[t1] ); + Engine::patternStore()->swapPattern(s_infoMap[t1], s_infoMap[t2]); + Engine::patternStore()->setCurrentPattern(s_infoMap[t1]); } -} \ No newline at end of file +} diff --git a/src/tracks/SampleTrack.cpp b/src/tracks/SampleTrack.cpp index 22f9c18a0..9c8ac4310 100644 --- a/src/tracks/SampleTrack.cpp +++ b/src/tracks/SampleTrack.cpp @@ -27,7 +27,8 @@ #include -#include "BBTrack.h" +#include "PatternStore.h" +#include "PatternTrack.h" #include "SamplePlayHandle.h" #include "SampleRecordHandle.h" #include "Song.h" @@ -67,7 +68,7 @@ bool SampleTrack::play( const TimePos & _start, const fpp_t _frames, bool played_a_note = false; // will be return variable clipVector clips; - ::BBTrack * bb_track = nullptr; + ::PatternTrack * pattern_track = nullptr; if( _clip_num >= 0 ) { if (_start > getClip(_clip_num)->length()) @@ -79,9 +80,9 @@ bool SampleTrack::play( const TimePos & _start, const fpp_t _frames, return false; } clips.push_back( getClip( _clip_num ) ); - if (trackContainer() == (TrackContainer*)Engine::getBBTrackContainer()) + if (trackContainer() == Engine::patternStore()) { - bb_track = BBTrack::findBBTrack( _clip_num ); + pattern_track = PatternTrack::findPatternTrack(_clip_num); setPlaying(true); } } @@ -143,7 +144,7 @@ bool SampleTrack::play( const TimePos & _start, const fpp_t _frames, { SamplePlayHandle* smpHandle = new SamplePlayHandle( st ); smpHandle->setVolumeModel( &m_volumeModel ); - smpHandle->setBBTrack( bb_track ); + smpHandle->setPatternTrack(pattern_track); handle = smpHandle; } handle->setOffset( _offset ); @@ -241,4 +242,4 @@ void SampleTrack::setPlayingClips( bool isPlaying ) void SampleTrack::updateMixerChannel() { m_audioPort.setNextMixerChannel( m_mixerChannelModel.value() ); -} \ No newline at end of file +} diff --git a/tests/src/tracks/AutomationTrackTest.cpp b/tests/src/tracks/AutomationTrackTest.cpp index 4df159604..8b44bbd90 100644 --- a/tests/src/tracks/AutomationTrackTest.cpp +++ b/tests/src/tracks/AutomationTrackTest.cpp @@ -28,11 +28,11 @@ #include "AutomationClip.h" #include "AutomationTrack.h" -#include "BBTrack.h" -#include "BBTrackContainer.h" #include "DetuningHelper.h" #include "InstrumentTrack.h" #include "MidiClip.h" +#include "PatternTrack.h" +#include "PatternStore.h" #include "TrackContainer.h" #include "Engine.h" @@ -157,12 +157,12 @@ private slots: QCOMPARE(clip->valueAt(TimePos(4, 0)), 1.0f); } - void testBBTrack() + void testPatternTrack() { auto song = Engine::getSong(); - auto bbContainer = Engine::getBBTrackContainer(); - BBTrack bbTrack(song); - Track* automationTrack = Track::create(Track::AutomationTrack, bbContainer); + auto patternStore = Engine::patternStore(); + PatternTrack patternTrack(song); + Track* automationTrack = Track::create(Track::AutomationTrack, patternStore); QVERIFY(automationTrack->numOfClips()); AutomationClip* c1 = dynamic_cast(automationTrack->getClip(0)); @@ -175,17 +175,17 @@ private slots: c1->putValue(10, 1.0, false); c1->addObject(&model); - QCOMPARE(bbContainer->automatedValuesAt( 0, bbTrack.index())[&model], 0.0f); - QCOMPARE(bbContainer->automatedValuesAt( 5, bbTrack.index())[&model], 0.5f); - QCOMPARE(bbContainer->automatedValuesAt(10, bbTrack.index())[&model], 1.0f); - QCOMPARE(bbContainer->automatedValuesAt(50, bbTrack.index())[&model], 1.0f); + QCOMPARE(patternStore->automatedValuesAt( 0, patternTrack.patternIndex())[&model], 0.0f); + QCOMPARE(patternStore->automatedValuesAt( 5, patternTrack.patternIndex())[&model], 0.5f); + QCOMPARE(patternStore->automatedValuesAt(10, patternTrack.patternIndex())[&model], 1.0f); + QCOMPARE(patternStore->automatedValuesAt(50, patternTrack.patternIndex())[&model], 1.0f); - BBTrack bbTrack2(song); + PatternTrack patternTrack2(song); - QCOMPARE(bbContainer->automatedValuesAt(5, bbTrack.index())[&model], 0.5f); - QVERIFY(! bbContainer->automatedValuesAt(5, bbTrack2.index()).size()); + QCOMPARE(patternStore->automatedValuesAt(5, patternTrack.patternIndex())[&model], 0.5f); + QVERIFY(! patternStore->automatedValuesAt(5, patternTrack2.patternIndex()).size()); - BBClip clip(&bbTrack); + PatternClip clip(&patternTrack); clip.changeLength(TimePos::ticksPerBar() * 2); clip.movePosition(0);