add undo to instrument editor (check for diffs on the current DivInstrument in insEdit, record them in a stack)
This commit is contained in:
parent
a318508b40
commit
5c9fd69ac1
8 changed files with 307 additions and 55 deletions
|
|
@ -605,7 +605,7 @@ void FurnaceGUI::drawDebug() {
|
|||
}
|
||||
if (ImGui::TreeNode("Recent Files")) {
|
||||
ImGui::Text("Items: %d - Max: %d",(int)recentFile.size(),settings.maxRecentFile);
|
||||
ImGui::Text("readPos: %d - writePos: %d",(int)recentFile.readPos,(int)recentFile.writePos);
|
||||
ImGui::Text("readPos: %d - writePos: %d",(int)recentFile.readPos,(int)recentFile.writePos());
|
||||
ImGui::Indent();
|
||||
for (size_t i=0; i<recentFile.size(); i++) {
|
||||
ImGui::Text("%d: %s",(int)i,recentFile[i].c_str());
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_UNDO:
|
||||
if (curWindow==GUI_WINDOW_SAMPLE_EDIT) {
|
||||
doUndoSample();
|
||||
} else if (curWindow==GUI_WINDOW_INS_EDIT) {
|
||||
doUndoInstrument();
|
||||
} else {
|
||||
doUndo();
|
||||
}
|
||||
|
|
@ -80,6 +82,8 @@ void FurnaceGUI::doAction(int what) {
|
|||
case GUI_ACTION_REDO:
|
||||
if (curWindow==GUI_WINDOW_SAMPLE_EDIT) {
|
||||
doRedoSample();
|
||||
} else if (curWindow==GUI_WINDOW_INS_EDIT) {
|
||||
doRedoInstrument();
|
||||
} else {
|
||||
doRedo();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8310,6 +8310,7 @@ FurnaceGUI::FurnaceGUI():
|
|||
localeRequiresChineseTrad(false),
|
||||
localeRequiresKorean(false),
|
||||
prevInsData(NULL),
|
||||
cachedCurInsPtr(NULL),
|
||||
pendingLayoutImport(NULL),
|
||||
pendingLayoutImportLen(0),
|
||||
pendingLayoutImportStep(0),
|
||||
|
|
|
|||
|
|
@ -2256,6 +2256,8 @@ class FurnaceGUI {
|
|||
std::vector<ImWchar> localeExtraRanges;
|
||||
|
||||
DivInstrument* prevInsData;
|
||||
DivInstrument cachedCurIns;
|
||||
DivInstrument* cachedCurInsPtr;
|
||||
|
||||
unsigned char* pendingLayoutImport;
|
||||
size_t pendingLayoutImportLen;
|
||||
|
|
@ -2922,6 +2924,9 @@ class FurnaceGUI {
|
|||
void doUndoSample();
|
||||
void doRedoSample();
|
||||
|
||||
void doUndoInstrument();
|
||||
void doRedoInstrument();
|
||||
|
||||
void play(int row=0);
|
||||
void setOrder(unsigned char order, bool forced=false);
|
||||
void stop();
|
||||
|
|
|
|||
|
|
@ -5250,6 +5250,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
ImGui::SetNextWindowSizeConstraints(ImVec2(440.0f*dpiScale,400.0f*dpiScale),ImVec2(canvasW,canvasH));
|
||||
}
|
||||
if (ImGui::Begin("Instrument Editor",&insEditOpen,globalWinFlags|(settings.allowEditDocking?0:ImGuiWindowFlags_NoDocking),_("Instrument Editor"))) {
|
||||
DivInstrument* ins=nullptr;
|
||||
if (curIns==-2) {
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY()+(ImGui::GetContentRegionAvail().y-ImGui::GetFrameHeightWithSpacing()+ImGui::GetStyle().ItemSpacing.y)*0.5f);
|
||||
CENTER_TEXT(_("waiting..."));
|
||||
|
|
@ -5277,6 +5278,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
curIns=i;
|
||||
wavePreviewInit=true;
|
||||
updateFMPreview=true;
|
||||
ins = e->song.ins[curIns];
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
|
|
@ -5299,7 +5301,7 @@ void FurnaceGUI::drawInsEdit() {
|
|||
ImGui::EndTable();
|
||||
}
|
||||
} else {
|
||||
DivInstrument* ins=e->song.ins[curIns];
|
||||
ins=e->song.ins[curIns];
|
||||
if (updateFMPreview) {
|
||||
renderFMPreview(ins);
|
||||
updateFMPreview=false;
|
||||
|
|
@ -7738,7 +7740,51 @@ void FurnaceGUI::drawInsEdit() {
|
|||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
if (ins) {
|
||||
bool insChanged = ins != cachedCurInsPtr;
|
||||
bool delayDiff = ImGui::IsMouseDown(ImGuiMouseButton_Left) || ImGui::IsMouseDown(ImGuiMouseButton_Right) || ImGui::GetIO().WantCaptureKeyboard;
|
||||
|
||||
// check against the last cached to see if diff -- note that modifications to instruments happen outside
|
||||
// drawInsEdit (e.g. cursor inputs are processed and can directly modify macro data)
|
||||
if (!insChanged && !delayDiff) {
|
||||
ins->recordUndoStepIfChanged(e->processTime, &cachedCurIns);
|
||||
}
|
||||
|
||||
if (insChanged || !delayDiff) {
|
||||
cachedCurIns = *ins;
|
||||
}
|
||||
|
||||
cachedCurInsPtr = ins;
|
||||
} else {
|
||||
cachedCurInsPtr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_INS_EDIT;
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void FurnaceGUI::doUndoInstrument() {
|
||||
if (!insEditOpen) return;
|
||||
if (curIns<0 || curIns>=(int)e->song.ins.size()) return;
|
||||
DivInstrument* ins=e->song.ins[curIns];
|
||||
// is locking the engine necessary? copied from doUndoSample
|
||||
e->lockEngine([this,ins]() {
|
||||
ins->undo();
|
||||
cachedCurInsPtr=ins;
|
||||
cachedCurIns=*ins;
|
||||
});
|
||||
}
|
||||
|
||||
void FurnaceGUI::doRedoInstrument() {
|
||||
if (!insEditOpen) return;
|
||||
if (curIns<0 || curIns>=(int)e->song.ins.size()) return;
|
||||
DivInstrument* ins=e->song.ins[curIns];
|
||||
// is locking the engine necessary? copied from doRedoSample
|
||||
e->lockEngine([this,ins]() {
|
||||
ins->redo();
|
||||
cachedCurInsPtr=ins;
|
||||
cachedCurIns=*ins;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue