feat(gui): add purge mode selector dialog

The engine already implements prime_volume_mode (Default/Saving/Fast)
but nothing in the UI could set it, leaving prime-saving unreachable on
multi-sub-nozzle extruders and fast purge unreachable on printers that
support it.

- new PurgeModeDialog with selectable Standard/Fast or
  Standard/Prime Saving cards depending on printer capability
- "Purge mode" sidebar button next to Flushing volumes; opens the
  dialog and stores the choice in the project config
- printer preset-load gating: button shown only when the printer has
  multiple sub-nozzles per extruder or sets support_fast_purge_mode;
  stale project values the printer cannot honor reset to Default
- enable fast purge on A2L 0.4 (support_fast_purge_mode), explicit
  default 0 in the common machine base
- new dialog strings added to OrcaSlicer.pot

Printers without these capabilities never show the button and their
projects keep prime_volume_mode at Default, so slicing output is
unchanged.
This commit is contained in:
SoftFever
2026-07-10 15:41:57 +08:00
parent b2eeed2622
commit 93a81179a1
13 changed files with 432 additions and 3 deletions

View File

@@ -170,6 +170,7 @@
#include "StepMeshDialog.hpp"
#include "FilamentMapDialog.hpp"
#include "CloneDialog.hpp"
#include "PurgeModeDialog.hpp"
#include "DeviceCore/DevFilaSystem.h"
#include "DeviceCore/DevManager.h"
@@ -551,6 +552,7 @@ struct Sidebar::priv
wxStaticLine* m_staticline2;
wxPanel* m_panel_project_title;
ScalableButton* m_filament_icon = nullptr;
Button * m_purge_mode_btn = nullptr;
Button * m_flushing_volume_btn = nullptr;
TextInput* m_search_item = nullptr;
StaticBox* m_search_bar = nullptr;
@@ -2663,12 +2665,13 @@ Sidebar::Sidebar(Plater *parent)
p->m_panel_filament_title->SetBackgroundColor(title_bg);
p->m_panel_filament_title->SetBackgroundColor2(0xF1F1F1);
p->m_panel_filament_title->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent &e) {
if (!p || !p->m_panel_filament_content || !m_scrolled_sizer || !p->m_bpButton_set_filament || !p->m_flushing_volume_btn || !p->m_bpButton_add_filament || !ams_btn)
if (!p || !p->m_panel_filament_content || !m_scrolled_sizer || !p->m_bpButton_set_filament || !p->m_purge_mode_btn || !p->m_flushing_volume_btn || !p->m_bpButton_add_filament || !ams_btn)
return;
// ORCA exclude area of del button from titlebar collapse/expand feature to fix undesired collapse when user spams del filament button
// also block fold/unfold feature when user clicks to spacing between icons
int exclude_pt = p->m_bpButton_set_filament->GetPosition().x; // maximum fixed item
if (p->m_flushing_volume_btn->IsShown()) exclude_pt = p->m_flushing_volume_btn->GetPosition().x;
if (p->m_purge_mode_btn->IsShown()) exclude_pt = p->m_purge_mode_btn->GetPosition().x;
else if (p->m_flushing_volume_btn->IsShown()) exclude_pt = p->m_flushing_volume_btn->GetPosition().x;
else if (p->m_bpButton_add_filament->IsShown()) exclude_pt = p->m_bpButton_add_filament->GetPosition().x - FromDIP(30); // reserve spacing for delete button
else if (ams_btn->IsShown()) exclude_pt = ams_btn->GetPosition().x;
if (e.GetPosition().x > exclude_pt)
@@ -2703,6 +2706,24 @@ Sidebar::Sidebar(Plater *parent)
bSizer39->AddStretchSpacer(1);
p->m_purge_mode_btn = new Button(p->m_panel_filament_title, _L("Purge mode"));
p->m_purge_mode_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Compact);
p->m_purge_mode_btn->Bind(wxEVT_BUTTON, [](wxCommandEvent &e) {
auto &preset_bundle = *wxGetApp().preset_bundle;
auto support_fast_purge_opt = preset_bundle.printers.get_edited_preset().config.option<ConfigOptionBool>("support_fast_purge_mode");
bool support_fast_purge = support_fast_purge_opt ? support_fast_purge_opt->value : false;
auto dlg_type = support_fast_purge ? PurgeModeDialogType::FastMode : PurgeModeDialogType::MultiNozzle;
PurgeModeDialog dlg(static_cast<wxWindow *>(wxGetApp().mainframe), dlg_type);
if (dlg.ShowModal() == wxID_OK) {
preset_bundle.project_config.set_key_value("prime_volume_mode", new ConfigOptionEnum<PrimeVolumeMode>(dlg.get_selected_mode()));
wxGetApp().plater()->update();
}
});
bSizer39->Add(p->m_purge_mode_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(4));
bSizer39->Hide(p->m_purge_mode_btn); // hidden on launch; shown only for printers that support purge mode selection
// BBS
// add wiping dialog
//wiping_dialog_button->SetFont(wxGetApp().normal_font());
@@ -3572,6 +3593,7 @@ void Sidebar::msw_rescale()
p->m_bpButton_del_filament->msw_rescale();
p->m_bpButton_ams_filament->msw_rescale();
p->m_bpButton_set_filament->msw_rescale();
p->m_purge_mode_btn->Rescale();
p->m_flushing_volume_btn->Rescale();
set_flushing_volume_warning(is_flush_config_modified()); // ORCA reapply appearance
@@ -3657,6 +3679,7 @@ void Sidebar::sys_color_changed()
p->m_bpButton_del_filament->msw_rescale();
p->m_bpButton_ams_filament->msw_rescale();
p->m_bpButton_set_filament->msw_rescale();
p->m_purge_mode_btn->Rescale();
p->m_flushing_volume_btn->Rescale();
set_flushing_volume_warning(is_flush_config_modified()); // ORCA reapply appearance
@@ -4426,6 +4449,17 @@ void Sidebar::show_SEMM_buttons()
Layout();
}
void Sidebar::enable_purge_mode_btn(bool enable)
{
if (!p || !p->m_purge_mode_btn)
return;
p->m_purge_mode_btn->Show(enable);
wxGetApp().CallAfter([this]() {
p->m_panel_filament_title->Layout();
this->Layout();
});
}
void Sidebar::update_dynamic_filament_list()
{
dynamic_filament_list.update();