mirror of https://github.com/stella-emu/stella.git
refactored undo functionality into UndoHandler class
This commit is contained in:
parent
c1cc678c19
commit
f4ab26f350
|
@ -21,6 +21,7 @@
|
|||
#include "Font.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
#include "UndoHandler.hxx"
|
||||
#include "EditableWidget.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -36,6 +37,8 @@ EditableWidget::EditableWidget(GuiObject* boss, const GUI::Font& font,
|
|||
_bgcolorlo = kDlgColor;
|
||||
_textcolor = kTextColor;
|
||||
_textcolorhi = kTextColor;
|
||||
|
||||
myUndoHandler = make_unique<UndoHandler>();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -47,8 +50,8 @@ void EditableWidget::setText(const string& str, bool)
|
|||
if(_filter(tolower(c)))
|
||||
_editString.push_back(c);
|
||||
|
||||
clearEdits();
|
||||
doEdit();
|
||||
myUndoHandler->reset();
|
||||
myUndoHandler->doo(_editString);
|
||||
|
||||
_caretPos = int(_editString.size());
|
||||
_selectSize = 0;
|
||||
|
@ -81,64 +84,13 @@ void EditableWidget::lostFocusWidget()
|
|||
_selectSize = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditableWidget::clearEdits()
|
||||
{
|
||||
_editBuffer.clear();
|
||||
_redoCount = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void EditableWidget::doEdit()
|
||||
{
|
||||
constexpr size_t UNDO_SIZE = 100;
|
||||
|
||||
// clear redos
|
||||
for(; _redoCount; _redoCount--)
|
||||
_editBuffer.pop_back();
|
||||
|
||||
if(_editBuffer.size() == UNDO_SIZE)
|
||||
_editBuffer.pop_front();
|
||||
_editBuffer.push_back(_editString);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool EditableWidget::undoEdit()
|
||||
{
|
||||
if(_editBuffer.size() - _redoCount - 1)
|
||||
{
|
||||
_redoCount++;
|
||||
_editString = _editBuffer[_editBuffer.size() - _redoCount - 1];
|
||||
_caretPos = int(_editString.size()); // TODO: put at last difference
|
||||
_selectSize = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool EditableWidget::redoEdit()
|
||||
{
|
||||
if(_redoCount)
|
||||
{
|
||||
_redoCount--;
|
||||
_editString = _editBuffer[_editBuffer.size() - _redoCount - 1];
|
||||
_caretPos = int(_editString.size()); // TODO: put at last difference
|
||||
_selectSize = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool EditableWidget::tryInsertChar(char c, int pos)
|
||||
{
|
||||
if(_filter(tolower(c)))
|
||||
{
|
||||
_editString.insert(pos, 1, c);
|
||||
doEdit();
|
||||
myUndoHandler->doo(_editString);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -245,9 +197,11 @@ bool EditableWidget::handleControlKeys(StellaKey key, StellaMod mod)
|
|||
case KBDK_Y:
|
||||
case KBDK_Z:
|
||||
if(key == KBDK_Y != instance().eventHandler().isQwertz())
|
||||
dirty = redoEdit();
|
||||
dirty = myUndoHandler->redo(_editString);
|
||||
else
|
||||
dirty = undoEdit();
|
||||
dirty = myUndoHandler->undo(_editString);
|
||||
_caretPos = int(_editString.size()); // TODO: put at last difference
|
||||
_selectSize = 0;
|
||||
break;
|
||||
|
||||
case KBDK_LEFT:
|
||||
|
@ -542,7 +496,7 @@ bool EditableWidget::killChar(int direction, bool addEdit)
|
|||
if(_selectSize < 0)
|
||||
_selectSize++;
|
||||
if(addEdit)
|
||||
doEdit();
|
||||
myUndoHandler->doo(_editString);
|
||||
}
|
||||
}
|
||||
else if(direction == 1) // Delete next character (delete)
|
||||
|
@ -552,7 +506,7 @@ bool EditableWidget::killChar(int direction, bool addEdit)
|
|||
if(_selectSize > 0)
|
||||
_selectSize--;
|
||||
if(addEdit)
|
||||
doEdit();
|
||||
myUndoHandler->doo(_editString);
|
||||
}
|
||||
|
||||
return handled;
|
||||
|
@ -575,7 +529,7 @@ bool EditableWidget::killLine(int direction)
|
|||
// remove selection for removed text
|
||||
if(_selectSize < 0)
|
||||
_selectSize = 0;
|
||||
doEdit();
|
||||
myUndoHandler->doo(_editString);
|
||||
}
|
||||
}
|
||||
else if(direction == 1) // erase from current position to end of line
|
||||
|
@ -590,7 +544,7 @@ bool EditableWidget::killLine(int direction)
|
|||
// remove selection for removed text
|
||||
if(_selectSize > 0)
|
||||
_selectSize = 0;
|
||||
doEdit();
|
||||
myUndoHandler->doo(_editString);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -626,7 +580,7 @@ bool EditableWidget::killLastWord()
|
|||
// remove selection for removed word
|
||||
if(_selectSize < 0)
|
||||
_selectSize = std::min(_selectSize + count, 0);
|
||||
doEdit();
|
||||
myUndoHandler->doo(_editString);
|
||||
}
|
||||
|
||||
return handled;
|
||||
|
@ -731,7 +685,7 @@ bool EditableWidget::killSelectedText(bool addEdit)
|
|||
_editString.erase(_caretPos, _selectSize);
|
||||
_selectSize = 0;
|
||||
if(addEdit)
|
||||
doEdit();
|
||||
myUndoHandler->doo(_editString);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -799,7 +753,7 @@ bool EditableWidget::pasteSelectedText()
|
|||
|
||||
if(selected || !pasted.empty())
|
||||
{
|
||||
doEdit();
|
||||
myUndoHandler->doo(_editString);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
#define EDITABLE_WIDGET_HXX
|
||||
|
||||
#include <functional>
|
||||
#include <deque>
|
||||
|
||||
#include "Widget.hxx"
|
||||
#include "Rect.hxx"
|
||||
#include "UndoHandler.hxx"
|
||||
|
||||
/**
|
||||
* Base class for widgets which need to edit text, like ListWidget and
|
||||
|
@ -102,11 +102,6 @@ class EditableWidget : public Widget, public CommandSender
|
|||
bool cutSelectedText();
|
||||
bool copySelectedText();
|
||||
bool pasteSelectedText();
|
||||
// Undo
|
||||
void clearEdits();
|
||||
void doEdit();
|
||||
bool undoEdit();
|
||||
bool redoEdit();
|
||||
|
||||
// Use the current TextFilter to insert a character into the
|
||||
// internal buffer
|
||||
|
@ -115,10 +110,10 @@ class EditableWidget : public Widget, public CommandSender
|
|||
private:
|
||||
bool _editable{true};
|
||||
string _editString;
|
||||
unique_ptr<UndoHandler> myUndoHandler;
|
||||
|
||||
std::deque<string> _editBuffer;
|
||||
int _redoCount{0};
|
||||
int _caretPos{0};
|
||||
|
||||
// Size of current selected text
|
||||
// 0 = no selection
|
||||
// <0 = selected left of caret
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
#include "UndoHandler.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
UndoHandler::UndoHandler(size_t size)
|
||||
: myRedoCount(0),
|
||||
mySize(size)
|
||||
{}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void UndoHandler::reset()
|
||||
{
|
||||
myBuffer.clear();
|
||||
myRedoCount = 0;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void UndoHandler::doo(const string& text)
|
||||
{
|
||||
// clear redos
|
||||
for(; myRedoCount; myRedoCount--)
|
||||
myBuffer.pop_front();
|
||||
|
||||
// limit buffer size
|
||||
if(myBuffer.size() == mySize)
|
||||
myBuffer.pop_back();
|
||||
|
||||
// add text to buffer
|
||||
myBuffer.push_front(text);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool UndoHandler::undo(string& text)
|
||||
{
|
||||
if(myBuffer.size() > myRedoCount + 1)
|
||||
{
|
||||
text = myBuffer[++myRedoCount];
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool UndoHandler::redo(string& text)
|
||||
{
|
||||
if(myRedoCount)
|
||||
{
|
||||
text = myBuffer[--myRedoCount];
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
||||
// and the Stella Team
|
||||
//
|
||||
// See the file "License.txt" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//============================================================================
|
||||
|
||||
|
||||
#ifndef UNDO_HANDLER_HXX
|
||||
#define UNDO_HANDLER_HXX
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include <deque>
|
||||
|
||||
/**
|
||||
* Class for providing undo/redo functionality
|
||||
*
|
||||
* @author Thomas Jentzsch
|
||||
*/
|
||||
class UndoHandler
|
||||
{
|
||||
public:
|
||||
UndoHandler(size_t size = 100);
|
||||
~UndoHandler() = default;
|
||||
|
||||
void reset();
|
||||
void doo(const string& text);
|
||||
bool undo(string& text);
|
||||
bool redo(string& text);
|
||||
|
||||
private:
|
||||
std::deque<string> myBuffer;
|
||||
size_t mySize;
|
||||
uInt32 myRedoCount;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
UndoHandler(const UndoHandler&) = delete;
|
||||
UndoHandler(UndoHandler&&) = delete;
|
||||
UndoHandler& operator=(const UndoHandler&) = delete;
|
||||
UndoHandler& operator=(UndoHandler&&) = delete;
|
||||
};
|
||||
#endif
|
|
@ -49,6 +49,7 @@ MODULE_OBJS := \
|
|||
src/gui/TimeLineWidget.o \
|
||||
src/gui/TimeMachineDialog.o \
|
||||
src/gui/TimeMachine.o \
|
||||
src/gui/UndoHandler.o \
|
||||
src/gui/UIDialog.o \
|
||||
src/gui/VideoAudioDialog.o \
|
||||
src/gui/WhatsNewDialog.o \
|
||||
|
|
|
@ -786,6 +786,7 @@
|
|||
<ClCompile Include="..\gui\TimeLineWidget.cxx" />
|
||||
<ClCompile Include="..\gui\TimeMachine.cxx" />
|
||||
<ClCompile Include="..\gui\TimeMachineDialog.cxx" />
|
||||
<ClCompile Include="..\gui\UndoHandler.cxx" />
|
||||
<ClCompile Include="..\gui\WhatsNewDialog.cxx" />
|
||||
<ClCompile Include="FSNodeWINDOWS.cxx" />
|
||||
<ClCompile Include="OSystemWINDOWS.cxx" />
|
||||
|
@ -1837,6 +1838,7 @@
|
|||
<ClInclude Include="..\gui\TimeLineWidget.hxx" />
|
||||
<ClInclude Include="..\gui\TimeMachine.hxx" />
|
||||
<ClInclude Include="..\gui\TimeMachineDialog.hxx" />
|
||||
<ClInclude Include="..\gui\UndoHandler.hxx" />
|
||||
<ClInclude Include="..\gui\WhatsNewDialog.hxx" />
|
||||
<ClInclude Include="..\libpng\pngdebug.h" />
|
||||
<ClInclude Include="..\libpng\pnginfo.h" />
|
||||
|
|
|
@ -1029,6 +1029,9 @@
|
|||
<ClCompile Include="..\common\VideoModeHandler.cxx">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\gui\UndoHandler.cxx">
|
||||
<Filter>Source Files\gui</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\common\bspf.hxx">
|
||||
|
@ -2117,6 +2120,9 @@
|
|||
<ClInclude Include="..\emucore\FBBackend.hxx">
|
||||
<Filter>Header Files\emucore</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\gui\UndoHandler.hxx">
|
||||
<Filter>Header Files\gui</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="stella.ico">
|
||||
|
|
Loading…
Reference in New Issue