diff --git a/Source/FamiTrackerDoc.cpp b/Source/FamiTrackerDoc.cpp index e81d8caa..43303d9f 100644 --- a/Source/FamiTrackerDoc.cpp +++ b/Source/FamiTrackerDoc.cpp @@ -2571,6 +2571,11 @@ const CSongData &CFamiTrackerDoc::GetSongData(unsigned int Index) const // // / return *m_pTracks[Index]; } +std::unique_ptr CFamiTrackerDoc::ReplaceSong(unsigned Index, std::unique_ptr pSong) { // // // + m_pTracks[Index].swap(pSong); + return std::move(pSong); +} + unsigned int CFamiTrackerDoc::GetTrackCount() const { return m_pTracks.size(); @@ -3277,30 +3282,6 @@ bool CFamiTrackerDoc::ArePatternsSame(unsigned int Track, unsigned int Channel, return song.GetPattern(Channel, Pattern1) == song.GetPattern(Channel, Pattern2); } -void CFamiTrackerDoc::PopulateUniquePatterns(unsigned int Track) // // // -{ - const int Rows = GetPatternLength(Track); - const int Frames = GetFrameCount(Track); - const auto &Song = GetSongData(Track); - auto pNew = std::make_unique(Rows); - - pNew->SetSongSpeed(GetSongSpeed(Track)); - pNew->SetSongTempo(GetSongTempo(Track)); - pNew->SetFrameCount(Frames); - pNew->SetSongGroove(GetSongGroove(Track)); - pNew->SetTitle(GetTrackTitle(Track)); - - for (int c = 0; c < GetChannelCount(); c++) { - pNew->SetEffectColumnCount(c, GetEffColumns(Track, c)); - for (int f = 0; f < Frames; f++) { - pNew->SetFramePattern(f, c, f); - pNew->GetPattern(c, f) = Song.GetPattern(c, Song.GetFramePattern(f, c)); - } - } - - m_pTracks[Track] = std::move(pNew); -} - void CFamiTrackerDoc::SwapInstruments(int First, int Second) { // Swap instruments diff --git a/Source/FamiTrackerDoc.h b/Source/FamiTrackerDoc.h index 0f8eba49..5551a116 100644 --- a/Source/FamiTrackerDoc.h +++ b/Source/FamiTrackerDoc.h @@ -147,6 +147,7 @@ class CFamiTrackerDoc : public CDocument, public CFTMComponentInterface // Local (song) data CSongData &GetSongData(unsigned int Index); // // // const CSongData &GetSongData(unsigned int Index) const; // // // + std::unique_ptr ReplaceSong(unsigned Index, std::unique_ptr pSong); // // // returns old song void SetPatternLength(unsigned int Track, unsigned int Length); void SetFrameCount(unsigned int Track, unsigned int Count); @@ -184,8 +185,6 @@ class CFamiTrackerDoc : public CDocument, public CFTMComponentInterface void ClearPatterns(unsigned int Track); void ClearPattern(unsigned int Track, unsigned int Frame, unsigned int Channel); - void PopulateUniquePatterns(unsigned int Track); // // // - bool InsertRow(unsigned int Track, unsigned int Frame, unsigned int Channel, unsigned int Row); bool ClearRowField(unsigned int Track, unsigned int Frame, unsigned int Channel, unsigned int Row, cursor_column_t Column); bool RemoveNote(unsigned int Track, unsigned int Frame, unsigned int Channel, unsigned int Row); diff --git a/Source/MainFrm.cpp b/Source/MainFrm.cpp index 676046e0..7addf670 100644 --- a/Source/MainFrm.cpp +++ b/Source/MainFrm.cpp @@ -3571,16 +3571,7 @@ void CMainFrame::OnEditRemoveUnusedSamples() void CMainFrame::OnEditPopulateUniquePatterns() // // // { - CFamiTrackerDoc *pDoc = static_cast(GetActiveDocument()); - - if (AfxMessageBox(IDS_POPULATE_PATTERNS, MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) == IDNO) - return; - - pDoc->PopulateUniquePatterns(m_iTrack); - pDoc->SetModifiedFlag(); - pDoc->SetExceededFlag(); - ResetUndo(); - pDoc->UpdateAllViews(NULL, UPDATE_FRAME); + AddAction(std::make_unique(m_iTrack)); } void CMainFrame::OnEditGoto() diff --git a/Source/PatternAction.cpp b/Source/PatternAction.cpp index 72e2365f..c1915a0e 100644 --- a/Source/PatternAction.cpp +++ b/Source/PatternAction.cpp @@ -1273,3 +1273,47 @@ void CPActionHighlight::UpdateView(CFamiTrackerDoc *pDoc) const { pDoc->UpdateAllViews(NULL, UPDATE_HIGHLIGHT); } + + + +bool CPActionUniquePatterns::SaveState(const CMainFrame &MainFrm) { + const auto *pDoc = static_cast(MainFrm.GetActiveView())->GetDocument(); + if (index_ >= pDoc->GetTrackCount()) + return false; + const auto &Song = pDoc->GetSongData(index_); + const int Rows = Song.GetPatternLength(); + const int Frames = Song.GetFrameCount(); + + songNew_ = std::make_unique(Rows); + songNew_->SetSongSpeed(Song.GetSongSpeed()); + songNew_->SetSongTempo(Song.GetSongTempo()); + songNew_->SetFrameCount(Frames); + songNew_->SetSongGroove(Song.GetSongGroove()); + songNew_->SetTitle(Song.GetTitle()); + + for (int c = 0; c < pDoc->GetChannelCount(); c++) { + songNew_->SetEffectColumnCount(c, Song.GetEffectColumnCount(c)); + for (int f = 0; f < Frames; f++) { + songNew_->SetFramePattern(f, c, f); + songNew_->GetPattern(c, f) = Song.GetPattern(c, Song.GetFramePattern(f, c)); + } + } + + return true; +} + +void CPActionUniquePatterns::Undo(CMainFrame &MainFrm) const { + ASSERT(song_); + auto pDoc = static_cast(MainFrm.GetActiveView())->GetDocument(); + songNew_ = pDoc->ReplaceSong(index_, std::move(song_)); +} + +void CPActionUniquePatterns::Redo(CMainFrame &MainFrm) const { + ASSERT(songNew_); + auto pDoc = static_cast(MainFrm.GetActiveView())->GetDocument(); + song_ = pDoc->ReplaceSong(index_, std::move(songNew_)); +} + +void CPActionUniquePatterns::UpdateView(CFamiTrackerDoc *pDoc) const { + pDoc->UpdateAllViews(NULL, UPDATE_FRAME); +} diff --git a/Source/PatternAction.h b/Source/PatternAction.h index 23e5b606..d001c29d 100644 --- a/Source/PatternAction.h +++ b/Source/PatternAction.h @@ -24,6 +24,7 @@ #pragma once #include // // // +#include // // // #include "Action.h" #include "PatternEditorTypes.h" #include "SongData.h" // // // @@ -79,7 +80,7 @@ class CPatternAction : public CAction public: enum ACTIONS { - ACT_EDIT_NOTE, + ACT_EDIT_NOTE = 1, ACT_REPLACE_NOTE, // // // ACT_INSERT_ROW, ACT_DELETE_ROW, @@ -395,3 +396,17 @@ class CPActionHighlight : public CPatternAction // // // private: stHighlight m_OldHighlight, m_NewHighlight; }; + +class CPActionUniquePatterns : public CPatternAction { +public: + CPActionUniquePatterns(unsigned index) : CPatternAction(0), index_(index) { } +private: + bool SaveState(const CMainFrame &MainFrm) override; + void Undo(CMainFrame &MainFrm) const override; + void Redo(CMainFrame &MainFrm) const override; + void UpdateView(CFamiTrackerDoc *pDoc) const; + + mutable std::unique_ptr song_; // ??? + mutable std::unique_ptr songNew_; + unsigned index_ = 0; +};