mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-04 01:20:57 +00:00
Make sure settings tab are still marked as modified even if modified variant is not currently selected
This commit is contained in:
@@ -430,6 +430,17 @@ enum FilamentMapMode {
|
||||
|
||||
extern std::string get_extruder_variant_string(ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type);
|
||||
|
||||
static std::set<NozzleVolumeType> get_valid_nozzle_volume_type() {
|
||||
std::set<NozzleVolumeType> type;
|
||||
for (int i = 0; i <= nvtMaxNozzleVolumeType; ++i) {
|
||||
auto t = static_cast<NozzleVolumeType>(i);
|
||||
// TODO: Orca: Support hybrid
|
||||
//if (t == nvtHybrid) continue;
|
||||
type.insert(t);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string get_nozzle_volume_type_string(NozzleVolumeType nozzle_volume_type);
|
||||
|
||||
static std::string bed_type_to_gcode_string(const BedType type)
|
||||
|
||||
@@ -88,6 +88,15 @@ static void validate_custom_gcode_cb(Tab* tab, const wxString& title, const t_co
|
||||
|
||||
static const std::vector<std::string> plate_keys = { "curr_bed_type", "skirt_start_angle", "first_layer_print_sequence", "first_layer_sequence_choice", "other_layers_print_sequence", "other_layers_sequence_choice", "print_sequence", "spiral_mode"};
|
||||
|
||||
static std::pair<std::string, std::string> extruder_variant_keys[]{
|
||||
{}, // invalid
|
||||
{"print_extruder_id", "print_extruder_variant"}, // Preset::TYPE_PRINT
|
||||
{}, // invalid
|
||||
{"", "filament_extruder_variant"}, // Preset::TYPE_FILAMENT filament don't use id anymore
|
||||
{}, // invalid
|
||||
{"printer_extruder_id", "printer_extruder_variant"}, // Preset::TYPE_PRINTER
|
||||
};
|
||||
|
||||
void Tab::Highlighter::set_timer_owner(wxEvtHandler* owner, int timerid/* = wxID_ANY*/)
|
||||
{
|
||||
m_timer.SetOwner(owner, timerid);
|
||||
@@ -487,12 +496,21 @@ void Tab::create_preset_tab()
|
||||
m_main_sizer->Add(m_tabctrl, 0, wxEXPAND | wxALL, 0 );
|
||||
|
||||
if (dynamic_cast<TabPrinter *>(this) || dynamic_cast<TabPrint *>(this)) {
|
||||
m_extruder_switch = new SwitchButton(panel);
|
||||
m_extruder_switch = new MultiSwitchButton(panel);
|
||||
m_extruder_switch->SetMaxSize({em_unit(this) * 24, -1});
|
||||
m_extruder_switch->SetLabels(_L("Left"), _L("Right"));
|
||||
m_extruder_switch->Bind(wxEVT_TOGGLEBUTTON, [this] (auto & evt) {
|
||||
m_extruder_switch->Bind(wxCUSTOMEVT_MULTISWITCH_SELECTION, [this](auto &evt) {
|
||||
evt.Skip();
|
||||
switch_excluder(evt.GetInt());
|
||||
int selection = evt.GetInt();
|
||||
|
||||
int extruder_id;
|
||||
NozzleVolumeType nozzle_type;
|
||||
parse_extruder_selection(selection, extruder_id, nozzle_type);
|
||||
int extruder_count = m_preset_bundle->get_printer_extruder_count();
|
||||
m_actual_nozzle_volumes.resize(extruder_count, NozzleVolumeType::nvtStandard);
|
||||
if (extruder_id >= 0 && extruder_id < m_preset_bundle->get_printer_extruder_count())
|
||||
m_actual_nozzle_volumes[extruder_id] = nozzle_type;
|
||||
|
||||
switch_excluder(extruder_id);
|
||||
reload_config();
|
||||
update_changed_ui();
|
||||
});
|
||||
@@ -557,6 +575,79 @@ void Tab::create_preset_tab()
|
||||
m_completed = true;
|
||||
}
|
||||
|
||||
void Tab::parse_extruder_selection(int selection, int &extruder_id, NozzleVolumeType &nozzle_type)
|
||||
{
|
||||
auto nozzle_volumes = m_preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type");
|
||||
int extruder_nums = m_preset_bundle->get_printer_extruder_count();
|
||||
|
||||
int current_index = 0;
|
||||
|
||||
for (int i = 0; i < extruder_nums; ++i) {
|
||||
NozzleVolumeType volume_type = NozzleVolumeType(nozzle_volumes->values[i]);
|
||||
|
||||
// TODO: Orca: Support hybrid
|
||||
//if (volume_type == NozzleVolumeType::nvtHybrid) {
|
||||
// if (selection == current_index) {
|
||||
// extruder_id = i;
|
||||
// nozzle_type = NozzleVolumeType::nvtStandard;
|
||||
// return;
|
||||
// } else if (selection == current_index + 1) {
|
||||
// extruder_id = i;
|
||||
// nozzle_type = NozzleVolumeType::nvtHighFlow;
|
||||
// return;
|
||||
// }
|
||||
// current_index += 2;
|
||||
//} else {
|
||||
if (selection == current_index) {
|
||||
extruder_id = i;
|
||||
nozzle_type = volume_type;
|
||||
return;
|
||||
}
|
||||
current_index += 1;
|
||||
//}
|
||||
}
|
||||
|
||||
extruder_id = 0;
|
||||
nozzle_type = NozzleVolumeType::nvtStandard;
|
||||
}
|
||||
|
||||
int Tab::calculate_selection_index_for_extruder(int extruder_id, NozzleVolumeType nozzle_type)
|
||||
{
|
||||
auto nozzle_volumes = m_preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type");
|
||||
int extruder_nums = m_preset_bundle->get_printer_extruder_count();
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < extruder_nums; ++i) {
|
||||
if (i == extruder_id) {
|
||||
// TODO: Orca: Support hybrid
|
||||
NozzleVolumeType volume_type = NozzleVolumeType(nozzle_volumes->values[i]);
|
||||
/*if (volume_type == NozzleVolumeType::nvtHybrid) {
|
||||
return nozzle_type == NozzleVolumeType::nvtHighFlow ? index + 1 : index;
|
||||
} else*/ {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
NozzleVolumeType volume_type = NozzleVolumeType(nozzle_volumes->values[i]);
|
||||
index += /*(volume_type == NozzleVolumeType::nvtHybrid) ? 2 :*/ 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Tab::get_current_active_extruder()
|
||||
{
|
||||
if (m_extruder_switch && m_extruder_switch->IsThisEnabled()) {
|
||||
int selection = m_extruder_switch->GetSelection();
|
||||
int extruder_id;
|
||||
NozzleVolumeType nozzle_type;
|
||||
parse_extruder_selection(selection, extruder_id, nozzle_type);
|
||||
return extruder_id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Tab::add_scaled_button(wxWindow* parent,
|
||||
ScalableButton** btn,
|
||||
const std::string& icon_name,
|
||||
@@ -917,7 +1008,8 @@ void Tab::update_changed_ui()
|
||||
}
|
||||
|
||||
update_custom_dirty(dirty_options, nonsys_options);
|
||||
|
||||
update_all_extruder_options_status();
|
||||
|
||||
filter_diff_option(dirty_options);
|
||||
filter_diff_option(nonsys_options);
|
||||
|
||||
@@ -936,6 +1028,7 @@ void Tab::update_changed_ui()
|
||||
}
|
||||
|
||||
decorate();
|
||||
update_extruder_switch_colors();
|
||||
|
||||
wxTheApp->CallAfter([this]() {
|
||||
if (parent()) //To avoid a crash, parent should be exist for a moment of a tree updating
|
||||
@@ -951,6 +1044,168 @@ void add_correct_opts_to_options_list(const std::string &opt_key, std::map<std::
|
||||
map.emplace(opt_key + "#0", value);
|
||||
}
|
||||
|
||||
void Tab::update_all_extruder_options_status()
|
||||
{
|
||||
if (!m_extruder_switch && !m_variant_combo) {
|
||||
return;
|
||||
}
|
||||
m_all_extruder_options_status.clear();
|
||||
|
||||
int extruder_count = m_preset_bundle->get_printer_extruder_count();
|
||||
auto extruders = m_preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnumsGeneric>("extruder_type");
|
||||
auto nozzle_volumes = m_preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type");
|
||||
|
||||
std::set<int> all_config_indices;
|
||||
for (int extruder_id = 0; extruder_id < extruder_count; ++extruder_id) {
|
||||
for (auto nozzle_type : get_valid_nozzle_volume_type()) {
|
||||
auto variant_keys = extruder_variant_keys[m_type >= Preset::TYPE_COUNT ? Preset::TYPE_PRINT : m_type];
|
||||
int config_index = m_config->get_index_for_extruder(
|
||||
extruder_id + 1,
|
||||
variant_keys.first,
|
||||
ExtruderType(extruders->values[extruder_id]),
|
||||
nozzle_type,
|
||||
variant_keys.second
|
||||
);
|
||||
if (config_index >= 0) {
|
||||
all_config_indices.insert(config_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto dirty_options = m_presets->current_dirty_options(true);
|
||||
auto nonsys_options = m_presets->current_different_from_parent_options(true);
|
||||
auto filter_extruder_options = [](const std::vector<std::string>& options) {
|
||||
std::vector<std::string> filtered_options;
|
||||
for (const auto& opt : options) {
|
||||
if (opt.find('#') != std::string::npos) {
|
||||
filtered_options.push_back(opt);
|
||||
}
|
||||
}
|
||||
return filtered_options;
|
||||
};
|
||||
|
||||
auto filtered_dirty_options = filter_extruder_options(dirty_options);
|
||||
auto filtered_nonsys_options = filter_extruder_options(nonsys_options);
|
||||
|
||||
for (int config_index : all_config_indices) {
|
||||
int status_value = m_opt_status_value;
|
||||
for (const auto &opt_key : filtered_dirty_options) {
|
||||
m_all_extruder_options_status[opt_key] = status_value & ~osInitValue;
|
||||
}
|
||||
for (const auto &opt_key : filtered_nonsys_options) {
|
||||
auto iter = m_all_extruder_options_status.find(opt_key);
|
||||
if (iter != m_all_extruder_options_status.end()) {
|
||||
iter->second &= ~osSystemValue;
|
||||
} else {
|
||||
m_all_extruder_options_status[opt_key] = status_value & ~osSystemValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::update_extruder_switch_colors()
|
||||
{
|
||||
if (!m_extruder_switch && !m_variant_combo) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto options = generate_extruder_options();
|
||||
auto extruders = m_preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnumsGeneric>("extruder_type");
|
||||
|
||||
for (size_t switch_index = 0; switch_index < options.size(); ++switch_index) {
|
||||
int selection = m_extruder_switch ? m_extruder_switch->GetSelection() : (m_variant_combo ? m_variant_combo->GetSelection() : 0);
|
||||
if (switch_index == selection) continue;
|
||||
|
||||
bool sys_extruder = true;
|
||||
bool modified_extruder = false;
|
||||
std::vector<PageShp> pages_to_check;
|
||||
|
||||
if (m_active_page) {
|
||||
if (m_active_page->title() == "Speed" || m_active_page->title() == "Motion ability" || m_active_page->title() == "Filament" ||
|
||||
m_active_page->title() == "Setting Overrides" || m_active_page->title() == "Multimaterial") {
|
||||
for (auto page_ptr : m_pages) {
|
||||
if (page_ptr.get() == m_active_page) {
|
||||
pages_to_check.push_back(page_ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pages_to_check.empty()) {
|
||||
continue;
|
||||
}
|
||||
check_extruder_options_status(switch_index, sys_extruder, modified_extruder, pages_to_check);
|
||||
|
||||
StateColor default_color(std::make_pair(0x6B6B6B, (int) StateColor::NotChecked), std::make_pair(0xFFFFFE, (int) StateColor::Normal));
|
||||
StateColor color = modified_extruder ? StateColor(m_modified_label_clr) : default_color;
|
||||
|
||||
if (m_extruder_switch)
|
||||
m_extruder_switch->SetButtonTextColor(switch_index, color);
|
||||
if (m_variant_combo) {
|
||||
Button *btn = m_variant_combo->GetButton(switch_index);
|
||||
if (btn) {
|
||||
m_variant_combo->SetButtonTextColor(switch_index, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tab::check_extruder_options_status(int index, bool &sys_extruder, bool &modified_extruder, const std::vector<PageShp>& pages_to_check)
|
||||
{
|
||||
int config_index = index;
|
||||
if (m_type == Preset::TYPE_PRINT || m_type == Preset::TYPE_PRINTER) {
|
||||
int extruder_id;
|
||||
NozzleVolumeType nozzle_type;
|
||||
parse_extruder_selection(index, extruder_id, nozzle_type);
|
||||
|
||||
auto extruders = m_preset_bundle->printers.get_edited_preset().config.option<ConfigOptionEnumsGeneric>("extruder_type");
|
||||
auto variant_keys = extruder_variant_keys[m_type >= Preset::TYPE_COUNT ? Preset::TYPE_PRINT : m_type];
|
||||
config_index = m_config->get_index_for_extruder(
|
||||
extruder_id + 1,
|
||||
variant_keys.first,
|
||||
ExtruderType(extruders->values[extruder_id]),
|
||||
nozzle_type,
|
||||
variant_keys.second
|
||||
);
|
||||
}
|
||||
|
||||
for (auto page : pages_to_check) {
|
||||
/*if (page->title() != "Speed" && page->title() != "Motion ability" && page->title() != "Filament" && page->title() != "Setting Overrides" && page->title() != "Multimaterial") {
|
||||
continue;
|
||||
}*/
|
||||
for (auto group : page->m_optgroups) {
|
||||
for (const auto &kvp : group->opt_map()) {
|
||||
std::string base_opt_key = kvp.second.first;
|
||||
// For filament tab, common options will not change color when edited
|
||||
if (m_type == Preset::TYPE_FILAMENT && kvp.second.second == -1) {
|
||||
continue;
|
||||
}
|
||||
std::string target_opt_key = base_opt_key + "#" + std::to_string(config_index);
|
||||
|
||||
auto status_iter = m_all_extruder_options_status.find(target_opt_key);
|
||||
if (status_iter != m_all_extruder_options_status.end()) {
|
||||
bool found_modified_for_this_config = false;
|
||||
const bool deep_compare = (m_type == Preset::TYPE_PRINTER || m_type == Preset::TYPE_PRINT || m_type == Preset::TYPE_FILAMENT || m_type == Preset::TYPE_SLA_MATERIAL ||
|
||||
m_type == Preset::TYPE_MODEL);
|
||||
auto original_dirty_options = m_presets->current_dirty_options(deep_compare);
|
||||
for (const std::string &orig_opt : original_dirty_options) {
|
||||
if (orig_opt == target_opt_key) {
|
||||
found_modified_for_this_config = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_modified_for_this_config) {
|
||||
sys_extruder = (status_iter->second & osSystemValue) != 0;
|
||||
modified_extruder |= (status_iter->second & osInitValue) == 0;
|
||||
|
||||
if (!sys_extruder && modified_extruder) { return; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void Tab::init_options_list()
|
||||
{
|
||||
if (!m_options_list.empty())
|
||||
@@ -1076,6 +1331,13 @@ void Tab::update_changed_tree_ui()
|
||||
get_sys_and_mod_flags("compatible_printers", sys_page, modified_page);
|
||||
}
|
||||
}
|
||||
if (page->title() == "Speed" || page->title() == "Motion ability" || page->title() == "Filament" || page->title() == "Setting Overrides" || page->title() == "Multimaterial") {
|
||||
auto options = generate_extruder_options();
|
||||
for (size_t switch_index = 0; switch_index < options.size(); ++switch_index) {
|
||||
std::vector<PageShp> pages_to_check = { page };
|
||||
check_extruder_options_status(switch_index, sys_page, modified_page, pages_to_check);
|
||||
}
|
||||
}
|
||||
for (auto group : page->m_optgroups)
|
||||
{
|
||||
if (!sys_page && modified_page)
|
||||
@@ -1292,9 +1554,9 @@ void Tab::msw_rescale()
|
||||
bmp->msw_rescale();
|
||||
|
||||
if (m_mode_view)
|
||||
{
|
||||
m_mode_view->Rescale();
|
||||
}
|
||||
if (m_extruder_switch)
|
||||
m_extruder_switch->Rescale();
|
||||
if (m_variant_combo)
|
||||
m_variant_combo->Rescale();
|
||||
|
||||
@@ -5372,7 +5634,7 @@ void TabPrinter::toggle_options()
|
||||
auto get_index_for_extruder =
|
||||
[this, &extruders, &nozzle_volumes](int extruder_id, int stride = 1) {
|
||||
return m_config->get_index_for_extruder(extruder_id + 1, "printer_extruder_id",
|
||||
ExtruderType(extruders->values[extruder_id]), NozzleVolumeType(nozzle_volumes->values[extruder_id]), "printer_extruder_variant", stride);
|
||||
ExtruderType(extruders->values[extruder_id]), get_actual_nozzle_volume_type(extruder_id), "printer_extruder_variant", stride);
|
||||
};
|
||||
|
||||
//BBS: whether the preset is Bambu Lab printer
|
||||
@@ -6460,7 +6722,11 @@ bool Tab::tree_sel_change_delayed(wxCommandEvent& event)
|
||||
// update_undo_buttons();
|
||||
this->OnActivate();
|
||||
m_parent->set_active_tab(this);
|
||||
GetParent()->Layout();
|
||||
wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo;
|
||||
if (variant_ctrl) {
|
||||
m_main_sizer->Show(variant_ctrl, variant_ctrl->IsThisEnabled() && !m_active_page->m_opt_id_map.empty() && !m_active_page->title().StartsWith("Extruder "));
|
||||
GetParent()->Layout();
|
||||
}
|
||||
|
||||
m_page_view->Thaw();
|
||||
return false;
|
||||
@@ -6471,11 +6737,9 @@ bool Tab::tree_sel_change_delayed(wxCommandEvent& event)
|
||||
return false;
|
||||
|
||||
m_active_page = page;
|
||||
if (m_extruder_switch) {
|
||||
m_main_sizer->Show(m_extruder_switch, m_extruder_switch->IsEnabled() && !m_active_page->m_opt_id_map.empty() && !m_active_page->title().StartsWith("Extruder"));
|
||||
GetParent()->Layout();
|
||||
} else if (m_variant_combo) {
|
||||
m_main_sizer->Show(m_variant_combo, m_variant_combo->IsEnabled() && !m_active_page->m_opt_id_map.empty());
|
||||
wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo;
|
||||
if (variant_ctrl) {
|
||||
m_main_sizer->Show(variant_ctrl, variant_ctrl->IsThisEnabled() && !m_active_page->m_opt_id_map.empty() && !m_active_page->title().StartsWith("Extruder"));
|
||||
GetParent()->Layout();
|
||||
}
|
||||
|
||||
@@ -7303,21 +7567,24 @@ void Tab::update_extruder_variants(int extruder_id)
|
||||
int extruder_nums = m_preset_bundle->get_printer_extruder_count();
|
||||
nozzle_volumes->values.resize(extruder_nums);
|
||||
if (extruder_nums == 2) {
|
||||
auto nozzle_volumes_def = m_preset_bundle->project_config.def()->get("nozzle_volume_type");
|
||||
wxString left, right;
|
||||
for (size_t i = 0; i < nozzle_volumes_def->enum_labels.size(); ++i) {
|
||||
if (nozzle_volumes->values[0] == i) left = _L(nozzle_volumes_def->enum_labels[i]);
|
||||
if (nozzle_volumes->values[1] == i) right = _L(nozzle_volumes_def->enum_labels[i]);
|
||||
auto options = generate_extruder_options();
|
||||
m_extruder_switch->SetOptions(options);
|
||||
|
||||
int selection_index;
|
||||
if (extruder_id >= 0) {
|
||||
NozzleVolumeType current_nozzle_type = get_actual_nozzle_volume_type(extruder_id);
|
||||
selection_index = calculate_selection_index_for_extruder(extruder_id, current_nozzle_type);
|
||||
} else {
|
||||
selection_index = m_extruder_switch->GetSelection();
|
||||
if (selection_index < 0) {
|
||||
selection_index = 0;
|
||||
}
|
||||
}
|
||||
m_extruder_switch->SetLabels(wxString::Format(_L("Left: %s"), left), wxString::Format(_L("Right: %s"), right));
|
||||
m_extruder_switch->SetValue(extruder_id == 1);
|
||||
|
||||
m_extruder_switch->SetSelection(selection_index);
|
||||
m_extruder_switch->Enable(true);
|
||||
assert(m_extruder_switch->IsEnabled());
|
||||
} else {
|
||||
m_extruder_switch->Enable(false);
|
||||
m_main_sizer->Show(m_extruder_switch, false);
|
||||
GetParent()->Layout();
|
||||
return;
|
||||
}
|
||||
} else if (m_variant_combo) {
|
||||
if (extruder_id >= 0)
|
||||
@@ -7333,29 +7600,43 @@ void Tab::update_extruder_variants(int extruder_id)
|
||||
m_variant_combo->Enable(options.size() > 1);
|
||||
}
|
||||
switch_excluder(extruder_id);
|
||||
if (m_extruder_switch) {
|
||||
m_main_sizer->Show(m_extruder_switch, m_active_page && !m_active_page->m_opt_id_map.empty());
|
||||
GetParent()->Layout();
|
||||
} else if (m_variant_combo) {
|
||||
m_main_sizer->Show(m_variant_combo, m_variant_combo->IsEnabled() && m_active_page && !m_active_page->m_opt_id_map.empty());
|
||||
wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo;
|
||||
if (variant_ctrl) {
|
||||
m_main_sizer->Show(variant_ctrl, variant_ctrl->IsThisEnabled() && m_active_page && !m_active_page->m_opt_id_map.empty() && !m_active_page->title().StartsWith("Extruder "));
|
||||
GetParent()->Layout();
|
||||
}
|
||||
}
|
||||
|
||||
NozzleVolumeType Tab::get_actual_nozzle_volume_type(int extruder_id)
|
||||
{
|
||||
int extruder_count = m_preset_bundle->get_printer_extruder_count();
|
||||
auto nozzle_volumes = m_preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type");
|
||||
if (extruder_count == 1) {
|
||||
if (extruder_id < 0)
|
||||
return NozzleVolumeType::nvtStandard;
|
||||
|
||||
return NozzleVolumeType(nozzle_volumes->values[extruder_id]);
|
||||
}
|
||||
|
||||
if (extruder_id < 0 || extruder_id >= extruder_count)
|
||||
return NozzleVolumeType::nvtStandard;
|
||||
|
||||
if (m_actual_nozzle_volumes.size() != static_cast<size_t>(extruder_count))
|
||||
m_actual_nozzle_volumes.resize(extruder_count, NozzleVolumeType::nvtStandard);
|
||||
|
||||
return m_actual_nozzle_volumes[extruder_id];
|
||||
}
|
||||
|
||||
void Tab::switch_excluder(int extruder_id)
|
||||
{
|
||||
Preset & printer_preset = m_preset_bundle->printers.get_edited_preset();
|
||||
auto nozzle_volumes = m_preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type");
|
||||
auto extruders = printer_preset.config.option<ConfigOptionEnumsGeneric>("extruder_type");
|
||||
std::pair<std::string, std::string> variant_keys[]{
|
||||
{}, {"print_extruder_id", "print_extruder_variant"}, // Preset::TYPE_PRINT
|
||||
{}, {"", "filament_extruder_variant"}, // Preset::TYPE_FILAMENT filament don't use id anymore
|
||||
{}, {"printer_extruder_id", "printer_extruder_variant"}, // Preset::TYPE_PRINTER
|
||||
};
|
||||
|
||||
if (!m_variant_combo && (extruder_id >= (int)nozzle_volumes->size() || extruder_id >= (int)extruders->size()))
|
||||
extruder_id = 0;
|
||||
if (m_extruder_switch && m_type != Preset::TYPE_PRINTER) {
|
||||
int current_extruder = m_extruder_switch->GetValue() ? 1 : 0;
|
||||
int current_extruder = get_current_active_extruder();
|
||||
if (extruder_id == -1)
|
||||
extruder_id = current_extruder;
|
||||
else if (extruder_id != current_extruder)
|
||||
@@ -7370,15 +7651,16 @@ void Tab::switch_excluder(int extruder_id)
|
||||
return;
|
||||
}
|
||||
auto get_index_for_extruder =
|
||||
[this, &extruders, &nozzle_volumes, variant_keys = variant_keys[m_type >= Preset::TYPE_COUNT ? Preset::TYPE_PRINT : m_type]](int extruder_id, int stride = 1) {
|
||||
[this, &extruders, &nozzle_volumes, variant_keys = extruder_variant_keys[m_type >= Preset::TYPE_COUNT ? Preset::TYPE_PRINT : m_type]](int extruder_id, int stride = 1) {
|
||||
return m_config->get_index_for_extruder(extruder_id + 1, variant_keys.first,
|
||||
ExtruderType(extruders->values[extruder_id]), NozzleVolumeType(nozzle_volumes->values[extruder_id]), variant_keys.second, stride);
|
||||
ExtruderType(extruders->values[extruder_id]), get_actual_nozzle_volume_type(extruder_id), variant_keys.second, stride);
|
||||
};
|
||||
auto index = m_variant_combo ? extruder_id : get_index_for_extruder(extruder_id == -1 ? 0 : extruder_id);
|
||||
if (index < 0)
|
||||
return;
|
||||
if (m_variant_combo)
|
||||
m_variant_combo->SetClientData(reinterpret_cast<void *>(static_cast<std::uintptr_t>(index)));
|
||||
if (m_extruder_switch) m_extruder_switch->SetClientData(reinterpret_cast<void*>(static_cast<std::uintptr_t>(index)));
|
||||
if (m_variant_combo) m_variant_combo->SetClientData(reinterpret_cast<void *>(static_cast<std::uintptr_t>(index)));
|
||||
wxWindow *variant_ctrl = m_extruder_switch ? (wxWindow *) m_extruder_switch : m_variant_combo;
|
||||
for (auto page : m_pages) {
|
||||
bool is_extruder = false;
|
||||
if (m_type == Preset::TYPE_PRINTER) {
|
||||
|
||||
@@ -251,6 +251,7 @@ protected:
|
||||
std::vector<Preset::Type> m_dependent_tabs;
|
||||
enum OptStatus { osSystemValue = 1, osInitValue = 2 };
|
||||
std::map<std::string, int> m_options_list;
|
||||
std::map<std::string, int> m_all_extruder_options_status;
|
||||
int m_opt_status_value = 0;
|
||||
|
||||
bool m_is_modified_values{ false };
|
||||
@@ -307,8 +308,9 @@ public:
|
||||
int m_update_cnt = 0;
|
||||
|
||||
ModeSwitchButton *m_mode_view = nullptr;
|
||||
SwitchButton *m_extruder_switch = nullptr;
|
||||
MultiSwitchButton *m_variant_combo = nullptr;
|
||||
MultiSwitchButton * m_extruder_switch = nullptr;
|
||||
MultiSwitchButton * m_variant_combo = nullptr;
|
||||
std::vector<NozzleVolumeType> m_actual_nozzle_volumes;
|
||||
|
||||
public:
|
||||
// BBS
|
||||
@@ -361,8 +363,11 @@ public:
|
||||
void decorate();
|
||||
void update_changed_ui();
|
||||
void get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page);
|
||||
void update_changed_tree_ui();
|
||||
void update_changed_tree_ui();
|
||||
void update_undo_buttons();
|
||||
void update_extruder_switch_colors();
|
||||
void update_all_extruder_options_status();
|
||||
void check_extruder_options_status(int index, bool &sys_extruder, bool &modified_extruder, const std::vector<PageShp>& pages_to_check);
|
||||
|
||||
void on_roll_back_value(const bool to_sys = false);
|
||||
|
||||
@@ -431,7 +436,12 @@ public:
|
||||
|
||||
void update_extruder_variants(int extruder_id = -1);
|
||||
void switch_excluder(int extruder_id = -1);
|
||||
std::vector<wxString> generate_extruder_options();
|
||||
void parse_extruder_selection(int selection, int &extruder_id, NozzleVolumeType &nozzle_type);
|
||||
int calculate_selection_index_for_extruder(int extruder_id, NozzleVolumeType nozzle_type);
|
||||
int get_current_active_extruder();
|
||||
|
||||
std::vector<wxString> generate_extruder_options();
|
||||
NozzleVolumeType get_actual_nozzle_volume_type(int extruder_id);
|
||||
|
||||
protected:
|
||||
void create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, const std::string& path, widget_t widget);
|
||||
|
||||
@@ -395,6 +395,171 @@ void ModeSwitchButton::update_tooltip()
|
||||
SetToolTip(m_tooltips[m_selection]);
|
||||
}
|
||||
|
||||
SwitchBoard::SwitchBoard(wxWindow *parent, wxString leftL, wxString right, wxSize size)
|
||||
: wxWindow(parent, wxID_ANY, wxDefaultPosition, size)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
SetDoubleBuffered(true);
|
||||
#endif //__WINDOWS__
|
||||
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
leftLabel = leftL;
|
||||
rightLabel = right;
|
||||
|
||||
SetMinSize(size);
|
||||
SetMaxSize(size);
|
||||
|
||||
Bind(wxEVT_PAINT, &SwitchBoard::paintEvent, this);
|
||||
Bind(wxEVT_LEFT_DOWN, &SwitchBoard::on_left_down, this);
|
||||
|
||||
Bind(wxEVT_ENTER_WINDOW, [this](auto &e) { SetCursor(wxCURSOR_HAND); });
|
||||
Bind(wxEVT_LEAVE_WINDOW, [this](auto &e) { SetCursor(wxCURSOR_ARROW); });
|
||||
}
|
||||
|
||||
void SwitchBoard::updateState(wxString target)
|
||||
{
|
||||
if (target.empty()) {
|
||||
if (!switch_left && !switch_right) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch_left = false;
|
||||
switch_right = false;
|
||||
} else {
|
||||
if (target == "left") {
|
||||
if (switch_left && !switch_right) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch_left = true;
|
||||
switch_right = false;
|
||||
} else if (target == "right") {
|
||||
if (!switch_left && switch_right) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch_left = false;
|
||||
switch_right = true;
|
||||
}
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SwitchBoard::paintEvent(wxPaintEvent &evt)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
render(dc);
|
||||
}
|
||||
|
||||
void SwitchBoard::render(wxDC &dc)
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
wxSize size = GetSize();
|
||||
wxMemoryDC memdc;
|
||||
wxBitmap bmp(size.x, size.y);
|
||||
memdc.SelectObject(bmp);
|
||||
memdc.Blit({0, 0}, size, &dc, {0, 0});
|
||||
|
||||
{
|
||||
wxGCDC dc2(memdc);
|
||||
doRender(dc2);
|
||||
}
|
||||
|
||||
memdc.SelectObject(wxNullBitmap);
|
||||
dc.DrawBitmap(bmp, 0, 0);
|
||||
#else
|
||||
doRender(dc);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SwitchBoard::doRender(wxDC &dc)
|
||||
{
|
||||
wxColour disable_color = wxColour(0xCECECE);
|
||||
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
|
||||
if (is_enable) {dc.SetBrush(wxBrush(0xeeeeee));
|
||||
} else {dc.SetBrush(disable_color);}
|
||||
dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 8);
|
||||
|
||||
/*left*/
|
||||
if (switch_left) {
|
||||
is_enable ? dc.SetBrush(wxBrush(wxColour(0, 150, 136))) : dc.SetBrush(disable_color);
|
||||
dc.DrawRoundedRectangle(0, 0, GetSize().x / 2, GetSize().y, 8);
|
||||
}
|
||||
|
||||
if (switch_left) {
|
||||
dc.SetTextForeground(*wxWHITE);
|
||||
} else {
|
||||
dc.SetTextForeground(0x333333);
|
||||
}
|
||||
|
||||
dc.SetFont(::Label::Body_13);
|
||||
Slic3r::GUI::WxFontUtils::get_suitable_font_size(0.6 * GetSize().GetHeight(), dc);
|
||||
|
||||
auto left_txt_size = dc.GetTextExtent(leftLabel);
|
||||
dc.DrawText(leftLabel, wxPoint((GetSize().x / 2 - left_txt_size.x) / 2, (GetSize().y - left_txt_size.y) / 2));
|
||||
|
||||
/*right*/
|
||||
if (switch_right) {
|
||||
if (is_enable) {dc.SetBrush(wxBrush(wxColour(0, 150, 136)));
|
||||
} else {dc.SetBrush(disable_color);}
|
||||
dc.DrawRoundedRectangle(GetSize().x / 2, 0, GetSize().x / 2, GetSize().y, 8);
|
||||
}
|
||||
|
||||
auto right_txt_size = dc.GetTextExtent(rightLabel);
|
||||
if (switch_right) {
|
||||
dc.SetTextForeground(*wxWHITE);
|
||||
} else {
|
||||
dc.SetTextForeground(0x333333);
|
||||
}
|
||||
dc.DrawText(rightLabel, wxPoint((GetSize().x / 2 - right_txt_size.x) / 2 + GetSize().x / 2, (GetSize().y - right_txt_size.y) / 2));
|
||||
|
||||
}
|
||||
|
||||
void SwitchBoard::on_left_down(wxMouseEvent &evt)
|
||||
{
|
||||
if (!is_enable) {
|
||||
return;
|
||||
}
|
||||
int index = -1;
|
||||
auto pos = ClientToScreen(evt.GetPosition());
|
||||
auto rect = ClientToScreen(wxPoint(0, 0));
|
||||
|
||||
if (pos.x > 0 && pos.x < rect.x + GetSize().x / 2) {
|
||||
switch_left = true;
|
||||
switch_right = false;
|
||||
index = 1;
|
||||
} else {
|
||||
switch_left = false;
|
||||
switch_right = true;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
if (auto_disable_when_switch)
|
||||
{
|
||||
is_enable = false;// make it disable while switching
|
||||
}
|
||||
Refresh();
|
||||
|
||||
wxCommandEvent event(wxCUSTOMEVT_SWITCH_POS);
|
||||
event.SetInt(index);
|
||||
wxPostEvent(this, event);
|
||||
}
|
||||
|
||||
bool SwitchBoard::Enable(bool enable /* = true */)
|
||||
{
|
||||
if (is_enable == enable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
is_enable = enable;
|
||||
Refresh();
|
||||
return true;
|
||||
}
|
||||
|
||||
MultiSwitchButton::MultiSwitchButton(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style)
|
||||
: StaticBox(parent, id, pos, size, style)
|
||||
, m_bg_color(StateColor(
|
||||
@@ -580,168 +745,3 @@ bool MultiSwitchButton::send_selection_event()
|
||||
GetEventHandler()->ProcessEvent(evt);
|
||||
return true;
|
||||
}
|
||||
|
||||
SwitchBoard::SwitchBoard(wxWindow *parent, wxString leftL, wxString right, wxSize size)
|
||||
: wxWindow(parent, wxID_ANY, wxDefaultPosition, size)
|
||||
{
|
||||
#ifdef __WINDOWS__
|
||||
SetDoubleBuffered(true);
|
||||
#endif //__WINDOWS__
|
||||
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
leftLabel = leftL;
|
||||
rightLabel = right;
|
||||
|
||||
SetMinSize(size);
|
||||
SetMaxSize(size);
|
||||
|
||||
Bind(wxEVT_PAINT, &SwitchBoard::paintEvent, this);
|
||||
Bind(wxEVT_LEFT_DOWN, &SwitchBoard::on_left_down, this);
|
||||
|
||||
Bind(wxEVT_ENTER_WINDOW, [this](auto &e) { SetCursor(wxCURSOR_HAND); });
|
||||
Bind(wxEVT_LEAVE_WINDOW, [this](auto &e) { SetCursor(wxCURSOR_ARROW); });
|
||||
}
|
||||
|
||||
void SwitchBoard::updateState(wxString target)
|
||||
{
|
||||
if (target.empty()) {
|
||||
if (!switch_left && !switch_right) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch_left = false;
|
||||
switch_right = false;
|
||||
} else {
|
||||
if (target == "left") {
|
||||
if (switch_left && !switch_right) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch_left = true;
|
||||
switch_right = false;
|
||||
} else if (target == "right") {
|
||||
if (!switch_left && switch_right) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch_left = false;
|
||||
switch_right = true;
|
||||
}
|
||||
}
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SwitchBoard::paintEvent(wxPaintEvent &evt)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
render(dc);
|
||||
}
|
||||
|
||||
void SwitchBoard::render(wxDC &dc)
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
wxSize size = GetSize();
|
||||
wxMemoryDC memdc;
|
||||
wxBitmap bmp(size.x, size.y);
|
||||
memdc.SelectObject(bmp);
|
||||
memdc.Blit({0, 0}, size, &dc, {0, 0});
|
||||
|
||||
{
|
||||
wxGCDC dc2(memdc);
|
||||
doRender(dc2);
|
||||
}
|
||||
|
||||
memdc.SelectObject(wxNullBitmap);
|
||||
dc.DrawBitmap(bmp, 0, 0);
|
||||
#else
|
||||
doRender(dc);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SwitchBoard::doRender(wxDC &dc)
|
||||
{
|
||||
wxColour disable_color = wxColour(0xCECECE);
|
||||
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
|
||||
if (is_enable) {dc.SetBrush(wxBrush(0xeeeeee));
|
||||
} else {dc.SetBrush(disable_color);}
|
||||
dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 8);
|
||||
|
||||
/*left*/
|
||||
if (switch_left) {
|
||||
is_enable ? dc.SetBrush(wxBrush(wxColour(0, 150, 136))) : dc.SetBrush(disable_color);
|
||||
dc.DrawRoundedRectangle(0, 0, GetSize().x / 2, GetSize().y, 8);
|
||||
}
|
||||
|
||||
if (switch_left) {
|
||||
dc.SetTextForeground(*wxWHITE);
|
||||
} else {
|
||||
dc.SetTextForeground(0x333333);
|
||||
}
|
||||
|
||||
dc.SetFont(::Label::Body_13);
|
||||
Slic3r::GUI::WxFontUtils::get_suitable_font_size(0.6 * GetSize().GetHeight(), dc);
|
||||
|
||||
auto left_txt_size = dc.GetTextExtent(leftLabel);
|
||||
dc.DrawText(leftLabel, wxPoint((GetSize().x / 2 - left_txt_size.x) / 2, (GetSize().y - left_txt_size.y) / 2));
|
||||
|
||||
/*right*/
|
||||
if (switch_right) {
|
||||
if (is_enable) {dc.SetBrush(wxBrush(wxColour(0, 150, 136)));
|
||||
} else {dc.SetBrush(disable_color);}
|
||||
dc.DrawRoundedRectangle(GetSize().x / 2, 0, GetSize().x / 2, GetSize().y, 8);
|
||||
}
|
||||
|
||||
auto right_txt_size = dc.GetTextExtent(rightLabel);
|
||||
if (switch_right) {
|
||||
dc.SetTextForeground(*wxWHITE);
|
||||
} else {
|
||||
dc.SetTextForeground(0x333333);
|
||||
}
|
||||
dc.DrawText(rightLabel, wxPoint((GetSize().x / 2 - right_txt_size.x) / 2 + GetSize().x / 2, (GetSize().y - right_txt_size.y) / 2));
|
||||
|
||||
}
|
||||
|
||||
void SwitchBoard::on_left_down(wxMouseEvent &evt)
|
||||
{
|
||||
if (!is_enable) {
|
||||
return;
|
||||
}
|
||||
int index = -1;
|
||||
auto pos = ClientToScreen(evt.GetPosition());
|
||||
auto rect = ClientToScreen(wxPoint(0, 0));
|
||||
|
||||
if (pos.x > 0 && pos.x < rect.x + GetSize().x / 2) {
|
||||
switch_left = true;
|
||||
switch_right = false;
|
||||
index = 1;
|
||||
} else {
|
||||
switch_left = false;
|
||||
switch_right = true;
|
||||
index = 0;
|
||||
}
|
||||
|
||||
if (auto_disable_when_switch)
|
||||
{
|
||||
is_enable = false;// make it disable while switching
|
||||
}
|
||||
Refresh();
|
||||
|
||||
wxCommandEvent event(wxCUSTOMEVT_SWITCH_POS);
|
||||
event.SetInt(index);
|
||||
wxPostEvent(this, event);
|
||||
}
|
||||
|
||||
bool SwitchBoard::Enable(bool enable /* = true */)
|
||||
{
|
||||
if (is_enable == enable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
is_enable = enable;
|
||||
Refresh();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8,12 +8,11 @@
|
||||
#include <vector>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/tglbtn.h>
|
||||
#include "Button.hpp"
|
||||
|
||||
wxDECLARE_EVENT(wxCUSTOMEVT_SWITCH_POS, wxCommandEvent);
|
||||
wxDECLARE_EVENT(wxCUSTOMEVT_MULTISWITCH_SELECTION, wxCommandEvent);
|
||||
|
||||
class Button;
|
||||
|
||||
class SwitchButton : public wxBitmapToggleButton
|
||||
{
|
||||
public:
|
||||
@@ -81,53 +80,6 @@ private:
|
||||
wxString m_tooltips[3];
|
||||
};
|
||||
|
||||
class MultiSwitchButton : public StaticBox
|
||||
{
|
||||
public:
|
||||
MultiSwitchButton(wxWindow *parent = nullptr, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition,
|
||||
const wxSize &size = wxDefaultSize, long style = 0);
|
||||
~MultiSwitchButton();
|
||||
|
||||
int AppendOption(const wxString &option, void *clientData = nullptr);
|
||||
void SetOptions(const std::vector<wxString> &options);
|
||||
void DeleteAllOptions();
|
||||
|
||||
unsigned int GetCount() const;
|
||||
|
||||
int GetSelection() const;
|
||||
void SetSelection(int index);
|
||||
wxString GetSelectedText() const;
|
||||
|
||||
wxString GetOptionText(unsigned int index) const;
|
||||
void SetOptionText(unsigned int index, const wxString &text);
|
||||
|
||||
void *GetOptionData(unsigned int index) const;
|
||||
void SetOptionData(unsigned int index, void *clientData);
|
||||
|
||||
void SetBackgroundColor(const StateColor &color);
|
||||
void SetTextColor(const StateColor &color);
|
||||
void SetButtonCornerRadius(double radius);
|
||||
void SetButtonPadding(const wxSize &padding);
|
||||
|
||||
void Rescale();
|
||||
|
||||
protected:
|
||||
void button_clicked(wxCommandEvent &event);
|
||||
void update_button_styles();
|
||||
|
||||
bool send_selection_event();
|
||||
|
||||
private:
|
||||
std::vector<Button *> btns;
|
||||
wxBoxSizer *sizer = nullptr;
|
||||
int sel = -1;
|
||||
|
||||
StateColor m_bg_color;
|
||||
StateColor m_text_color;
|
||||
double m_button_radius;
|
||||
wxSize m_button_padding;
|
||||
};
|
||||
|
||||
class SwitchBoard : public wxWindow
|
||||
{
|
||||
public:
|
||||
@@ -163,4 +115,63 @@ private:
|
||||
bool auto_disable_when_switch = false;
|
||||
};
|
||||
|
||||
class MultiSwitchButton : public StaticBox
|
||||
{
|
||||
public:
|
||||
MultiSwitchButton(wxWindow *parent = nullptr, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition,
|
||||
const wxSize &size = wxDefaultSize, long style = 0);
|
||||
~MultiSwitchButton();
|
||||
|
||||
int AppendOption(const wxString &option, void *clientData = nullptr);
|
||||
void SetOptions(const std::vector<wxString> &options);
|
||||
void DeleteAllOptions();
|
||||
|
||||
unsigned int GetCount() const;
|
||||
|
||||
int GetSelection() const;
|
||||
void SetSelection(int index);
|
||||
wxString GetSelectedText() const;
|
||||
|
||||
Button* GetButton(unsigned int index) const
|
||||
{
|
||||
return index >= 0 && index < btns.size() ? btns[index] : nullptr;
|
||||
}
|
||||
|
||||
wxString GetOptionText(unsigned int index) const;
|
||||
void SetOptionText(unsigned int index, const wxString &text);
|
||||
|
||||
void *GetOptionData(unsigned int index) const;
|
||||
void SetOptionData(unsigned int index, void *clientData);
|
||||
|
||||
void SetBackgroundColor(const StateColor &color);
|
||||
void SetTextColor(const StateColor &color);
|
||||
void SetButtonTextColor(int index, const StateColor &color)
|
||||
{
|
||||
if (index >= btns.size()) return;
|
||||
|
||||
btns[index]->SetTextColor(color);
|
||||
btns[index]->Refresh();
|
||||
}
|
||||
void SetButtonCornerRadius(double radius);
|
||||
void SetButtonPadding(const wxSize &padding);
|
||||
|
||||
void Rescale();
|
||||
|
||||
protected:
|
||||
void button_clicked(wxCommandEvent &event);
|
||||
void update_button_styles();
|
||||
|
||||
bool send_selection_event();
|
||||
|
||||
private:
|
||||
std::vector<Button *> btns;
|
||||
wxBoxSizer *sizer = nullptr;
|
||||
int sel = -1;
|
||||
|
||||
StateColor m_bg_color;
|
||||
StateColor m_text_color;
|
||||
double m_button_radius;
|
||||
wxSize m_button_padding;
|
||||
};
|
||||
|
||||
#endif // !slic3r_GUI_SwitchButton_hpp_
|
||||
|
||||
Reference in New Issue
Block a user