diff --git a/src/action.h b/src/action.h index 1e60e1d..fb06a58 100644 --- a/src/action.h +++ b/src/action.h @@ -3,8 +3,9 @@ class Action { public: - enum class Direction { Undo, Redo } m_direction; + enum class Direction { Undo, Redo } m_direction = Direction::Undo; bool was_saved = false; + Direction reverse_direction() const { return (Direction)(1 - (int)m_direction); } virtual void run() = 0; virtual void undo() = 0; virtual Action* get_redo() = 0; diff --git a/src/canvas.cpp b/src/canvas.cpp index 0e6c74c..a260d2d 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -141,7 +141,12 @@ void Canvas::pick_end() } void Canvas::clear(const glm::vec4& c/*={0,0,0,1}*/) { - snap_history({ 0, 1, 2, 3, 4, 5 }); + auto a = new ActionLayerClear; + a->m_layer = m_layers[m_current_layer_idx]; + a->m_snap = std::make_shared(a->m_layer->snapshot()); + a->m_color = c; + ActionManager::add(a); + m_layers[m_current_layer_idx]->clear(c); m_unsaved = true; } @@ -1638,24 +1643,35 @@ void Canvas::clear_context() } }; -void Canvas::import_equirectangular(std::string file_path) +void Canvas::import_equirectangular(std::string file_path, std::shared_ptr layer /*= nullptr*/) { - std::thread t(&Canvas::import_equirectangular_thread, this, file_path); + std::thread t(&Canvas::import_equirectangular_thread, this, file_path, layer); t.detach(); } -void Canvas::import_equirectangular_thread(std::string file_path) +void Canvas::import_equirectangular_thread(std::string file_path, std::shared_ptr layer /*= nullptr*/) { BT_SetTerminate(); + + Image img; + if (!img.load_file(file_path)) + return; + App::I.async_start(); + + if (!layer) + layer = m_layers[m_current_layer_idx]; gl_state gl; gl.save(); - snap_history({0,1,2,3,4,5}); - m_unsaved = true; - Image img; - img.load_file(file_path); + auto a = new ActionImportEquirect; + a->m_layer = layer; + a->m_snap = std::make_shared(layer->snapshot()); + a->m_path = file_path; + ActionManager::add(a); + + m_unsaved = true; if (img.width == img.height / 6) { @@ -1702,8 +1718,8 @@ void Canvas::import_equirectangular_thread(std::string file_path) } for (int i = 0; i < 6; i++) { - m_layers[m_current_layer_idx]->m_dirty_box[i] = glm::vec4(0, 0, m_width, m_height); - m_layers[m_current_layer_idx]->m_dirty_face[i] = true; + layer->m_dirty_box[i] = glm::vec4(0, 0, m_width, m_height); + layer->m_dirty_face[i] = true; } App::I.async_update(); gl.restore(); diff --git a/src/canvas.h b/src/canvas.h index c326fa0..d4c64db 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -200,8 +200,8 @@ public: void snapshot_restore(); void snap_history(const std::vector& planes); void clear_context(); - void import_equirectangular(std::string file_path); - void import_equirectangular_thread(std::string file_path); + void import_equirectangular(std::string file_path, std::shared_ptr layer = nullptr); + void import_equirectangular_thread(std::string file_path, std::shared_ptr layer = nullptr); void export_equirectangular(std::string file_path, std::function on_complete = nullptr); void export_equirectangular_thread(std::string file_path); void export_layers(std::string file_name, std::function on_complete = nullptr); diff --git a/src/canvas_actions.cpp b/src/canvas_actions.cpp index a86fa03..40023f9 100644 --- a/src/canvas_actions.cpp +++ b/src/canvas_actions.cpp @@ -96,3 +96,51 @@ Action* ActionStroke::get_redo() action->clear_layer = false; return action; } + +////////////////////////////////////////////////////////////////////////// + +Action* ActionLayerClear::get_redo() +{ + auto a = new ActionLayerClear; + a->m_direction = reverse_direction(); + a->m_snap = m_snap; + a->m_layer = m_layer; + a->m_color = m_color; + return a; +} + +void ActionLayerClear::undo() +{ + if (m_direction == Direction::Undo) + { + m_layer->restore(*m_snap); + } + else + { + m_layer->clear(m_color); + } +} + +////////////////////////////////////////////////////////////////////////// + +Action* ActionImportEquirect::get_redo() +{ + auto a = new ActionImportEquirect; + a->m_direction = reverse_direction(); + a->m_snap = m_snap; + a->m_layer = m_layer; + a->m_path = m_path; + return a; +} + +void ActionImportEquirect::undo() +{ + if (m_direction == Direction::Undo) + { + m_layer->restore(*m_snap); + } + else + { + Canvas::I->import_equirectangular_thread(m_path, m_layer); + } +} diff --git a/src/canvas_actions.h b/src/canvas_actions.h index ef0eef1..d354b2a 100644 --- a/src/canvas_actions.h +++ b/src/canvas_actions.h @@ -18,3 +18,25 @@ public: virtual void undo() override; virtual size_t memory() override; }; + +struct ActionLayerClear : public Action +{ + std::shared_ptr m_snap; + std::shared_ptr m_layer; + glm::vec4 m_color; + virtual void run() override { } + virtual size_t memory() override { return m_snap->memsize(); } + virtual Action* get_redo() override; + virtual void undo() override; +}; + +struct ActionImportEquirect : public Action +{ + std::shared_ptr m_snap; + std::shared_ptr m_layer; + std::string m_path; + virtual void run() override { } + virtual size_t memory() override { return m_snap->memsize(); } + virtual Action* get_redo() override; + virtual void undo() override; +}; diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index 56ce510..c74ba37 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -1577,7 +1577,7 @@ void CanvasModeFloodFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc) virtual Action* get_redo() override { auto a = new ActionFloodFill; - a->m_direction = (Direction)(1 - (int)m_direction); + a->m_direction = reverse_direction(); a->m_layer = m_layer; a->m_snap = m_snap; a->m_pos = m_pos; diff --git a/src/node_panel_layer.cpp b/src/node_panel_layer.cpp index 79bf937..778a303 100644 --- a/src/node_panel_layer.cpp +++ b/src/node_panel_layer.cpp @@ -507,7 +507,7 @@ Action* ActionLayerMerge::get_redo() a->m_layer_node = m_layer_node; a->m_panel = m_panel; a->m_snap = m_snap; - a->m_direction = m_direction == Direction::Undo ? Direction::Redo : Direction::Undo; + a->m_direction = reverse_direction(); return a; }