Rename Beat/Bassline to Pattern (#6284)
- BB* -> Pattern* - BBTrackContainer -> PatternStore - BBTrackContainerView -> PatternEditor - BBEditor -> PatternEditorWindow Does not touch save files
@@ -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
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
</instrumenttrack>
|
||||
</track>
|
||||
<track type="1" muted="0" name="Beat/Bassline 0" solo="0">
|
||||
<track type="1" muted="0" name="Pattern 0" solo="0">
|
||||
<bbtrack>
|
||||
<trackcontainer visible="1" width="580" height="300" type="bbtrackcontainer" x="610" y="5" maximized="0" minimized="0">
|
||||
<track type="0" muted="0" name="Clap.ds" solo="0">
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
</instrumenttrack>
|
||||
</track>
|
||||
<track type="1" muted="0" name="Beat/Bassline 0" solo="0">
|
||||
<track type="1" muted="0" name="Pattern 0" solo="0">
|
||||
<bbtrack>
|
||||
<trackcontainer visible="1" width="580" height="300" type="bbtrackcontainer" x="610" y="5" maximized="0" minimized="0">
|
||||
<track type="0" muted="0" name="Clave.ds" solo="0">
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
</sampletrack>
|
||||
</track>
|
||||
<track muted="0" type="1" name="Beat/Bassline 0" solo="0">
|
||||
<track muted="0" type="1" name="Pattern 0" solo="0">
|
||||
<bbtrack>
|
||||
<trackcontainer width="640" x="610" y="5" maximized="0" height="400" visible="0" type="bbtrackcontainer" minimized="0">
|
||||
<track muted="0" type="0" name="Kicker" solo="0">
|
||||
|
||||
|
Before Width: | Height: | Size: 810 B After Width: | Height: | Size: 810 B |
|
Before Width: | Height: | Size: 614 B After Width: | Height: | Size: 614 B |
|
Before Width: | Height: | Size: 539 B After Width: | Height: | Size: 539 B |
|
Before Width: | Height: | Size: 581 B After Width: | Height: | Size: 581 B |
@@ -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 */
|
||||
|
||||
|
Before Width: | Height: | Size: 216 B After Width: | Height: | Size: 216 B |
|
Before Width: | Height: | Size: 208 B After Width: | Height: | Size: 208 B |
|
Before Width: | Height: | Size: 195 B After Width: | Height: | Size: 195 B |
|
Before Width: | Height: | Size: 185 B After Width: | Height: | Size: 185 B |
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* BBTrackContainer.h - model-component of BB-Editor
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* 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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -93,7 +93,7 @@ private:
|
||||
|
||||
QStaticText m_staticTextName;
|
||||
|
||||
bool m_legacySEBB;
|
||||
bool m_legacySEPattern;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* BBClip.h
|
||||
* PatternClip.h
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -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
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* BBClipView.h
|
||||
* PatternClipView.h
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -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 <QStaticText>
|
||||
|
||||
|
||||
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
|
||||
#endif
|
||||
@@ -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 <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -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
|
||||
108
include/PatternStore.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* PatternStore.h - model-component of Pattern Editor
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* 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
|
||||
@@ -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 <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -24,25 +23,26 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BB_TRACK_H
|
||||
#define BB_TRACK_H
|
||||
#ifndef PATTERN_TRACK_H
|
||||
#define PATTERN_TRACK_H
|
||||
|
||||
|
||||
#include <QtCore/QMap>
|
||||
|
||||
#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<Track *> m_disabledTracks;
|
||||
|
||||
typedef QMap<BBTrack *, int> infoMap;
|
||||
typedef QMap<PatternTrack*, int> infoMap;
|
||||
static infoMap s_infoMap;
|
||||
|
||||
friend class BBTrackView;
|
||||
friend class PatternTrackView;
|
||||
} ;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* BBTrackView.h
|
||||
* PatternTrackView.h
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -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 <QtCore/QObject>
|
||||
|
||||
#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
|
||||
#endif
|
||||
@@ -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;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
} ;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -198,7 +198,7 @@ signals:
|
||||
void resized();
|
||||
|
||||
private:
|
||||
QAction* m_addBBTrackAction;
|
||||
QAction* m_addPatternTrackAction;
|
||||
QAction* m_addSampleTrackAction;
|
||||
QAction* m_addAutomationTrackAction;
|
||||
QAction* m_setProportionalSnapAction;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
typedef QVector<Track *> TrackList;
|
||||
enum TrackContainerTypes
|
||||
{
|
||||
BBContainer,
|
||||
PatternContainer,
|
||||
SongContainer
|
||||
} ;
|
||||
|
||||
|
||||
@@ -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<InstrumentTrack*>(
|
||||
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<MidiClip*>( 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 )
|
||||
|
||||
@@ -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<BBTrack *>(track);
|
||||
element = bbTrack->saveState(dataFile, dataFile.content());
|
||||
patternTrack = dynamic_cast<PatternTrack*>(track);
|
||||
element = patternTrack->saveState(dataFile, dataFile.content());
|
||||
|
||||
std::vector<std::pair<int,int>> 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<std::pair<int,int>> 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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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 *> AutomationClip::clipsForModel( const AutomatableModel
|
||||
QVector<AutomationClip *> 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 )
|
||||
|
||||
@@ -1,257 +0,0 @@
|
||||
/*
|
||||
* BBTrackContainer.cpp - model-component of BB-Editor
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* BBClip.cpp - implementation of class bbClip
|
||||
* PatternClip.cpp - implementation of class PatternClip
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -22,19 +22,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BBClip.h"
|
||||
#include "PatternClip.h"
|
||||
|
||||
#include <QDomElement>
|
||||
|
||||
#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<BBTrack *>( getTrack() )->index();
|
||||
return dynamic_cast<PatternTrack*>(getTrack())->patternIndex();
|
||||
}
|
||||
|
||||
|
||||
|
||||
ClipView * BBClip::createView( TrackView * _tv )
|
||||
ClipView* PatternClip::createView(TrackView* tv)
|
||||
{
|
||||
return new BBClipView( this, _tv );
|
||||
}
|
||||
return new PatternClipView(this, tv);
|
||||
}
|
||||
258
src/core/PatternStore.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* PatternStore.cpp - model-component of Pattern Editor
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
|
||||
@@ -26,9 +26,10 @@
|
||||
#include <QDir>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -67,7 +67,7 @@ SampleClip::SampleClip( Track * _track ) :
|
||||
|
||||
switch( getTrack()->trackContainer()->type() )
|
||||
{
|
||||
case TrackContainer::BBContainer:
|
||||
case TrackContainer::PatternContainer:
|
||||
setAutoResize( true );
|
||||
break;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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<BBTrack*>(tracklist.at(0));
|
||||
auto bbContainer = Engine::getBBTrackContainer();
|
||||
container = bbContainer;
|
||||
clipNum = bbTrack->index();
|
||||
Q_ASSERT(tracklist.at(0)->type() == Track::PatternTrack);
|
||||
auto patternTrack = dynamic_cast<PatternTrack*>(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<BBTrack *>( t )->index() );
|
||||
Track * t = Track::create(Track::PatternTrack, this);
|
||||
Engine::patternStore()->setCurrentPattern(dynamic_cast<PatternTrack*>(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<InstrumentTrack * >( t )->loadInstrument(
|
||||
"tripleoscillator" );
|
||||
t = Track::create( Track::InstrumentTrack,
|
||||
Engine::getBBTrackContainer() );
|
||||
t = Track::create(Track::InstrumentTrack, Engine::patternStore());
|
||||
dynamic_cast<InstrumentTrack * >( 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<ExportFilter *> (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
|
||||
{
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -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<BBClip *>(clip))
|
||||
else if (auto* pattern = dynamic_cast<PatternClip*>(clip))
|
||||
{
|
||||
auto bbIndex = dynamic_cast<class BBTrack*>(bb->getTrack())->index();
|
||||
auto bbContainer = Engine::getBBTrackContainer();
|
||||
auto patIndex = dynamic_cast<class PatternTrack*>(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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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<InstrumentTrack *>(
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<QWidget*>{
|
||||
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<QWidget*> 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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<bool> inUse(m_mixerChannelViews.size(), false);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* BBClipView.cpp
|
||||
* PatternClipView.cpp
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -22,23 +22,23 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "BBClipView.h"
|
||||
#include "PatternClipView.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
|
||||
#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<BBClip *>( _clip ) ),
|
||||
m_patternClip(dynamic_cast<PatternClip*>(_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<int>( 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();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* BBTrackView.cpp
|
||||
* PatternTrackView.cpp
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -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 );
|
||||
}
|
||||
Engine::patternStore()->setCurrentPattern(m_patternTrack->patternIndex());
|
||||
getGUI()->patternEditor()->parentWidget()->show();
|
||||
getGUI()->patternEditor()->setFocus(Qt::ActiveWindowFocusReason);
|
||||
}
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
/*
|
||||
* BBEditor.cpp - basic main-window for editing of beats and basslines
|
||||
*
|
||||
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* 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 <QAction>
|
||||
#include <QKeyEvent>
|
||||
#include <QLayout>
|
||||
|
||||
#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<MidiClip *>( ( *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<MidiClip *>( ( *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<BBTrackContainer*>(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<BBTrack *>( newTrack )->index() );
|
||||
|
||||
// Track still have the clips which is undesirable in this case, clear the track
|
||||
newTrack->lock();
|
||||
newTrack->deleteClips();
|
||||
newTrack->unlock();
|
||||
}
|
||||
}
|
||||
329
src/gui/editors/PatternEditor.cpp
Normal file
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* PatternEditor.cpp - basic main-window for editing patterns
|
||||
*
|
||||
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* 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 <QAction>
|
||||
#include <QKeyEvent>
|
||||
#include <QLayout>
|
||||
|
||||
#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<MidiClip*>((*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<MidiClip*>((*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<PatternStore*>(model());
|
||||
const int currentPattern = ps->currentPattern();
|
||||
|
||||
PatternTrack* pt = PatternTrack::findPatternTrack(currentPattern);
|
||||
|
||||
if (pt)
|
||||
{
|
||||
// Clone the track
|
||||
Track* newTrack = pt->clone();
|
||||
ps->setCurrentPattern(static_cast<PatternTrack*>(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();
|
||||
}
|
||||
@@ -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<int> 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)" ) );
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -30,12 +30,12 @@
|
||||
#include <QPainter>
|
||||
|
||||
#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<int>( 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 ) );
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
|
||||
#include "MidiClip.h"
|
||||
|
||||
#include "BBTrackContainer.h"
|
||||
#include "GuiApplication.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "PatternStore.h"
|
||||
#include "PianoRoll.h"
|
||||
|
||||
#include <limits>
|
||||
@@ -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
|
||||
|
||||
@@ -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 <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -21,69 +21,68 @@
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
#include "BBTrack.h"
|
||||
#include "PatternTrack.h"
|
||||
|
||||
#include <QDomElement>
|
||||
#include <QMenu>
|
||||
#include <QPainter>
|
||||
|
||||
#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<BBTrack *>( _track1 );
|
||||
BBTrack * t2 = dynamic_cast<BBTrack *>( _track2 );
|
||||
PatternTrack* t1 = dynamic_cast<PatternTrack*>(track1);
|
||||
PatternTrack* t2 = dynamic_cast<PatternTrack*>(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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
#include <QDomElement>
|
||||
|
||||
#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() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<AutomationClip*>(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);
|
||||
|
||||
|
||||