OrcaSlicer latest
OrcaSlicer
Loading...
Searching...
No Matches
Slic3r::GUI::PublishSettingsDialog Class Reference

#include </home/runner/work/OrcaSlicer/OrcaSlicer/src/slic3r/GUI/PublishSettingsDialog.hpp>

Inheritance diagram for Slic3r::GUI::PublishSettingsDialog:
Collaboration diagram for Slic3r::GUI::PublishSettingsDialog:

Classes

struct  Row
struct  Subcategory
struct  Category
struct  MixedVisualSpec
struct  SectionGroup

Public Member Functions

 PublishSettingsDialog (wxWindow *parent=nullptr, const std::vector< std::string > *published_keys=nullptr, const std::vector< Slic3r::PublishedMaterialEntry > *material_keys=nullptr)
 ~PublishSettingsDialog ()
std::vector< std::string > GetPublishedKeys () const
std::vector< Slic3r::PublishedMaterialEntry > GetPublishedMaterialKeys () const
void EndModal (int retCode) override
float scale_factor () const
float prev_scale_factor () const
void set_scale_factor (float v)
void set_prev_scale_factor (float v)
void set_em_unit (int v)
bool force_rescale () const
int em_unit () const
const wxFont & normal_font () const
void enable_force_rescale ()
int ShowModal ()

Protected Member Functions

void on_dpi_changed (const wxRect &suggested_rect) override
void on_sys_color_changed () override

Private Types

enum class  Section { Print , Printer , Material }
enum class  RowKind { Setting , Color , Type }
enum class  FilterMode { Text , SelectedOnly , UnselectedOnly }

Private Member Functions

void fit_to_content ()
void refresh_mixed_tab_bitmaps ()
void build_option_model ()
void apply_selection (const std::vector< std::string > &published_keys, const std::vector< Slic3r::PublishedMaterialEntry > &material_keys)
void apply_filter (const wxString &filter_text)
void apply_pseudo_filter (bool selected_only)
void refresh_filter (const wxString &filter)
void select_all (bool value)
void select_visible (bool value)
void show_menu (wxMouseEvent &evt)
void set_row_bold (Row &row, bool bold)
void on_full_toggle (size_t category_index)
void on_enable_toggle (size_t category_index)
bool category_has_selection (const Category &cat) const
void refresh_tab_indicators ()
std::vector< MixedDependencyIssue > unpublished_mixed_components () const
void add_mixed_visual (size_t category_index, const MixedVisualSpec &spec)
size_t section_group_for (Section kind)
size_t category_index_for (const wxString &title, Section section, size_t group, size_t source_index, const PublishMaterialIdentity &identity=PublishMaterialIdentity(), bool is_mixed=false)
size_t subcategory_index_for (size_t category_index, const wxString &title, const wxString &icon)
void add_row_ui (const std::string &key, const wxString &label, const wxString &value, const wxString &unit, size_t category_index, size_t subcategory_index, RowKind kind=RowKind::Setting)
std::vector< std::string > full_keys_for_slot () const
void save_scroll_position (Category &category)
void show_outer_page (size_t section_index)
void show_inner_page (size_t section_index, int inner_index)
void show_mixed_page (size_t section_index, int mixed_index)
void on_outer_tab_changed (wxCommandEvent &event)
void on_inner_tab_changed (size_t section_index, wxCommandEvent &event)
void on_mixed_tab_changed (size_t section_index, wxCommandEvent &event)
bool row_is_visible (const Row &row) const
void apply_visibility ()
void bind_tab_events ()
void setup_variant_switch (size_t section_index)
void update_em_unit ()
bool is_new_scale_factor () const
void rescale (const wxRect &suggested_rect)

Static Private Member Functions

static MixedVisualSpec make_mixed_visual_spec (const Slic3r::DynamicPrintConfig &full, size_t slot)

Private Attributes

TabCtrl * m_outer_tabs {nullptr}
wxPanel * m_outer_host {nullptr}
wxBoxSizer * m_outer_host_sizer {nullptr}
int m_selected_outer {-1}
wxBoxSizer * m_fb_sizer {nullptr}
FilterMode m_filter_mode {FilterMode::Text}
TextInput * m_filter_box {nullptr}
wxTextCtrl * m_filter_ctrl {nullptr}
wxStaticBitmap * m_menu_button {nullptr}
wxStaticText * m_pseudo_chip {nullptr}
wxString m_info_nonsel
wxString m_info_allsel
wxString m_info_empty
wxString m_info_mix
ScalableBitmap m_search
ScalableBitmap m_menu
std::vector< Row > m_rows
std::vector< Category > m_categories
std::vector< SectionGroup > m_sections
float m_scale_factor
int m_em_unit
wxFont m_normal_font
float m_prev_scale_factor
bool m_can_rescale
bool m_force_rescale
int m_new_font_point_size

Detailed Description


Class Documentation

◆ Slic3r::GUI::PublishSettingsDialog::Row

struct Slic3r::GUI::PublishSettingsDialog::Row
Collaboration diagram for Slic3r::GUI::PublishSettingsDialog::Row:
Class Members
wxString category
::CheckBox * check {nullptr}
wxStaticText * check_label {nullptr}
wxStaticBitmap * color_chip {nullptr}
bool dirty {false}
size_t inner_index {0}
wxSizerItem * item {nullptr}
string key
RowKind kind {RowKind::Setting}
wxString label
bool matches_filter {false}
size_t outer_index {0}
Section section {Section::Print}
wxString section_title
wxString subcategory
wxString unit
wxStaticText * unit_label {nullptr}
wxString value
wxStaticText * value_label {nullptr}

◆ Slic3r::GUI::PublishSettingsDialog::Subcategory

struct Slic3r::GUI::PublishSettingsDialog::Subcategory
Collaboration diagram for Slic3r::GUI::PublishSettingsDialog::Subcategory:
Class Members
::StaticLine * header {nullptr}
wxSizerItem * item {nullptr}
vector< size_t > rows
wxString title

◆ Slic3r::GUI::PublishSettingsDialog::Category

struct Slic3r::GUI::PublishSettingsDialog::Category
Collaboration diagram for Slic3r::GUI::PublishSettingsDialog::Category:
Class Members
::CheckBox * enable_check {nullptr}
wxStaticText * enable_label {nullptr}
wxStaticBitmap * filament_color_chip {nullptr}
string filament_id
size_t filament_slot {0}
string filament_type
string filament_vendor
::CheckBox * full_check {nullptr}
wxStaticText * full_label {nullptr}
wxSizerItem * full_line_item {nullptr}
size_t group {0}
wxStaticText * info {nullptr}
bool is_mixed {false}
wxBoxSizer * list_sizer {nullptr}
wxPanel * page {nullptr}
vector< size_t > rows
wxScrolledWindow * scroll {nullptr}
wxPoint scroll_pos {0, 0}
Section section {Section::Print}
size_t source_index {0}
vector< Subcategory > subs
wxString title
wxStaticText * title_label {nullptr}

◆ Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec

struct Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec
Collaboration diagram for Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec:
Class Members
vector< wxColour > component_colours
vector< pair< double, double > > gradient_anchors
vector< pair< double, double > > gradient_samples
bool is_gradient {false}
vector< double > ratios
vector< double > tri_weights
bool valid {false}

◆ Slic3r::GUI::PublishSettingsDialog::SectionGroup

struct Slic3r::GUI::PublishSettingsDialog::SectionGroup
Collaboration diagram for Slic3r::GUI::PublishSettingsDialog::SectionGroup:
Class Members
vector< size_t > categories
ScalableBitmap icon_bmp
string icon_name
Section kind {Section::Print}
vector< size_t > mixed_categories
TabCtrl * mixed_tabs {nullptr}
wxPanel * page {nullptr}
wxPanel * page_host {nullptr}
wxBoxSizer * page_host_sizer {nullptr}
int selected_inner {-1}
int selected_mixed {-1}
TabCtrl * tabs {nullptr}
wxString title
MultiSwitchButton * variant_switch {nullptr}

Member Enumeration Documentation

◆ FilterMode

Enumerator
Text 
SelectedOnly 
UnselectedOnly 
294{ Text, SelectedOnly, UnselectedOnly };

◆ RowKind

Enumerator
Setting 
Color 
Type 
100 {
101 Setting, // a regular setting key
102 Color, // material colour requirement (filament_colour)
103 Type, // material type requirement (read-only text)
104 };
Type
Definition CustomGCode.hpp:18
std::array< std::size_t, 3 > Color
Definition ColorUtils.hpp:15

◆ Section

Enumerator
Print 
Printer 
Material 
95{ Print, Printer, Material };
@ Printer
Definition PrePrintChecker.hpp:21

Constructor & Destructor Documentation

◆ PublishSettingsDialog()

Slic3r::GUI::PublishSettingsDialog::PublishSettingsDialog ( wxWindow * parent = nullptr,
const std::vector< std::string > * published_keys = nullptr,
const std::vector< Slic3r::PublishedMaterialEntry > * material_keys = nullptr )
647 : DPIDialog(parent ? parent : static_cast<wxWindow*>(wxGetApp().mainframe),
648 wxID_ANY,
649 _L("Publish 3MF..."),
650 wxDefaultPosition,
651 wxDefaultSize,
652 wxCAPTION | wxCLOSE_BOX | wxRESIZE_BORDER | wxFULL_REPAINT_ON_RESIZE)
653 , m_search(this, "search", 16)
654 , m_menu(this, "filter", 16)
655{
656 SetBackgroundColour(*wxWHITE);
657
658 // --- filter bar: search box, All/None, menu button ---
659 wxPanel* f_bar = new wxPanel(this, wxID_ANY);
660 f_bar->SetBackgroundColour(GetBackgroundColour());
661 wxBoxSizer* f_sizer = new wxBoxSizer(wxHORIZONTAL);
662
663 m_filter_box = new TextInput(f_bar, "", "", "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
664 m_filter_box->SetIcon(m_search.bmp());
665 m_filter_box->SetMinSize(FromDIP(wxSize(200, 24)));
666 m_filter_box->SetSize(FromDIP(wxSize(-1, 24)));
667 m_filter_box->SetFocus();
668 m_filter_ctrl = m_filter_box->GetTextCtrl();
670 m_filter_ctrl->SetSize(wxSize(-1, FromDIP(16))); // centers text vertically
671 m_filter_ctrl->SetHint(_L("Type to filter..."));
672 m_filter_ctrl->Bind(wxEVT_TEXT, [this](auto&) { apply_filter(m_filter_ctrl->GetValue()); });
673 m_filter_ctrl->Bind(wxEVT_TEXT_ENTER, [this](auto&) { apply_filter(m_filter_ctrl->GetValue()); });
674 m_filter_ctrl->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {
676 apply_filter(m_filter_ctrl->GetValue());
677 e.Skip();
678 });
679 f_sizer->Add(m_filter_box, 1, wxEXPAND);
680
681 m_fb_sizer = new wxBoxSizer(wxHORIZONTAL);
682 auto create_btn = [this, f_bar](wxString title, bool select) {
683 auto btn = new wxStaticText(f_bar, wxID_ANY, title);
684 btn->SetForegroundColour("#009687");
685 btn->SetCursor(wxCURSOR_HAND);
686 btn->SetFont(Label::Body_13);
687 btn->Bind(wxEVT_LEFT_DOWN, [this, select](wxMouseEvent&) { select_all(select); });
688 m_fb_sizer->Add(btn, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
689 };
690 f_sizer->Add(m_fb_sizer, 0, wxALIGN_CENTER_VERTICAL);
691 create_btn(_L("All"), true);
692 create_btn(_L("None"), false);
693
694 // Indicator for the menu's pseudo filters: sits where All/None go while they are hidden.
695 // Labels reuse the menu entries (no new strings); clicking the chip returns to text
696 // filtering, keeping the search box contents.
697 m_pseudo_chip = new wxStaticText(f_bar, wxID_ANY, "");
698 m_pseudo_chip->SetForegroundColour("#009687");
699 m_pseudo_chip->SetCursor(wxCURSOR_HAND);
701 m_pseudo_chip->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent&) { apply_filter(m_filter_ctrl->GetValue()); });
702 m_pseudo_chip->Hide();
703 f_sizer->Add(m_pseudo_chip, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
704
705 m_menu_button = new wxStaticBitmap(f_bar, wxID_ANY, m_menu.bmp());
706 m_menu_button->SetCursor(wxCURSOR_HAND);
707 m_menu_button->Bind(wxEVT_LEFT_DOWN, &PublishSettingsDialog::show_menu, this);
708 f_sizer->Add(m_menu_button, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(10));
709
710 f_bar->SetSizerAndFit(f_sizer);
711
712 m_outer_tabs = new TabCtrl(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_tab_style);
714 m_outer_tabs->SetBackgroundColour(GetBackgroundColour());
715
716 m_outer_host = new wxPanel(this, wxID_ANY);
717#ifdef __WINDOWS__
718 m_outer_host->SetDoubleBuffered(true);
719#endif
720 m_outer_host->SetBackgroundColour(GetBackgroundColour());
721 m_outer_host_sizer = new wxBoxSizer(wxVERTICAL);
723
724 wxBoxSizer* w_sizer = new wxBoxSizer(wxVERTICAL);
725
726 wxStaticText* msg = new wxStaticText(this, wxID_ANY, _L("Select which settings to be published in the 3MF file"));
727 msg->SetFont(Label::Body_13);
728 msg->Wrap(-1);
729 w_sizer->Add(msg, 0, wxRIGHT | wxLEFT | wxTOP, FromDIP(10));
730
731 w_sizer->Add(f_bar, 0, wxRIGHT | wxLEFT | wxTOP | wxEXPAND, FromDIP(10));
732 w_sizer->Add(m_outer_tabs, 0, wxRIGHT | wxLEFT | wxTOP | wxEXPAND, FromDIP(10));
733 w_sizer->Add(m_outer_host, 1, wxRIGHT | wxLEFT | wxTOP | wxEXPAND, FromDIP(10));
734
736
737 // Seed from a remembered session selection or a freshly loaded published 3MF (authoritative).
738 if (published_keys != nullptr || material_keys != nullptr)
739 apply_selection(published_keys != nullptr ? *published_keys : std::vector<std::string>(),
740 material_keys != nullptr ? *material_keys : std::vector<Slic3r::PublishedMaterialEntry>());
741
742 auto dlg_btns = new DialogButtons(this, {"OK", "Cancel"});
743
744 dlg_btns->GetOK()->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
745 // Publish is always allowed: no settings selected means no settings override. Warn only
746 // when an enabled mixed filament would ship without the material of one of its
747 // components; "Publish anyway" accepts that and publishes anyway.
748 if (const std::vector<MixedDependencyIssue> issues = unpublished_mixed_components(); !issues.empty()) {
749 const DynamicPrintConfig full = wxGetApp().preset_bundle->full_config();
750 MixedFilamentWarningDialog warn(this, full, issues);
751 if (warn.ShowModal() != wxID_OK)
752 return; // Cancel: dismiss the warning and stay in this dialog
753 }
754 EndModal(wxID_OK);
755 });
756 dlg_btns->GetCANCEL()->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { EndModal(wxID_CANCEL); });
757
758 // Guide links, bottom-left, sharing the footer row with the OK/Cancel buttons (pushed right).
759 wxBoxSizer* links_sizer = new wxBoxSizer(wxHORIZONTAL);
760
761 auto wiki_btn = new Button(this, "", "toolbar_wiki", 0, 15);
762 auto wiki_url = "https://www.orcaslicer.com/wiki/publishing_3mf/publish_3mf";
763 wiki_btn->SetToolTip(_L("Wiki Guide") + "\n" + wiki_url);
764 wiki_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Circle);
765 wiki_btn->SetCanFocus(false);
766 wiki_btn->Bind(wxEVT_LEFT_DOWN, ([wiki_url](auto& e) {wxLaunchDefaultBrowser(wiki_url);}));
767
768 auto video_btn = new Button(this, "", "toolbar_video_guide", 0, 15);
769 auto video_url = "https://www.youtube.com/watch?v=-xt1N29UIOg";
770 video_btn->SetToolTip(_L("Video Guide") + "\n" + video_url);
771 video_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Circle);
772 video_btn->SetCanFocus(false);
773 video_btn->Bind(wxEVT_LEFT_DOWN, ([video_url](auto& e) {wxLaunchDefaultBrowser(video_url);}));
774
775 links_sizer->Add(wiki_btn , 0, wxLEFT, FromDIP(10));
776 links_sizer->Add(video_btn, 0, wxLEFT, FromDIP(10));
777
778 wxBoxSizer* footer = new wxBoxSizer(wxHORIZONTAL);
779 footer->Add(links_sizer, 0, wxALIGN_CENTER_VERTICAL);
780 footer->AddStretchSpacer();
781 footer->Add(dlg_btns, 0, wxALIGN_CENTER_VERTICAL);
782 auto* footer_line = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
783 footer_line->SetBackgroundColour(wxColour("#CECECE"));
784 footer_line->SetMinSize(wxSize(-1, 1));
785 footer_line->SetMaxSize(wxSize(-1, 1));
786 w_sizer->Add(footer_line, 0, wxRIGHT | wxLEFT | wxTOP | wxEXPAND, FromDIP(10));
787 w_sizer->Add(footer, 0, wxEXPAND, FromDIP(10));
788
789 SetSizerAndFit(w_sizer);
790 fit_to_content(); // initial size only; the dialog is resizable
791 wxGetApp().UpdateDlgDarkUI(this);
792 // The dark-UI walk re-colours the tab strips after the compositions were baked; rebuild so
793 // they carry the theme-resolved background (the sidebar resolves its colours at paint time,
794 // this dialog bakes, so the bake has to happen after the walk).
796}
@ Confirm
Definition Button.hpp:25
@ Circle
Definition Button.hpp:37
#define _L(s)
Definition OBJ.cpp:34
class WXDLLIMPEXP_FWD_CORE wxStaticText
Definition ProgressDialog.hpp:30
static wxFont Body_13
Definition Label.hpp:54
static wxFont Body_14
Definition Label.hpp:53
void EndModal(int retCode) override
Definition GUI_Utils.hpp:305
TextInput * m_filter_box
Definition PublishSettingsDialog.hpp:296
@ Text
Definition PublishSettingsDialog.hpp:294
wxStaticText * m_pseudo_chip
Definition PublishSettingsDialog.hpp:301
void fit_to_content()
Definition PublishSettingsDialog.cpp:804
wxStaticBitmap * m_menu_button
Definition PublishSettingsDialog.hpp:298
void select_all(bool value)
Definition PublishSettingsDialog.cpp:1858
void refresh_mixed_tab_bitmaps()
Definition PublishSettingsDialog.cpp:2330
wxPanel * m_outer_host
Definition PublishSettingsDialog.hpp:289
ScalableBitmap m_menu
Definition PublishSettingsDialog.hpp:308
void show_menu(wxMouseEvent &evt)
Definition PublishSettingsDialog.cpp:1910
void apply_filter(const wxString &filter_text)
Definition PublishSettingsDialog.cpp:1739
ScalableBitmap m_search
Definition PublishSettingsDialog.hpp:307
wxBoxSizer * m_outer_host_sizer
Definition PublishSettingsDialog.hpp:290
wxTextCtrl * m_filter_ctrl
Definition PublishSettingsDialog.hpp:297
FilterMode m_filter_mode
Definition PublishSettingsDialog.hpp:295
void build_option_model()
Definition PublishSettingsDialog.cpp:835
std::vector< MixedDependencyIssue > unpublished_mixed_components() const
Definition PublishSettingsDialog.cpp:2068
void apply_selection(const std::vector< std::string > &published_keys, const std::vector< Slic3r::PublishedMaterialEntry > &material_keys)
Definition PublishSettingsDialog.cpp:1968
TabCtrl * m_outer_tabs
Definition PublishSettingsDialog.hpp:288
wxBoxSizer * m_fb_sizer
Definition PublishSettingsDialog.hpp:292
wxMouseEvent
Definition CameraPopup.cpp:47

References _L, apply_filter(), apply_selection(), Label::Body_13, Label::Body_14, build_option_model(), Circle, Confirm, Slic3r::GUI::DPIDialog::EndModal(), fit_to_content(), Slic3r::GUI::DialogButtons::GetOK(), m_fb_sizer, m_filter_box, m_filter_ctrl, m_filter_mode, m_menu, m_menu_button, m_outer_host, m_outer_host_sizer, m_outer_tabs, m_pseudo_chip, m_search, refresh_mixed_tab_bitmaps(), select_all(), show_menu(), Slic3r::GUI::DPIAware< P >::ShowModal(), Text, unpublished_mixed_components(), Slic3r::GUI::wxMouseEvent, and wxStaticText.

Here is the call graph for this function:

◆ ~PublishSettingsDialog()

Slic3r::GUI::PublishSettingsDialog::~PublishSettingsDialog ( )
833{}

Member Function Documentation

◆ add_mixed_visual()

void Slic3r::GUI::PublishSettingsDialog::add_mixed_visual ( size_t category_index,
const MixedVisualSpec & spec )
private
1439{
1440 if (category_index >= m_categories.size() || !spec.valid)
1441 return;
1442 Category& category = m_categories[category_index];
1443 if (category.page == nullptr || category.page->GetSizer() == nullptr || category.scroll == nullptr || spec.component_colours.empty())
1444 return;
1445
1446 auto* viz = new wxPanel(category.page, wxID_ANY);
1447 viz->SetBackgroundStyle(wxBG_STYLE_PAINT);
1448 // Theme colours and DIP metrics are resolved inside the paint handler so dark-mode toggles
1449 // and DPI changes are picked up on the next repaint without any explicit listener. The
1450 // ternary fill cache lives inside the shared triangle painter (FilamentBitmapUtils).
1451 viz->Bind(wxEVT_PAINT, [this, panel = viz, spec](wxPaintEvent&) {
1452 const wxColour bg = StateColor::darkModeColorFor(*wxWHITE);
1453 wxBufferedPaintDC pdc(panel);
1454 pdc.SetBackground(wxBrush(bg));
1455 pdc.Clear();
1456 const wxRect rc = panel->GetClientRect();
1457 if (rc.width <= 0 || rc.height <= 0)
1458 return;
1459
1460 const size_t n = spec.component_colours.size();
1461
1462 if (spec.tri_weights.size() == 3 && n == 3 && !spec.is_gradient) {
1463 // Ternary mix: read-only miniature of the MixedFilamentDialog's triangle picker.
1464 const MixedTriangleTheme tri_theme{StateColor::darkModeColorFor(*wxWHITE), StateColor::darkModeColorFor(wxColour("#CECECE")),
1465 StateColor::darkModeColorFor(wxColour("#262E30")),
1466 StateColor::darkModeColorFor(wxColour(107, 107, 107))};
1467 draw_mixed_triangle_picker(pdc, rc.GetSize(), {spec.component_colours[0], spec.component_colours[1], spec.component_colours[2]},
1468 {spec.tri_weights[0], spec.tri_weights[1], spec.tri_weights[2]}, tri_theme);
1469 draw_mixed_triangle_labels(pdc, rc.GetSize(), {spec.tri_weights[0], spec.tri_weights[1], spec.tri_weights[2]}, tri_theme);
1470 } else if (!spec.is_gradient) {
1471 // Ratio bar. A 2-component slot matches the MixedFilamentDialog's continuous blend +
1472 // divider (with its two end labels); wider non-gradient mixes (rare) fall back to one
1473 // solid segment per component.
1474 if (n == 2) {
1475 const int bar_h = FromDIP(27);
1476 draw_mixed_ratio_blend_bar(pdc, wxRect(rc.x, rc.y, rc.width, bar_h), spec.component_colours[0], spec.component_colours[1],
1477 spec.ratios[1]);
1478 // Read-only twin of the dialog's left/right percentage labels.
1479 pdc.SetFont(::Label::Body_12);
1480 pdc.SetTextForeground(StateColor::darkModeColorFor(wxColour(107, 107, 107)));
1481 const wxString la = wxString::Format("%d%%", int(std::lround(spec.ratios[0] * 100.0)));
1482 const wxString lb = wxString::Format("%d%%", int(std::lround(spec.ratios[1] * 100.0)));
1483 const int lab_y = rc.y + bar_h + FromDIP(2);
1484 pdc.DrawText(la, rc.x, lab_y);
1485 pdc.DrawText(lb, rc.x + rc.width - pdc.GetTextExtent(lb).GetWidth(), lab_y);
1486 } else {
1487 draw_mixed_ratio_segments(pdc, rc, spec.component_colours, spec.ratios);
1488 // Percent label centred in each segment wide enough to hold it.
1489 std::vector<double> shares = spec.ratios;
1490 double total = 0.0;
1491 for (double r : shares)
1492 total += r;
1493 if (total <= 0.0) {
1494 shares.assign(n, 1.0 / n);
1495 total = 1.0;
1496 }
1497 pdc.SetFont(::Label::Body_12);
1498 int x0 = rc.x;
1499 for (size_t i = 0; i < n; ++i) {
1500 const int x1 = (i + 1 < n) ? rc.x + int(std::lround(std::accumulate(shares.begin(), shares.begin() + i + 1, 0.0) /
1501 total * double(rc.width))) :
1502 rc.x + rc.width;
1503 const int w = std::max(1, x1 - x0);
1504 const wxString text = wxString::Format("%d%%", int(std::lround(shares[i] / total * 100.0)));
1505 const wxSize tsz = pdc.GetTextExtent(text);
1506 if (tsz.GetWidth() + FromDIP(4) <= w) {
1507 const wxColour& c = spec.component_colours[i];
1508 const double lum = 0.299 * c.Red() + 0.587 * c.Green() + 0.114 * c.Blue();
1509 pdc.SetTextForeground(lum > 140 ? wxColour("#262E30") : *wxWHITE);
1510 pdc.DrawText(text, x0 + (w - tsz.GetWidth()) / 2, rc.y + (rc.height - tsz.GetHeight()) / 2);
1511 }
1512 x0 = x1;
1513 }
1514 }
1515 } else {
1516 // Gradient: read-only miniature of the GradientCurveEditor plot, drawn through the
1517 // shared painter so it anti-aliases and keeps the square proportions and labels.
1518 const MixedGradientTheme grad_theme{StateColor::darkModeColorFor(*wxWHITE),
1519 StateColor::darkModeColorFor(wxColour(238, 238, 238)),
1520 StateColor::darkModeColorFor(wxColour(107, 107, 107)),
1521 StateColor::darkModeColorFor(wxColour(107, 107, 107)),
1522 StateColor::darkModeColorFor(wxColour(38, 46, 48)),
1523 StateColor::darkModeColorFor(wxColour(172, 172, 172)),
1525 std::vector<MixedGradientCurve> curves;
1526 std::vector<wxPoint2DDouble> anchors;
1527 if (spec.gradient_samples.size() >= 2 && n >= 2) {
1528 const wxRect plot = mixed_gradient_plot_rect(rc.GetSize());
1529 auto lift_alpha = [](wxColour c) {
1530 if (c.Alpha() == 0)
1531 c.Set(c.Red(), c.Green(), c.Blue(), 150);
1532 return c;
1533 };
1534 // First component's ratio solid, its mirror twin for the other.
1535 const wxColour col_a = lift_alpha(spec.component_colours[0]);
1536 const wxColour col_b = lift_alpha(spec.component_colours[1]);
1537 std::vector<wxPoint2DDouble> pts_a, pts_b;
1538 pts_a.reserve(spec.gradient_samples.size());
1539 pts_b.reserve(spec.gradient_samples.size());
1540 for (const auto& [t, r] : spec.gradient_samples) {
1541 pts_a.push_back({plot.x + t * plot.width, plot.y + (1.0 - r) * plot.height});
1542 pts_b.push_back({plot.x + t * plot.width, plot.y + r * plot.height});
1543 }
1544 // Control-point anchors of the stored curve on the first component's line.
1545 anchors.reserve(spec.gradient_anchors.size());
1546 for (const auto& [t, r] : spec.gradient_anchors)
1547 anchors.push_back({plot.x + t * plot.width, plot.y + (1.0 - r) * plot.height});
1548 curves.push_back({std::move(pts_a), col_a, 4});
1549 curves.push_back({std::move(pts_b), col_b, 2});
1550 }
1551 draw_mixed_gradient_plot(pdc, rc.GetSize(), curves, anchors, grad_theme);
1552 }
1553 });
1554
1555 // Fixed DIP size, left-aligned: the visualization keeps its proportions no matter how the
1556 // dialog is resized (the paint handler draws into whatever client rect the panel ends up
1557 // with, so nothing else has to change). Sizes mirror the MixedFilamentDialog controls: the
1558 // gradient plot and triangle picker match the editor's 260x200 / 160x160, the ratio bar is
1559 // the dialog's 27px bar plus its label line.
1560 int viz_h;
1561 int viz_w;
1562 if (spec.is_gradient) {
1563 viz_w = 260;
1564 viz_h = 200;
1565 } else if (spec.tri_weights.size() == 3 && spec.component_colours.size() == 3) {
1566 viz_w = 160;
1567 viz_h = 160;
1568 } else {
1569 viz_w = 240;
1570 viz_h = spec.component_colours.size() == 2 ? 50 : 30;
1571 }
1572 const wxSize viz_sz(FromDIP(viz_w), FromDIP(viz_h));
1573 viz->SetMinSize(viz_sz);
1574 viz->SetMaxSize(viz_sz);
1575 // Parented to the page right above the scroll area, so it is always shown with the tab:
1576 // the "Enable" toggle keeps gating only the rows/info below, never this preview.
1577 wxSizer* page_sizer = category.page->GetSizer();
1578 int scroll_idx = -1;
1579 for (size_t i = 0; i < page_sizer->GetChildren().size(); ++i)
1580 if (page_sizer->GetChildren()[i]->GetWindow() == category.scroll) {
1581 scroll_idx = int(i);
1582 break;
1583 }
1584 if (scroll_idx < 0)
1585 page_sizer->Add(viz, 0, wxLEFT | wxRIGHT | wxTOP, FromDIP(10)); // defensive: no scroll item
1586 else
1587 page_sizer->Insert(scroll_idx, viz, 0, wxLEFT | wxRIGHT | wxTOP, FromDIP(10));
1588}
static wxFont Body_12
Definition Label.hpp:55
std::vector< Category > m_categories
Definition PublishSettingsDialog.hpp:311
Definition PublishSettingsDialog.hpp:139
static wxColour darkModeColorFor(wxColour const &color)
Definition StateColor.cpp:219
void draw_mixed_gradient_plot(wxDC &raw_dc, const wxSize &canvas, const std::vector< MixedGradientCurve > &curves, const std::vector< wxPoint2DDouble > &anchors, const MixedGradientTheme &theme)
Definition FilamentBitmapUtils.cpp:537
void draw_mixed_ratio_segments(wxDC &dc, const wxRect &rect, const std::vector< wxColour > &colours, const std::vector< double > &shares)
Definition FilamentBitmapUtils.cpp:701
void draw_mixed_ratio_blend_bar(wxDC &dc, const wxRect &rect, const wxColour &first, const wxColour &second, double second_fraction)
Definition FilamentBitmapUtils.cpp:680
void draw_mixed_triangle_labels(wxDC &dc, const wxSize &size, const std::array< double, 3 > &weights, const MixedTriangleTheme &theme)
Definition FilamentBitmapUtils.cpp:845
void draw_mixed_triangle_picker(wxDC &dc, const wxSize &size, const std::array< wxColour, 3 > &colours, const std::array< double, 3 > &weights, const MixedTriangleTheme &theme)
Definition FilamentBitmapUtils.cpp:769
wxRect mixed_gradient_plot_rect(const wxSize &sz)
Definition FilamentBitmapUtils.cpp:527

References Label::Body_12, Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::component_colours, StateColor::darkModeColorFor(), Slic3r::GUI::draw_mixed_gradient_plot(), Slic3r::GUI::draw_mixed_ratio_blend_bar(), Slic3r::GUI::draw_mixed_ratio_segments(), Slic3r::GUI::draw_mixed_triangle_labels(), Slic3r::GUI::draw_mixed_triangle_picker(), Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::gradient_anchors, Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::gradient_samples, Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::is_gradient, m_categories, Slic3r::GUI::mixed_gradient_plot_rect(), Slic3r::GUI::PublishSettingsDialog::Category::page, Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::ratios, Slic3r::GUI::PublishSettingsDialog::Category::scroll, Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::tri_weights, and Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::valid.

Referenced by build_option_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_row_ui()

void Slic3r::GUI::PublishSettingsDialog::add_row_ui ( const std::string & key,
const wxString & label,
const wxString & value,
const wxString & unit,
size_t category_index,
size_t subcategory_index,
RowKind kind = RowKind::Setting )
private
1341{
1342 Category& category = m_categories[category_index];
1343 Row row;
1344 row.key = key;
1345 row.label = label;
1346 row.value = value;
1347 row.unit = unit;
1348 row.kind = kind;
1349 row.category = category.title;
1350 row.subcategory = category.subs[subcategory_index].title;
1351 row.section = category.section;
1352 row.section_title = m_sections[category.group].title;
1353 row.outer_index = category.group;
1354 row.inner_index = category_index;
1355 const size_t row_index = m_rows.size();
1356 m_rows.push_back(std::move(row));
1357 Row& current = m_rows[row_index];
1358 current.check = new ::CheckBox(category.scroll, wxID_ANY);
1359 current.check->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& event) {
1361 event.Skip();
1362 });
1363 auto* row_sizer = new wxBoxSizer(wxHORIZONTAL);
1364 current.check_label = add_checkbox_label(category.scroll, row_sizer, current.check, label + ":", wxEmptyString,
1365 24 * wxGetApp().em_unit());
1366 // The value is read-only text (incl. the Type row: the published type is the slot's
1367 // normalized type, not author-editable).
1368 current.value_label = new wxStaticText(category.scroll, wxID_ANY, value, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
1369 current.value_label->SetFont(Label::Body_14);
1370 current.value_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30")));
1371 current.value_label->SetToolTip(unit.IsEmpty() ? value : value + " " + unit);
1372 if (kind == RowKind::Color && !value.IsEmpty()) {
1373 // The colour swatch carries this slot's 1-based number, like the main GUI swatches.
1374 const std::string chip_label = std::to_string(category.filament_slot + 1);
1375 if (wxBitmap* chip = get_extruder_color_icon(value.ToStdString(), chip_label, FromDIP(20), FromDIP(20))) {
1376 current.color_chip = new wxStaticBitmap(category.scroll, wxID_ANY, *chip);
1377 row_sizer->Add(current.color_chip, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(8));
1378 }
1379 }
1380 row_sizer->Add(current.value_label, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(8));
1381 if (!unit.IsEmpty()) {
1382 current.unit_label = new wxStaticText(category.scroll, wxID_ANY, unit);
1383 current.unit_label->SetFont(Label::Body_14);
1384 current.unit_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#6B6B6B")));
1385 row_sizer->Add(current.unit_label, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(4));
1386 }
1387 current.item = category.list_sizer->Add(row_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(5));
1388 category.rows.push_back(row_index);
1389 category.subs[subcategory_index].rows.push_back(row_index);
1390}
int em_unit() const
Definition GUI_Utils.hpp:203
std::string key
Definition PublishSettingsDialog.hpp:107
std::vector< SectionGroup > m_sections
Definition PublishSettingsDialog.hpp:312
std::vector< Row > m_rows
Definition PublishSettingsDialog.hpp:310
void refresh_tab_indicators()
Definition PublishSettingsDialog.cpp:2216
@ Color
Definition PublishSettingsDialog.hpp:102
Definition PublishSettingsDialog.hpp:106
wxStaticText * add_checkbox_label(wxWindow *parent, wxBoxSizer *sizer, ::CheckBox *check, const wxString &label, const wxString &tooltip, int label_width=0)
Definition PublishSettingsDialog.cpp:68
wxBitmap * get_extruder_color_icon(std::vector< std::string > colors, bool is_gradient, std::string label, int icon_width, int icon_height, const std::vector< wxColour > *ramp)
Definition wxExtensions.cpp:633

References Label::Body_14, Slic3r::GUI::PublishSettingsDialog::Row::category, Slic3r::GUI::PublishSettingsDialog::Row::check, Slic3r::GUI::PublishSettingsDialog::Row::check_label, Color, Slic3r::GUI::PublishSettingsDialog::Row::color_chip, StateColor::darkModeColorFor(), Slic3r::GUI::DPIAware< wxDialog >::em_unit(), Slic3r::GUI::PublishSettingsDialog::Category::filament_slot, get_extruder_color_icon(), Slic3r::GUI::PublishSettingsDialog::Category::group, Slic3r::GUI::PublishSettingsDialog::Row::inner_index, Slic3r::GUI::PublishSettingsDialog::Row::item, Slic3r::GUI::PublishSettingsDialog::Row::key, Slic3r::GUI::PublishSettingsDialog::Row::kind, Slic3r::GUI::PublishSettingsDialog::Row::label, Slic3r::GUI::PublishSettingsDialog::Category::list_sizer, m_categories, m_rows, m_sections, Slic3r::GUI::PublishSettingsDialog::Row::outer_index, refresh_tab_indicators(), Slic3r::GUI::PublishSettingsDialog::Category::rows, Slic3r::GUI::PublishSettingsDialog::Category::scroll, Slic3r::GUI::PublishSettingsDialog::Category::section, Slic3r::GUI::PublishSettingsDialog::Row::section, Slic3r::GUI::PublishSettingsDialog::Row::section_title, Slic3r::GUI::PublishSettingsDialog::Row::subcategory, Slic3r::GUI::PublishSettingsDialog::Category::subs, Slic3r::GUI::PublishSettingsDialog::Category::title, Slic3r::GUI::PublishSettingsDialog::Row::unit, Slic3r::GUI::PublishSettingsDialog::Row::unit_label, Slic3r::GUI::PublishSettingsDialog::Row::value, Slic3r::GUI::PublishSettingsDialog::Row::value_label, and wxStaticText.

Referenced by build_option_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ apply_filter()

void Slic3r::GUI::PublishSettingsDialog::apply_filter ( const wxString & filter_text)
private
1740{
1742 refresh_filter(filter_text.Lower());
1743}
void refresh_filter(const wxString &filter)
Definition PublishSettingsDialog.cpp:1751

References m_filter_mode, refresh_filter(), and Text.

Referenced by PublishSettingsDialog(), select_visible(), and show_menu().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ apply_pseudo_filter()

void Slic3r::GUI::PublishSettingsDialog::apply_pseudo_filter ( bool selected_only)
private
1746{
1748 refresh_filter(wxString()); // the pseudo modes ignore the search text
1749}
@ UnselectedOnly
Definition PublishSettingsDialog.hpp:294
@ SelectedOnly
Definition PublishSettingsDialog.hpp:294

References m_filter_mode, refresh_filter(), SelectedOnly, and UnselectedOnly.

Referenced by show_menu().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ apply_selection()

void Slic3r::GUI::PublishSettingsDialog::apply_selection ( const std::vector< std::string > & published_keys,
const std::vector< Slic3r::PublishedMaterialEntry > & material_keys )
private
1970{
1971 // The supplied selection is authoritative: clear the dirty-default pre-check first so a
1972 // dirty key the user deselected stays off, then re-select exactly what the selection names.
1973 for (Row& row : m_rows)
1974 if (row.check != nullptr)
1975 row.check->SetValue(false);
1976 for (Category& cat : m_categories) {
1977 if (cat.section != Section::Material)
1978 continue;
1979 if (cat.enable_check != nullptr)
1980 cat.enable_check->SetValue(false);
1981 if (cat.full_check != nullptr)
1982 cat.full_check->SetValue(false);
1983 }
1984
1985 // Print / printer rows: match by exact row key (the full "#N" opt_id where present).
1986 for (const std::string& key : published_keys)
1987 for (Row& row : m_rows)
1988 if ((row.section == Section::Print || row.section == Section::Printer) && row.check != nullptr && row.key == key) {
1989 row.check->SetValue(true);
1990 break;
1991 }
1992
1993 // Per-slot material selections, applied positionally by slot.
1994 for (const Slic3r::PublishedMaterialEntry& entry : material_keys) {
1995 if (entry.slot < 0)
1996 continue;
1997 bool entry_mixed = false;
1998 for (const std::string& k : entry.keys)
1999 if (publish_mixed_keys().count(publish_base_key(k)) != 0) {
2000 entry_mixed = true;
2001 break;
2002 }
2003 size_t cat_idx = size_t(-1);
2004 for (size_t c = 0; c < m_categories.size(); ++c) {
2005 const Category& cat = m_categories[c];
2006 if (cat.section != Section::Material || cat.is_mixed != entry_mixed || cat.filament_slot != size_t(entry.slot))
2007 continue;
2008 cat_idx = c;
2009 break;
2010 }
2011 if (cat_idx == size_t(-1))
2012 continue; // slot not present in the receiver (out of range / skipped)
2013 Category& cat = m_categories[cat_idx];
2014 if (cat.enable_check != nullptr) {
2015 cat.enable_check->SetValue(true);
2016 on_enable_toggle(cat_idx);
2017 }
2018 if (entry.full && cat.full_check != nullptr) {
2019 cat.full_check->SetValue(true);
2020 on_full_toggle(cat_idx);
2021 } else {
2022 // Setting rows are keyed by the base key.
2023 for (const std::string& key : entry.keys) {
2024 const std::string base = publish_base_key(key);
2025 for (const size_t r : cat.rows) {
2026 Row& row = m_rows[r];
2027 if (row.kind == RowKind::Setting && row.key == base) {
2028 row.check->SetValue(true);
2029 break;
2030 }
2031 }
2032 }
2033 if (entry.publish_type && !entry.publish_type_value.empty())
2034 for (const size_t r : cat.rows)
2035 if (m_rows[r].kind == RowKind::Type && m_rows[r].check != nullptr) {
2036 m_rows[r].check->SetValue(true);
2037 break;
2038 }
2039 if (entry.publish_color && !entry.color.empty())
2040 for (const size_t r : cat.rows)
2041 if (m_rows[r].kind == RowKind::Color && m_rows[r].check != nullptr) {
2042 m_rows[r].check->SetValue(true);
2043 break;
2044 }
2045 }
2046 }
2047
2050}
static unsigned int count
Definition AuxiliaryDataViewModel.cpp:246
void on_enable_toggle(size_t category_index)
Definition PublishSettingsDialog.cpp:1403
@ Print
Definition PublishSettingsDialog.hpp:95
@ Printer
Definition PublishSettingsDialog.hpp:95
@ Material
Definition PublishSettingsDialog.hpp:95
void apply_visibility()
Definition PublishSettingsDialog.cpp:1827
@ Setting
Definition PublishSettingsDialog.hpp:101
@ Type
Definition PublishSettingsDialog.hpp:103
void on_full_toggle(size_t category_index)
Definition PublishSettingsDialog.cpp:1392
const std::set< std::string > & publish_mixed_keys()
Definition PublishSettings.cpp:111
std::string publish_base_key(const std::string &key)
Definition PublishSettings.cpp:20

References apply_visibility(), Slic3r::GUI::PublishSettingsDialog::Row::check, Color, count, Slic3r::GUI::PublishSettingsDialog::Category::enable_check, Slic3r::GUI::PublishSettingsDialog::Category::filament_slot, Slic3r::GUI::PublishSettingsDialog::Category::full_check, Slic3r::GUI::PublishSettingsDialog::Category::is_mixed, Slic3r::GUI::PublishSettingsDialog::Row::key, Slic3r::GUI::PublishSettingsDialog::Row::kind, m_categories, m_rows, Material, on_enable_toggle(), on_full_toggle(), Print, Printer, Slic3r::publish_base_key(), Slic3r::publish_mixed_keys(), refresh_tab_indicators(), Slic3r::GUI::PublishSettingsDialog::Category::rows, Slic3r::GUI::PublishSettingsDialog::Category::section, Setting, and Type.

Referenced by PublishSettingsDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ apply_visibility()

void Slic3r::GUI::PublishSettingsDialog::apply_visibility ( )
private
1828{
1829 Freeze();
1830 for (Category& category : m_categories) {
1831 // A disabled material slot hides everything below its header (rows, info and the Full
1832 // Publish line); enable it first to reveal its settings.
1833 const bool enabled = category.section != Section::Material ||
1834 (category.enable_check != nullptr && category.enable_check->GetValue());
1835 if (category.scroll != nullptr)
1836 category.scroll->Show(enabled);
1837 if (category.full_line_item != nullptr)
1838 category.full_line_item->Show(enabled);
1839 bool category_any = false;
1840 for (size_t r : category.rows)
1841 category_any = category_any || m_rows[r].matches_filter;
1842 category.info->Show(enabled && !category_any);
1843 for (Subcategory& sub : category.subs) {
1844 bool sub_any = false;
1845 for (size_t r : sub.rows)
1846 sub_any = sub_any || m_rows[r].matches_filter;
1847 if (sub.header != nullptr)
1848 sub.item->Show(enabled && sub_any);
1849 for (size_t r : sub.rows)
1850 m_rows[r].item->Show(enabled && m_rows[r].matches_filter);
1851 }
1852 category.list_sizer->Layout();
1853 category.scroll->FitInside();
1854 }
1855 Thaw();
1856}
Definition PublishSettingsDialog.hpp:130

References Slic3r::GUI::PublishSettingsDialog::Subcategory::header, Slic3r::GUI::PublishSettingsDialog::Subcategory::item, m_categories, m_rows, Material, and Slic3r::GUI::PublishSettingsDialog::Subcategory::rows.

Referenced by apply_selection(), build_option_model(), on_enable_toggle(), refresh_filter(), and select_all().

Here is the caller graph for this function:

◆ bind_tab_events()

void Slic3r::GUI::PublishSettingsDialog::bind_tab_events ( )
private
1727{
1728 m_outer_tabs->Bind(wxEVT_TAB_SEL_CHANGED, &PublishSettingsDialog::on_outer_tab_changed, this);
1729 for (size_t section_index = 0; section_index < m_sections.size(); ++section_index) {
1730 m_sections[section_index].tabs->Bind(wxEVT_TAB_SEL_CHANGED,
1731 [this, section_index](wxCommandEvent& event) { on_inner_tab_changed(section_index, event); });
1732 if (m_sections[section_index].mixed_tabs != nullptr)
1733 m_sections[section_index].mixed_tabs->Bind(wxEVT_TAB_SEL_CHANGED, [this, section_index](wxCommandEvent& event) {
1734 on_mixed_tab_changed(section_index, event);
1735 });
1736 }
1737}
void on_mixed_tab_changed(size_t section_index, wxCommandEvent &event)
Definition PublishSettingsDialog.cpp:1718
void on_outer_tab_changed(wxCommandEvent &event)
Definition PublishSettingsDialog.cpp:1704
void on_inner_tab_changed(size_t section_index, wxCommandEvent &event)
Definition PublishSettingsDialog.cpp:1711

References m_outer_tabs, m_sections, on_inner_tab_changed(), on_mixed_tab_changed(), and on_outer_tab_changed().

Referenced by build_option_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_option_model()

void Slic3r::GUI::PublishSettingsDialog::build_option_model ( )
private
836{
837 // Structural / non-publishable keys, shared with the published-3MF overlay path.
838 const std::set<std::string>& denylist = publish_structural_keys();
839 // Base keys already added in the print section (dedup across pages/optgroups). The printer
840 // section keeps its own printer_added set keyed by the full per-extruder "#N" opt_id, so
841 // every extruder gets its own row (see Phase 1 below).
842 std::set<std::string> added;
843
844 PresetBundle* bundle = wxGetApp().preset_bundle;
845 DynamicPrintConfig full = bundle->full_config();
846
847 m_info_nonsel = _L("No selected items...");
848 m_info_allsel = _L("All items selected...");
849 m_info_empty = _L("No matching items...");
850 m_info_mix = _L("Mixed filament - published as a whole when \"Enable\" above is selected");
851
852 // Tab order differs from Section's enum order (Print, Printer, Material): the dialog
853 // presents Printer, Filament, Process.
854 m_sections.reserve(3);
856 for (Section kind : tab_order)
857 section_group_for(kind);
859
860 // Shared per-option label/value computation; returns false when the option must be skipped
861 // (denylisted / unknown / empty label). value is the stringified value; unit the translated
862 // sidetext (may be empty).
863 auto option_text = [&denylist, &full](const std::string& opt_id, const std::string& pure_key, wxString& label, wxString& value,
864 wxString& unit) -> bool {
865 if (denylist.count(pure_key) > 0)
866 return false;
867 const ConfigOptionDef* def = print_config_def.get(pure_key);
868 if (def == nullptr)
869 return false;
870 label = _(def->full_label.empty() ? def->label : def->full_label);
871 if (label.IsEmpty())
872 return false;
873 value = get_string_value(opt_id, full);
874 unit = _(def->sidetext);
875 if (unit == "%" && value.EndsWith("%"))
876 unit.clear();
877 return true;
878 };
879
880 // --- Phase 1: printer per-extruder retraction settings (first, mirroring the sidebar's
881 // Printer group), from the printer tab's "Extruder" page. One inner tab per extruder (named
882 // as on the printer tab's switch, e.g. "Left Extruder"/"Right Extruder" via
883 // Tab::translate_category), each holding that extruder's Retraction and Z-Hop rows with
884 // per-extruder "#N" values.
885 {
887 std::set<std::string> printer_added;
888 for (Tab* tab : wxGetApp().tabs_list) {
889 // The page's controls edit the extruder chosen on the printer tab's switch, so its
890 // option list is read once per extruder.
891 auto* printer_tab = dynamic_cast<TabPrinter*>(tab);
892 const Page* page = printer_tab ? printer_tab->extruder_page() : nullptr;
893 if (page == nullptr)
894 continue;
895 const size_t extruders_count = printer_tab->m_extruders_count;
896 for (size_t extruder_idx = 0; extruder_idx < extruders_count; ++extruder_idx) {
897 const wxString page_title = Tab::translate_category(extruders_count > 1 ? wxString::Format("Extruder %d", int(extruder_idx + 1)) : wxString("Extruder"), tab->m_type);
898 // Retraction and Z-Hop values are stored per variant column, not per extruder.
899 const int variant_index = printer_tab->extruder_variant_index(int(extruder_idx));
900 for (const ConfigOptionsGroupShp& optgroup : page->m_optgroups) {
901 // Allowlist on the untranslated optgroup title; the "Retraction when
902 // switching material" group is intentionally skipped.
903 if (optgroup->title != "Retraction" && optgroup->title != "Z-Hop")
904 continue;
905 const wxString subcategory = _(optgroup->title);
906 for (const auto& opt : optgroup->opt_map()) {
907 const std::string& pure_key = opt.second.first;
908 // Rows are keyed by the full per-extruder "#N" opt_id so each extruder
909 // tab publishes its own value; GetPublishedKeys() emits the checked rows
910 // as-is.
911 const std::string opt_id = pure_key + "#" + std::to_string(variant_index);
912 if (!printer_added.insert(opt_id).second)
913 continue;
914 wxString label, value, unit;
915 if (!option_text(opt_id, pure_key, label, value, unit))
916 continue;
917 size_t cat_index = category_index_for(page_title, Section::Printer, g, extruder_idx);
918 size_t sub_index = subcategory_index_for(cat_index, subcategory, optgroup->icon);
919 add_row_ui(opt_id, label, value, unit, cat_index, sub_index);
920 }
921 }
922 }
923 }
924 }
925
926 // --- Phase 2: per-material sections synthesized from the filament tab's "Setting
927 // Overrides" page, under the Filament group.
928 {
930 Tab* filament_tab = nullptr;
931 for (Tab* tab : wxGetApp().tabs_list)
932 if (tab->m_type == Preset::TYPE_FILAMENT) {
933 filament_tab = tab;
934 break;
935 }
936 if (filament_tab != nullptr) {
937 const Page* overrides_page = nullptr;
938 for (const PageShp& page : filament_tab->m_pages)
939 if (page->title() == "Setting Overrides") {
940 overrides_page = page.get();
941 break;
942 }
943
944 if (overrides_page != nullptr) {
945 // Mixed-color slots are virtual: they carry no per-key Material/Retraction
946 // settings; their "Enable" toggle always embeds the mix definition (components,
947 // ratios, gradient). Detect them via the project-level flag.
948 const ConfigOptionBools* is_mixed_opt = full.opt<ConfigOptionBools>("filament_is_mixed");
949 // Only the slots the project actually uses: base/MMU-painted volume extruders,
950 // support/wall/infill overrides and custom-gcode tool changes, plus the physical
951 // components of any in-use mixed slot. Unused slots get no section at all (and are
952 // therefore never published). One section per used slot, disambiguated by its
953 // colour chip and slot identity while showing the bare name.
954 const std::set<size_t> used_slots = project_used_filament_slots(*bundle, full, wxGetApp().plater()->model());
955 for (size_t slot = 0; slot < bundle->filament_presets.size(); ++slot) {
956 if (used_slots.find(slot) == used_slots.end())
957 continue;
958 const bool is_mixed = is_mixed_opt != nullptr && slot < is_mixed_opt->size() && is_mixed_opt->values[slot];
959 const PublishMaterialIdentity identity = material_identity(slot, full);
960 // A mixed slot's title is its component composition (e.g. "1 (60%) + 2
961 // (40%)"), not the cloned preset's name shown in the main GUI.
962 const wxString title = is_mixed ? mixed_filament_label(full, slot) : material_title(slot, bundle, full);
963 const size_t category_index = category_index_for(title, Section::Material, g, slot, identity, is_mixed);
964
965 if (is_mixed) {
966 // A mixed slot publishes as one unit (its definition); nothing to select
967 // per-key. Its component filaments are auto-enabled + Full Published when
968 // "Enable" is checked (see on_enable_toggle). Its page still shows what
969 // would be published: a ratio bar, or the gradient graph.
970 add_mixed_visual(category_index, make_mixed_visual_spec(full, slot));
971 continue;
972 }
973
974 // Material requirement rows: an optional filament colour and/or a
975 // vendor-agnostic material type for this slot, in their own optgroup so they
976 // stay visually separated from the setting rows.
977 {
978 const size_t req_sub = subcategory_index_for(category_index, _L("Material"), "custom-gcode_filament");
979 add_row_ui("filament_colour", _L("Color"), from_u8(filament_color_hex(full, slot)), wxString(), category_index,
980 req_sub, RowKind::Color);
981 std::string type;
982 if (const auto* types = full.opt<ConfigOptionStrings>("filament_type"))
983 if (slot < types->size())
984 type = types->get_at(slot);
985 add_row_ui("filament_type", _L("Type"), from_u8(normalize_filament_type(type)), wxString(), category_index, req_sub,
987 }
988
989 // A material section must not repeat a key; the same key may appear in other
990 // material sections - that is intended.
991 std::set<std::string> material_added;
992
993 for (const ConfigOptionsGroupShp& optgroup : overrides_page->m_optgroups) {
994 // Allowlist on the untranslated optgroup title; "Ironing" is skipped.
995 if (optgroup->title != "Retraction" && optgroup->title != "Retraction when switching material")
996 continue;
997 for (const auto& opt : optgroup->opt_map()) {
998 // Row keys are base keys; the load side applies them positionally.
999 const std::string& opt_id = opt.first;
1000 std::string base = publish_base_key(opt_id);
1001 if (!material_added.insert(base).second)
1002 continue;
1003 // Show the value of this slot; fall back to slot 0 if out of range.
1004 std::string value_opt_id = base + "#" + std::to_string(slot);
1005 if (const ConfigOption* opt_cfg = full.option(base))
1006 if (const auto* vec = dynamic_cast<const ConfigOptionVectorBase*>(opt_cfg))
1007 if (vec->size() > 0 && slot >= vec->size())
1008 value_opt_id = base + "#0";
1009 wxString label, value, unit;
1010 if (!option_text(value_opt_id, base, label, value, unit))
1011 continue;
1012 size_t sub_index = subcategory_index_for(category_index, _(optgroup->title), optgroup->icon);
1013 add_row_ui(base, label, value, unit, category_index, sub_index);
1014 }
1015 }
1016 }
1017 }
1018 }
1019 }
1020
1021 // --- Phase 3: process (print) settings; grouping matches the process tab.
1022 {
1024 for (Tab* tab : wxGetApp().tabs_list) {
1025 if (tab->m_type != Preset::TYPE_PRINT)
1026 continue;
1027 size_t page_index = 0;
1028 for (const PageShp& page : tab->m_pages) {
1029 wxString category = Tab::translate_category(page->title(), tab->m_type);
1030 const size_t category_index = category_index_for(category, Section::Print, g, page_index);
1031
1032 for (const ConfigOptionsGroupShp& optgroup : page->m_optgroups) {
1033 for (const auto& opt : optgroup->opt_map()) {
1034 // opt_map() key is the opt_id (may carry "#N"); the value is
1035 // (pure_opt_key, opt_index).
1036 const std::string& opt_id = opt.first;
1037 const std::string& pure_key = opt.second.first;
1038 // A key may appear in more than one page/group; keep the first.
1039 if (!added.insert(pure_key).second)
1040 continue;
1041 wxString label, value, unit;
1042 if (!option_text(opt_id, pure_key, label, value, unit))
1043 continue;
1044 size_t sub_index = subcategory_index_for(category_index, _(optgroup->title), optgroup->icon);
1045 add_row_ui(opt_id, label, value, unit, category_index, sub_index);
1046 }
1047 }
1048 ++page_index;
1049 }
1050 }
1051 }
1052
1053 // Pre-check the dirty (modified) settings and mark them bold (per-slot match, across all
1054 // sections; collect_dirty_settings_keys unions the prints, printers and filaments).
1055 // Dirty keys carry a "#N" per-extruder/per-slot suffix (deep_diff), so the base key alone
1056 // cannot distinguish which extruder/filament slot changed: match the row's exact key, and
1057 // for material rows (base key + per-slot value) the base key plus the section's slot.
1058 std::set<std::string> dirty_keys;
1059 for (const std::string& key : collect_dirty_settings_keys(*wxGetApp().preset_bundle))
1060 dirty_keys.insert(key);
1061 for (Row& row : m_rows) {
1062 // The Color/Type requirement rows are not "dirty overrides": never auto-checked.
1063 if (row.kind != RowKind::Setting)
1064 continue;
1065 bool dirty = dirty_keys.count(row.key) != 0;
1066 if (!dirty && row.section == Section::Material)
1067 dirty = dirty_keys.count(publish_base_key(row.key) + "#" + std::to_string(m_categories[row.inner_index].filament_slot)) != 0;
1068 row.dirty = dirty;
1069 if (row.dirty) {
1070 row.check->SetValue(true);
1071 set_row_bold(row, true);
1072 }
1073 }
1074
1075 // Wire the "Enable" checkboxes: toggling one reveals/hides the slot's settings below the
1076 // header (and, for a mixed slot, auto-selects its components). Bind by index so the lambda
1077 // stays valid even if the vector is reallocated later.
1078 for (size_t c = 0; c < m_categories.size(); ++c)
1079 if (m_categories[c].enable_check != nullptr)
1080 m_categories[c].enable_check->Bind(wxEVT_TOGGLEBUTTON, [this, c](wxCommandEvent& event) {
1082 event.Skip();
1083 });
1084
1085 // Wire the "Full Publish" checkboxes (physical slots): toggling one disables/enables the
1086 // material's rows.
1087 for (size_t c = 0; c < m_categories.size(); ++c)
1088 if (m_categories[c].full_check != nullptr)
1089 m_categories[c].full_check->Bind(wxEVT_TOGGLEBUTTON, [this, c](wxCommandEvent& event) {
1090 on_full_toggle(c);
1091 event.Skip();
1092 });
1093
1094 // No filter is active at startup: every row matches until the user types.
1095 for (Row& row : m_rows)
1096 row.matches_filter = true;
1098
1099 for (Category& category : m_categories) {
1100 category.scroll->FitInside();
1101 category.list_sizer->Layout();
1102 }
1103 for (SectionGroup& section : m_sections)
1104 if (!section.categories.empty())
1105 section.tabs->SelectItem(0);
1106 // Orca: the Printer section shows its extruders on the same switch as the printer tab's Extruder page.
1107 for (size_t s = 0; s < m_sections.size(); ++s)
1108 if (m_sections[s].kind == Section::Printer && m_sections[s].categories.size() > 1)
1110 if (!m_sections.empty()) {
1111 m_outer_tabs->SelectItem(0);
1112 show_outer_page(0);
1113 }
1115}
#define _(s)
Definition 3mf.cpp:306
const ConfigOptionDef * get(const t_config_option_key &opt_key) const
Definition Config.hpp:2662
void add_row_ui(const std::string &key, const wxString &label, const wxString &value, const wxString &unit, size_t category_index, size_t subcategory_index, RowKind kind=RowKind::Setting)
Definition PublishSettingsDialog.cpp:1334
wxString m_info_mix
Definition PublishSettingsDialog.hpp:305
size_t subcategory_index_for(size_t category_index, const wxString &title, const wxString &icon)
Definition PublishSettingsDialog.cpp:1313
Section
Definition PublishSettingsDialog.hpp:95
static MixedVisualSpec make_mixed_visual_spec(const Slic3r::DynamicPrintConfig &full, size_t slot)
Definition PublishSettingsDialog.cpp:598
size_t section_group_for(Section kind)
Definition PublishSettingsDialog.cpp:1117
void bind_tab_events()
Definition PublishSettingsDialog.cpp:1726
wxString m_info_empty
Definition PublishSettingsDialog.hpp:304
void setup_variant_switch(size_t section_index)
Definition PublishSettingsDialog.cpp:1653
wxString m_info_nonsel
Definition PublishSettingsDialog.hpp:302
void add_mixed_visual(size_t category_index, const MixedVisualSpec &spec)
Definition PublishSettingsDialog.cpp:1438
wxString m_info_allsel
Definition PublishSettingsDialog.hpp:303
size_t category_index_for(const wxString &title, Section section, size_t group, size_t source_index, const PublishMaterialIdentity &identity=PublishMaterialIdentity(), bool is_mixed=false)
Definition PublishSettingsDialog.cpp:1178
void set_row_bold(Row &row, bool bold)
Definition PublishSettingsDialog.cpp:1590
void show_outer_page(size_t section_index)
Definition PublishSettingsDialog.cpp:1602
Definition PublishSettingsDialog.hpp:192
static wxString translate_category(const wxString &title, Preset::Type preset_type, bool translate=true)
Definition Tab.cpp:823
@ TYPE_PRINT
Definition Preset.hpp:246
@ TYPE_FILAMENT
Definition Preset.hpp:248
wxString material_title(size_t slot, const PresetBundle *bundle, const DynamicPrintConfig &full)
Definition PublishSettingsDialog.cpp:160
PublishMaterialIdentity material_identity(size_t slot, const DynamicPrintConfig &full)
Definition PublishSettingsDialog.cpp:132
std::set< size_t > project_used_filament_slots(const PresetBundle &bundle, const DynamicPrintConfig &full, const Model &model)
Definition PublishSettingsDialog.cpp:382
wxString mixed_filament_label(const DynamicPrintConfig &full, size_t slot)
Definition PublishSettingsDialog.cpp:189
std::string filament_color_hex(const DynamicPrintConfig &full, size_t slot)
Definition PublishSettingsDialog.cpp:124
static Plater * plater()
Definition GUI_Factories.cpp:400
std::shared_ptr< Page > PageShp
Definition Tab.hpp:150
std::shared_ptr< ConfigOptionsGroup > ConfigOptionsGroupShp
Definition BedShapeDialog.hpp:31
wxString get_string_value(const std::string &opt_key, const DynamicPrintConfig &config)
Definition ConfigValueFormatter.cpp:73
wxString from_u8(const std::string &str)
Definition GUI.cpp:544
Transform< N, T > identity()
Definition Point.hpp:106
std::vector< std::string > collect_dirty_settings_keys(const PresetBundle &bundle)
Definition PublishSettings.cpp:178
const PrintConfigDef print_config_def
Definition PrintConfig.cpp:10099
ConfigOptionBoolsTempl< false > ConfigOptionBools
Definition Config.hpp:2066
const std::set< std::string > & publish_structural_keys()
Definition PublishSettings.cpp:90
std::string normalize_filament_type(const std::string &type)
Definition PublishSettings.cpp:47

References _, _L, add_mixed_visual(), add_row_ui(), apply_visibility(), bind_tab_events(), category_index_for(), Slic3r::collect_dirty_settings_keys(), Color, Slic3r::PresetBundle::filament_presets, Slic3r::GUI::from_u8(), Slic3r::PresetBundle::full_config(), Slic3r::ConfigOptionDef::full_label, Slic3r::GUI::get_string_value(), Slic3r::identity(), Slic3r::ConfigOptionDef::label, m_categories, m_info_allsel, m_info_empty, m_info_mix, m_info_nonsel, Slic3r::GUI::Page::m_optgroups, m_outer_tabs, Slic3r::GUI::Tab::m_pages, m_rows, m_sections, make_mixed_visual_spec(), Material, Slic3r::normalize_filament_type(), on_enable_toggle(), on_full_toggle(), Slic3r::DynamicConfig::opt(), Slic3r::ConfigBase::option(), Slic3r::GUI::plater(), Print, Slic3r::print_config_def, Printer, Slic3r::publish_base_key(), Slic3r::publish_structural_keys(), refresh_tab_indicators(), section_group_for(), set_row_bold(), Setting, setup_variant_switch(), show_outer_page(), Slic3r::ConfigOptionDef::sidetext, Slic3r::ConfigOptionVector< unsigned char >::size(), subcategory_index_for(), Slic3r::GUI::Tab::translate_category(), Type, Slic3r::Preset::TYPE_FILAMENT, Slic3r::Preset::TYPE_PRINT, and Slic3r::ConfigOptionVector< unsigned char >::values.

Referenced by PublishSettingsDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ category_has_selection()

bool Slic3r::GUI::PublishSettingsDialog::category_has_selection ( const Category & cat) const
private
2205{
2206 // A material slot publishes (or not) as a whole, gated by "Enable".
2207 if (cat.section == Section::Material)
2208 return cat.enable_check != nullptr && cat.enable_check->GetValue();
2209 // Print/Printer categories have no gate: any checked row counts.
2210 for (const size_t r : cat.rows)
2211 if (m_rows[r].check->GetValue())
2212 return true;
2213 return false;
2214}
bool check(ModelVolumeType volume_type)
Definition GLGizmoEmboss.cpp:515

References Slic3r::GUI::PublishSettingsDialog::Category::enable_check, m_rows, Material, Slic3r::GUI::PublishSettingsDialog::Category::rows, and Slic3r::GUI::PublishSettingsDialog::Category::section.

Referenced by refresh_tab_indicators().

Here is the caller graph for this function:

◆ category_index_for()

size_t Slic3r::GUI::PublishSettingsDialog::category_index_for ( const wxString & title,
Section section,
size_t group,
size_t source_index,
const PublishMaterialIdentity & identity = PublishMaterialIdentity(),
bool is_mixed = false )
private
1180{
1181 // Dedup across both tab rows (physical + mixed); mixed slots are never duplicated anyway.
1182 auto match = [&](const Category& existing) {
1183 return existing.title == title && existing.section == section && existing.source_index == source_index &&
1184 existing.filament_id == identity.id && existing.filament_type == identity.type &&
1185 existing.filament_vendor == identity.vendor;
1186 };
1187 for (size_t i : m_sections[group].categories)
1188 if (match(m_categories[i]))
1189 return i;
1190 for (size_t i : m_sections[group].mixed_categories)
1191 if (match(m_categories[i]))
1192 return i;
1193
1194 Category category;
1195 category.title = title;
1196 category.section = section;
1197 category.group = group;
1198 category.source_index = source_index;
1199 category.filament_type = identity.type;
1200 category.filament_vendor = identity.vendor;
1201 category.filament_id = identity.id;
1202 category.filament_slot = source_index;
1203 category.is_mixed = is_mixed;
1204 category.page = new wxPanel(m_sections[group].page_host, wxID_ANY);
1205 category.page->SetBackgroundColour(GetBackgroundColour());
1206 auto* page_sizer = new wxBoxSizer(wxVERTICAL);
1207
1208 // The physical slot's colour chip decorates the page header and the inner tab; it carries
1209 // the 1-based slot number, mirroring the main GUI's filament swatches. A mixed slot has no
1210 // header at all: its page is just the Enable toggle above the (always visible) definition
1211 // preview - the identification lives in the tab strip's composition bitmap.
1212 std::string hex;
1213 std::string chip_label;
1214 if (section == Section::Material && !is_mixed) {
1215 const DynamicPrintConfig full = wxGetApp().preset_bundle->full_config();
1216 hex = filament_color_hex(full, source_index);
1217 chip_label = std::to_string(source_index + 1);
1218 }
1219
1220 if (section == Section::Material) {
1221 if (is_mixed) {
1222 // No chip/title: the lone "Enable" checkbox tops the page.
1223 auto* enable_sizer = new wxBoxSizer(wxHORIZONTAL);
1224 category.enable_check = new ::CheckBox(category.page, wxID_ANY);
1225 category.enable_label = add_checkbox_label(category.page, enable_sizer, category.enable_check, _L("Enable"),
1226 _L("Publish this mixed filament and enable + Full Publish its component filaments"));
1227 page_sizer->Add(enable_sizer, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(6));
1228 } else {
1229 // Line 1: [chip] [title] [Enable]. The Enable checkbox gates the whole slot: while
1230 // it is unchecked nothing below the title is shown and nothing of it is published.
1231 auto* header_sizer = new wxBoxSizer(wxHORIZONTAL);
1232 if (wxBitmap* chip = get_extruder_color_icon(hex, chip_label, FromDIP(20), FromDIP(20))) {
1233 category.filament_color_chip = new wxStaticBitmap(category.page, wxID_ANY, *chip);
1234 header_sizer->Add(category.filament_color_chip, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(4));
1235 }
1236 category.title_label = new wxStaticText(category.page, wxID_ANY, title);
1237 category.title_label->SetFont(Label::Head_14);
1238 header_sizer->Add(category.title_label, 0, wxALIGN_CENTER_VERTICAL);
1239 auto* enable_sizer = new wxBoxSizer(wxHORIZONTAL);
1240 category.enable_check = new ::CheckBox(category.page, wxID_ANY);
1241 category.enable_label = add_checkbox_label(category.page, enable_sizer, category.enable_check, _L("Enable"),
1242 _L("Publish this filament slot in the 3MF file"));
1243 header_sizer->Add(enable_sizer, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(10));
1244 page_sizer->Add(header_sizer, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(6));
1245
1246 // Line 2: the "Full Publish" toggle, on its own line below the title (hidden until
1247 // the slot is enabled), aligned with the colour chip above it.
1248 auto* full_sizer = new wxBoxSizer(wxHORIZONTAL);
1249 category.full_check = new ::CheckBox(category.page, wxID_ANY);
1250 category.full_label = add_checkbox_label(category.page, full_sizer, category.full_check, _L("Full Publish"),
1251 _L("Embed the entire filament of this slot in the 3MF file"));
1252 category.full_line_item = page_sizer->Add(full_sizer, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, FromDIP(6));
1253 }
1254 }
1255
1256 category.scroll = new wxScrolledWindow(category.page, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
1257 category.scroll->SetScrollRate(0, FromDIP(20));
1258 category.scroll->SetBackgroundColour(GetBackgroundColour());
1259 category.list_sizer = new wxBoxSizer(wxVERTICAL);
1260 category.scroll->SetSizer(category.list_sizer);
1261 category.scroll->DisableFocusFromKeyboard();
1262 category.scroll->Bind(wxEVT_RIGHT_DOWN, &PublishSettingsDialog::show_menu, this);
1263 category.info = new wxStaticText(category.scroll, wxID_ANY, is_mixed ? m_info_mix : m_info_empty);
1264 category.info->SetFont(Label::Body_13);
1265 category.list_sizer->Add(category.info, 1, wxALIGN_CENTER_HORIZONTAL | wxALL, FromDIP(10));
1266 category.info->Hide();
1267 page_sizer->Add(category.scroll, 1, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(4));
1268 // A material slot starts disabled: its rows (and its Full Publish line) stay hidden until
1269 // "Enable" is checked.
1270 if (section == Section::Material)
1271 category.scroll->Hide();
1272 category.page->SetSizer(page_sizer);
1273 category.page->Hide();
1274
1275 const size_t category_index = m_categories.size();
1276 m_categories.push_back(std::move(category));
1277 // Mixed slots live in a second tab row below the physical filament tabs.
1278 if (is_mixed)
1279 m_sections[group].mixed_categories.push_back(category_index);
1280 else
1281 m_sections[group].categories.push_back(category_index);
1282 if (section == Section::Material) {
1283 TabCtrl* target = is_mixed ? m_sections[group].mixed_tabs : m_sections[group].tabs;
1284 if (is_mixed) {
1285 // The tab's whole composition (mix chip + components + percents) lives in one
1286 // bitmap; the text is empty because a TabCtrl item cannot interleave images into
1287 // its text.
1288 const DynamicPrintConfig full_cfg = wxGetApp().preset_bundle->full_config();
1289 const wxBitmap tab_bmp = mixed_filament_tab_bitmap(full_cfg, source_index, FromDIP(20), target->GetBackgroundColour());
1290 if (tab_bmp.IsOk())
1291 target->AppendItem(wxString(), tab_bmp);
1292 else
1293 target->AppendItem(title);
1294 } else if (wxBitmap* chip = get_extruder_color_icon(hex, chip_label, FromDIP(20), FromDIP(20))) {
1295 target->AppendItem(title, *chip);
1296 } else {
1297 target->AppendItem(title);
1298 }
1299 } else {
1300 m_sections[group].tabs->AppendItem(title);
1301 }
1302 m_sections[group].page_host_sizer->Add(m_categories[category_index].page, 1, wxEXPAND);
1303 if (is_mixed) {
1304 if (m_sections[group].selected_mixed < 0)
1305 m_sections[group].selected_mixed = 0;
1306 m_sections[group].mixed_tabs->Show();
1307 } else if (m_sections[group].selected_inner < 0) {
1308 m_sections[group].selected_inner = 0;
1309 }
1310 return category_index;
1311}
static wxFont Head_14
Definition Label.hpp:45
wxString title
Definition PublishSettingsDialog.hpp:140
int AppendItem(const wxString &item, int image=-1, int selImage=-1, void *clientData=nullptr)
Definition TabCtrl.cpp:103
wxBitmap mixed_filament_tab_bitmap(const DynamicPrintConfig &full, size_t slot, int swatch_sz, const wxColour &tab_bg)
Definition PublishSettingsDialog.cpp:280

References _L, TabCtrl::AppendItem(), Label::Body_13, Slic3r::GUI::PublishSettingsDialog::Category::enable_check, Slic3r::GUI::PublishSettingsDialog::Category::enable_label, Slic3r::GUI::PublishSettingsDialog::Category::filament_color_chip, Slic3r::GUI::PublishSettingsDialog::Category::filament_id, Slic3r::GUI::PublishSettingsDialog::Category::filament_slot, Slic3r::GUI::PublishSettingsDialog::Category::filament_type, Slic3r::GUI::PublishSettingsDialog::Category::filament_vendor, Slic3r::GUI::PublishSettingsDialog::Category::full_check, Slic3r::GUI::PublishSettingsDialog::Category::full_label, Slic3r::GUI::PublishSettingsDialog::Category::full_line_item, get_extruder_color_icon(), Slic3r::GUI::PublishSettingsDialog::Category::group, Label::Head_14, Slic3r::identity(), Slic3r::GUI::PublishSettingsDialog::Category::info, Slic3r::GUI::PublishSettingsDialog::Category::is_mixed, Slic3r::GUI::PublishSettingsDialog::Category::list_sizer, m_categories, m_info_empty, m_info_mix, m_sections, Material, Slic3r::GUI::PublishSettingsDialog::Category::page, Slic3r::GUI::PublishSettingsDialog::Category::scroll, Slic3r::GUI::PublishSettingsDialog::Category::section, show_menu(), Slic3r::GUI::PublishSettingsDialog::Category::source_index, Slic3r::GUI::PublishSettingsDialog::Category::title, Slic3r::GUI::PublishSettingsDialog::Category::title_label, and wxStaticText.

Referenced by build_option_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ em_unit()

int Slic3r::GUI::DPIAware< wxDialog >::em_unit ( ) const
inlineinherited
203{ return m_em_unit; }
Definition GUI_Utils.hpp:107

Referenced by Slic3r::GUI::AuxiliaryDialog::AuxiliaryDialog(), Slic3r::GUI::CopyrightsDialog::CopyrightsDialog(), Slic3r::GUI::DesignTextDialog::DesignTextDialog(), Slic3r::GUI::EditGCodeDialog::EditGCodeDialog(), Slic3r::GUI::FileArchiveDialog::FileArchiveDialog(), Slic3r::GUI::MsgNoUpdates::MsgNoUpdates(), Slic3r::GUI::MsgUpdateForced::MsgUpdateForced(), Slic3r::GUI::OAuthDialog::OAuthDialog(), Slic3r::GUI::ParamsDialog::ParamsDialog(), Slic3r::GUI::PhysicalPrinterDialog::PhysicalPrinterDialog(), Slic3r::GUI::SettingsDialog::SettingsDialog(), anonymous_namespace{3DPrinterOS.cpp}::TokenAuthDialog::TokenAuthDialog(), anonymous_namespace{3DPrinterOS.cpp}::UploadOptionsDialog::UploadOptionsDialog(), Slic3r::GUI::PublishSettingsDialog::add_row_ui(), Slic3r::GUI::DiffPresetDialog::complete_dialog_creation(), Slic3r::GUI::DiffPresetDialog::create_edit_sizer(), Slic3r::GUI::DiffPresetDialog::create_presets_sizer(), Slic3r::GUI::DiffPresetDialog::create_tree(), Slic3r::GUI::ElegooPrintHostSendDialog::init(), Slic3r::GUI::FlashforgePrintHostSendDialog::init(), Slic3r::GUI::PrintHostSendDialog::init(), Slic3r::GUI::AboutDialog::on_dpi_changed(), Slic3r::GUI::AuxiliaryDialog::on_dpi_changed(), Slic3r::GUI::BedShapeDialog::on_dpi_changed(), Slic3r::GUI::ConfigWizard::on_dpi_changed(), Slic3r::GUI::CopyrightsDialog::on_dpi_changed(), Slic3r::GUI::DiffPresetDialog::on_dpi_changed(), Slic3r::GUI::EditGCodeDialog::on_dpi_changed(), Slic3r::GUI::FileArchiveDialog::on_dpi_changed(), Slic3r::GUI::OAuthDialog::on_dpi_changed(), Slic3r::GUI::ObjectTableDialog::on_dpi_changed(), Slic3r::GUI::ParamsDialog::on_dpi_changed(), Slic3r::GUI::PhysicalPrinterDialog::on_dpi_changed(), Slic3r::GUI::PrintHostQueueDialog::on_dpi_changed(), Slic3r::GUI::PurgeModeDialog::on_dpi_changed(), Slic3r::GUI::SavePresetDialog::on_dpi_changed(), Slic3r::GUI::SendSystemInfoDialog::on_dpi_changed(), Slic3r::GUI::SettingsDialog::on_dpi_changed(), and Slic3r::GUI::UnsavedChangesDialog::on_dpi_changed().

Here is the caller graph for this function:

◆ enable_force_rescale()

void Slic3r::GUI::DPIAware< wxDialog >::enable_force_rescale ( )
inlineinherited
206{ m_force_rescale = true; }

◆ EndModal()

void Slic3r::GUI::DPIDialog::EndModal ( int retCode)
inlineoverrideinherited
306 {
307 if (!dialogStack.empty() && dialogStack.front() != this) {
308 // This is a bug in wxWidgets
309 // when the dialog is not top modal dialog, EndModal() just hide dialog without quit
310 // the modal event loop. And the modal event loop blocks us from bottom widgets.
311 // Solution: let user click it manually or close outside. FIXME
312 BOOST_LOG_TRIVIAL(warning) << "DPIAware::EndModal Error: dialogStack is not empty, but top dialog is not this one. retCode=" << retCode;
313 return;
314 }
315
316 return wxDialog::EndModal(retCode);
317 }
std::deque< wxDialog * > dialogStack
Definition GUI_Utils.cpp:549

References Slic3r::GUI::dialogStack.

Referenced by Slic3r::GUI::CloneDialog::CloneDialog(), Slic3r::GUI::ConfigWizard::ConfigWizard(), Slic3r::GUI::CreatePresetSuccessfulDialog::CreatePresetSuccessfulDialog(), Slic3r::GUI::DeleteConfirmDialog::DeleteConfirmDialog(), Slic3r::GUI::DesignVariableDialog::DesignVariableDialog(), Slic3r::GUI::anonymous_namespace{PrintHostDialogs.cpp}::FlashforgeSlotDialog::FlashforgeSlotDialog(), Slic3r::GUI::GuideFrame::GuideFrame(), Slic3r::GUI::InputIpAddressDialog::InputIpAddressDialog(), Slic3r::GUI::ManualNozzleCountDialog::ManualNozzleCountDialog(), Slic3r::GUI::MsgUpdateConfig::MsgUpdateConfig(), Slic3r::GUI::MsgUpdateForced::MsgUpdateForced(), Slic3r::GUI::MultiChoiceDialog::MultiChoiceDialog(), Slic3r::GUI::NetworkErrorDialog::NetworkErrorDialog(), Slic3r::GUI::NetworkPluginRestartDialog::NetworkPluginRestartDialog(), Slic3r::GUI::PartSkipConfirmDialog::PartSkipConfirmDialog(), Slic3r::GUI::PhysicalPrinterDialog::PhysicalPrinterDialog(), Slic3r::GUI::PlateNameEditDialog::PlateNameEditDialog(), Slic3r::GUI::PlateSettingsDialog::PlateSettingsDialog(), Slic3r::GUI::PublishSettingsDialog::PublishSettingsDialog(), Slic3r::GUI::SelectMachineDialog::SelectMachineDialog(), Slic3r::GUI::SendFailedConfirm::SendFailedConfirm(), Slic3r::GUI::SendSystemInfoDialog::SendSystemInfoDialog(), Slic3r::GUI::ShortcutCaptureDialog::ShortcutCaptureDialog(), Slic3r::GUI::SingleChoiceDialog::SingleChoiceDialog(), StepMeshDialog::StepMeshDialog(), Slic3r::GUI::SyncAmsInfoDialog::SyncAmsInfoDialog(), anonymous_namespace{3DPrinterOS.cpp}::TokenAuthDialog::TokenAuthDialog(), Slic3r::GUI::UpdatePluginDialog::UpdatePluginDialog(), Slic3r::GUI::UpdateVersionDialog::UpdateVersionDialog(), Slic3r::GUI::wgtDeviceNozzleRackUpgradeDlg::wgtDeviceNozzleRackUpgradeDlg(), Slic3r::GUI::SavePresetDialog::accept(), Slic3r::GUI::MsgDialog::add_button(), Slic3r::GUI::TipsDialog::add_button(), Slic3r::GUI::FilamentPickerDialog::BindEvents(), Slic3r::GUI::PluginPickerDialog::build_capability_ui(), Slic3r::GUI::BedShapeDialog::build_dialog(), Slic3r::GUI::PluginPickerDialog::build_ui(), Slic3r::GUI::UnsavedChangesDialog::close(), Slic3r::GUI::FileArchiveDialog::create_btn_sizer(), Slic3r::GUI::ColorDecomposeDialog::create_button_panel(), Slic3r::GUI::MixedFilamentDialog::create_button_panel(), Slic3r::GUI::CreateFilamentPresetDialog::create_dialog_buttons(), Slic3r::GUI::CreatePresetForPrinterDialog::create_dialog_buttons(), Slic3r::GUI::EditFilamentPresetDialog::create_dialog_buttons(), Slic3r::GUI::ExportConfigsDialog::create_dialog_buttons(), Slic3r::GUI::PreferencesDialog::create_item_language_combobox(), Slic3r::GUI::PreferencesDialog::create_item_region_combobox(), Slic3r::GUI::PreferencesDialog::create_items(), Slic3r::GUI::CreatePrinterPresetDialog::create_page1_dialog_buttons(), Slic3r::GUI::CreatePrinterPresetDialog::create_page2_dialog_buttons(), Slic3r::GUI::ExportConfigsDialog::data_init(), Slic3r::GUI::WebDialog::destroy_silently(), Slic3r::GUI::EditFilamentPresetDialog::edit_preset(), Slic3r::GUI::ConnectPrinterDialog::end_modal(), Slic3r::GUI::PrintHostSendDialog::EndModal(), Slic3r::GUI::ColorPickerDialog::finish(), Slic3r::GUI::WebDialog::finish(), Slic3r::GUI::Newer3mfVersionDialog::get_btn_sizer(), Slic3r::GUI::ScoreDialog::get_button_sizer(), Slic3r::GUI::WebViewHostDialog::handle_common_script_command(), Slic3r::GUI::ExportPresetBundleDialog::InitExportData(), Slic3r::GUI::SelectMachineDialog::navigate_to_timelapse_page(), Slic3r::GUI::BindMachineDialog::on_bind_success(), Slic3r::GUI::ConnectPrinterDialog::on_button_confirm(), Slic3r::GUI::RecenterDialog::on_button_confirm(), Slic3r::GUI::BindMachineDialog::on_cancel(), Slic3r::GUI::EditCalibrationHistoryDialog::on_cancel(), Slic3r::GUI::InputIpAddressDialog::on_cancel(), Slic3r::GUI::NewCalibrationHistoryDialog::on_cancel(), Slic3r::GUI::OAuthDialog::on_cancel(), Slic3r::GUI::PingCodeBindDialog::on_cancel(), Slic3r::GUI::SelectMachineDialog::on_cancel(), Slic3r::GUI::SendToPrinterDialog::on_cancel(), Slic3r::GUI::SyncAmsInfoDialog::on_cancel(), Slic3r::GUI::UnBindMachineDialog::on_cancel(), Slic3r::GUI::WebDialog::on_close_window(), Slic3r::GUI::NetworkPluginDownloadDialog::on_dont_ask(), Slic3r::GUI::NetworkPluginDownloadDialog::on_download(), Slic3r::GUI::EditDevNameDialog::on_edit_name(), Slic3r::GUI::ConfirmBeforeSendDialog::on_hide(), Slic3r::GUI::PrivacyUpdateDialog::on_hide(), Slic3r::GUI::ShortcutCaptureDialog::on_key(), Slic3r::GUI::TextureImportDialog::on_ok_clicked(), Slic3r::GUI::FileArchiveDialog::on_open_button(), Slic3r::GUI::NetworkPluginDownloadDialog::on_remind_later(), Slic3r::GUI::ProjectDropDialog::on_select_cancel(), Slic3r::GUI::SavePresetDialog::on_select_cancel(), Slic3r::GUI::ProjectDropDialog::on_select_ok(), Slic3r::GUI::SendMultiMachinePage::on_send(), Slic3r::GUI::NetworkPluginDownloadDialog::on_skip(), Slic3r::GUI::TextureImportDialog::on_skip_clicked(), Slic3r::GUI::NetworkPluginDownloadDialog::on_skip_version(), Slic3r::GUI::Cornering_Test_Dlg::on_start(), Slic3r::GUI::FlowRateCalibrationDialog::on_start(), Slic3r::GUI::Input_Shaping_Damp_Test_Dlg::on_start(), Slic3r::GUI::Input_Shaping_Freq_Test_Dlg::on_start(), Slic3r::GUI::MaxVolumetricSpeed_Test_Dlg::on_start(), Slic3r::GUI::PA_Calibration_Dlg::on_start(), Slic3r::GUI::Retraction_Test_Dlg::on_start(), Slic3r::GUI::Temp_Calibration_Dlg::on_start(), Slic3r::GUI::VFA_Test_Dlg::on_start(), Slic3r::GUI::CalibrationDialog::on_start_calibration(), Slic3r::GUI::UnBindMachineDialog::on_unbind_printer(), Slic3r::GUI::PartSkipDialog::OnApplyDialog(), anonymous_namespace{3DPrinterOS.cpp}::TokenAuthDialog::OnCancel(), Slic3r::GUI::AboutDialog::onCloseDialog(), Slic3r::GUI::CopyrightsDialog::onCloseDialog(), Slic3r::GUI::MultiNozzleSyncDialog::OnRackStatusReadingFinished(), Slic3r::GUI::GuideFrame::OnScriptMessage(), Slic3r::GUI::InputIpAddressDialog::OnTimer(), Slic3r::GUI::KBShortcutsDialog::open_mouse_preferences(), Slic3r::GUI::TroubleshootDialog::PackAll(), Slic3r::GUI::TroubleshootDialog::RebuildSystemProfiles(), Slic3r::GUI::SpeedDialWebDialog::run_action(), Slic3r::GUI::OAuthDialog::Show(), Slic3r::GUI::MultiNozzleSyncDialog::UpdateButton(), and Slic3r::GUI::CreatePrinterPresetDialog::validate_input_valid().

◆ fit_to_content()

void Slic3r::GUI::PublishSettingsDialog::fit_to_content ( )
private
805{
806 static const wxSize BASE{530, 530}; // base size in DIP, the minimum the dialog can shrink to
807 static const wxSize CAP{1300, 850}; // hard cap in DIP, the maximum the dialog can grow to
808
809 int strip = m_outer_tabs->GetFullSize();
810 for (const SectionGroup& section : m_sections) {
811 strip = std::max(strip, section.tabs->GetFullSize());
812 if (section.mixed_tabs != nullptr)
813 strip = std::max(strip, section.mixed_tabs->GetFullSize());
814 }
815
816 // Minimum width: whatever keeps every tab visible (never below the base). strip is device
817 // pixels (Button min sizes); BASE/CAP are DIP and converted over.
818 const int min_w = std::max(strip + 2 * FromDIP(10), FromDIP(BASE.x));
819
820 // Initial size: prefer proportional growth within the caps.
821 const int w = std::clamp(min_w, FromDIP(BASE.x), FromDIP(CAP.x));
822 const double f = double(w) / FromDIP(BASE.x);
823 const int h = std::clamp(int(FromDIP(BASE.y) * f), FromDIP(BASE.y), FromDIP(CAP.y));
824
825 const wxRect area = wxDisplay(this).GetClientArea();
826 const int max_w = area.width * 9 / 10;
827 const int max_h = area.height * 9 / 10;
828
829 SetMinSize(wxSize(std::min(min_w, max_w), std::min(FromDIP(BASE.y), max_h)));
830 SetSize(std::min(w, max_w), std::min(h, max_h));
831}
double area(const ExPolygon &poly)
Definition ExPolygon.hpp:511
static double f(double x, double z_sin, double z_cos, bool vertical, bool flip)
Definition FillGyroid.cpp:124

References Slic3r::area(), Slic3r::f(), m_outer_tabs, and m_sections.

Referenced by PublishSettingsDialog(), and on_dpi_changed().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ force_rescale()

bool Slic3r::GUI::DPIAware< wxDialog >::force_rescale ( ) const
inlineinherited
201{ return m_force_rescale; }

◆ full_keys_for_slot()

std::vector< std::string > Slic3r::GUI::PublishSettingsDialog::full_keys_for_slot ( ) const
private
2246{
2247 // The canonical filament preset keys minus the structural keys the published overlay must
2248 // never touch (inherits, compatibility, *_settings_id, ...), plus filament_colour (not a
2249 // member of Preset::filament_options). Values travel in the exported config, masked to
2250 // this slot, and are applied on load onto the receiver's slot.
2251 const std::set<std::string>& denylist = publish_structural_keys();
2252 std::vector<std::string> keys;
2253 for (const std::string& key : Preset::filament_options())
2254 if (denylist.count(key) == 0)
2255 keys.emplace_back(key);
2256 keys.emplace_back("filament_colour");
2257 return keys;
2258}
static const std::vector< std::string > & filament_options()
Definition Preset.cpp:1706

References Slic3r::Preset::filament_options(), and Slic3r::publish_structural_keys().

Referenced by GetPublishedMaterialKeys().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetPublishedKeys()

std::vector< std::string > Slic3r::GUI::PublishSettingsDialog::GetPublishedKeys ( ) const
2053{
2054 std::vector<std::string> out;
2055 // Process and printer sections both travel through published_keys (the load-side overlay
2056 // applies process keys to the prints edited preset and the allowlisted printer keys to the
2057 // printers edited preset); material keys use a separate API. Printer rows carry the full
2058 // per-extruder "#N" opt_id (built in Phase 1), so a checked row publishes exactly that
2059 // extruder's value - per-extruder selection is independent.
2060 for (const Row& row : m_rows) {
2061 if ((row.section != Section::Print && row.section != Section::Printer) || !row.check->GetValue())
2062 continue;
2063 out.push_back(row.key);
2064 }
2065 return out;
2066}

References m_rows, Print, and Printer.

Referenced by Slic3r::GUI::MainFrame::publish_project().

Here is the caller graph for this function:

◆ GetPublishedMaterialKeys()

std::vector< Slic3r::PublishedMaterialEntry > Slic3r::GUI::PublishSettingsDialog::GetPublishedMaterialKeys ( ) const
2121{
2122 std::vector<Slic3r::PublishedMaterialEntry> out;
2123 for (const Category& cat : m_categories) {
2124 if (cat.section != Section::Material)
2125 continue;
2126 // A slot that is not "Enable"d publishes nothing at all.
2127 if (cat.enable_check != nullptr && !cat.enable_check->GetValue())
2128 continue;
2129 Slic3r::PublishedMaterialEntry entry;
2130 entry.filament_type = cat.filament_type;
2131 entry.filament_vendor = cat.filament_vendor;
2132 entry.filament_id = cat.filament_id;
2133 entry.slot = static_cast<int>(cat.filament_slot);
2134 // The author's preset id distinguishes exact variants that share filament_id
2135 // ("Generic PLA" vs "Generic PLA Matte"), so the receiver can match precisely; the
2136 // preset name is the most direct identity and is matched first on load.
2137 PresetBundle* bundle = wxGetApp().preset_bundle;
2138 if (bundle != nullptr && cat.filament_slot < bundle->filament_presets.size()) {
2139 if (const Preset* preset = bundle->filaments.find_preset(bundle->filament_presets[cat.filament_slot], false, true)) {
2140 entry.setting_id = preset->setting_id;
2141 entry.preset_name = preset->name;
2142 }
2143 }
2144 // A mixed slot publishes as one unit: its definition (components, ratios, gradient)
2145 // always travels (its Enable implies this), and the component filaments are enabled +
2146 // Full Published by on_enable_toggle into their own entries.
2147 if (cat.is_mixed) {
2148 Slic3r::PublishedMaterialEntry mixed_entry;
2149 mixed_entry.filament_type = cat.filament_type;
2150 mixed_entry.filament_vendor = cat.filament_vendor;
2151 mixed_entry.filament_id = cat.filament_id;
2152 mixed_entry.slot = static_cast<int>(cat.filament_slot);
2153 // The mix's own colour (blended) is a property of the definition, not a
2154 // requirement row; carry it so the receiver renders the swatch.
2155 const DynamicPrintConfig full_cfg = wxGetApp().preset_bundle->full_config();
2156 const std::string mix_color = filament_color_hex(full_cfg, cat.filament_slot);
2157 if (!mix_color.empty()) {
2158 mixed_entry.publish_color = true;
2159 mixed_entry.color = mix_color;
2160 }
2161 for (const std::string& key : publish_mixed_keys())
2162 mixed_entry.keys.emplace_back(key);
2163 out.push_back(std::move(mixed_entry));
2164 continue;
2165 }
2166 // "Full Publish": the whole filament preset is embedded; type and colour are implicitly
2167 // published, and the per-key rows are disabled / their state ignored.
2168 if (cat.full_check != nullptr && cat.full_check->GetValue()) {
2169 entry.full = true;
2170 entry.full_keys = full_keys_for_slot();
2171 entry.publish_type = true;
2172 entry.publish_type_value = normalize_filament_type(cat.filament_type);
2173 for (size_t r : cat.rows) {
2174 const Row& row = m_rows[r];
2175 if (row.kind == RowKind::Color && !row.value.IsEmpty()) {
2176 entry.publish_color = true;
2177 entry.color = row.value.ToStdString();
2178 }
2179 }
2180 out.push_back(std::move(entry));
2181 continue;
2182 }
2183 for (size_t r : cat.rows) {
2184 const Row& row = m_rows[r];
2185 if (!row.check->GetValue())
2186 continue;
2187 if (row.kind == RowKind::Color) {
2188 entry.publish_color = true;
2189 entry.color = row.value.ToStdString();
2190 } else if (row.kind == RowKind::Type) {
2191 entry.publish_type = true;
2192 entry.publish_type_value = row.value.ToStdString();
2193 } else {
2194 entry.keys.push_back(row.key);
2195 }
2196 }
2197 // Nothing checked at all -> nothing to write.
2198 if (!entry.keys.empty() || entry.publish_type || entry.publish_color)
2199 out.push_back(std::move(entry));
2200 }
2201 return out;
2202}
std::vector< std::string > full_keys_for_slot() const
Definition PublishSettingsDialog.cpp:2245
std::string publish_type_value
Definition PublishSettings.hpp:71
int slot
Definition PublishSettings.hpp:57
std::string filament_vendor
Definition PublishSettings.hpp:46
bool publish_color
Definition PublishSettings.hpp:73
std::string filament_type
Definition PublishSettings.hpp:45
std::string color
Definition PublishSettings.hpp:74
std::string preset_name
Definition PublishSettings.hpp:55
@ Preset
Definition calib.hpp:39
std::string setting_id
Definition PublishSettings.hpp:51
std::vector< std::string > full_keys
Definition PublishSettings.hpp:66
bool full
Definition PublishSettings.hpp:63
std::vector< std::string > keys
Definition PublishSettings.hpp:58
std::string filament_id
Definition PublishSettings.hpp:47
bool publish_type
Definition PublishSettings.hpp:70

References Slic3r::GUI::PublishSettingsDialog::Row::check, Color, Slic3r::PublishedMaterialEntry::color, Slic3r::PublishedMaterialEntry::filament_id, Slic3r::PresetBundle::filament_presets, Slic3r::PublishedMaterialEntry::filament_type, Slic3r::PublishedMaterialEntry::filament_vendor, Slic3r::PresetBundle::filaments, Slic3r::PresetCollection::find_preset(), Slic3r::PublishedMaterialEntry::full, Slic3r::PublishedMaterialEntry::full_keys, full_keys_for_slot(), Slic3r::GUI::PublishSettingsDialog::Row::key, Slic3r::PublishedMaterialEntry::keys, Slic3r::GUI::PublishSettingsDialog::Row::kind, m_categories, m_rows, Material, Slic3r::normalize_filament_type(), Slic3r::PublishedMaterialEntry::preset_name, Slic3r::PublishedMaterialEntry::publish_color, Slic3r::publish_mixed_keys(), Slic3r::PublishedMaterialEntry::publish_type, Slic3r::PublishedMaterialEntry::publish_type_value, Slic3r::PublishedMaterialEntry::setting_id, Slic3r::PublishedMaterialEntry::slot, Type, and Slic3r::GUI::PublishSettingsDialog::Row::value.

Referenced by Slic3r::GUI::MainFrame::publish_project().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_new_scale_factor()

bool Slic3r::GUI::DPIAware< wxDialog >::is_new_scale_factor ( ) const
inlineprivateinherited
262{ return fabs(m_scale_factor - m_prev_scale_factor) > 0.001; }

◆ make_mixed_visual_spec()

PublishSettingsDialog::MixedVisualSpec Slic3r::GUI::PublishSettingsDialog::make_mixed_visual_spec ( const Slic3r::DynamicPrintConfig & full,
size_t slot )
staticprivate
599{
600 MixedVisualSpec spec;
601 const std::vector<unsigned int> comps = mixed_slot_components(full, slot);
602 if (comps.empty())
603 return spec;
604
605 const auto* grad_opt = full.opt<ConfigOptionBools>("filament_mixed_gradient");
606 spec.is_gradient = grad_opt != nullptr && slot < grad_opt->size() && grad_opt->values[slot];
607
608 const auto* colours = full.opt<ConfigOptionStrings>("filament_colour");
609 for (unsigned int cid : comps) {
610 std::string hex = "#D9D9D9";
611 if (colours != nullptr && cid >= 1 && cid <= colours->size())
612 hex = colours->values[cid - 1];
613 const wxColour c(hex);
614 spec.component_colours.push_back(c.IsOk() ? c : wxColour("#D9D9D9"));
615 }
616
617 if (!spec.is_gradient) {
618 // Sublayer shares; parse_mixed_ratios already falls back to equal shares and
619 // normalizes to sum 1.
620 spec.ratios.assign(comps.size(), 1.0 / comps.size());
621 if (const auto* ratios_opt = full.opt<ConfigOptionStrings>("filament_mixed_sublayer_ratios"))
622 if (slot < ratios_opt->size()) {
623 const std::vector<double> rs = parse_mixed_ratios(ratios_opt->values[slot], comps.size());
624 if (rs.size() == comps.size())
625 spec.ratios = rs;
626 }
627 if (comps.size() == 3)
628 spec.tri_weights = spec.ratios; // the picker's barycentric shares
629 } else {
630 const Slic3r::GradientCurve curve = mixed_gradient_curve(full, slot);
631 constexpr int kSamples = 256;
632 for (int i = 0; i <= kSamples; ++i) {
633 const double t = double(i) / kSamples;
634 spec.gradient_samples.emplace_back(t, sample_gradient_curve(curve, t));
635 }
636 for (const Slic3r::GradientAnchor& anchor : curve.points)
637 spec.gradient_anchors.emplace_back(anchor.x, anchor.y);
638 }
639
640 spec.valid = true;
641 return spec;
642}
size_t size() const override
Definition Config.hpp:722
T * opt(const t_config_option_key &opt_key, bool create=false)
Definition Config.hpp:3007
Definition PublishSettingsDialog.hpp:180
std::vector< unsigned int > mixed_slot_components(const DynamicPrintConfig &full, size_t slot)
Definition PublishSettingsDialog.cpp:178
Slic3r::GradientCurve mixed_gradient_curve(const Slic3r::DynamicPrintConfig &cfg, size_t slot)
Definition FilamentBitmapUtils.cpp:138
double x
Definition FilamentMixer.hpp:23
double y
Definition FilamentMixer.hpp:24
double sample_gradient_curve(const GradientCurve &c, double t)
Definition FilamentMixer.cpp:357
std::vector< double > parse_mixed_ratios(const std::string &str, size_t n_components)
Definition FilamentMixer.cpp:404
std::vector< GradientAnchor > points
Definition FilamentMixer.hpp:32

References Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::component_colours, Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::gradient_anchors, Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::gradient_samples, Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::is_gradient, Slic3r::GUI::mixed_gradient_curve(), Slic3r::DynamicConfig::opt(), Slic3r::parse_mixed_ratios(), Slic3r::GradientCurve::points, Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::ratios, Slic3r::sample_gradient_curve(), Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::tri_weights, Slic3r::GUI::PublishSettingsDialog::MixedVisualSpec::valid, Slic3r::GradientAnchor::x, and Slic3r::GradientAnchor::y.

Referenced by build_option_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ normal_font()

◆ on_dpi_changed()

void Slic3r::GUI::PublishSettingsDialog::on_dpi_changed ( const wxRect & suggested_rect)
overrideprotectedvirtual

Implements Slic3r::GUI::DPIAware< wxDialog >.

2261{
2262 // Rescale toolbar bitmaps and icons; collapse chevrons are vector-drawn and repaint.
2263 m_search.msw_rescale();
2264 m_menu.msw_rescale();
2265 m_filter_box->SetIcon(m_search.bmp());
2266 m_menu_button->SetBitmap(m_menu.bmp());
2267 m_outer_tabs->Rescale();
2268
2269 const DynamicPrintConfig full = wxGetApp().preset_bundle->full_config();
2270
2271 for (Category& cat : m_categories) {
2272 if (cat.full_check != nullptr)
2273 cat.full_check->Refresh();
2274 if (cat.enable_check != nullptr)
2275 cat.enable_check->Refresh();
2276 if (cat.title_label != nullptr)
2277 cat.title_label->Refresh();
2278 if (cat.filament_color_chip != nullptr) {
2279 // Mixed pages have no header chip; this only ever fires for physical slots.
2280 if (wxBitmap* chip = get_extruder_color_icon(filament_color_hex(full, cat.filament_slot), std::to_string(cat.filament_slot + 1),
2281 FromDIP(20), FromDIP(20))) {
2282 cat.filament_color_chip->SetBitmap(*chip);
2283 }
2284 }
2285 cat.scroll->FitInside();
2286 cat.list_sizer->Layout();
2287 }
2288
2289 for (size_t s = 0; s < m_sections.size(); ++s) {
2290 SectionGroup& section = m_sections[s];
2291 section.icon_bmp.msw_rescale();
2292 if (section.icon_bmp.bmp().IsOk())
2293 m_outer_tabs->SetItemBitmap(s, section.icon_bmp.bmp());
2294 section.tabs->Rescale();
2295 if (section.mixed_tabs != nullptr)
2296 section.mixed_tabs->Rescale();
2297 if (section.variant_switch != nullptr)
2298 section.variant_switch->Rescale();
2299 }
2300
2301 // Refresh the per-row Color chips at the new DPI (they carry the slot number too).
2302 for (Row& row : m_rows) {
2303 if (row.color_chip != nullptr && !row.value.IsEmpty()) {
2304 const std::string chip_label = (row.inner_index < m_categories.size()) ?
2305 std::to_string(m_categories[row.inner_index].filament_slot + 1) :
2306 "";
2307 if (wxBitmap* chip = get_extruder_color_icon(row.value.ToStdString(), chip_label, FromDIP(20), FromDIP(20)))
2308 row.color_chip->SetBitmap(*chip);
2309 }
2310 }
2311
2312 for (size_t category_index = 0; category_index < m_categories.size(); ++category_index) {
2313 const Category& category = m_categories[category_index];
2314 if (category.section != Section::Material || category.is_mixed)
2315 continue;
2316 if (wxBitmap* chip = get_extruder_color_icon(filament_color_hex(full, category.filament_slot),
2317 std::to_string(category.filament_slot + 1), FromDIP(20), FromDIP(20))) {
2318 const SectionGroup& section = m_sections[category.group];
2319 const auto iter = std::find(section.categories.begin(), section.categories.end(), category_index);
2320 if (iter != section.categories.end())
2321 m_sections[category.group].tabs->SetItemBitmap(static_cast<unsigned int>(iter - section.categories.begin()), *chip);
2322 }
2323 }
2325
2326 fit_to_content(); // tab buttons' min widths grew with the DPI: re-fit (incl. resize floor)
2327 Refresh();
2328}

References ScalableBitmap::bmp(), Slic3r::GUI::PublishSettingsDialog::SectionGroup::categories, Slic3r::GUI::PublishSettingsDialog::Category::filament_slot, fit_to_content(), get_extruder_color_icon(), Slic3r::GUI::PublishSettingsDialog::Category::group, Slic3r::GUI::PublishSettingsDialog::SectionGroup::icon_bmp, Slic3r::GUI::PublishSettingsDialog::Category::is_mixed, m_categories, m_filter_box, m_menu, m_menu_button, m_outer_tabs, m_rows, m_search, m_sections, Material, Slic3r::GUI::PublishSettingsDialog::SectionGroup::mixed_tabs, ScalableBitmap::msw_rescale(), refresh_mixed_tab_bitmaps(), MultiSwitchButton::Rescale(), TabCtrl::Rescale(), Slic3r::GUI::PublishSettingsDialog::Category::section, Slic3r::GUI::PublishSettingsDialog::SectionGroup::tabs, and Slic3r::GUI::PublishSettingsDialog::SectionGroup::variant_switch.

Here is the call graph for this function:

◆ on_enable_toggle()

void Slic3r::GUI::PublishSettingsDialog::on_enable_toggle ( size_t category_index)
private
1404{
1405 Category& cat = m_categories[category_index];
1406 const bool enabled = cat.enable_check->GetValue();
1407
1408 // A published mixed filament needs its component filaments published too: mark the slots it
1409 // uses as "Enable"d and Full Published so the mix's physical components always ship their
1410 // identities.
1411 if (cat.is_mixed && enabled) {
1412 const DynamicPrintConfig full = wxGetApp().preset_bundle->full_config();
1413 const std::vector<unsigned int> components = mixed_slot_components(full, cat.filament_slot);
1414 for (const unsigned int component : components) {
1415 // Components are 1-based physical filament indices.
1416 const size_t component_slot = size_t(component) - 1;
1417 for (size_t c = 0; c < m_categories.size(); ++c) {
1418 Category& comp_cat = m_categories[c];
1419 if (comp_cat.section != Section::Material || comp_cat.is_mixed || comp_cat.filament_slot != component_slot)
1420 continue;
1421 if (comp_cat.enable_check != nullptr)
1422 comp_cat.enable_check->SetValue(true);
1423 if (comp_cat.full_check != nullptr)
1424 comp_cat.full_check->SetValue(true);
1425 on_full_toggle(c);
1426 }
1427 }
1428 }
1429
1430 // Reveal/hide everything below the slot's header (rows, info, Full Publish line) and refresh
1431 // the visibility of the auto-selected component slots.
1433 if (cat.page != nullptr)
1434 cat.page->GetSizer()->Layout();
1436}

References apply_visibility(), Slic3r::GUI::PublishSettingsDialog::Category::enable_check, Slic3r::GUI::PublishSettingsDialog::Category::filament_slot, Slic3r::GUI::PublishSettingsDialog::Category::full_check, Slic3r::GUI::PublishSettingsDialog::Category::is_mixed, m_categories, Material, on_full_toggle(), Slic3r::GUI::PublishSettingsDialog::Category::page, refresh_tab_indicators(), and Slic3r::GUI::PublishSettingsDialog::Category::section.

Referenced by apply_selection(), build_option_model(), and select_all().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_full_toggle()

void Slic3r::GUI::PublishSettingsDialog::on_full_toggle ( size_t category_index)
private
1393{
1394 Category& cat = m_categories[category_index];
1395 const bool full = cat.full_check->GetValue();
1396 for (size_t r : cat.rows) {
1397 m_rows[r].check->Enable(!full);
1398 m_rows[r].check_label->Enable(!full);
1399 }
1401}

References Slic3r::GUI::PublishSettingsDialog::Category::full_check, m_categories, m_rows, refresh_tab_indicators(), and Slic3r::GUI::PublishSettingsDialog::Category::rows.

Referenced by apply_selection(), build_option_model(), and on_enable_toggle().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_inner_tab_changed()

void Slic3r::GUI::PublishSettingsDialog::on_inner_tab_changed ( size_t section_index,
wxCommandEvent & event )
private
1712{
1713 const int selection = event.GetInt();
1714 if (section_index < m_sections.size() && selection >= 0 && selection < static_cast<int>(m_sections[section_index].categories.size()))
1715 show_inner_page(section_index, selection);
1716}
void show_inner_page(size_t section_index, int inner_index)
Definition PublishSettingsDialog.cpp:1625

References m_sections, and show_inner_page().

Referenced by bind_tab_events().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_mixed_tab_changed()

void Slic3r::GUI::PublishSettingsDialog::on_mixed_tab_changed ( size_t section_index,
wxCommandEvent & event )
private
1719{
1720 const int selection = event.GetInt();
1721 if (section_index < m_sections.size() && selection >= 0 &&
1722 selection < static_cast<int>(m_sections[section_index].mixed_categories.size()))
1723 show_mixed_page(section_index, selection);
1724}
void show_mixed_page(size_t section_index, int mixed_index)
Definition PublishSettingsDialog.cpp:1679

References m_sections, and show_mixed_page().

Referenced by bind_tab_events().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_outer_tab_changed()

void Slic3r::GUI::PublishSettingsDialog::on_outer_tab_changed ( wxCommandEvent & event)
private
1705{
1706 const int selection = event.GetInt();
1707 if (selection >= 0 && selection < static_cast<int>(m_sections.size()))
1708 show_outer_page(static_cast<size_t>(selection));
1709}

References m_sections, and show_outer_page().

Referenced by bind_tab_events().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ on_sys_color_changed()

void Slic3r::GUI::PublishSettingsDialog::on_sys_color_changed ( )
overrideprotectedvirtual

Reimplemented from Slic3r::GUI::DPIAware< wxDialog >.

2349{
2350 // The mixed-tab compositions bake the tab strip's background colour: rebuild them when the
2351 // theme changes (on_dpi_changed covers rescales).
2353 Refresh();
2354}

References refresh_mixed_tab_bitmaps().

Here is the call graph for this function:

◆ prev_scale_factor()

float Slic3r::GUI::DPIAware< wxDialog >::prev_scale_factor ( ) const
inlineinherited
196{ return m_prev_scale_factor; }

◆ refresh_filter()

void Slic3r::GUI::PublishSettingsDialog::refresh_filter ( const wxString & filter)
private
1752{
1753 Freeze();
1754 const bool pseudo = m_filter_mode != FilterMode::Text;
1755 const bool want_checked = m_filter_mode == FilterMode::SelectedOnly;
1756 m_fb_sizer->Show(!pseudo);
1757 if (pseudo) {
1758 // "×" marks the chip as a dismissible filter state (U+00D7, present in all UI fonts).
1759 m_pseudo_chip->SetLabel((want_checked ? _L("Filter selected") : _L("Filter non-selected")) + " " + wxString::FromUTF8("\u00d7"));
1760 }
1761 m_pseudo_chip->Show(pseudo);
1762
1763 // Row matches are computed first; page and optgroup visibility is applied below.
1764 if (pseudo) {
1765 for (Row& row : m_rows)
1766 row.matches_filter = row.check->IsEnabled() && row.check->GetValue() == want_checked;
1767 } else {
1768 const bool clear = filter.IsEmpty();
1769 for (Row& row : m_rows) {
1770 row.matches_filter = clear || (row.section_title + " " + row.category + " " + row.subcategory + " " + row.label + " " +
1771 row.value + " " + row.unit)
1772 .Lower()
1773 .Contains(filter);
1774 }
1775 }
1776
1777 size_t first_outer = 0;
1778 int first_inner = -1;
1779 bool active_has_match = false;
1780 for (size_t s = 0; s < m_sections.size(); ++s) {
1781 for (size_t inner = 0; inner < m_sections[s].categories.size(); ++inner) {
1782 Category& category = m_categories[m_sections[s].categories[inner]];
1783 bool has_match = false;
1784 for (size_t r : category.rows)
1785 has_match = has_match || m_rows[r].matches_filter;
1786 category.info->Show(!has_match);
1787 if (!has_match)
1788 // A mixed slot has no selectable rows: always explain it is published whole.
1789 category.info->SetLabel(category.is_mixed ? m_info_mix :
1790 (pseudo ? (want_checked ? m_info_nonsel : m_info_allsel) : m_info_empty));
1791 if (has_match && first_inner < 0) {
1792 first_outer = s;
1793 first_inner = static_cast<int>(inner);
1794 }
1795 if (static_cast<int>(s) == m_selected_outer && static_cast<int>(inner) == m_sections[s].selected_inner)
1796 active_has_match = has_match;
1797 }
1798 // Mixed slots have no rows: they can never match a filter, so they always fall back to
1799 // their explanatory hint (shown once the slot is enabled).
1800 for (size_t mixed : m_sections[s].mixed_categories) {
1801 Category& category = m_categories[mixed];
1802 category.info->Show(true);
1803 category.info->SetLabel(m_info_mix);
1804 }
1805 }
1806 if (!active_has_match && first_inner >= 0 &&
1807 (m_selected_outer != static_cast<int>(first_outer) || m_sections[first_outer].selected_inner != first_inner)) {
1808 if (m_selected_outer != static_cast<int>(first_outer)) {
1809 m_outer_tabs->SelectItem(static_cast<int>(first_outer));
1810 show_outer_page(first_outer);
1811 }
1812 m_sections[first_outer].tabs->SelectItem(first_inner);
1813 show_inner_page(first_outer, first_inner);
1814 }
1815
1817 for (Category& category : m_categories) {
1818 save_scroll_position(category);
1819 category.scroll->FitInside();
1820 category.list_sizer->Layout();
1821 category.scroll->Scroll(category.scroll_pos.x, category.scroll_pos.y);
1822 }
1823 Layout();
1824 Thaw();
1825}
void save_scroll_position(Category &category)
Definition PublishSettingsDialog.cpp:1596
int m_selected_outer
Definition PublishSettingsDialog.hpp:291

References _L, apply_visibility(), Slic3r::GUI::PublishSettingsDialog::Category::info, Slic3r::GUI::PublishSettingsDialog::Category::is_mixed, m_categories, m_fb_sizer, m_filter_mode, m_info_allsel, m_info_empty, m_info_mix, m_info_nonsel, m_outer_tabs, m_pseudo_chip, m_rows, m_sections, m_selected_outer, Slic3r::GUI::PublishSettingsDialog::Category::rows, save_scroll_position(), SelectedOnly, show_inner_page(), show_outer_page(), and Text.

Referenced by apply_filter(), and apply_pseudo_filter().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ refresh_mixed_tab_bitmaps()

void Slic3r::GUI::PublishSettingsDialog::refresh_mixed_tab_bitmaps ( )
private
2331{
2332 // The mixed-tab composition bitmaps bake the tab strip's background colour and DPI-scaled
2333 // text, so both a theme flip and a DPI change have to rebuild them.
2334 const DynamicPrintConfig full = wxGetApp().preset_bundle->full_config();
2335 for (SectionGroup& section : m_sections) {
2336 if (section.mixed_tabs == nullptr)
2337 continue;
2338 const wxColour tab_bg = section.mixed_tabs->GetBackgroundColour();
2339 for (size_t i = 0; i < section.mixed_categories.size(); ++i) {
2340 const Category& category = m_categories[section.mixed_categories[i]];
2341 const wxBitmap tab_bmp = mixed_filament_tab_bitmap(full, category.filament_slot, FromDIP(20), tab_bg);
2342 if (tab_bmp.IsOk())
2343 section.mixed_tabs->SetItemBitmap(static_cast<unsigned int>(i), tab_bmp);
2344 }
2345 }
2346}

References Slic3r::GUI::PublishSettingsDialog::Category::filament_slot, m_categories, and m_sections.

Referenced by PublishSettingsDialog(), on_dpi_changed(), and on_sys_color_changed().

Here is the caller graph for this function:

◆ refresh_tab_indicators()

void Slic3r::GUI::PublishSettingsDialog::refresh_tab_indicators ( )
private
2217{
2218 for (size_t s = 0; s < m_sections.size(); ++s) {
2219 SectionGroup& section = m_sections[s];
2220 bool any = false;
2221 for (size_t i = 0; i < section.categories.size(); ++i) {
2222 const bool on = category_has_selection(m_categories[section.categories[i]]);
2223 section.tabs->SetItemIndicator(static_cast<unsigned int>(i), on);
2224 // The switch has no indicator dot; mark its option text instead.
2225 if (section.variant_switch != nullptr) {
2226 const wxString& title = m_categories[section.categories[i]].title;
2227 const wxString text = on ? title + wxString(" ") + wxString(wxUniChar(0x2022)) : title;
2228 if (section.variant_switch->GetOptionText(static_cast<unsigned int>(i)) != text) {
2229 section.variant_switch->SetOptionText(static_cast<unsigned int>(i), text);
2230 section.page->Layout();
2231 }
2232 }
2233 any = any || on;
2234 }
2235 if (section.mixed_tabs != nullptr)
2236 for (size_t i = 0; i < section.mixed_categories.size(); ++i) {
2237 const bool on = category_has_selection(m_categories[section.mixed_categories[i]]);
2238 section.mixed_tabs->SetItemIndicator(static_cast<unsigned int>(i), on);
2239 any = any || on;
2240 }
2241 m_outer_tabs->SetItemIndicator(static_cast<unsigned int>(s), any);
2242 }
2243}
bool category_has_selection(const Category &cat) const
Definition PublishSettingsDialog.cpp:2204

References Slic3r::GUI::PublishSettingsDialog::SectionGroup::categories, category_has_selection(), MultiSwitchButton::GetOptionText(), m_categories, m_outer_tabs, m_sections, Slic3r::GUI::PublishSettingsDialog::SectionGroup::mixed_categories, Slic3r::GUI::PublishSettingsDialog::SectionGroup::mixed_tabs, Slic3r::GUI::PublishSettingsDialog::SectionGroup::page, TabCtrl::SetItemIndicator(), MultiSwitchButton::SetOptionText(), Slic3r::GUI::PublishSettingsDialog::SectionGroup::tabs, and Slic3r::GUI::PublishSettingsDialog::SectionGroup::variant_switch.

Referenced by add_row_ui(), apply_selection(), build_option_model(), on_enable_toggle(), on_full_toggle(), select_all(), and select_visible().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ rescale()

void Slic3r::GUI::DPIAware< wxDialog >::rescale ( const wxRect & suggested_rect)
inlineprivateinherited
265 {
266 this->Freeze();
267
268 m_force_rescale = false;
269
270 // set normal application font as a current window font
271 m_normal_font = this->GetFont();
272
274
275 // rescale missed controls sizes and images
277
278 this->Layout();
279 this->Thaw();
280
281 // reset previous scale factor from current scale factor value
283 }
virtual void on_dpi_changed(const wxRect &suggested_rect)=0
void update_em_unit()
Definition GUI_Utils.hpp:249

◆ row_is_visible()

bool Slic3r::GUI::PublishSettingsDialog::row_is_visible ( const Row & row) const
private
1879{
1880 if (m_selected_outer < 0 || m_selected_outer >= static_cast<int>(m_sections.size()) ||
1881 row.outer_index != static_cast<size_t>(m_selected_outer) || m_sections[m_selected_outer].selected_inner < 0 ||
1882 m_sections[m_selected_outer].selected_inner >= static_cast<int>(m_sections[m_selected_outer].categories.size()) ||
1883 row.inner_index != m_sections[m_selected_outer].categories[m_sections[m_selected_outer].selected_inner] || !row.matches_filter ||
1884 !row.check->IsEnabled())
1885 return false;
1886 return row.item->IsShown();
1887}

References Slic3r::GUI::PublishSettingsDialog::Row::check, Slic3r::GUI::PublishSettingsDialog::Row::inner_index, Slic3r::GUI::PublishSettingsDialog::Row::item, m_sections, m_selected_outer, Slic3r::GUI::PublishSettingsDialog::Row::matches_filter, and Slic3r::GUI::PublishSettingsDialog::Row::outer_index.

Referenced by select_visible(), and show_menu().

Here is the caller graph for this function:

◆ save_scroll_position()

void Slic3r::GUI::PublishSettingsDialog::save_scroll_position ( Category & category)
private
1597{
1598 if (category.scroll != nullptr)
1599 category.scroll->GetViewStart(&category.scroll_pos.x, &category.scroll_pos.y);
1600}

References Slic3r::GUI::PublishSettingsDialog::Category::scroll, and Slic3r::GUI::PublishSettingsDialog::Category::scroll_pos.

Referenced by refresh_filter(), show_inner_page(), show_mixed_page(), and show_outer_page().

Here is the caller graph for this function:

◆ scale_factor()

float Slic3r::GUI::DPIAware< wxDialog >::scale_factor ( ) const
inlineinherited
195{ return m_scale_factor; }

◆ section_group_for()

size_t Slic3r::GUI::PublishSettingsDialog::section_group_for ( Section kind)
private
1118{
1119 for (size_t i = 0; i < m_sections.size(); ++i)
1120 if (m_sections[i].kind == kind)
1121 return i;
1122
1123 SectionGroup section;
1124 section.kind = kind;
1125 const size_t new_index = m_sections.size();
1126 switch (kind) {
1127 case Section::Printer:
1128 section.title = _L("Printer");
1129 section.icon_name = "printer";
1130 break;
1131 case Section::Material:
1132 section.title = _L("Filament");
1133 section.icon_name = "filament";
1134 break;
1135 case Section::Print:
1136 section.title = _L("Process");
1137 section.icon_name = "process";
1138 break;
1139 }
1140 section.icon_bmp = ScalableBitmap(this, section.icon_name, 16);
1141
1142 section.page = new wxPanel(m_outer_host, wxID_ANY);
1143 section.page->SetBackgroundColour(GetBackgroundColour());
1144 auto* page_sizer = new wxBoxSizer(wxVERTICAL);
1145 section.tabs = new TabCtrl(section.page, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_tab_style);
1146 section.tabs->SetFont(Label::Body_14);
1147 section.tabs->SetBackgroundColour(GetBackgroundColour());
1148 page_sizer->Add(section.tabs, 0, wxEXPAND);
1149 // Mixed-color filament slots get a second tab strip below the physical filament tabs; only
1150 // the Material section has them.
1151 if (kind == Section::Material) {
1152 section.mixed_tabs = new TabCtrl(section.page, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_tab_style);
1153 section.mixed_tabs->SetFont(Label::Body_14);
1154 section.mixed_tabs->SetBackgroundColour(GetBackgroundColour());
1155 page_sizer->Add(section.mixed_tabs, 0, wxEXPAND | wxTOP, FromDIP(2));
1156 section.mixed_tabs->Hide();
1157 }
1158 section.page_host = new wxPanel(section.page, wxID_ANY);
1159#ifdef __WINDOWS__
1160 section.page_host->SetDoubleBuffered(true);
1161#endif
1162 section.page_host->SetBackgroundColour(GetBackgroundColour());
1163 section.page_host_sizer = new wxBoxSizer(wxVERTICAL);
1164 section.page_host->SetSizer(section.page_host_sizer);
1165 page_sizer->Add(section.page_host, 1, wxEXPAND | wxTOP, FromDIP(4));
1166 section.page->SetSizer(page_sizer);
1167
1168 if (section.icon_bmp.bmp().IsOk())
1169 m_outer_tabs->AppendItem(section.title, section.icon_bmp.bmp());
1170 else
1171 m_outer_tabs->AppendItem(section.title);
1172 m_outer_host_sizer->Add(section.page, 1, wxEXPAND);
1173 section.page->Hide();
1174 m_sections.push_back(std::move(section));
1175 return new_index;
1176}
Section kind
Definition PublishSettingsDialog.hpp:194

References _L, ScalableBitmap::bmp(), Label::Body_14, Slic3r::GUI::PublishSettingsDialog::SectionGroup::icon_bmp, Slic3r::GUI::PublishSettingsDialog::SectionGroup::icon_name, Slic3r::GUI::PublishSettingsDialog::SectionGroup::kind, m_outer_host, m_outer_host_sizer, m_outer_tabs, m_sections, Material, Slic3r::GUI::PublishSettingsDialog::SectionGroup::mixed_tabs, Slic3r::GUI::PublishSettingsDialog::SectionGroup::page, Slic3r::GUI::PublishSettingsDialog::SectionGroup::page_host, Slic3r::GUI::PublishSettingsDialog::SectionGroup::page_host_sizer, Print, Printer, TabCtrl::SetFont(), Slic3r::GUI::PublishSettingsDialog::SectionGroup::tabs, and Slic3r::GUI::PublishSettingsDialog::SectionGroup::title.

Referenced by build_option_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_all()

void Slic3r::GUI::PublishSettingsDialog::select_all ( bool value)
private
1859{
1860 // "All" skips disabled (gated) rows; "None" leaves a gated row's preserved value.
1861 for (Row& row : m_rows)
1862 if (row.check->IsEnabled())
1863 row.check->SetValue(value);
1864 // "All" also enables every material slot (so its rows/Full Publish become visible and the
1865 // selection is actually exported); "None" disables them all again.
1866 for (Category& cat : m_categories)
1867 if (cat.section == Section::Material && cat.enable_check != nullptr)
1868 cat.enable_check->SetValue(value);
1869 // CheckBox::SetValue does not emit wxEVT_TOGGLEBUTTON, so re-run the enable handlers to
1870 // propagate mixed-slot components and refresh visibility as if the user had clicked.
1871 for (size_t c = 0; c < m_categories.size(); ++c)
1872 if (m_categories[c].section == Section::Material)
1876}

References apply_visibility(), m_categories, m_rows, Material, on_enable_toggle(), and refresh_tab_indicators().

Referenced by PublishSettingsDialog(), and show_menu().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_visible()

void Slic3r::GUI::PublishSettingsDialog::select_visible ( bool value)
private
1890{
1891 // In a pseudo-filter view the rows being toggled would all disappear; drop the filter
1892 // afterwards so the result stays visible.
1893 const bool clear_pseudo = (m_filter_mode == FilterMode::UnselectedOnly && !value) ||
1895
1896 // Toggle the rows visible under the *current* filter.
1897 for (Row& row : m_rows)
1898 if (row_is_visible(row))
1899 row.check->SetValue(value);
1900
1901 if (clear_pseudo) {
1902 // Note: SetValue() may fire wxEVT_TEXT on some platforms, re-entering apply_filter() -
1903 // that is fine; the rows above were already toggled and the trailing call is idempotent.
1904 m_filter_ctrl->ChangeValue("");
1905 apply_filter(""); // resync visibility and the All/None bar
1906 }
1908}
bool row_is_visible(const Row &row) const
Definition PublishSettingsDialog.cpp:1878

References apply_filter(), m_filter_ctrl, m_filter_mode, m_rows, refresh_tab_indicators(), row_is_visible(), SelectedOnly, and UnselectedOnly.

Referenced by show_menu().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_em_unit()

void Slic3r::GUI::DPIAware< wxDialog >::set_em_unit ( int v)
inlineinherited
200{ m_em_unit = v; }

◆ set_prev_scale_factor()

void Slic3r::GUI::DPIAware< wxDialog >::set_prev_scale_factor ( float v)
inlineinherited

◆ set_row_bold()

void Slic3r::GUI::PublishSettingsDialog::set_row_bold ( Row & row,
bool bold )
private
1591{
1592 // Rebase on the dialog's body font so clearing bold restores the exact original font.
1593 row.check_label->SetFont(bold ? Label::Body_13.Bold() : Label::Body_13);
1594}
static wxString bold(const wxString &str)
Definition GUI.cpp:335

References Label::Body_13, Slic3r::GUI::bold(), and Slic3r::GUI::PublishSettingsDialog::Row::check_label.

Referenced by build_option_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_scale_factor()

void Slic3r::GUI::DPIAware< wxDialog >::set_scale_factor ( float v)
inlineinherited
198{ m_scale_factor = v; }

◆ setup_variant_switch()

void Slic3r::GUI::PublishSettingsDialog::setup_variant_switch ( size_t section_index)
private
1654{
1655 SectionGroup& section = m_sections[section_index];
1656 std::vector<wxString> titles;
1657 for (size_t category : section.categories)
1658 titles.push_back(m_categories[category].title);
1659
1660 section.variant_switch = new MultiSwitchButton(section.page);
1661 section.variant_switch->SetFitToOptions();
1662 section.variant_switch->SetOptions(titles);
1663 section.variant_switch->SetSelection(section.selected_inner);
1664 section.variant_switch->Bind(wxCUSTOMEVT_MULTISWITCH_SELECTION, [this, section_index](wxCommandEvent& evt) {
1665 evt.Skip();
1666 // The hidden tab strip stays the selection model; its event shows the page.
1667 SectionGroup& sec = m_sections[section_index];
1668 if (evt.GetInt() != sec.selected_inner)
1669 sec.tabs->SelectItem(evt.GetInt());
1670 });
1671
1672 // The switch takes the place of the tab strip, centered like on the printer tab.
1673 wxSizer* page_sizer = section.page->GetSizer();
1674 page_sizer->Insert(1, section.variant_switch, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(4));
1675 section.tabs->Hide();
1676 section.page->Layout();
1677}

References Slic3r::GUI::PublishSettingsDialog::SectionGroup::categories, m_categories, m_sections, Slic3r::GUI::PublishSettingsDialog::SectionGroup::page, Slic3r::GUI::PublishSettingsDialog::SectionGroup::selected_inner, TabCtrl::SelectItem(), MultiSwitchButton::SetFitToOptions(), MultiSwitchButton::SetOptions(), MultiSwitchButton::SetSelection(), Slic3r::GUI::PublishSettingsDialog::SectionGroup::tabs, and Slic3r::GUI::PublishSettingsDialog::SectionGroup::variant_switch.

Referenced by build_option_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_inner_page()

void Slic3r::GUI::PublishSettingsDialog::show_inner_page ( size_t section_index,
int inner_index )
private
1626{
1627 if (section_index >= m_sections.size())
1628 return;
1629 SectionGroup& section = m_sections[section_index];
1630 if (inner_index < 0 || inner_index >= static_cast<int>(section.categories.size()))
1631 return;
1632 if (section.selected_inner >= 0 && section.selected_inner < static_cast<int>(section.categories.size())) {
1633 save_scroll_position(m_categories[section.categories[section.selected_inner]]);
1634 m_categories[section.categories[section.selected_inner]].page->Hide();
1635 }
1636 if (section.selected_mixed >= 0 && section.selected_mixed < static_cast<int>(section.mixed_categories.size())) {
1637 save_scroll_position(m_categories[section.mixed_categories[section.selected_mixed]]);
1638 m_categories[section.mixed_categories[section.selected_mixed]].page->Hide();
1639 section.selected_mixed = -1;
1640 }
1641 section.selected_inner = inner_index;
1642 if (section.variant_switch != nullptr)
1643 section.variant_switch->SetSelection(inner_index); // fires its event, which ignores the shown page
1644 Category& category = m_categories[section.categories[inner_index]];
1645 category.page->Show();
1646 category.scroll->FitInside();
1647 category.scroll->Scroll(category.scroll_pos.x, category.scroll_pos.y);
1648 if (section.mixed_tabs != nullptr)
1649 section.mixed_tabs->Unselect();
1650 section.page_host_sizer->Layout();
1651}

References Slic3r::GUI::PublishSettingsDialog::SectionGroup::categories, m_categories, m_sections, Slic3r::GUI::PublishSettingsDialog::SectionGroup::mixed_categories, Slic3r::GUI::PublishSettingsDialog::SectionGroup::mixed_tabs, Slic3r::GUI::PublishSettingsDialog::Category::page, Slic3r::GUI::PublishSettingsDialog::SectionGroup::page_host_sizer, save_scroll_position(), Slic3r::GUI::PublishSettingsDialog::Category::scroll, Slic3r::GUI::PublishSettingsDialog::Category::scroll_pos, Slic3r::GUI::PublishSettingsDialog::SectionGroup::selected_inner, Slic3r::GUI::PublishSettingsDialog::SectionGroup::selected_mixed, MultiSwitchButton::SetSelection(), TabCtrl::Unselect(), and Slic3r::GUI::PublishSettingsDialog::SectionGroup::variant_switch.

Referenced by on_inner_tab_changed(), refresh_filter(), and show_outer_page().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_menu()

void Slic3r::GUI::PublishSettingsDialog::show_menu ( wxMouseEvent & evt)
private
1911{
1912 bool filtering = !m_filter_ctrl->GetValue().IsEmpty() || m_filter_mode != FilterMode::Text;
1913 bool list_empty = true;
1914 if (m_selected_outer >= 0) {
1915 for (const Row& row : m_rows)
1916 if (row_is_visible(row)) {
1917 list_empty = false;
1918 break;
1919 }
1920 }
1921
1922 wxMenu m;
1923 m.Append(kPublishSelectAll, _L("Select All"))->Enable(!filtering);
1924 m.Append(kPublishDeselectAll, _L("Deselect All"))->Enable(!filtering);
1925 m.AppendSeparator();
1926 m.Append(kPublishSelectVisible, _L("Select visible"))->Enable(!list_empty && filtering);
1927 m.Append(kPublishDeselectVisible, _L("Deselect visible"))->Enable(!list_empty && filtering);
1928 m.AppendSeparator();
1929 m.AppendCheckItem(kPublishFilterSelected, _L("Filter selected"));
1930 m.AppendCheckItem(kPublishFilterNonSelected, _L("Filter non-selected"));
1931 m.Check(kPublishFilterSelected, m_filter_mode == FilterMode::SelectedOnly);
1932 m.Check(kPublishFilterNonSelected, m_filter_mode == FilterMode::UnselectedOnly);
1933
1934 m.Bind(
1935 wxEVT_MENU,
1936 [this](wxCommandEvent& e) {
1937 switch (e.GetId()) {
1938 case kPublishSelectAll: select_all(true); break;
1939 case kPublishDeselectAll: select_all(false); break;
1940 case kPublishSelectVisible: select_visible(true); break;
1941 case kPublishDeselectVisible: select_visible(false); break;
1943 // Clicking the active entry again clears the pseudo filter.
1945 apply_filter(m_filter_ctrl->GetValue());
1946 else
1947 apply_pseudo_filter(true);
1948 break;
1951 apply_filter(m_filter_ctrl->GetValue());
1952 else
1953 apply_pseudo_filter(false);
1954 break;
1955 default: break;
1956 }
1957 },
1959
1960 wxWindow* src = dynamic_cast<wxWindow*>(evt.GetEventObject());
1961 if (!src)
1962 return;
1963 wxPoint screen_pos = src->ClientToScreen(evt.GetPosition());
1964 wxPoint local_pos = ScreenToClient(screen_pos);
1965 PopupMenu(&m, local_pos);
1966}
void select_visible(bool value)
Definition PublishSettingsDialog.cpp:1889
void apply_pseudo_filter(bool selected_only)
Definition PublishSettingsDialog.cpp:1745
@ kPublishSelectAll
Definition PublishSettingsDialog.cpp:110
@ kPublishDeselectAll
Definition PublishSettingsDialog.cpp:111
@ kPublishFilterNonSelected
Definition PublishSettingsDialog.cpp:115
@ kPublishFilterSelected
Definition PublishSettingsDialog.cpp:114
@ kPublishDeselectVisible
Definition PublishSettingsDialog.cpp:113
@ kPublishSelectVisible
Definition PublishSettingsDialog.cpp:112

References _L, apply_filter(), apply_pseudo_filter(), m_filter_ctrl, m_filter_mode, m_rows, m_selected_outer, row_is_visible(), select_all(), select_visible(), SelectedOnly, Text, UnselectedOnly, and Slic3r::GUI::wxMouseEvent.

Referenced by PublishSettingsDialog(), and category_index_for().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_mixed_page()

void Slic3r::GUI::PublishSettingsDialog::show_mixed_page ( size_t section_index,
int mixed_index )
private
1680{
1681 if (section_index >= m_sections.size())
1682 return;
1683 SectionGroup& section = m_sections[section_index];
1684 if (mixed_index < 0 || mixed_index >= static_cast<int>(section.mixed_categories.size()))
1685 return;
1686 if (section.selected_mixed >= 0 && section.selected_mixed < static_cast<int>(section.mixed_categories.size())) {
1687 save_scroll_position(m_categories[section.mixed_categories[section.selected_mixed]]);
1688 m_categories[section.mixed_categories[section.selected_mixed]].page->Hide();
1689 }
1690 if (section.selected_inner >= 0 && section.selected_inner < static_cast<int>(section.categories.size())) {
1691 save_scroll_position(m_categories[section.categories[section.selected_inner]]);
1692 m_categories[section.categories[section.selected_inner]].page->Hide();
1693 section.selected_inner = -1;
1694 }
1695 section.selected_mixed = mixed_index;
1696 Category& category = m_categories[section.mixed_categories[mixed_index]];
1697 category.page->Show();
1698 category.scroll->FitInside();
1699 category.scroll->Scroll(category.scroll_pos.x, category.scroll_pos.y);
1700 section.tabs->Unselect();
1701 section.page_host_sizer->Layout();
1702}

References Slic3r::GUI::PublishSettingsDialog::SectionGroup::categories, m_categories, m_sections, Slic3r::GUI::PublishSettingsDialog::SectionGroup::mixed_categories, Slic3r::GUI::PublishSettingsDialog::Category::page, Slic3r::GUI::PublishSettingsDialog::SectionGroup::page_host_sizer, save_scroll_position(), Slic3r::GUI::PublishSettingsDialog::Category::scroll, Slic3r::GUI::PublishSettingsDialog::Category::scroll_pos, Slic3r::GUI::PublishSettingsDialog::SectionGroup::selected_inner, Slic3r::GUI::PublishSettingsDialog::SectionGroup::selected_mixed, Slic3r::GUI::PublishSettingsDialog::SectionGroup::tabs, and TabCtrl::Unselect().

Referenced by on_mixed_tab_changed(), and show_outer_page().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ show_outer_page()

void Slic3r::GUI::PublishSettingsDialog::show_outer_page ( size_t section_index)
private
1603{
1604 if (section_index >= m_sections.size())
1605 return;
1606 if (m_selected_outer >= 0 && m_selected_outer < static_cast<int>(m_sections.size())) {
1608 if (old_section.selected_inner >= 0 && old_section.selected_inner < static_cast<int>(old_section.categories.size()))
1609 save_scroll_position(m_categories[old_section.categories[old_section.selected_inner]]);
1610 if (old_section.selected_mixed >= 0 && old_section.selected_mixed < static_cast<int>(old_section.mixed_categories.size()))
1611 save_scroll_position(m_categories[old_section.mixed_categories[old_section.selected_mixed]]);
1612 m_sections[m_selected_outer].page->Hide();
1613 }
1614 m_selected_outer = static_cast<int>(section_index);
1615 SectionGroup& section = m_sections[section_index];
1616 section.page->Show();
1617 // Restore whichever tab row (physical or mixed) was active.
1618 if (section.selected_inner >= 0)
1619 show_inner_page(section_index, section.selected_inner);
1620 else if (section.selected_mixed >= 0)
1621 show_mixed_page(section_index, section.selected_mixed);
1622 m_outer_host_sizer->Layout();
1623}

References Slic3r::GUI::PublishSettingsDialog::SectionGroup::categories, m_categories, m_outer_host_sizer, m_sections, m_selected_outer, Slic3r::GUI::PublishSettingsDialog::SectionGroup::mixed_categories, Slic3r::GUI::PublishSettingsDialog::SectionGroup::page, save_scroll_position(), Slic3r::GUI::PublishSettingsDialog::SectionGroup::selected_inner, Slic3r::GUI::PublishSettingsDialog::SectionGroup::selected_mixed, show_inner_page(), and show_mixed_page().

Referenced by build_option_model(), on_outer_tab_changed(), and refresh_filter().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ShowModal()

◆ subcategory_index_for()

size_t Slic3r::GUI::PublishSettingsDialog::subcategory_index_for ( size_t category_index,
const wxString & title,
const wxString & icon )
private
1314{
1315 Category& category = m_categories[category_index];
1316 for (size_t i = 0; i < category.subs.size(); ++i)
1317 if (category.subs[i].title == title)
1318 return i;
1319
1320 Subcategory sub;
1321 sub.title = title;
1322 if (!title.IsEmpty()) {
1323 sub.header = new ::StaticLine(category.scroll, false, title, icon);
1324 sub.header->SetFont(Label::Head_14);
1325 sub.header->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636")));
1326 auto* wrap = new wxBoxSizer(wxVERTICAL);
1327 wrap->Add(sub.header, 0, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(6));
1328 sub.item = category.list_sizer->Add(wrap, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(5));
1329 }
1330 category.subs.push_back(std::move(sub));
1331 return category.subs.size() - 1;
1332}
wxString title
Definition PublishSettingsDialog.hpp:131

References StateColor::darkModeColorFor(), Label::Head_14, Slic3r::GUI::PublishSettingsDialog::Subcategory::header, Slic3r::GUI::PublishSettingsDialog::Subcategory::item, Slic3r::GUI::PublishSettingsDialog::Category::list_sizer, m_categories, Slic3r::GUI::PublishSettingsDialog::Category::scroll, Slic3r::GUI::PublishSettingsDialog::Category::subs, and Slic3r::GUI::PublishSettingsDialog::Subcategory::title.

Referenced by build_option_model().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ unpublished_mixed_components()

std::vector< MixedDependencyIssue > Slic3r::GUI::PublishSettingsDialog::unpublished_mixed_components ( ) const
private
2069{
2070 std::vector<MixedDependencyIssue> out;
2071 for (const Category& cat : m_categories) {
2072 if (!cat.is_mixed || cat.section != Section::Material)
2073 continue;
2074 // Only enabled mixed slots depend on their components being published.
2075 if (cat.enable_check == nullptr || !cat.enable_check->GetValue())
2076 continue;
2077 const DynamicPrintConfig full = wxGetApp().preset_bundle->full_config();
2078 // Components are 1-based physical filament indices.
2079 for (const unsigned int component : mixed_slot_components(full, cat.filament_slot)) {
2080 const size_t component_slot = size_t(component) - 1;
2081 // Find the component slot's material category (one exists per physical slot).
2082 const Category* comp_cat = nullptr;
2083 for (const Category& other : m_categories) {
2084 if (other.section == Section::Material && !other.is_mixed && other.filament_slot == component_slot) {
2085 comp_cat = &other;
2086 break;
2087 }
2088 }
2089 if (comp_cat == nullptr || comp_cat->enable_check == nullptr)
2090 continue;
2091 // Missing when the component's "Enable" is off, or it is enabled with neither
2092 // "Full Publish" nor the "Type" requirement row checked. Colour never counts:
2093 // the receiver renders the mix from its own components' colours.
2094 if (!comp_cat->enable_check->GetValue()) {
2095 out.push_back({cat.filament_slot, component_slot, MixedDependencyIssue::Reason::Disabled});
2096 continue;
2097 }
2098 if (comp_cat->full_check != nullptr && comp_cat->full_check->GetValue())
2099 continue;
2100 bool type_checked = false;
2101 for (const size_t r : comp_cat->rows) {
2102 const Row& row = m_rows[r];
2103 if (row.kind == RowKind::Type && row.check->GetValue()) {
2104 type_checked = true;
2105 break;
2106 }
2107 }
2108 if (!type_checked)
2109 out.push_back({cat.filament_slot, component_slot, MixedDependencyIssue::Reason::MaterialNotPublished});
2110 }
2111 }
2112 // Deterministic order for the warning rows: by mixed slot, then component slot. The same
2113 // (mix, component) pair cannot repeat: each mix's components come from a config list.
2114 std::sort(out.begin(), out.end(), [](const MixedDependencyIssue& a, const MixedDependencyIssue& b) {
2115 return std::tie(a.mixed_slot, a.component_slot) < std::tie(b.mixed_slot, b.component_slot);
2116 });
2117 return out;
2118}
@ MaterialNotPublished
Definition PublishSettingsDialog.hpp:56
@ Disabled
Definition PublishSettingsDialog.hpp:56

References Slic3r::GUI::PublishSettingsDialog::Row::check, Slic3r::GUI::MixedDependencyIssue::Disabled, Slic3r::GUI::PublishSettingsDialog::Category::enable_check, Slic3r::GUI::PublishSettingsDialog::Category::full_check, Slic3r::GUI::PublishSettingsDialog::Row::kind, m_categories, m_rows, Material, Slic3r::GUI::MixedDependencyIssue::MaterialNotPublished, Slic3r::GUI::PublishSettingsDialog::Category::rows, and Type.

Referenced by PublishSettingsDialog().

Here is the caller graph for this function:

◆ update_em_unit()

void Slic3r::GUI::DPIAware< wxDialog >::update_em_unit ( )
inlineprivateinherited
250 {
251 // Linux specific issue : get_dpi_for_window(this) still doesn't responce to the Display's scale in new wxWidgets(3.1.3).
252 // So, calculate the m_em_unit value from the font size, as before
253#if !defined(__WXGTK__)
255#else
256 // initialize default width_unit according to the width of the one symbol ("m") of the currently active font of this window.
257 m_em_unit = std::max<size_t>(10, this->GetTextExtent("m").x - 1);
258#endif // __WXGTK__
259 }

Member Data Documentation

◆ m_can_rescale

bool Slic3r::GUI::DPIAware< wxDialog >::m_can_rescale
privateinherited
235{ true };

◆ m_categories

◆ m_em_unit

int Slic3r::GUI::DPIAware< wxDialog >::m_em_unit
privateinherited

◆ m_fb_sizer

wxBoxSizer* Slic3r::GUI::PublishSettingsDialog::m_fb_sizer {nullptr}
private
292{nullptr}; // "All"/"None" buttons sizer

Referenced by PublishSettingsDialog(), and refresh_filter().

◆ m_filter_box

TextInput* Slic3r::GUI::PublishSettingsDialog::m_filter_box {nullptr}
private
296{nullptr};

Referenced by PublishSettingsDialog(), and on_dpi_changed().

◆ m_filter_ctrl

wxTextCtrl* Slic3r::GUI::PublishSettingsDialog::m_filter_ctrl {nullptr}
private
297{nullptr};

Referenced by PublishSettingsDialog(), select_visible(), and show_menu().

◆ m_filter_mode

FilterMode Slic3r::GUI::PublishSettingsDialog::m_filter_mode {FilterMode::Text}
private

◆ m_force_rescale

bool Slic3r::GUI::DPIAware< wxDialog >::m_force_rescale
privateinherited
236{ false };

◆ m_info_allsel

wxString Slic3r::GUI::PublishSettingsDialog::m_info_allsel
private

◆ m_info_empty

wxString Slic3r::GUI::PublishSettingsDialog::m_info_empty
private

◆ m_info_mix

wxString Slic3r::GUI::PublishSettingsDialog::m_info_mix
private

◆ m_info_nonsel

wxString Slic3r::GUI::PublishSettingsDialog::m_info_nonsel
private

◆ m_menu

ScalableBitmap Slic3r::GUI::PublishSettingsDialog::m_menu
private

◆ m_menu_button

wxStaticBitmap* Slic3r::GUI::PublishSettingsDialog::m_menu_button {nullptr}
private
298{nullptr};

Referenced by PublishSettingsDialog(), and on_dpi_changed().

◆ m_new_font_point_size

int Slic3r::GUI::DPIAware< wxDialog >::m_new_font_point_size
privateinherited

◆ m_normal_font

wxFont Slic3r::GUI::DPIAware< wxDialog >::m_normal_font
privateinherited

◆ m_outer_host

wxPanel* Slic3r::GUI::PublishSettingsDialog::m_outer_host {nullptr}
private
289{nullptr};

Referenced by PublishSettingsDialog(), and section_group_for().

◆ m_outer_host_sizer

wxBoxSizer* Slic3r::GUI::PublishSettingsDialog::m_outer_host_sizer {nullptr}
private

◆ m_outer_tabs

TabCtrl* Slic3r::GUI::PublishSettingsDialog::m_outer_tabs {nullptr}
private

◆ m_prev_scale_factor

float Slic3r::GUI::DPIAware< wxDialog >::m_prev_scale_factor
privateinherited

◆ m_pseudo_chip

wxStaticText* Slic3r::GUI::PublishSettingsDialog::m_pseudo_chip {nullptr}
private
301{nullptr};

Referenced by PublishSettingsDialog(), and refresh_filter().

◆ m_rows

◆ m_scale_factor

float Slic3r::GUI::DPIAware< wxDialog >::m_scale_factor
privateinherited

◆ m_search

ScalableBitmap Slic3r::GUI::PublishSettingsDialog::m_search
private

◆ m_sections

◆ m_selected_outer

int Slic3r::GUI::PublishSettingsDialog::m_selected_outer {-1}
private

The documentation for this class was generated from the following files: