implement action redo
This commit is contained in:
@@ -709,6 +709,7 @@
|
|||||||
</button-custom>
|
</button-custom>
|
||||||
</node>
|
</node>
|
||||||
<button id="btn-undo" width="50" height="100%" margin="0 5 0 0" text="Undo"/>
|
<button id="btn-undo" width="50" height="100%" margin="0 5 0 0" text="Undo"/>
|
||||||
|
<button id="btn-redo" width="50" height="100%" margin="0 5 0 0" text="Redo"/>
|
||||||
<!--
|
<!--
|
||||||
<button-custom id="btn-layer" width="50" height="100%" margin="0 5 0 0" thickness="1" border-color="0 0 0 1" pad="6" align="center" justify="center">
|
<button-custom id="btn-layer" width="50" height="100%" margin="0 5 0 0" thickness="1" border-color="0 0 0 1" pad="6" align="center" justify="center">
|
||||||
<icon width="100%" height="100%" icon="disk"/>
|
<icon width="100%" height="100%" icon="disk"/>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ ActionManager ActionManager::I;
|
|||||||
|
|
||||||
void ActionManager::add(Action *action)
|
void ActionManager::add(Action *action)
|
||||||
{
|
{
|
||||||
|
I.m_redos = std::stack<std::unique_ptr<Action>>();
|
||||||
I.m_actions.emplace(action);
|
I.m_actions.emplace(action);
|
||||||
I.m_memory += action->memory();
|
I.m_memory += action->memory();
|
||||||
//LOG("History: %.2f KB", I.m_memory / 1024.f);
|
//LOG("History: %.2f KB", I.m_memory / 1024.f);
|
||||||
@@ -15,6 +16,11 @@ void ActionManager::add(Action *action)
|
|||||||
|
|
||||||
void ActionManager::undo()
|
void ActionManager::undo()
|
||||||
{
|
{
|
||||||
|
if (I.m_actions.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
I.m_redos.emplace(I.m_actions.top()->get_redo());
|
||||||
|
|
||||||
I.m_actions.top()->undo();
|
I.m_actions.top()->undo();
|
||||||
I.m_memory -= I.m_actions.top()->memory();
|
I.m_memory -= I.m_actions.top()->memory();
|
||||||
I.m_actions.pop();
|
I.m_actions.pop();
|
||||||
@@ -22,6 +28,20 @@ void ActionManager::undo()
|
|||||||
App::I.update_memory_usage(I.m_memory);
|
App::I.update_memory_usage(I.m_memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActionManager::redo()
|
||||||
|
{
|
||||||
|
if (I.m_redos.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
I.m_actions.emplace(I.m_redos.top()->get_redo());
|
||||||
|
I.m_memory += I.m_actions.top()->memory();
|
||||||
|
|
||||||
|
I.m_redos.top()->undo();
|
||||||
|
I.m_redos.pop();
|
||||||
|
//LOG("History: %.2f KB", I.m_memory / 1024.f);
|
||||||
|
App::I.update_memory_usage(I.m_memory);
|
||||||
|
}
|
||||||
|
|
||||||
void ActionManager::clear()
|
void ActionManager::clear()
|
||||||
{
|
{
|
||||||
while (!I.m_actions.empty())
|
while (!I.m_actions.empty())
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ class Action
|
|||||||
public:
|
public:
|
||||||
virtual void run() = 0;
|
virtual void run() = 0;
|
||||||
virtual void undo() = 0;
|
virtual void undo() = 0;
|
||||||
|
virtual Action* get_redo() = 0;
|
||||||
virtual size_t memory() = 0;
|
virtual size_t memory() = 0;
|
||||||
virtual ~Action(){};
|
virtual ~Action(){};
|
||||||
};
|
};
|
||||||
@@ -14,9 +15,11 @@ class ActionManager
|
|||||||
public:
|
public:
|
||||||
static ActionManager I;
|
static ActionManager I;
|
||||||
std::stack<std::unique_ptr<Action>> m_actions;
|
std::stack<std::unique_ptr<Action>> m_actions;
|
||||||
|
std::stack<std::unique_ptr<Action>> m_redos;
|
||||||
size_t m_memory = 0;
|
size_t m_memory = 0;
|
||||||
static void add(Action* action);
|
static void add(Action* action);
|
||||||
static void undo();
|
static void undo();
|
||||||
|
static void redo();
|
||||||
static void clear();
|
static void clear();
|
||||||
static bool empty()
|
static bool empty()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,8 +55,13 @@ void App::init_toolbar_main()
|
|||||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-undo"))
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-undo"))
|
||||||
{
|
{
|
||||||
button->on_click = [this, button](Node*) {
|
button->on_click = [this, button](Node*) {
|
||||||
if (!ActionManager::empty())
|
ActionManager::undo();
|
||||||
ActionManager::undo();
|
};
|
||||||
|
}
|
||||||
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-redo"))
|
||||||
|
{
|
||||||
|
button->on_click = [this, button](Node*) {
|
||||||
|
ActionManager::redo();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-clean-memory"))
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-clean-memory"))
|
||||||
|
|||||||
@@ -160,6 +160,35 @@ void ui::Canvas::snap_history(const std::vector<int>& planes)
|
|||||||
action->clear_layer = true;
|
action->clear_layer = true;
|
||||||
ActionManager::add(action);
|
ActionManager::add(action);
|
||||||
}
|
}
|
||||||
|
ui::ActionStroke* ui::Canvas::create_action(int layer)
|
||||||
|
{
|
||||||
|
auto action = new ActionStroke;
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if (!m_layers[layer].m_dirty_face[i])
|
||||||
|
continue; // no stroke on this face, skip it
|
||||||
|
|
||||||
|
m_layers[layer].m_rtt[i].bindFramebuffer();
|
||||||
|
|
||||||
|
// save image before commit
|
||||||
|
glm::vec2 box_or = xy(m_layers[layer].m_dirty_box[i]);
|
||||||
|
glm::vec2 box_sz = zw(m_layers[layer].m_dirty_box[i]) - xy(m_layers[layer].m_dirty_box[i]);
|
||||||
|
action->m_image[i] = std::make_unique<uint8_t[]>(box_sz.x * box_sz.y * 4);
|
||||||
|
glReadPixels(box_or.x, box_or.y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get());
|
||||||
|
|
||||||
|
action->m_box[i] = m_layers[layer].m_dirty_box[i];
|
||||||
|
action->m_old_box[i] = m_layers[layer].m_dirty_box[i];
|
||||||
|
action->m_old_dirty[i] = m_layers[layer].m_dirty_face[i];
|
||||||
|
|
||||||
|
m_layers[layer].m_rtt[i].unbindFramebuffer();
|
||||||
|
}
|
||||||
|
// save history
|
||||||
|
action->m_layer_idx = layer;
|
||||||
|
action->m_canvas = this;
|
||||||
|
action->m_stroke = std::move(m_current_stroke);
|
||||||
|
action->clear_layer = true;
|
||||||
|
return action;
|
||||||
|
}
|
||||||
void ui::Canvas::stroke_end()
|
void ui::Canvas::stroke_end()
|
||||||
{
|
{
|
||||||
if (!m_current_stroke)
|
if (!m_current_stroke)
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ public:
|
|||||||
void snapshot_save(std::string data_path);
|
void snapshot_save(std::string data_path);
|
||||||
void snapshot_restore();
|
void snapshot_restore();
|
||||||
void snap_history(const std::vector<int>& planes);
|
void snap_history(const std::vector<int>& planes);
|
||||||
|
class ActionStroke* create_action(int layer);
|
||||||
void clear_context();
|
void clear_context();
|
||||||
void import_equirectangular(std::string file_path);
|
void import_equirectangular(std::string file_path);
|
||||||
void import_equirectangular_thread(std::string file_path);
|
void import_equirectangular_thread(std::string file_path);
|
||||||
@@ -174,6 +175,11 @@ public:
|
|||||||
virtual void run() override
|
virtual void run() override
|
||||||
{
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
virtual Action* get_redo()
|
||||||
|
{
|
||||||
|
auto redo = m_canvas->create_action(m_layer_idx);
|
||||||
|
return redo;
|
||||||
}
|
}
|
||||||
virtual void undo() override
|
virtual void undo() override
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user