diff --git a/resources/images/topbar_save_inactive.svg b/resources/images/topbar_save_inactive.svg
new file mode 100644
index 000000000..98773de83
--- /dev/null
+++ b/resources/images/topbar_save_inactive.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/slic3r/GUI/BBLTopbar.cpp b/src/slic3r/GUI/BBLTopbar.cpp
index 7a6ed81a2..3bfd9a936 100644
--- a/src/slic3r/GUI/BBLTopbar.cpp
+++ b/src/slic3r/GUI/BBLTopbar.cpp
@@ -180,19 +180,19 @@ void BBLTopbarArt::DrawButton(wxDC& dc, wxWindow* wnd, const wxAuiToolBarItem& i
}
}
-BBLTopbar::BBLTopbar(wxFrame* parent)
+BBLTopbar::BBLTopbar(wxFrame* parent)
: wxAuiToolBar(parent, ID_TOOL_BAR, wxDefaultPosition, wxDefaultSize, wxAUI_TB_TEXT | wxAUI_TB_HORZ_TEXT)
-{
+{
Init(parent);
}
BBLTopbar::BBLTopbar(wxWindow* pwin, wxFrame* parent)
- : wxAuiToolBar(pwin, ID_TOOL_BAR, wxDefaultPosition, wxDefaultSize, wxAUI_TB_TEXT | wxAUI_TB_HORZ_TEXT)
-{
+ : wxAuiToolBar(pwin, ID_TOOL_BAR, wxDefaultPosition, wxDefaultSize, wxAUI_TB_TEXT | wxAUI_TB_HORZ_TEXT)
+{
Init(parent);
}
-void BBLTopbar::Init(wxFrame* parent)
+void BBLTopbar::Init(wxFrame* parent)
{
SetArtProvider(new BBLTopbarArt());
m_frame = parent;
@@ -230,8 +230,9 @@ void BBLTopbar::Init(wxFrame* parent)
this->AddSpacer(FromDIP(10));
wxBitmap save_bitmap = create_scaled_bitmap("topbar_save", nullptr, TOPBAR_ICON_SIZE);
- wxAuiToolBarItem* save_btn = this->AddTool(wxID_SAVE, "", save_bitmap);
-
+ m_save_item = this->AddTool(wxID_SAVE, "", save_bitmap);
+ wxBitmap save_inactive_bitmap = create_scaled_bitmap("topbar_save_inactive", nullptr, TOPBAR_ICON_SIZE);
+ m_save_item->SetDisabledBitmap(save_inactive_bitmap);
this->AddSpacer(FromDIP(10));
wxBitmap undo_bitmap = create_scaled_bitmap("topbar_undo", nullptr, TOPBAR_ICON_SIZE);
@@ -348,6 +349,7 @@ void BBLTopbar::OnSaveProject(wxAuiToolBarEvent& event)
MainFrame* main_frame = dynamic_cast(m_frame);
Plater* plater = main_frame->plater();
plater->save_project();
+ EnableSaveItem(false);
}
void BBLTopbar::OnUndo(wxAuiToolBarEvent& event)
@@ -364,6 +366,30 @@ void BBLTopbar::OnRedo(wxAuiToolBarEvent& event)
plater->redo();
}
+void BBLTopbar::EnableSaveItem(bool enable)
+{
+ if (m_save_item) {
+ this->EnableTool(m_save_item->GetId(), enable);
+ Refresh();
+ }
+}
+
+void BBLTopbar::EnableUndoItem(bool enable)
+{
+ if (m_undo_item) {
+ this->EnableTool(m_undo_item->GetId(), enable);
+ Refresh();
+ }
+}
+
+void BBLTopbar::EnableRedoItem(bool enable)
+{
+ if (m_redo_item) {
+ this->EnableTool(m_redo_item->GetId(), enable);
+ Refresh();
+ }
+}
+
void BBLTopbar::EnableUndoRedoItems()
{
this->EnableTool(m_undo_item->GetId(), true);
@@ -636,7 +662,7 @@ void BBLTopbar::OnMouseLeftDown(wxMouseEvent& event)
wxPoint frame_pos = m_frame->GetScreenPosition();
m_delta = mouse_pos - frame_pos;
- if (FindToolByCurrentPosition() == NULL
+ if (FindToolByCurrentPosition() == NULL
|| this->FindToolByCurrentPosition() == m_title_item)
{
CaptureMouse();
@@ -646,7 +672,7 @@ void BBLTopbar::OnMouseLeftDown(wxMouseEvent& event)
return;
#endif // __WXMSW__
}
-
+
event.Skip();
}
@@ -674,7 +700,7 @@ void BBLTopbar::OnMouseMotion(wxMouseEvent& event)
if (event.Dragging() && event.LeftIsDown())
{
- // leave max state and adjust position
+ // leave max state and adjust position
if (m_frame->IsMaximized()) {
wxRect rect = m_frame->GetRect();
// Filter unexcept mouse move
diff --git a/src/slic3r/GUI/BBLTopbar.hpp b/src/slic3r/GUI/BBLTopbar.hpp
index 78820813a..3a44db70d 100644
--- a/src/slic3r/GUI/BBLTopbar.hpp
+++ b/src/slic3r/GUI/BBLTopbar.hpp
@@ -39,7 +39,7 @@ public:
void OnPublishClicked(wxAuiToolBarEvent &event);
wxAuiToolBarItem* FindToolByCurrentPosition();
-
+
void SetFileMenu(wxMenu* file_menu);
void AddDropDownSubMenu(wxMenu* sub_menu, const wxString& title);
void AddDropDownMenuItem(wxMenuItem* menu_item);
@@ -49,6 +49,9 @@ public:
void SetMaximizedSize();
void SetWindowSize();
+ void EnableSaveItem(bool enable);
+ void EnableUndoItem(bool enable);
+ void EnableRedoItem(bool enable);
void EnableUndoRedoItems();
void DisableUndoRedoItems();
@@ -68,8 +71,9 @@ private:
wxAuiToolBarItem* m_title_item;
wxAuiToolBarItem* m_account_item;
wxAuiToolBarItem* m_model_store_item;
-
+
wxAuiToolBarItem *m_publish_item;
+ wxAuiToolBarItem *m_save_item;
wxAuiToolBarItem* m_undo_item;
wxAuiToolBarItem* m_redo_item;
wxAuiToolBarItem* m_calib_item;
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index 2070b5c2a..030494eda 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -688,7 +688,13 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
evt.IsShown() ? manger->start_refresher() : manger->stop_refresher();
}
});
-
+ Bind(wxEVT_IDLE, ([this](wxIdleEvent &e) {
+ if (m_topbar && m_plater) {
+ m_topbar->EnableSaveItem(can_save());
+ m_topbar->EnableUndoItem(m_plater->can_undo());
+ m_topbar->EnableRedoItem(m_plater->can_redo());
+ }
+ }));
#ifdef _MSW_DARK_MODE
wxGetApp().UpdateDarkUIWin(this);
#endif // _MSW_DARK_MODE
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index b5b4aee68..c6ffa6a19 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -14337,6 +14337,10 @@ void Plater::export_toolpaths_to_obj() const
p->preview->get_canvas3d()->export_toolpaths_to_obj(into_u8(path).c_str());
}
+bool Plater::is_empty_project() {
+ return model().objects.empty();
+}
+
bool Plater::is_multi_extruder_ams_empty()
{
std::vector extruder_ams_count_str = p->config->option("extruder_ams_count", true)->values;
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index 5bf08d850..2a292513e 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -338,7 +338,7 @@ public:
void set_using_exported_file(bool exported_file) {
m_exported_file = exported_file;
}
-
+ bool is_empty_project();
bool is_multi_extruder_ams_empty();
// BBS
wxString get_project_name();