mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
BugFix Undo history
Force store of first status, and limit number of undo steps (even if huge number of 1000).
This commit is contained in:
@@ -43,24 +43,25 @@
|
|||||||
using namespace tinyxml2;
|
using namespace tinyxml2;
|
||||||
|
|
||||||
|
|
||||||
Action::Action(): history_step_(0), history_max_step_(0),
|
Action::Action(): history_step_(0), history_max_step_(0), history_min_step_(0),
|
||||||
snapshot_id_(0), snapshot_node_(nullptr), interpolator_(nullptr), interpolator_node_(nullptr)
|
snapshot_id_(0), snapshot_node_(nullptr), interpolator_(nullptr), interpolator_node_(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Action::init()
|
void Action::init(const std::string &label)
|
||||||
{
|
{
|
||||||
// clean the history
|
// clean the history
|
||||||
history_doc_.Clear();
|
history_doc_.Clear();
|
||||||
history_step_ = 0;
|
history_step_ = 0;
|
||||||
history_max_step_ = 0;
|
history_min_step_ = 1;
|
||||||
|
history_max_step_ = 1;
|
||||||
|
|
||||||
// reset snapshot
|
// reset snapshot
|
||||||
snapshot_id_ = 0;
|
snapshot_id_ = 0;
|
||||||
snapshot_node_ = nullptr;
|
snapshot_node_ = nullptr;
|
||||||
|
|
||||||
store("Session start");
|
store(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
// must be called in a thread running in parrallel of the rendering
|
// must be called in a thread running in parrallel of the rendering
|
||||||
@@ -131,8 +132,12 @@ void captureMixerSession(Session *se, std::string node, std::string label, tinyx
|
|||||||
|
|
||||||
void Action::storeSession(Session *se, std::string label)
|
void Action::storeSession(Session *se, std::string label)
|
||||||
{
|
{
|
||||||
//
|
// force lock for creation of first step
|
||||||
if (!Action::manager().history_access_.try_lock())
|
if (Action::manager().history_step_ < 1)
|
||||||
|
Action::manager().history_access_.lock();
|
||||||
|
// try lock for storing history in normal case
|
||||||
|
// (i.e. priority to realtime performance over storing history)
|
||||||
|
else if (!Action::manager().history_access_.try_lock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// incremental naming of history nodes
|
// incremental naming of history nodes
|
||||||
@@ -146,6 +151,14 @@ void Action::storeSession(Session *se, std::string label)
|
|||||||
}
|
}
|
||||||
Action::manager().history_max_step_ = Action::manager().history_step_;
|
Action::manager().history_max_step_ = Action::manager().history_step_;
|
||||||
|
|
||||||
|
// Ensure a maximum amount of stored steps (even very big, just to ensure memory limit)
|
||||||
|
if (Action::manager().history_max_step_ - Action::manager().history_min_step_ > MAX_COUNT_HISTORY) {
|
||||||
|
XMLElement *node = Action::manager().history_doc_.FirstChildElement( HISTORY_NODE(Action::manager().history_min_step_+1).c_str() );
|
||||||
|
if ( node )
|
||||||
|
Action::manager().history_doc_.DeleteChild(node);
|
||||||
|
Action::manager().history_min_step_++;
|
||||||
|
}
|
||||||
|
|
||||||
// capture current session
|
// capture current session
|
||||||
captureMixerSession(se,
|
captureMixerSession(se,
|
||||||
HISTORY_NODE(Action::manager().history_step_),
|
HISTORY_NODE(Action::manager().history_step_),
|
||||||
@@ -158,9 +171,7 @@ void Action::storeSession(Session *se, std::string label)
|
|||||||
|
|
||||||
void Action::store(const std::string &label)
|
void Action::store(const std::string &label)
|
||||||
{
|
{
|
||||||
// TODO: set a maximum amount of stored steps? (even very big, just to ensure memory limit)
|
// ignore if no label is given
|
||||||
|
|
||||||
// ignore if locked or if no label is given
|
|
||||||
if (label.empty())
|
if (label.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include <tinyxml2.h>
|
#include <tinyxml2.h>
|
||||||
|
|
||||||
|
#define MAX_COUNT_HISTORY 1000
|
||||||
|
|
||||||
class Session;
|
class Session;
|
||||||
class Interpolator;
|
class Interpolator;
|
||||||
class FrameBufferImage;
|
class FrameBufferImage;
|
||||||
@@ -26,7 +28,7 @@ public:
|
|||||||
static Action _instance;
|
static Action _instance;
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
void init ();
|
void init (const std::string &label);
|
||||||
|
|
||||||
// Undo History
|
// Undo History
|
||||||
void store (const std::string &label);
|
void store (const std::string &label);
|
||||||
@@ -36,6 +38,7 @@ public:
|
|||||||
|
|
||||||
inline uint current () const { return history_step_; }
|
inline uint current () const { return history_step_; }
|
||||||
inline uint max () const { return history_max_step_; }
|
inline uint max () const { return history_max_step_; }
|
||||||
|
inline uint min () const { return history_min_step_; }
|
||||||
std::string label (uint s) const;
|
std::string label (uint s) const;
|
||||||
std::string shortlabel (uint s) const;
|
std::string shortlabel (uint s) const;
|
||||||
FrameBufferImage *thumbnail (uint s) const;
|
FrameBufferImage *thumbnail (uint s) const;
|
||||||
@@ -66,6 +69,7 @@ private:
|
|||||||
tinyxml2::XMLDocument history_doc_;
|
tinyxml2::XMLDocument history_doc_;
|
||||||
uint history_step_;
|
uint history_step_;
|
||||||
uint history_max_step_;
|
uint history_max_step_;
|
||||||
|
uint history_min_step_;
|
||||||
std::mutex history_access_;
|
std::mutex history_access_;
|
||||||
static void storeSession(Session *se, std::string label);
|
static void storeSession(Session *se, std::string label);
|
||||||
void restore(uint target);
|
void restore(uint target);
|
||||||
|
|||||||
@@ -1555,7 +1555,7 @@ void Mixer::swap()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reset History manager
|
// reset History manager
|
||||||
Action::manager().init();
|
Action::manager().init("Session start");
|
||||||
|
|
||||||
// notification
|
// notification
|
||||||
if (session_->filename().empty())
|
if (session_->filename().empty())
|
||||||
|
|||||||
@@ -1064,7 +1064,7 @@ void UserInterface::showMenuEdit()
|
|||||||
bool has_clipboard = (clipboard != nullptr && strlen(clipboard) > 0 && SessionLoader::isClipboard(clipboard));
|
bool has_clipboard = (clipboard != nullptr && strlen(clipboard) > 0 && SessionLoader::isClipboard(clipboard));
|
||||||
|
|
||||||
// UNDO
|
// UNDO
|
||||||
if ( ImGui::MenuItem( MENU_UNDO, SHORTCUT_UNDO, false, Action::manager().current() > 1) )
|
if ( ImGui::MenuItem( MENU_UNDO, SHORTCUT_UNDO, false, Action::manager().current() > Action::manager().min()) )
|
||||||
Action::manager().undo();
|
Action::manager().undo();
|
||||||
if ( ImGui::MenuItem( MENU_REDO, SHORTCUT_REDO, false, Action::manager().current() < Action::manager().max()) )
|
if ( ImGui::MenuItem( MENU_REDO, SHORTCUT_REDO, false, Action::manager().current() < Action::manager().max()) )
|
||||||
Action::manager().redo();
|
Action::manager().redo();
|
||||||
@@ -4898,7 +4898,7 @@ void Navigator::RenderMainPannelSession()
|
|||||||
static bool _tooltip = 0;
|
static bool _tooltip = 0;
|
||||||
|
|
||||||
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y -ImGui::GetFrameHeight() ));
|
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y -ImGui::GetFrameHeight() ));
|
||||||
if ( Action::manager().current() > 1 ) {
|
if ( Action::manager().current() > Action::manager().min() ) {
|
||||||
if ( ImGuiToolkit::IconButton( ICON_FA_UNDO, "Undo" ) )
|
if ( ImGuiToolkit::IconButton( ICON_FA_UNDO, "Undo" ) )
|
||||||
Action::manager().undo();
|
Action::manager().undo();
|
||||||
} else
|
} else
|
||||||
@@ -4920,7 +4920,8 @@ void Navigator::RenderMainPannelSession()
|
|||||||
int count_over = 0;
|
int count_over = 0;
|
||||||
ImVec2 size = ImVec2( ImGui::GetContentRegionAvailWidth(), ImGui::GetTextLineHeight() );
|
ImVec2 size = ImVec2( ImGui::GetContentRegionAvailWidth(), ImGui::GetTextLineHeight() );
|
||||||
|
|
||||||
for (uint i = Action::manager().max(); i > 0; --i) {
|
for (uint i = Action::manager().max();
|
||||||
|
i >= Action::manager().min(); --i) {
|
||||||
|
|
||||||
if (ImGui::Selectable( Action::manager().shortlabel(i).c_str(), i == Action::manager().current(), ImGuiSelectableFlags_AllowDoubleClick, size )) {
|
if (ImGui::Selectable( Action::manager().shortlabel(i).c_str(), i == Action::manager().current(), ImGuiSelectableFlags_AllowDoubleClick, size )) {
|
||||||
// go to on double clic
|
// go to on double clic
|
||||||
@@ -4978,7 +4979,7 @@ void Navigator::RenderMainPannelSession()
|
|||||||
if ( Action::manager().max() > 1 ) {
|
if ( Action::manager().max() > 1 ) {
|
||||||
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_top.y ));
|
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_top.y ));
|
||||||
if (ImGuiToolkit::IconButton( 12, 14, "Clear history"))
|
if (ImGuiToolkit::IconButton( 12, 14, "Clear history"))
|
||||||
Action::manager().init();
|
Action::manager().init("Reset");
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - 2.f * ImGui::GetFrameHeightWithSpacing()));
|
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - 2.f * ImGui::GetFrameHeightWithSpacing()));
|
||||||
|
|||||||
Reference in New Issue
Block a user