mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-16 15:32:09 +00:00
Merge branch 'main' into dev/extruder-toggle
This commit is contained in:
@@ -864,10 +864,10 @@ std::string GCodeWriter::_spiral_travel_to_z(double z, const Vec2d &ij_offset, c
|
||||
// Determine number of segments based on Resolution
|
||||
// --------------------------------------------------------------------
|
||||
const double ref_resolution = 0.01; // reference resolution in mm
|
||||
const double ref_segments = 16.0; // reference number of segments at reference resolution
|
||||
const double ref_segments = 8.0; // reference number of segments at reference resolution
|
||||
|
||||
// number of linear segments to use for approximating the arc, clamp between 4 and 24
|
||||
const int segments = std::clamp(int(std::round(ref_segments * (ref_resolution / m_resolution))), 4, 24);
|
||||
// number of linear segments to use for approximating the arc, clamp between 4 and 16
|
||||
const int segments = std::clamp(int(std::round(ref_segments * (ref_resolution / m_resolution))), 4, 16);
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
const double px = m_pos(0) - m_x_offset; // take plate offset into consideration
|
||||
|
||||
@@ -581,14 +581,6 @@ void Preset::load_info(const std::string& file)
|
||||
catch (...) {
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: workaround for current info file convert, will remove it later
|
||||
if (this->updated_time == 0) {
|
||||
this->updated_time = (long long)Slic3r::Utils::get_current_time_utc();
|
||||
//this->sync_info = "update";
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("old info file, updated time to %1%") % this->updated_time;
|
||||
save_info();
|
||||
}
|
||||
}
|
||||
|
||||
void Preset::save_info(std::string file)
|
||||
@@ -2186,19 +2178,29 @@ bool PresetCollection::load_user_preset(std::string name, std::map<std::string,
|
||||
}
|
||||
}
|
||||
|
||||
// base_id
|
||||
if (preset_values.find(BBL_JSON_KEY_BASE_ID) == preset_values.end()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format("can not find base_id, not loading for user preset %1%") % canonical_name;
|
||||
unlock();
|
||||
return false;
|
||||
// base_id is only required for presets inheriting from a parent. Root presets
|
||||
// with an empty "inherits" field intentionally have no base_id.
|
||||
std::string based_id;
|
||||
const auto base_id = preset_values.find(BBL_JSON_KEY_BASE_ID);
|
||||
if (base_id != preset_values.end()) {
|
||||
based_id = base_id->second;
|
||||
} else {
|
||||
const auto inherits_iter = preset_values.find(BBL_JSON_KEY_INHERITS);
|
||||
const bool preset_inherits_from_parent = inherits_iter != preset_values.end() && !inherits_iter->second.empty();
|
||||
if (preset_inherits_from_parent) {
|
||||
// This indicates that there is inherits exists but there is no base_id
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__
|
||||
<< boost::format("can not find base_id, not loading for user preset %1%") % canonical_name;
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::string cloud_base_id = preset_values[BBL_JSON_KEY_BASE_ID];
|
||||
|
||||
//filament_id
|
||||
std::string cloud_filament_id;
|
||||
if ((m_type == Preset::TYPE_FILAMENT) && preset_values.find(BBL_JSON_KEY_FILAMENT_ID) != preset_values.end()) {
|
||||
cloud_filament_id = preset_values[BBL_JSON_KEY_FILAMENT_ID];
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << canonical_name << " filament_id: " << cloud_filament_id << " base_id: " << cloud_base_id;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << canonical_name << " filament_id: " << cloud_filament_id << " base_id: " << based_id;
|
||||
}
|
||||
|
||||
DynamicPrintConfig new_config, cloud_config;
|
||||
@@ -2271,7 +2273,7 @@ bool PresetCollection::load_user_preset(std::string name, std::map<std::string,
|
||||
iter->version = cloud_version.value();
|
||||
iter->user_id = cloud_user_id;
|
||||
iter->setting_id = cloud_setting_id;
|
||||
iter->base_id = cloud_base_id;
|
||||
iter->base_id = based_id;
|
||||
iter->filament_id = cloud_filament_id;
|
||||
update_alias(*iter);
|
||||
//presets_loaded.emplace_back(*it->second);
|
||||
@@ -2290,7 +2292,7 @@ bool PresetCollection::load_user_preset(std::string name, std::map<std::string,
|
||||
preset.version = cloud_version.value();
|
||||
preset.user_id = cloud_user_id;
|
||||
preset.setting_id = cloud_setting_id;
|
||||
preset.base_id = cloud_base_id;
|
||||
preset.base_id = based_id;
|
||||
preset.filament_id = cloud_filament_id;
|
||||
update_alias(preset);
|
||||
|
||||
@@ -3651,20 +3653,22 @@ void PresetCollection::set_custom_preset_alias(Preset &preset)
|
||||
// For printers, there is nothing to remove
|
||||
// For prints AKA processes, the postfix should be kept
|
||||
// Alias should be set here, as the preset name may be augmented further later (i.e., prefixing relative path for bundles)
|
||||
std::string alias_name;
|
||||
std::string preset_name = get_preset_bare_name(preset.name);
|
||||
if (m_type == Preset::Type::TYPE_FILAMENT && preset.config.has(BBL_JSON_KEY_INHERITS) && preset.config.option<ConfigOptionString>(BBL_JSON_KEY_INHERITS)->value.empty()) {
|
||||
if (alias_name.empty()) {
|
||||
size_t end_pos = preset_name.find_first_of("@");
|
||||
if (end_pos != std::string::npos) {
|
||||
alias_name = preset_name.substr(0, end_pos);
|
||||
boost::trim_right(alias_name);
|
||||
}
|
||||
std::string bare_preset_name = get_preset_bare_name(preset.name);
|
||||
std::string alias_name = bare_preset_name;
|
||||
|
||||
const bool is_root_filament_preset =
|
||||
m_type == Preset::Type::TYPE_FILAMENT &&
|
||||
preset.config.has(BBL_JSON_KEY_INHERITS) &&
|
||||
preset.config.option<ConfigOptionString>(BBL_JSON_KEY_INHERITS)->value.empty();
|
||||
if (is_root_filament_preset) {
|
||||
const size_t suffix_separator_pos = bare_preset_name.find_first_of("@");
|
||||
if (suffix_separator_pos != std::string::npos) {
|
||||
alias_name = bare_preset_name.substr(0, suffix_separator_pos);
|
||||
boost::trim_right(alias_name);
|
||||
if (alias_name.empty())
|
||||
alias_name = bare_preset_name;
|
||||
}
|
||||
}
|
||||
else {
|
||||
alias_name = preset_name;
|
||||
}
|
||||
|
||||
preset.alias = std::move(alias_name);
|
||||
m_map_alias_to_profile_name[preset.alias].push_back(preset.name);
|
||||
|
||||
@@ -606,13 +606,24 @@ VendorType PresetBundle::get_current_vendor_type()
|
||||
{
|
||||
auto t = VendorType::Unknown;
|
||||
auto config = &printers.get_edited_preset().config;
|
||||
const auto* printer_model = config->opt<ConfigOptionString>("printer_model");
|
||||
if (printer_model == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": printer_model is "
|
||||
<< (config->has("printer_model") ? "not a string" : "missing")
|
||||
<< ", vendor type is Unknown";
|
||||
return t;
|
||||
}
|
||||
|
||||
std::string vendor_name;
|
||||
for (auto vendor_profile : vendors) {
|
||||
for (auto vendor_model : vendor_profile.second.models)
|
||||
if (vendor_model.name == config->opt_string("printer_model")) {
|
||||
for (const auto& vendor_profile : vendors) {
|
||||
for (const auto& vendor_model : vendor_profile.second.models) {
|
||||
if (vendor_model.name == printer_model->value) {
|
||||
vendor_name = vendor_profile.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!vendor_name.empty())
|
||||
break;
|
||||
}
|
||||
if (!vendor_name.empty())
|
||||
{
|
||||
@@ -3779,7 +3790,17 @@ int PresetBundle::get_printer_extruder_count() const
|
||||
{
|
||||
const Preset& printer_preset = this->printers.get_edited_preset();
|
||||
|
||||
int count = printer_preset.config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
|
||||
const auto* nozzle_diameter = printer_preset.config.option<ConfigOptionFloats>("nozzle_diameter");
|
||||
if (nozzle_diameter == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": nozzle_diameter is missing, using 1 extruder";
|
||||
return 1;
|
||||
}
|
||||
if (nozzle_diameter->values.empty()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": nozzle_diameter is empty, using 1 extruder";
|
||||
return 1;
|
||||
}
|
||||
|
||||
int count = int(nozzle_diameter->values.size());
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -46,11 +46,23 @@ void name_tbb_thread_pool_threads_set_locale();
|
||||
template<class Fn>
|
||||
inline boost::thread create_thread(boost::thread::attributes &attrs, Fn &&fn)
|
||||
{
|
||||
// Duplicating the stack allocation size of Thread Building Block worker
|
||||
// threads of the thread pool: allocate 4MB on a 64bit system, allocate 2MB
|
||||
// on a 32bit system by default.
|
||||
|
||||
attrs.set_stack_size((sizeof(void*) == 4) ? (2048 * 1024) : (4096 * 1024));
|
||||
// Stack size for our worker threads. Originally duplicated TBB's pool
|
||||
// default (4 MB), but the Emboss text-cut path calls into CGAL's
|
||||
// Polygon_mesh_processing::corefine, which falls back from filtered
|
||||
// interval arithmetic to exact rational arithmetic (mpq_class) on
|
||||
// near-degenerate input, and the constrained 2D triangulation walker
|
||||
// (Triangulation_2::march_locate_2D) can recurse deeply enough to
|
||||
// exceed 4 MB on real models -- producing a SIGBUS at the next thread's
|
||||
// stack guard page on macOS / Linux.
|
||||
//
|
||||
// 16 MB chosen as 4x defensive headroom over the observed crash
|
||||
// threshold (n=1 reproducer at exactly 4 MB on macOS arm64). All three
|
||||
// platforms defer-commit reserved stack pages: macOS / Linux mmap the
|
||||
// stack and only fault in pages on touch; Boost.Thread on Win32 passes
|
||||
// STACK_SIZE_PARAM_IS_A_RESERVATION to _beginthreadex, so the value is
|
||||
// a reserve, not the initial commit. Resident memory therefore stays
|
||||
// proportional to actual stack depth on every target.
|
||||
attrs.set_stack_size(16 * 1024 * 1024);
|
||||
return boost::thread{attrs, std::forward<Fn>(fn)};
|
||||
}
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ void DeviceErrorDialog::init_button_list()
|
||||
init_button(PROBLEM_SOLVED_RESUME, _L("Problem Solved and Resume"));
|
||||
init_button(TURN_OFF_FIRE_ALARM, _L("Got it, Turn off the Fire Alarm."));
|
||||
init_button(RETRY_PROBLEM_SOLVED, _L("Retry (problem solved)"));
|
||||
init_button(CANCLE, _L("Cancel"));
|
||||
init_button(CANCEL, _L("Cancel"));
|
||||
init_button(STOP_DRYING, _L("Stop Drying"));
|
||||
init_button(PROCEED, _L("Proceed"));
|
||||
init_button(DBL_CHECK_CANCEL, _L("Cancel"));
|
||||
@@ -445,7 +445,7 @@ void DeviceErrorDialog::on_button_click(ActionButton btn_id)
|
||||
m_obj->command_ams_control("resume");
|
||||
break;
|
||||
}
|
||||
case DeviceErrorDialog::CANCLE: {
|
||||
case DeviceErrorDialog::CANCEL: {
|
||||
break;
|
||||
}
|
||||
case DeviceErrorDialog::STOP_DRYING: {
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
|
||||
RETRY_PROBLEM_SOLVED = 34,
|
||||
STOP_DRYING = 35,
|
||||
CANCLE = 37,
|
||||
CANCEL = 37,
|
||||
REMOVE_CLOSE_BTN = 39, // special case, do not show close button
|
||||
PROCEED = 41,
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ FilamentMapDialog::FilamentMapDialog(wxWindow *parent,
|
||||
main_sizer->Add(bottom_panel, 0, wxEXPAND);
|
||||
|
||||
m_ok_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_ok, this);
|
||||
m_cancel_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_cancle, this);
|
||||
m_cancel_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_cancel, this);
|
||||
SetEscapeId(wxID_CANCEL);
|
||||
Bind(wxEVT_CHAR_HOOK, [this](wxKeyEvent& e) {
|
||||
if (e.GetKeyCode() == WXK_ESCAPE) {
|
||||
@@ -286,7 +286,7 @@ void FilamentMapDialog::on_ok(wxCommandEvent &event)
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void FilamentMapDialog::on_cancle(wxCommandEvent &event) { EndModal(wxID_CANCEL); }
|
||||
void FilamentMapDialog::on_cancel(wxCommandEvent &event) { EndModal(wxID_CANCEL); }
|
||||
|
||||
void FilamentMapDialog::update_panel_status(PageType page)
|
||||
{
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
void set_modal_btn_labels(const wxString& left_label, const wxString& right_label);
|
||||
private:
|
||||
void on_ok(wxCommandEvent &event);
|
||||
void on_cancle(wxCommandEvent &event);
|
||||
void on_cancel(wxCommandEvent &event);
|
||||
void on_switch_mode(wxCommandEvent &event);
|
||||
void on_checkbox(wxCommandEvent &event);
|
||||
|
||||
|
||||
@@ -4803,7 +4803,7 @@ void GUI_App::handle_http_error(unsigned int status, std::string body, const std
|
||||
void GUI_App::on_http_error(wxCommandEvent &evt)
|
||||
{
|
||||
int status = evt.GetInt();
|
||||
std::string provider = ORCA_CLOUD_PROVIDER;
|
||||
std::string provider = "";
|
||||
std::string body_str;
|
||||
|
||||
// Extract provider and body from event data
|
||||
@@ -4845,18 +4845,24 @@ void GUI_App::on_http_error(wxCommandEvent &evt)
|
||||
// request login
|
||||
if (status == 401) {
|
||||
if (m_agent) {
|
||||
if (m_agent->is_user_login(provider)) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "logout: http error 401.";
|
||||
this->request_user_logout(provider);
|
||||
if (!provider.empty() && m_agent->is_user_login(provider)) {
|
||||
if (std::chrono::steady_clock::now() - m_last_401_error_time > 30s) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "logout: http error 401.";
|
||||
this->request_user_logout(provider);
|
||||
|
||||
if (!m_show_http_error_msgdlg) {
|
||||
MessageDialog msg_dlg(nullptr, _L("Login information expired. Please login again."), "", wxAPPLY | wxOK);
|
||||
m_show_http_error_msgdlg = true;
|
||||
auto modal_result = msg_dlg.ShowModal();
|
||||
if (modal_result == wxOK || modal_result == wxCLOSE) {
|
||||
m_show_http_error_msgdlg = false;
|
||||
return;
|
||||
if (!m_show_http_error_msgdlg) {
|
||||
MessageDialog msg_dlg(nullptr, _L("Login information expired. Please login again."), "", wxAPPLY | wxOK);
|
||||
m_show_http_error_msgdlg = true;
|
||||
auto modal_result = msg_dlg.ShowModal();
|
||||
if (modal_result == wxOK || modal_result == wxCLOSE) {
|
||||
m_show_http_error_msgdlg = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_last_401_error_time = std::chrono::steady_clock::now();
|
||||
} else {
|
||||
BOOST_LOG_TRIVIAL(warning) << "401 encountered within grace period, suppressing logout";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4874,11 +4880,11 @@ void GUI_App::on_http_error(wxCommandEvent &evt)
|
||||
if (provider == ORCA_CLOUD_PROVIDER && status >= 400 && code != HttpErrorVersionLimited) {
|
||||
wxString msg;
|
||||
if (!error.empty()) {
|
||||
msg = wxString::Format(_L("API error (HTTP %u): %s"), status, wxString::FromUTF8(error));
|
||||
msg = wxString::Format(_L("Failed to connect to OrcaCloud.\nPlease check your network connectivity\n(HTTP %u): %s"), status, wxString::FromUTF8(error));
|
||||
} else {
|
||||
msg = wxString::Format(_L("API error (HTTP %u)"), status);
|
||||
msg = wxString::Format(_L("Failed to connect to OrcaCloud.\nPlease check your network connectivity\n(HTTP %u)"), status);
|
||||
}
|
||||
|
||||
|
||||
if (app_config->get_bool("developer_mode")) {
|
||||
// Use notification manager if ImGui is ready; fall back to wxMessageBox on Linux
|
||||
// where ImGui may not be initialized until the user switches to the Prepare tab.
|
||||
@@ -4893,7 +4899,7 @@ void GUI_App::on_http_error(wxCommandEvent &evt)
|
||||
|
||||
if (!m_is_error_shown) {
|
||||
m_is_error_shown = true;
|
||||
wxMessageBox(msg, _L("Orca Cloud API Error"), wxOK | wxICON_ERROR, wxGetApp().mainframe);
|
||||
wxMessageBox(msg, _L("Cloud Error"), wxOK | wxICON_ERROR, wxGetApp().mainframe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4931,6 +4937,10 @@ void GUI_App::on_user_login_handle(wxCommandEvent &evt)
|
||||
std::string provider = evt.GetString().ToStdString();
|
||||
if (provider.empty()) provider = ORCA_CLOUD_PROVIDER;
|
||||
|
||||
// Reset 401 grace period so transient token-propagation 401s
|
||||
// during login warmup don't trigger immediate logout.
|
||||
m_last_401_error_time = std::chrono::steady_clock::now();
|
||||
|
||||
m_agent->connect_server();
|
||||
// get machine list
|
||||
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
||||
@@ -5841,25 +5851,32 @@ void GUI_App::reload_settings()
|
||||
return;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " cloud user preset number is: " << user_presets.size();
|
||||
// Check the user presets for any system vendors that need to be installed
|
||||
for (auto data : user_presets) {
|
||||
if (!check_preset_parent_available(data))
|
||||
add_pending_vendor_preset(data);
|
||||
}
|
||||
load_pending_vendors();
|
||||
preset_bundle->load_user_presets(*app_config, user_presets, ForwardCompatibilitySubstitutionRule::Enable);
|
||||
preset_bundle->save_user_presets(*app_config, get_delete_cache_presets());
|
||||
if (is_main_thread_active()) {
|
||||
auto refresh_synced_ui = [this, user_presets = std::move(user_presets)]() mutable {
|
||||
if (is_closing() || !preset_bundle || !app_config || !mainframe)
|
||||
return;
|
||||
|
||||
// Check the user presets for any system vendors that need to be installed
|
||||
for (auto data : user_presets) {
|
||||
if (!check_preset_parent_available(data))
|
||||
add_pending_vendor_preset(data);
|
||||
}
|
||||
load_pending_vendors();
|
||||
preset_bundle->load_user_presets(*app_config, user_presets, ForwardCompatibilitySubstitutionRule::Enable);
|
||||
preset_bundle->save_user_presets(*app_config, get_delete_cache_presets());
|
||||
|
||||
// Orca: settings changed, refresh ui to reflect the new preset values
|
||||
mainframe->update_side_preset_ui();
|
||||
for (auto tab : tabs_list) {
|
||||
tab->reload_config();
|
||||
tab->update_changed_ui();
|
||||
}
|
||||
if (plater_)
|
||||
plater_->sidebar().update_all_preset_comboboxes();
|
||||
} else {
|
||||
CallAfter([this] {
|
||||
mainframe->update_side_preset_ui();
|
||||
if (plater_)
|
||||
plater_->sidebar().update_all_preset_comboboxes();
|
||||
});
|
||||
}
|
||||
};
|
||||
if (is_main_thread_active())
|
||||
refresh_synced_ui();
|
||||
else
|
||||
CallAfter(refresh_synced_ui);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -326,6 +326,7 @@ private:
|
||||
bool m_adding_script_handler { false };
|
||||
bool m_side_popup_status{false};
|
||||
bool m_show_http_error_msgdlg{false};
|
||||
std::chrono::steady_clock::time_point m_last_401_error_time;
|
||||
bool m_show_error_msgdlg{false};
|
||||
wxString m_info_dialog_content;
|
||||
HttpServer m_http_server;
|
||||
@@ -493,7 +494,7 @@ public:
|
||||
void request_open_project(std::string project_id);
|
||||
void request_remove_project(std::string project_id);
|
||||
|
||||
void handle_http_error(unsigned int status, std::string body, const std::string& provider = ORCA_CLOUD_PROVIDER);
|
||||
void handle_http_error(unsigned int status, std::string body, const std::string& provider = "");
|
||||
void on_http_error(wxCommandEvent &evt);
|
||||
void on_update_machine_list(wxCommandEvent& evt);
|
||||
void on_user_login(wxCommandEvent &evt);
|
||||
|
||||
@@ -2788,9 +2788,6 @@ void MainFrame::init_menubar_as_editor()
|
||||
info_dlg.ShowModal();
|
||||
return;
|
||||
}
|
||||
if (m_plater)
|
||||
m_plater->get_notification_manager()->push_notification(
|
||||
into_u8(_L("Syncing presets from cloud\u2026")));
|
||||
wxGetApp().restart_sync_user_preset();
|
||||
}, "", nullptr,
|
||||
[this]() {
|
||||
|
||||
@@ -664,6 +664,14 @@ void ParamsPanel::update_mode()
|
||||
|
||||
sync_mode_view(m_mode_view);
|
||||
sync_mode_view(m_current_tab ? dynamic_cast<Tab*>(m_current_tab)->m_mode_view : nullptr);
|
||||
|
||||
auto sync_mode_icon = [&](ScalableButton* mode_icon) {
|
||||
if (mode_icon == nullptr)
|
||||
return;
|
||||
mode_icon->Show(app_mode != comDevelop);
|
||||
};
|
||||
sync_mode_icon(m_mode_icon);
|
||||
sync_mode_icon(m_current_tab ? dynamic_cast<Tab*>(m_current_tab)->m_mode_icon : nullptr);
|
||||
}
|
||||
|
||||
void ParamsPanel::msw_rescale()
|
||||
|
||||
@@ -824,7 +824,7 @@ bool PartSkipDialog::IsAllChecked()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PartSkipDialog::IsAllCancled()
|
||||
bool PartSkipDialog::IsAllCanceled()
|
||||
{
|
||||
for (auto &[part_id, part_state] : m_parts_state) {
|
||||
if (part_state == PartState::psChecked) return false;
|
||||
@@ -851,7 +851,7 @@ void PartSkipDialog::OnAllCheckbox(wxCommandEvent &event)
|
||||
|
||||
void PartSkipDialog::UpdateApplyButtonStatus()
|
||||
{
|
||||
if (IsAllCancled()) {
|
||||
if (IsAllCanceled()) {
|
||||
m_apply_btn->SetStyle(ButtonStyle::Regular, ButtonType::Choice);
|
||||
m_apply_btn->SetToolTip(_L("Nothing selected"));
|
||||
m_enable_apply_btn = false;
|
||||
|
||||
@@ -153,7 +153,7 @@ private:
|
||||
void UpdateDialogUI();
|
||||
void UpdateApplyButtonStatus();
|
||||
bool IsAllChecked();
|
||||
bool IsAllCancled();
|
||||
bool IsAllCanceled();
|
||||
|
||||
void OnRetryButton(wxCommandEvent &event);
|
||||
void OnAllCheckbox(wxCommandEvent &event);
|
||||
|
||||
@@ -146,7 +146,6 @@ protected:
|
||||
|
||||
//BBS: GUI refactor
|
||||
wxPanel* m_top_panel;
|
||||
ScalableButton* m_mode_icon; // ORCA m_static_title replacement
|
||||
wxBoxSizer* m_main_sizer;
|
||||
wxBoxSizer* m_top_sizer;
|
||||
wxBoxSizer* m_top_left_sizer;
|
||||
@@ -308,6 +307,7 @@ public:
|
||||
int m_update_cnt = 0;
|
||||
|
||||
ModeSwitchButton *m_mode_view = nullptr;
|
||||
ScalableButton* m_mode_icon = nullptr; // ORCA m_static_title replacement
|
||||
wxSizer * m_variant_sizer = nullptr;
|
||||
MultiSwitchButton * m_extruder_switch = nullptr;
|
||||
MultiSwitchButton * m_variant_combo = nullptr;
|
||||
|
||||
@@ -42,7 +42,8 @@ static std::map<wxColour, wxColour> gDarkColors{
|
||||
{"#D7E8DE", "#1F2B27"}, // rgb(215, 232, 222) Not Used anymore // Leftover from BBS
|
||||
{"#2B3436", "#808080"}, // rgb(43, 52, 54) Not Used anymore // Leftover from BBS. Was used as main fill color of icons
|
||||
{"#ABABAB", "#ABABAB"},
|
||||
{"#D9D9D9", "#2D2D32"}, // rgb(217, 217, 217) Sidebar > Toggle button track color
|
||||
{"#D9D9D9", "#27272A"}, // rgb(217, 217, 217) Sidebar > Toggle button track color
|
||||
{"#FFFEFE", "#D9D9D9"}, // rgb(255, 254, 254) Sidebar > Toggle button thumb color
|
||||
{"#EBF9F0", "#293F34"},
|
||||
//{"#F0F0F0", "#4C4C54"},
|
||||
// ORCA
|
||||
|
||||
@@ -220,14 +220,40 @@ void SwitchButton::update()
|
||||
ModeSwitchButton::ModeSwitchButton(wxWindow* parent, wxWindowID id)
|
||||
{
|
||||
background_color = StateColor(
|
||||
std::make_pair(wxColour(0xF1, 0xF1, 0xF1), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour(0xE3, 0xE3, 0xE3), (int) StateColor::Pressed),
|
||||
std::make_pair(wxColour(0xD9, 0xD9, 0xD9), (int) StateColor::Normal));
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Normal)
|
||||
);
|
||||
border_color = StateColor(
|
||||
std::make_pair(wxColour(0xEA, 0xEA, 0xEA), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour(0xBC, 0xBC, 0xBC), (int) StateColor::Hovered),
|
||||
std::make_pair(wxColour(0xC8, 0xC8, 0xC8), (int) StateColor::Focused),
|
||||
std::make_pair(wxColour(0xCE, 0xCE, 0xCE), (int) StateColor::Normal));
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Hovered | ~StateColor::Focused),
|
||||
std::make_pair(wxColour("#26A69A"), (int) StateColor::Focused),
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Normal)
|
||||
);
|
||||
track_background = StateColor(
|
||||
std::make_pair(wxColour("#009688"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#009688"), (int) StateColor::Normal)
|
||||
);
|
||||
track_border = StateColor(
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#009688"), (int) StateColor::Hovered | ~StateColor::Focused),
|
||||
std::make_pair(wxColour("#26A69A"), (int) StateColor::Focused),
|
||||
std::make_pair(wxColour("#009688"), (int) StateColor::Normal)
|
||||
);
|
||||
dot_active = StateColor(
|
||||
std::make_pair(wxColour("#FFFEFE"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#FFFEFE"), (int) StateColor::Normal)
|
||||
);
|
||||
dot_dimmed = StateColor(
|
||||
std::make_pair(wxColour("#EEEEEE"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#EEEEEE"), (int) StateColor::Normal)
|
||||
);
|
||||
text_color = StateColor(
|
||||
std::make_pair(wxColour("#6B6B6B"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#6B6B6B"), (int) StateColor::Normal)
|
||||
);
|
||||
|
||||
state_handler.attach(std::vector<StateColor const*>{&dot_active, &dot_dimmed, &text_color});
|
||||
state_handler.update_binds();
|
||||
|
||||
StaticBox::Create(parent, id, wxDefaultPosition, wxDefaultSize, 0);
|
||||
SetBackgroundColour(StaticBox::GetParentBackgroundColor(parent));
|
||||
@@ -263,7 +289,7 @@ void ModeSwitchButton::SelectAndNotify(int selection)
|
||||
|
||||
void ModeSwitchButton::Rescale()
|
||||
{
|
||||
const wxSize button_size = FromDIP(wxSize(48, 20));
|
||||
const wxSize button_size = FromDIP(wxSize(48, 18));
|
||||
SetMinSize(button_size);
|
||||
SetMaxSize(button_size);
|
||||
SetSize(button_size);
|
||||
@@ -274,63 +300,70 @@ void ModeSwitchButton::Rescale()
|
||||
bool ModeSwitchButton::Enable(bool enable /* = true */)
|
||||
{
|
||||
const bool changed = StaticBox::Enable(enable);
|
||||
if (changed)
|
||||
if (changed){
|
||||
wxCommandEvent e(EVT_ENABLE_CHANGED);
|
||||
e.SetEventObject(this);
|
||||
GetEventHandler()->ProcessEvent(e);
|
||||
m_enabled = enable; // IsEnabled() not works because variable changes after paint event
|
||||
Refresh();
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
void ModeSwitchButton::doRender(wxDC& dc)
|
||||
{
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(wxBrush(GetBackgroundColour()));
|
||||
dc.DrawRectangle(GetClientRect());
|
||||
|
||||
const wxRect bounds = GetClientRect().Deflate(1);
|
||||
const wxRect bounds = GetClientRect();
|
||||
if (bounds.width <= 0 || bounds.height <= 0)
|
||||
return;
|
||||
|
||||
const int states = state_handler.states();
|
||||
const bool hovered = (states & StateHandler::Hovered) != 0;
|
||||
const bool focused = (states & StateHandler::Focused) != 0;
|
||||
const bool disabled = !IsEnabled();
|
||||
|
||||
const wxColour track_fill = disabled ? wxColour(0xD0, 0xD0, 0xD4) :
|
||||
m_pressed ? wxColour(0x5A, 0x5D, 0x64) : wxColour(0x66, 0x69, 0x70);
|
||||
const wxColour track_border = disabled ? wxColour(0xDD, 0xDD, 0xE0) :
|
||||
focused ? wxColour("#009688") :
|
||||
hovered ? wxColour(0x7A, 0x7D, 0x84) : wxColour(0x75, 0x78, 0x7F);
|
||||
const wxColour active_fill = disabled ? wxColour(0x9E, 0xBE, 0xB9) :
|
||||
m_pressed ? wxColour(0x00877B) : wxColour("#009688");
|
||||
const wxColour active_dot = disabled ? wxColour(0xEC, 0xF4, 0xF2) : wxColour(0xB7, 0xEB, 0xE3);
|
||||
const wxColour inactive_dot = disabled ? wxColour(0xF2, 0xF2, 0xF4) : wxColour(0xB5, 0xB7, 0xBD);
|
||||
const wxColour thumb_fill = disabled ? wxColour(0xFA, 0xFA, 0xFA) : *wxWHITE;
|
||||
const wxColour thumb_border = disabled ? wxColour(0xE7, 0xE7, 0xEA) : wxColour(0xDD, 0xDF, 0xE3);
|
||||
|
||||
dc.SetPen(wxPen(track_border, 1));
|
||||
dc.SetBrush(wxBrush(track_fill));
|
||||
dc.DrawRoundedRectangle(bounds, bounds.height / 2.0);
|
||||
|
||||
const wxRect thumb = thumb_rect_for(m_selection);
|
||||
const int fill_right = std::min(bounds.GetRight(), thumb.GetX() + thumb.GetWidth() / 2 + FromDIP(2));
|
||||
wxRect active(bounds.x, bounds.y, fill_right - bounds.x + 1, bounds.height);
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(wxBrush(active_fill));
|
||||
dc.DrawRoundedRectangle(active, bounds.height / 2.0);
|
||||
dc.SetBrush(wxBrush(GetBackgroundColour()));
|
||||
dc.DrawRectangle(bounds);
|
||||
|
||||
const int dot_radius = std::max(FromDIP(1), thumb.height / 7);
|
||||
for (int idx = 0; idx < 3; ++idx) {
|
||||
if (idx == m_selection)
|
||||
continue;
|
||||
int states = state_handler.states();
|
||||
double v_center = bounds.height / 2.0;
|
||||
|
||||
const wxRect slot = thumb_rect_for(idx);
|
||||
const wxPoint center(slot.GetX() + slot.GetWidth() / 2, slot.GetY() + slot.GetHeight() / 2);
|
||||
dc.SetBrush(wxBrush(idx < m_selection ? active_dot : inactive_dot));
|
||||
dc.DrawCircle(center, dot_radius);
|
||||
// Background
|
||||
dc.SetPen(wxPen(border_color.colorForStates(states), 1));
|
||||
dc.SetBrush(wxBrush(background_color.colorForStates(states)));
|
||||
dc.DrawRoundedRectangle(bounds, v_center);
|
||||
|
||||
if (m_enabled) {
|
||||
double dot_dist = (bounds.width - bounds.height) * 0.50;
|
||||
|
||||
// Track
|
||||
dc.SetPen(wxPen(track_border.colorForStates(states), 1));
|
||||
dc.SetBrush(wxBrush(track_background.colorForStates(states)));
|
||||
wxRect track_rc = bounds;
|
||||
track_rc.width = int(v_center * 2.0 + dot_dist * m_selection);
|
||||
dc.DrawRoundedRectangle(track_rc, v_center);
|
||||
|
||||
// Dots
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
for (int idx = 0; idx < 3; ++idx) {
|
||||
dc.SetBrush(wxBrush((idx <= m_selection ? dot_active : dot_dimmed).colorForStates(states)));
|
||||
dc.DrawCircle(wxPoint(v_center + dot_dist * idx, v_center), track_rc.height * (double)(idx == m_selection ? 0.32 : 0.16));
|
||||
}
|
||||
}
|
||||
else { // Developer mode
|
||||
wxString str = "DEV";
|
||||
int kerning = 3; // pixels between chars
|
||||
dc.SetTextForeground(text_color.colorForStates(states));
|
||||
|
||||
dc.SetPen(wxPen(thumb_border, 1));
|
||||
dc.SetBrush(wxBrush(thumb_fill));
|
||||
dc.DrawRoundedRectangle(thumb, thumb.height / 2.0);
|
||||
wxCoord totalWidth = 0;
|
||||
for (char c : str)
|
||||
totalWidth += dc.GetTextExtent(wxString(c)).x + kerning;
|
||||
totalWidth -= kerning;
|
||||
|
||||
wxCoord x = bounds.x + (bounds.width - totalWidth) / 2;
|
||||
wxCoord y = bounds.y + (bounds.height - dc.GetTextExtent(str).y) / 2 - 1;
|
||||
|
||||
for (char c : str) {
|
||||
wxString ch(c);
|
||||
dc.DrawText(ch, x, y);
|
||||
x += dc.GetTextExtent(ch).x + kerning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModeSwitchButton::mouseDown(wxMouseEvent& event)
|
||||
|
||||
@@ -77,7 +77,13 @@ private:
|
||||
private:
|
||||
int m_selection { 0 };
|
||||
bool m_pressed { false };
|
||||
bool m_enabled { true };
|
||||
wxString m_tooltips[3];
|
||||
StateColor dot_active;
|
||||
StateColor dot_dimmed;
|
||||
StateColor text_color;
|
||||
StateColor track_background;
|
||||
StateColor track_border;
|
||||
};
|
||||
|
||||
class SwitchBoard : public wxWindow
|
||||
|
||||
@@ -50,7 +50,10 @@ std::map<std::string, std::string> BBLCloudServiceAgent::get_extra_header()
|
||||
{
|
||||
std::map<std::string, std::string> extra_headers;
|
||||
extra_headers.emplace("X-BBL-Client-Type", "slicer");
|
||||
extra_headers.emplace("X-BBL-Client-Name", SLIC3R_APP_NAME);
|
||||
|
||||
// Unable to get camera live view when the printer is connected to cloud for H2D
|
||||
extra_headers.emplace("X-BBL-Client-Name", "BambuStudio");
|
||||
|
||||
extra_headers.emplace("X-BBL-Client-Version", GUI::wxGetApp().get_bbl_client_version());
|
||||
#if defined(__WINDOWS__)
|
||||
#ifdef _M_X64
|
||||
|
||||
Reference in New Issue
Block a user