Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
229
Src/external_dependencies/openmpt-trunk/mptrack/Undo.h
Normal file
229
Src/external_dependencies/openmpt-trunk/mptrack/Undo.h
Normal file
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* Undo.h
|
||||
* ------
|
||||
* Purpose: Editor undo buffer functionality.
|
||||
* Notes : (currently none)
|
||||
* Authors: Olivier Lapicque
|
||||
* OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
|
||||
#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 // 100,000 undo steps for each undo type!
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Pattern Undo
|
||||
|
||||
|
||||
class CPatternUndo
|
||||
{
|
||||
protected:
|
||||
static constexpr auto DELETE_PATTERN = PATTERNINDEX_INVALID;
|
||||
|
||||
struct UndoInfo
|
||||
{
|
||||
std::vector<ModChannelSettings> channelInfo; // Optional old channel information (pan / volume / etc.)
|
||||
std::vector<ModCommand> content; // Rescued pattern content
|
||||
const char *description; // Name of this undo action
|
||||
ROWINDEX numPatternRows; // Original number of pattern rows (in case of resize, DELETE_PATTERN in case of deletion)
|
||||
ROWINDEX firstRow, numRows;
|
||||
PATTERNINDEX pattern;
|
||||
CHANNELINDEX firstChannel, numChannels;
|
||||
bool linkToPrevious; // This undo information is linked with the previous undo information
|
||||
|
||||
bool OnlyChannelSettings() const noexcept
|
||||
{
|
||||
return !channelInfo.empty() && numRows < 1 && !linkToPrevious;
|
||||
}
|
||||
};
|
||||
|
||||
using undobuf_t = std::vector<UndoInfo>;
|
||||
|
||||
undobuf_t UndoBuffer;
|
||||
undobuf_t RedoBuffer;
|
||||
CModDoc &modDoc;
|
||||
|
||||
// Pattern undo helper functions
|
||||
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:
|
||||
|
||||
// Removes all undo steps from the buffer.
|
||||
void ClearUndo();
|
||||
// Adds a new action to the undo buffer.
|
||||
bool PrepareUndo(PATTERNINDEX pattern, CHANNELINDEX firstChn, ROWINDEX firstRow, CHANNELINDEX numChns, ROWINDEX numRows, const char *description, bool linkToPrevious = false, bool storeChannelInfo = false);
|
||||
// Adds a new action only affecting channel data to the undo buffer.
|
||||
bool PrepareChannelUndo(CHANNELINDEX firstChn, CHANNELINDEX numChns, const char *description);
|
||||
// Undoes the most recent action.
|
||||
PATTERNINDEX Undo();
|
||||
// Redoes the most recent action.
|
||||
PATTERNINDEX Redo();
|
||||
// Returns true if any actions can currently be undone.
|
||||
bool CanUndo() const { return !UndoBuffer.empty(); }
|
||||
// Returns true if any actions can currently be redone.
|
||||
bool CanRedo() const { return !RedoBuffer.empty(); }
|
||||
// Returns true if a channel-specific action (no pattern data) can currently be undone.
|
||||
bool CanUndoChannelSettings() const { return !UndoBuffer.empty() && UndoBuffer.back().OnlyChannelSettings(); }
|
||||
// Returns true if a channel-specific action (no pattern data) actions can currently be redone.
|
||||
bool CanRedoChannelSettings() const { return !RedoBuffer.empty() && RedoBuffer.back().OnlyChannelSettings(); }
|
||||
// Remove the latest added undo step from the undo buffer
|
||||
void RemoveLastUndoStep();
|
||||
// Get name of next undo item
|
||||
CString GetUndoName() const { return GetName(UndoBuffer); }
|
||||
// Get name of next redo item
|
||||
CString GetRedoName() const { return GetName(RedoBuffer); }
|
||||
// Adjust undo buffers for rearranged patterns
|
||||
void RearrangePatterns(const std::vector<PATTERNINDEX> &newIndex);
|
||||
|
||||
CPatternUndo(CModDoc &parent) : modDoc(parent) { }
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Sample Undo
|
||||
|
||||
// We will differentiate between different types of undo actions so that we don't have to copy the whole sample everytime.
|
||||
enum sampleUndoTypes
|
||||
{
|
||||
sundo_none, // no changes to sample itself, e.g. loop point update
|
||||
sundo_update, // silence, amplify, normalize, dc offset - update complete sample section
|
||||
sundo_delete, // delete part of the sample
|
||||
sundo_invert, // invert sample phase, apply again to undo
|
||||
sundo_reverse, // reverse sample, ditto
|
||||
sundo_unsign, // unsign sample, ditto
|
||||
sundo_insert, // insert data, delete inserted data to undo
|
||||
sundo_replace, // replace complete sample (16->8Bit, up/downsample, downmix to mono, pitch shifting / time stretching, trimming, pasting)
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
|
||||
// Sample undo helper functions
|
||||
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:
|
||||
|
||||
// Sample undo functions
|
||||
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();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Instrument Undo
|
||||
|
||||
|
||||
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;
|
||||
|
||||
// Instrument undo helper functions
|
||||
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:
|
||||
|
||||
// Instrument undo functions
|
||||
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
|
Loading…
Add table
Add a link
Reference in a new issue