123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- #pragma once
- #include "openmpt/all/BuildSettings.hpp"
- #include "../soundlib/ModChannel.h"
- #include "../soundlib/modcommand.h"
- OPENMPT_NAMESPACE_BEGIN
- class CModDoc;
- struct ModSample;
- #define MAX_UNDO_LEVEL 100000
- class CPatternUndo
- {
- protected:
- static constexpr auto DELETE_PATTERN = PATTERNINDEX_INVALID;
- struct UndoInfo
- {
- std::vector<ModChannelSettings> channelInfo;
- std::vector<ModCommand> content;
- const char *description;
- ROWINDEX numPatternRows;
- ROWINDEX firstRow, numRows;
- PATTERNINDEX pattern;
- CHANNELINDEX firstChannel, numChannels;
- bool linkToPrevious;
- bool OnlyChannelSettings() const noexcept
- {
- return !channelInfo.empty() && numRows < 1 && !linkToPrevious;
- }
- };
- using undobuf_t = std::vector<UndoInfo>;
- undobuf_t UndoBuffer;
- undobuf_t RedoBuffer;
- CModDoc &modDoc;
-
- PATTERNINDEX Undo(undobuf_t &fromBuf, undobuf_t &toBuf, bool linkedFromPrevious);
- bool PrepareBuffer(undobuf_t &buffer, PATTERNINDEX pattern, CHANNELINDEX firstChn, ROWINDEX firstRow, CHANNELINDEX numChns, ROWINDEX numRows, const char *description, bool linkToPrevious, bool storeChannelInfo) const;
- static CString GetName(const undobuf_t &buffer);
- static void RearrangePatterns(undobuf_t &buffer, const std::vector<PATTERNINDEX> &newIndex);
- public:
-
- void ClearUndo();
-
- bool PrepareUndo(PATTERNINDEX pattern, CHANNELINDEX firstChn, ROWINDEX firstRow, CHANNELINDEX numChns, ROWINDEX numRows, const char *description, bool linkToPrevious = false, bool storeChannelInfo = false);
-
- bool PrepareChannelUndo(CHANNELINDEX firstChn, CHANNELINDEX numChns, const char *description);
-
- PATTERNINDEX Undo();
-
- PATTERNINDEX Redo();
-
- bool CanUndo() const { return !UndoBuffer.empty(); }
-
- bool CanRedo() const { return !RedoBuffer.empty(); }
-
- bool CanUndoChannelSettings() const { return !UndoBuffer.empty() && UndoBuffer.back().OnlyChannelSettings(); }
-
- bool CanRedoChannelSettings() const { return !RedoBuffer.empty() && RedoBuffer.back().OnlyChannelSettings(); }
-
- void RemoveLastUndoStep();
-
- CString GetUndoName() const { return GetName(UndoBuffer); }
-
- CString GetRedoName() const { return GetName(RedoBuffer); }
-
- void RearrangePatterns(const std::vector<PATTERNINDEX> &newIndex);
- CPatternUndo(CModDoc &parent) : modDoc(parent) { }
- };
- enum sampleUndoTypes
- {
- sundo_none,
- sundo_update,
- sundo_delete,
- sundo_invert,
- sundo_reverse,
- sundo_unsign,
- sundo_insert,
- sundo_replace,
- };
- class CSampleUndo
- {
- protected:
- struct UndoInfo
- {
- ModSample OldSample;
- mpt::charbuf<MAX_SAMPLENAME> oldName;
- void *samplePtr = nullptr;
- const char *description = nullptr;
- SmpLength changeStart = 0, changeEnd = 0;
- sampleUndoTypes changeType = sundo_none;
- };
- using undobuf_t = std::vector<std::vector<UndoInfo>>;
- undobuf_t UndoBuffer;
- undobuf_t RedoBuffer;
- CModDoc &modDoc;
-
- void ClearUndo(undobuf_t &buffer, const SAMPLEINDEX smp);
- void DeleteStep(undobuf_t &buffer, const SAMPLEINDEX smp, const size_t step);
- bool SampleBufferExists(const undobuf_t &buffer, const SAMPLEINDEX smp) const;
- void RestrictBufferSize(undobuf_t &buffer, size_t &capacity);
- size_t GetBufferCapacity(const undobuf_t &buffer) const;
- void RearrangeSamples(undobuf_t &buffer, const std::vector<SAMPLEINDEX> &newIndex);
- bool PrepareBuffer(undobuf_t &buffer, const SAMPLEINDEX smp, sampleUndoTypes changeType, const char *description, SmpLength changeStart, SmpLength changeEnd);
- bool Undo(undobuf_t &fromBuf, undobuf_t &toBuf, const SAMPLEINDEX smp);
- public:
-
- void ClearUndo();
- void ClearUndo(const SAMPLEINDEX smp) { ClearUndo(UndoBuffer, smp); ClearUndo(RedoBuffer, smp); }
- bool PrepareUndo(const SAMPLEINDEX smp, sampleUndoTypes changeType, const char *description, SmpLength changeStart = 0, SmpLength changeEnd = 0);
- bool Undo(const SAMPLEINDEX smp);
- bool Redo(const SAMPLEINDEX smp);
- bool CanUndo(const SAMPLEINDEX smp) const { return SampleBufferExists(UndoBuffer, smp) && !UndoBuffer[smp - 1].empty(); }
- bool CanRedo(const SAMPLEINDEX smp) const { return SampleBufferExists(RedoBuffer, smp) && !RedoBuffer[smp - 1].empty(); }
- void RemoveLastUndoStep(const SAMPLEINDEX smp);
- const char *GetUndoName(const SAMPLEINDEX smp) const;
- const char *GetRedoName(const SAMPLEINDEX smp) const;
- void RestrictBufferSize();
- void RearrangeSamples(const std::vector<SAMPLEINDEX> &newIndex) { RearrangeSamples(UndoBuffer, newIndex); RearrangeSamples(RedoBuffer, newIndex); }
- CSampleUndo(CModDoc &parent) : modDoc(parent) { }
- ~CSampleUndo()
- {
- ClearUndo();
- };
- };
- class CInstrumentUndo
- {
- protected:
- struct UndoInfo
- {
- ModInstrument instr;
- const char *description = nullptr;
- EnvelopeType editedEnvelope = ENV_MAXTYPES;
- };
- using undobuf_t = std::vector<std::vector<UndoInfo>>;
- undobuf_t UndoBuffer;
- undobuf_t RedoBuffer;
- CModDoc &modDoc;
-
- void ClearUndo(undobuf_t &buffer, const INSTRUMENTINDEX ins);
- void DeleteStep(undobuf_t &buffer, const INSTRUMENTINDEX ins, const size_t step);
- bool InstrumentBufferExists(const undobuf_t &buffer, const INSTRUMENTINDEX ins) const;
- void RearrangeInstruments(undobuf_t &buffer, const std::vector<INSTRUMENTINDEX> &newIndex);
- void RearrangeSamples(undobuf_t &buffer, const INSTRUMENTINDEX ins, std::vector<SAMPLEINDEX> &newIndex);
- bool PrepareBuffer(undobuf_t &buffer, const INSTRUMENTINDEX ins, const char *description, EnvelopeType envType);
- bool Undo(undobuf_t &fromBuf, undobuf_t &toBuf, const INSTRUMENTINDEX ins);
- public:
-
- void ClearUndo();
- void ClearUndo(const INSTRUMENTINDEX ins) { ClearUndo(UndoBuffer, ins); ClearUndo(RedoBuffer, ins); }
- bool PrepareUndo(const INSTRUMENTINDEX ins, const char *description, EnvelopeType envType = ENV_MAXTYPES);
- bool Undo(const INSTRUMENTINDEX ins);
- bool Redo(const INSTRUMENTINDEX ins);
- bool CanUndo(const INSTRUMENTINDEX ins) const { return InstrumentBufferExists(UndoBuffer, ins) && !UndoBuffer[ins - 1].empty(); }
- bool CanRedo(const INSTRUMENTINDEX ins) const { return InstrumentBufferExists(RedoBuffer, ins) && !RedoBuffer[ins - 1].empty(); }
- void RemoveLastUndoStep(const INSTRUMENTINDEX ins);
- const char *GetUndoName(const INSTRUMENTINDEX ins) const;
- const char *GetRedoName(const INSTRUMENTINDEX ins) const;
- void RearrangeInstruments(const std::vector<INSTRUMENTINDEX> &newIndex) { RearrangeInstruments(UndoBuffer, newIndex); RearrangeInstruments(RedoBuffer, newIndex); }
- void RearrangeSamples(const INSTRUMENTINDEX ins, std::vector<SAMPLEINDEX> &newIndex) { RearrangeSamples(UndoBuffer, ins, newIndex); RearrangeSamples(RedoBuffer, ins, newIndex); }
- CInstrumentUndo(CModDoc &parent) : modDoc(parent) { }
- ~CInstrumentUndo()
- {
- ClearUndo();
- };
- };
- OPENMPT_NAMESPACE_END
|