mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-13 21:01:45 +08:00
Project dirty state manager -> plater dirty state
This commit is contained in:
parent
edbb1d0f69
commit
926ecd0585
@ -6190,6 +6190,9 @@ bool Plater::can_mirror() const { return p->can_mirror(); }
|
|||||||
bool Plater::can_split(bool to_objects) const { return p->can_split(to_objects); }
|
bool Plater::can_split(bool to_objects) const { return p->can_split(to_objects); }
|
||||||
const UndoRedo::Stack& Plater::undo_redo_stack_main() const { return p->undo_redo_stack_main(); }
|
const UndoRedo::Stack& Plater::undo_redo_stack_main() const { return p->undo_redo_stack_main(); }
|
||||||
void Plater::clear_undo_redo_stack_main() { p->undo_redo_stack_main().clear(); }
|
void Plater::clear_undo_redo_stack_main() { p->undo_redo_stack_main().clear(); }
|
||||||
|
#if ENABLE_PROJECT_DIRTY_STATE
|
||||||
|
const UndoRedo::Stack& Plater::undo_redo_stack_active() const { return p->undo_redo_stack(); }
|
||||||
|
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||||
void Plater::enter_gizmos_stack() { p->enter_gizmos_stack(); }
|
void Plater::enter_gizmos_stack() { p->enter_gizmos_stack(); }
|
||||||
void Plater::leave_gizmos_stack() { p->leave_gizmos_stack(); }
|
void Plater::leave_gizmos_stack() { p->leave_gizmos_stack(); }
|
||||||
bool Plater::inside_snapshot_capture() { return p->inside_snapshot_capture(); }
|
bool Plater::inside_snapshot_capture() { return p->inside_snapshot_capture(); }
|
||||||
|
@ -242,6 +242,9 @@ public:
|
|||||||
// For the memory statistics.
|
// For the memory statistics.
|
||||||
const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const;
|
const Slic3r::UndoRedo::Stack& undo_redo_stack_main() const;
|
||||||
void clear_undo_redo_stack_main();
|
void clear_undo_redo_stack_main();
|
||||||
|
#if ENABLE_PROJECT_DIRTY_STATE
|
||||||
|
const Slic3r::UndoRedo::Stack& undo_redo_stack_active() const;
|
||||||
|
#endif // ENABLE_PROJECT_DIRTY_STATE
|
||||||
// Enter / leave the Gizmos specific Undo / Redo stack. To be used by the SLA support point editing gizmo.
|
// Enter / leave the Gizmos specific Undo / Redo stack. To be used by the SLA support point editing gizmo.
|
||||||
void enter_gizmos_stack();
|
void enter_gizmos_stack();
|
||||||
void leave_gizmos_stack();
|
void leave_gizmos_stack();
|
||||||
|
@ -1,19 +1,68 @@
|
|||||||
#include "libslic3r/libslic3r.h"
|
#include "libslic3r/libslic3r.h"
|
||||||
|
|
||||||
#include "ProjectDirtyStateManager.hpp"
|
#include "ProjectDirtyStateManager.hpp"
|
||||||
#include "ImGuiWrapper.hpp"
|
#include "ImGuiWrapper.hpp"
|
||||||
#include "GUI_App.hpp"
|
#include "GUI_App.hpp"
|
||||||
#include "MainFrame.hpp"
|
#include "MainFrame.hpp"
|
||||||
|
#include "I18N.hpp"
|
||||||
|
#include "Plater.hpp"
|
||||||
|
#include "../Utils/UndoRedo.hpp"
|
||||||
|
|
||||||
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#if ENABLE_PROJECT_DIRTY_STATE
|
#if ENABLE_PROJECT_DIRTY_STATE
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
enum class EStackType
|
||||||
|
{
|
||||||
|
Main,
|
||||||
|
Gizmo
|
||||||
|
};
|
||||||
|
|
||||||
|
static const UndoRedo::Snapshot* get_active_snapshot(const UndoRedo::Stack& stack) {
|
||||||
|
const std::vector<UndoRedo::Snapshot>& snapshots = stack.snapshots();
|
||||||
|
const size_t active_snapshot_time = stack.active_snapshot_time();
|
||||||
|
const auto it = std::lower_bound(snapshots.begin(), snapshots.end(), UndoRedo::Snapshot(active_snapshot_time));
|
||||||
|
const int idx = it - snapshots.begin() - 1;
|
||||||
|
const Slic3r::UndoRedo::Snapshot* ret = (0 < idx && (size_t)idx < snapshots.size() - 1) ?
|
||||||
|
&snapshots[idx] : nullptr;
|
||||||
|
|
||||||
|
assert(ret != nullptr);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const UndoRedo::Snapshot* get_last_valid_snapshot(EStackType type, const UndoRedo::Stack& stack) {
|
||||||
|
auto skip_main = [](const UndoRedo::Snapshot& snapshot) {
|
||||||
|
return boost::starts_with(snapshot.name, _utf8("Selection"));
|
||||||
|
};
|
||||||
|
|
||||||
|
const UndoRedo::Snapshot* snapshot = get_active_snapshot(stack);
|
||||||
|
|
||||||
|
const UndoRedo::Snapshot* curr = snapshot;
|
||||||
|
const std::vector<UndoRedo::Snapshot>& snapshots = stack.snapshots();
|
||||||
|
while (type == EStackType::Main && skip_main(*curr)) {
|
||||||
|
curr = &(*std::lower_bound(snapshots.begin(), snapshots.end(), UndoRedo::Snapshot(curr->timestamp - 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return curr;
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectDirtyStateManager::update_from_undo_redo_stack(const Slic3r::UndoRedo::Stack& main_stack, const Slic3r::UndoRedo::Stack& active_stack)
|
void ProjectDirtyStateManager::update_from_undo_redo_stack(const Slic3r::UndoRedo::Stack& main_stack, const Slic3r::UndoRedo::Stack& active_stack)
|
||||||
{
|
{
|
||||||
if (!wxGetApp().initialized())
|
if (!wxGetApp().initialized())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (&main_stack == &active_stack)
|
||||||
|
update_from_undo_redo_main_stack(main_stack);
|
||||||
|
else
|
||||||
|
update_from_undo_redo_gizmo_stack(active_stack);
|
||||||
|
|
||||||
wxGetApp().mainframe->update_title();
|
wxGetApp().mainframe->update_title();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,8 +80,27 @@ void ProjectDirtyStateManager::update_from_presets()
|
|||||||
void ProjectDirtyStateManager::reset_after_save()
|
void ProjectDirtyStateManager::reset_after_save()
|
||||||
{
|
{
|
||||||
reset_initial_presets();
|
reset_initial_presets();
|
||||||
|
|
||||||
m_state.reset();
|
m_state.reset();
|
||||||
|
|
||||||
|
const Plater* plater = wxGetApp().plater();
|
||||||
|
const UndoRedo::Stack& main_stack = plater->undo_redo_stack_main();
|
||||||
|
const UndoRedo::Stack& active_stack = plater->undo_redo_stack_active();
|
||||||
|
|
||||||
|
if (&main_stack == &active_stack) {
|
||||||
|
const UndoRedo::Snapshot* active_snapshot = get_active_snapshot(main_stack);
|
||||||
|
const UndoRedo::Snapshot* valid_snapshot = get_last_valid_snapshot(EStackType::Main, main_stack);
|
||||||
|
|
||||||
|
// std::cout << "SAVE - active: " << active_snapshot->timestamp << " - " << active_snapshot->name << "\n";
|
||||||
|
// std::cout << "SAVE - valid: " << valid_snapshot->timestamp << " - " << valid_snapshot->name << "\n";
|
||||||
|
|
||||||
|
m_last_save.main = valid_snapshot->timestamp;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const UndoRedo::Snapshot* active_snapshot = get_active_snapshot(active_stack);
|
||||||
|
|
||||||
|
// std::cout << "SAVE - active: " << active_snapshot->timestamp << " - " << active_snapshot->name << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
wxGetApp().mainframe->update_title();
|
wxGetApp().mainframe->update_title();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,35 +116,66 @@ void ProjectDirtyStateManager::reset_initial_presets()
|
|||||||
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
||||||
void ProjectDirtyStateManager::render_debug_window() const
|
void ProjectDirtyStateManager::render_debug_window() const
|
||||||
{
|
{
|
||||||
|
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||||
|
|
||||||
auto color = [](bool value) {
|
auto color = [](bool value) {
|
||||||
return value ? ImVec4(1.0f, 0.49f, 0.216f, 1.0f) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
return value ? ImVec4(1.0f, 0.49f, 0.216f, 1.0f) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
};
|
};
|
||||||
auto text = [](bool value) {
|
auto text = [](bool value) {
|
||||||
return value ? "true" : "false";
|
return value ? "true" : "false";
|
||||||
};
|
};
|
||||||
|
auto append_item = [color, text, &imgui](const std::string& name, bool value) {
|
||||||
|
imgui.text_colored(color(value), name);
|
||||||
|
ImGui::SameLine();
|
||||||
|
imgui.text_colored(color(value), text(value));
|
||||||
|
};
|
||||||
|
|
||||||
std::string title = "Project dirty state statistics";
|
imgui.begin(std::string( "Project dirty state statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
||||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
|
||||||
imgui.begin(title, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
|
|
||||||
|
|
||||||
bool dirty = is_dirty();
|
|
||||||
imgui.text_colored(color(dirty), "State:");
|
|
||||||
ImGui::SameLine();
|
|
||||||
imgui.text_colored(color(dirty), text(dirty));
|
|
||||||
|
|
||||||
|
append_item("State:", is_dirty());
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
imgui.text_colored(color(m_state.plater), "Plater:");
|
append_item("Plater:", m_state.plater);
|
||||||
ImGui::SameLine();
|
append_item("Presets:", m_state.presets);
|
||||||
imgui.text_colored(color(m_state.plater), text(m_state.plater));
|
append_item("Current gizmo:", m_state.current_gizmo);
|
||||||
|
|
||||||
imgui.text_colored(color(m_state.presets), "Presets:");
|
|
||||||
ImGui::SameLine();
|
|
||||||
imgui.text_colored(color(m_state.presets), text(m_state.presets));
|
|
||||||
|
|
||||||
imgui.end();
|
imgui.end();
|
||||||
}
|
}
|
||||||
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
||||||
|
|
||||||
|
void ProjectDirtyStateManager::update_from_undo_redo_main_stack(const Slic3r::UndoRedo::Stack& stack)
|
||||||
|
{
|
||||||
|
m_state.plater = false;
|
||||||
|
|
||||||
|
const UndoRedo::Snapshot* active_snapshot = get_active_snapshot(stack);
|
||||||
|
|
||||||
|
// std::cout << "UPDATE - active: " << active_snapshot->timestamp << " - " << active_snapshot->name << "\n";
|
||||||
|
|
||||||
|
if (active_snapshot->name == _utf8("New Project") ||
|
||||||
|
active_snapshot->name == _utf8("Reset Project") ||
|
||||||
|
boost::starts_with(active_snapshot->name, _utf8("Load Project:")))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const UndoRedo::Snapshot* valid_snapshot = get_last_valid_snapshot(EStackType::Main, stack);
|
||||||
|
|
||||||
|
// std::cout << "UPDATE - valid: " << valid_snapshot->timestamp << " - " << valid_snapshot->name << "\n";
|
||||||
|
|
||||||
|
m_state.plater = valid_snapshot->timestamp != m_last_save.main;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProjectDirtyStateManager::update_from_undo_redo_gizmo_stack(const Slic3r::UndoRedo::Stack& stack)
|
||||||
|
{
|
||||||
|
m_state.current_gizmo = false;
|
||||||
|
|
||||||
|
const UndoRedo::Snapshot* active_snapshot = get_active_snapshot(stack);
|
||||||
|
|
||||||
|
// std::cout << "UPDATE - active: " << active_snapshot->timestamp << " - " << active_snapshot->name << "\n";
|
||||||
|
|
||||||
|
if (active_snapshot->name == "Gizmos-Initial")
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_state.current_gizmo = true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
||||||
|
@ -17,15 +17,29 @@ class ProjectDirtyStateManager
|
|||||||
{
|
{
|
||||||
bool plater{ false };
|
bool plater{ false };
|
||||||
bool presets{ false };
|
bool presets{ false };
|
||||||
|
bool current_gizmo{ false };
|
||||||
|
|
||||||
bool is_dirty() const { return plater || presets; }
|
bool is_dirty() const { return plater || presets || current_gizmo; }
|
||||||
void reset() {
|
void reset() {
|
||||||
plater = false;
|
plater = false;
|
||||||
presets = false;
|
presets = false;
|
||||||
|
current_gizmo = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Timestamps
|
||||||
|
{
|
||||||
|
size_t main{ 0 };
|
||||||
|
size_t gizmo{ 0 };
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
main = 0;
|
||||||
|
gizmo = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DirtyState m_state;
|
DirtyState m_state;
|
||||||
|
Timestamps m_last_save;
|
||||||
|
|
||||||
// keeps track of initial selected presets
|
// keeps track of initial selected presets
|
||||||
std::array<std::string, Preset::TYPE_COUNT> m_initial_presets;
|
std::array<std::string, Preset::TYPE_COUNT> m_initial_presets;
|
||||||
@ -39,6 +53,10 @@ public:
|
|||||||
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
#if ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
||||||
void render_debug_window() const;
|
void render_debug_window() const;
|
||||||
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
#endif // ENABLE_PROJECT_DIRTY_STATE_DEBUG_WINDOW
|
||||||
|
|
||||||
|
private:
|
||||||
|
void update_from_undo_redo_main_stack(const Slic3r::UndoRedo::Stack& stack);
|
||||||
|
void update_from_undo_redo_gizmo_stack(const Slic3r::UndoRedo::Stack& stack);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
|
@ -387,8 +387,8 @@ class TabPrint : public Tab
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TabPrint(wxNotebook* parent) :
|
TabPrint(wxNotebook* parent) :
|
||||||
// Tab(parent, _(L("Print Settings")), L("print")) {}
|
// Tab(parent, _L("Print Settings"), L("print")) {}
|
||||||
Tab(parent, _(L("Print Settings")), Slic3r::Preset::TYPE_PRINT) {}
|
Tab(parent, _L("Print Settings"), Slic3r::Preset::TYPE_PRINT) {}
|
||||||
~TabPrint() {}
|
~TabPrint() {}
|
||||||
|
|
||||||
void build() override;
|
void build() override;
|
||||||
@ -421,8 +421,8 @@ private:
|
|||||||
std::map<std::string, wxCheckBox*> m_overrides_options;
|
std::map<std::string, wxCheckBox*> m_overrides_options;
|
||||||
public:
|
public:
|
||||||
TabFilament(wxNotebook* parent) :
|
TabFilament(wxNotebook* parent) :
|
||||||
// Tab(parent, _(L("Filament Settings")), L("filament")) {}
|
// Tab(parent, _L("Filament Settings"), L("filament")) {}
|
||||||
Tab(parent, _(L("Filament Settings")), Slic3r::Preset::TYPE_FILAMENT) {}
|
Tab(parent, _L("Filament Settings"), Slic3r::Preset::TYPE_FILAMENT) {}
|
||||||
~TabFilament() {}
|
~TabFilament() {}
|
||||||
|
|
||||||
void build() override;
|
void build() override;
|
||||||
@ -467,7 +467,7 @@ public:
|
|||||||
|
|
||||||
// TabPrinter(wxNotebook* parent) : Tab(parent, _(L("Printer Settings")), L("printer")) {}
|
// TabPrinter(wxNotebook* parent) : Tab(parent, _(L("Printer Settings")), L("printer")) {}
|
||||||
TabPrinter(wxNotebook* parent) :
|
TabPrinter(wxNotebook* parent) :
|
||||||
Tab(parent, _(L("Printer Settings")), Slic3r::Preset::TYPE_PRINTER) {}
|
Tab(parent, _L("Printer Settings"), Slic3r::Preset::TYPE_PRINTER) {}
|
||||||
~TabPrinter() {}
|
~TabPrinter() {}
|
||||||
|
|
||||||
void build() override;
|
void build() override;
|
||||||
@ -504,8 +504,8 @@ class TabSLAMaterial : public Tab
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TabSLAMaterial(wxNotebook* parent) :
|
TabSLAMaterial(wxNotebook* parent) :
|
||||||
// Tab(parent, _(L("Material Settings")), L("sla_material")) {}
|
// Tab(parent, _L("Material Settings"), L("sla_material")) {}
|
||||||
Tab(parent, _(L("Material Settings")), Slic3r::Preset::TYPE_SLA_MATERIAL) {}
|
Tab(parent, _L("Material Settings"), Slic3r::Preset::TYPE_SLA_MATERIAL) {}
|
||||||
~TabSLAMaterial() {}
|
~TabSLAMaterial() {}
|
||||||
|
|
||||||
void build() override;
|
void build() override;
|
||||||
@ -524,8 +524,8 @@ class TabSLAPrint : public Tab
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TabSLAPrint(wxNotebook* parent) :
|
TabSLAPrint(wxNotebook* parent) :
|
||||||
// Tab(parent, _(L("Print Settings")), L("sla_print")) {}
|
// Tab(parent, _L("Print Settings"), L("sla_print")) {}
|
||||||
Tab(parent, _(L("Print Settings")), Slic3r::Preset::TYPE_SLA_PRINT) {}
|
Tab(parent, _L("Print Settings"), Slic3r::Preset::TYPE_SLA_PRINT) {}
|
||||||
~TabSLAPrint() {}
|
~TabSLAPrint() {}
|
||||||
|
|
||||||
ogStaticText* m_support_object_elevation_description_line = nullptr;
|
ogStaticText* m_support_object_elevation_description_line = nullptr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user