mirror of
https://github.com/QIDITECH/QIDISlicer.git
synced 2026-02-01 08:28:42 +03:00
version update
This commit is contained in:
@@ -289,8 +289,8 @@ AboutDialog::AboutDialog()
|
||||
"<a href=\"https://qidi3d.com/\">%5%</a>"
|
||||
"<br /><br />"
|
||||
"%6%<br />"
|
||||
"%11% © 2023-2024 QIDI Technology. <br />"
|
||||
"%7% © 2016-2024 Prusa Research. <br />"
|
||||
"%11% © 2023-2025 QIDI Technology. <br />"
|
||||
"%7% © 2016-2025 Prusa Research. <br />"
|
||||
"%8% © 2011-2018 Alessandro Ranellucci. <br />"
|
||||
"<a href=\"http://slic3r.org/\">Slic3r</a> %9% "
|
||||
"<a href=\"http://www.gnu.org/licenses/agpl-3.0.html\">%10%</a>."
|
||||
|
||||
@@ -137,6 +137,19 @@ Downloader::Downloader()
|
||||
Bind(EVT_DWNLDR_FILE_CANCELED, &Downloader::on_canceled, this);
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool is_any_subdomain(const std::string& url, const std::vector<std::string>& subdomains)
|
||||
{
|
||||
for (const std::string& sub : subdomains)
|
||||
{
|
||||
if(FileGet::is_subdomain(url, sub))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Downloader::start_download(const std::string& full_url)
|
||||
{
|
||||
assert(m_initialized);
|
||||
@@ -153,14 +166,14 @@ void Downloader::start_download(const std::string& full_url)
|
||||
|
||||
size_t id = get_next_id();
|
||||
|
||||
if (!boost::starts_with(escaped_url, "https://") || !FileGet::is_subdomain(escaped_url, "printables.com")) {
|
||||
std::string msg = format(_L("Download won't start. Download URL doesn't point to https://printables.com : %1%"), escaped_url);
|
||||
if (!boost::starts_with(escaped_url, "https://") || !is_any_subdomain(escaped_url, {"printables.com", "thingiverse.com"})) {
|
||||
std::string msg = format(_L("Download won't start. Download URL doesn't point to allowed subdomains : %1%"), escaped_url);
|
||||
BOOST_LOG_TRIVIAL(error) << msg;
|
||||
NotificationManager* ntf_mngr = wxGetApp().notification_manager();
|
||||
ntf_mngr->push_notification(NotificationType::CustomNotification, NotificationManager::NotificationLevel::RegularNotificationLevel, msg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_downloads.emplace_back(std::make_unique<Download>(id, std::move(escaped_url), this, m_dest_folder, true));
|
||||
NotificationManager* ntf_mngr = wxGetApp().notification_manager();
|
||||
ntf_mngr->push_download_URL_progress_notification(id, m_downloads.back()->get_filename(), std::bind(&Downloader::user_action_callback, this, std::placeholders::_1, std::placeholders::_2));
|
||||
@@ -199,7 +212,7 @@ void Downloader::on_progress(wxCommandEvent& event)
|
||||
float percent = (float)std::stoi(into_u8(event.GetString())) / 100.f;
|
||||
//BOOST_LOG_TRIVIAL(error) << "progress " << id << ": " << percent;
|
||||
NotificationManager* ntf_mngr = wxGetApp().notification_manager();
|
||||
BOOST_LOG_TRIVIAL(trace) << "Download "<< id << ": " << percent;
|
||||
//BOOST_LOG_TRIVIAL(trace) << "Download "<< id << ": " << percent;
|
||||
ntf_mngr->set_download_URL_progress(id, percent);
|
||||
}
|
||||
void Downloader::on_error(wxCommandEvent& event)
|
||||
@@ -247,7 +260,9 @@ bool Downloader::user_action_callback(DownloaderUserAction action, int id)
|
||||
|
||||
void Downloader::on_name_change(wxCommandEvent& event)
|
||||
{
|
||||
|
||||
size_t id = event.GetInt();
|
||||
NotificationManager* ntf_mngr = wxGetApp().notification_manager();
|
||||
ntf_mngr->set_download_URL_filename(id, into_u8(event.GetString()));
|
||||
}
|
||||
|
||||
void Downloader::on_paused(wxCommandEvent& event)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
|
||||
#include "format.hpp"
|
||||
#include "GUI.hpp"
|
||||
@@ -64,6 +65,26 @@ unsigned get_current_pid()
|
||||
return ::getpid();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string extract_filename_from_header(const std::string& headers) {
|
||||
// Split the headers into lines
|
||||
std::istringstream header_stream(headers);
|
||||
std::string line;
|
||||
|
||||
while (std::getline(header_stream, line)) {
|
||||
if (line.find("content-disposition") != std::string::npos) {
|
||||
// Apply regex to extract filename from the content-disposition line
|
||||
std::regex filename_regex("filename\\s*=\\s*\"([^\"]+)\"", std::regex::icase);
|
||||
std::smatch match;
|
||||
|
||||
if (std::regex_search(line, match, filename_regex) && match.size() > 1) {
|
||||
return match.str(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
// int = DOWNLOAD ID; string = file path
|
||||
@@ -107,6 +128,8 @@ FileGet::priv::priv(int ID, std::string&& url, const std::string& filename, wxEv
|
||||
, m_dest_folder(dest_folder)
|
||||
, m_load_after(load_after)
|
||||
{
|
||||
// Prevent ':' in filename
|
||||
m_filename.erase(std::remove(m_filename.begin(), m_filename.end(), ':'), m_filename.end());
|
||||
}
|
||||
|
||||
void FileGet::priv::get_perform()
|
||||
@@ -125,7 +148,7 @@ void FileGet::priv::get_perform()
|
||||
std::string extension = dest_path.extension().string();
|
||||
std::string just_filename = m_filename.substr(0, m_filename.size() - extension.size());
|
||||
std::string final_filename = just_filename;
|
||||
// Find unsed filename
|
||||
// Find unused filename
|
||||
try {
|
||||
size_t version = 0;
|
||||
while (boost::filesystem::exists(m_dest_folder / (final_filename + extension)) || boost::filesystem::exists(m_dest_folder / (final_filename + extension + "." + std::to_string(get_current_pid()) + ".download")))
|
||||
@@ -150,7 +173,6 @@ void FileGet::priv::get_perform()
|
||||
}
|
||||
|
||||
m_filename = final_filename + extension;
|
||||
|
||||
m_tmp_path = m_dest_folder / (m_filename + "." + std::to_string(get_current_pid()) + ".download");
|
||||
|
||||
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE);
|
||||
@@ -217,7 +239,12 @@ void FileGet::priv::get_perform()
|
||||
m_evt_handler->QueueEvent(evt);
|
||||
return;
|
||||
}
|
||||
|
||||
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_PROGRESS);
|
||||
int percent_total = 100;
|
||||
evt->SetString(std::to_string(percent_total));
|
||||
evt->SetInt(m_id);
|
||||
m_evt_handler->QueueEvent(evt);
|
||||
|
||||
if (m_absolute_size < progress.dltotal) {
|
||||
m_absolute_size = progress.dltotal;
|
||||
}
|
||||
@@ -243,13 +270,48 @@ void FileGet::priv::get_perform()
|
||||
m_written = written_previously + written_this_session;
|
||||
}
|
||||
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_PROGRESS);
|
||||
int percent_total = (written_previously + progress.dlnow) * 100 / m_absolute_size;
|
||||
int percent_total = m_absolute_size == 0 ? 0 : (written_previously + progress.dlnow) * 100 / m_absolute_size;
|
||||
evt->SetString(std::to_string(percent_total));
|
||||
evt->SetInt(m_id);
|
||||
m_evt_handler->QueueEvent(evt);
|
||||
}
|
||||
|
||||
})
|
||||
.on_headers([&](const std::string& headers) {
|
||||
// we are looking for content-disposition header in response, to use it as correct filename
|
||||
std::string new_filename = extract_filename_from_header(headers);
|
||||
if (new_filename.empty()) {
|
||||
return;
|
||||
}
|
||||
// Find unused filename
|
||||
boost::filesystem::path temp_dest_path = m_dest_folder / new_filename;
|
||||
std::string extension = temp_dest_path.extension().string();
|
||||
std::string just_filename = new_filename.substr(0, new_filename.size() - extension.size());
|
||||
std::string final_filename = just_filename;
|
||||
try {
|
||||
size_t version = 0;
|
||||
while (boost::filesystem::exists(m_dest_folder / (final_filename + extension)))
|
||||
{
|
||||
++version;
|
||||
if (version > 999) {
|
||||
BOOST_LOG_TRIVIAL(error) << GUI::format("Failed to find suitable filename. Last name: %1%." , (m_dest_folder / (final_filename + extension)).string());
|
||||
return;
|
||||
}
|
||||
final_filename = GUI::format("%1%(%2%)", just_filename, std::to_string(version));
|
||||
}
|
||||
} catch (const boost::filesystem::filesystem_error& e)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to resolved filename from headers.";
|
||||
return;
|
||||
}
|
||||
m_filename = final_filename + extension;
|
||||
dest_path = m_dest_folder / m_filename;
|
||||
|
||||
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_NAME_CHANGE);
|
||||
evt->SetString(from_u8(m_filename));
|
||||
evt->SetInt(m_id);
|
||||
m_evt_handler->QueueEvent(evt);
|
||||
})
|
||||
.on_error([&](std::string body, std::string error, unsigned http_status) {
|
||||
if (file != NULL)
|
||||
fclose(file);
|
||||
@@ -264,15 +326,21 @@ void FileGet::priv::get_perform()
|
||||
.on_complete([&](std::string body, unsigned /* http_status */) {
|
||||
try
|
||||
{
|
||||
// If server is not sending Content-Length header, the progress function does not write all data to file.
|
||||
// We need to write it now.
|
||||
if (written_this_session < body.size()) {
|
||||
std::string part_for_write = body.substr(written_this_session);
|
||||
fwrite(part_for_write.c_str(), 1, part_for_write.size(), file);
|
||||
}
|
||||
fclose(file);
|
||||
boost::filesystem::rename(m_tmp_path, dest_path);
|
||||
}
|
||||
catch (const std::exception& /*e*/)
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
//TODO: report?
|
||||
//error_message = GUI::format("Failed to write and move %1% to %2%", tmp_path, dest_path);
|
||||
wxCommandEvent* evt = new wxCommandEvent(EVT_DWNLDR_FILE_ERROR);
|
||||
evt->SetString("Failed to write and move.");
|
||||
evt->SetString(GUI::format("Failed to write and move %1% to %2%", m_tmp_path, dest_path));
|
||||
evt->SetInt(m_id);
|
||||
m_evt_handler->QueueEvent(evt);
|
||||
return;
|
||||
|
||||
@@ -688,7 +688,7 @@ wxWindow* CheckBox::GetNewWin(wxWindow* parent, const wxString& label /*= wxEmpt
|
||||
if (wxGetApp().suppress_round_corners())
|
||||
return new ::CheckBox(parent, label);
|
||||
|
||||
return new ::SwitchButton(parent, label);
|
||||
return new ::DeviceSwitchButton(parent, label); //y25
|
||||
}
|
||||
|
||||
void CheckBox::SetValue(wxWindow* win, bool value)
|
||||
@@ -698,7 +698,7 @@ void CheckBox::SetValue(wxWindow* win, bool value)
|
||||
ch_b->SetValue(value);
|
||||
}
|
||||
else {
|
||||
if (::SwitchButton* ch_b = dynamic_cast<::SwitchButton*>(win))
|
||||
if (::DeviceSwitchButton* ch_b = dynamic_cast<::DeviceSwitchButton*>(win)) //y25
|
||||
ch_b->SetValue(value);
|
||||
}
|
||||
}
|
||||
@@ -708,7 +708,7 @@ bool CheckBox::GetValue(wxWindow* win)
|
||||
if (wxGetApp().suppress_round_corners())
|
||||
return dynamic_cast<::CheckBox*>(win)->GetValue();
|
||||
|
||||
return dynamic_cast<::SwitchButton*>(win)->GetValue();
|
||||
return dynamic_cast<::DeviceSwitchButton*>(win)->GetValue(); //y25
|
||||
}
|
||||
|
||||
void CheckBox::Rescale(wxWindow* win)
|
||||
@@ -716,13 +716,13 @@ void CheckBox::Rescale(wxWindow* win)
|
||||
if (wxGetApp().suppress_round_corners())
|
||||
dynamic_cast<::CheckBox*>(win)->Rescale();
|
||||
else
|
||||
dynamic_cast<::SwitchButton*>(win)->Rescale();
|
||||
dynamic_cast<::DeviceSwitchButton*>(win)->Rescale(); //y25
|
||||
}
|
||||
|
||||
void CheckBox::SysColorChanged(wxWindow* win)
|
||||
{
|
||||
if (!wxGetApp().suppress_round_corners())
|
||||
dynamic_cast<::SwitchButton*>(win)->SysColorChange();
|
||||
dynamic_cast<::DeviceSwitchButton*>(win)->SysColorChange(); //y25
|
||||
}
|
||||
|
||||
void CheckBox::SetValue(bool value)
|
||||
@@ -730,7 +730,7 @@ void CheckBox::SetValue(bool value)
|
||||
if (wxGetApp().suppress_round_corners())
|
||||
dynamic_cast<::CheckBox*>(window)->SetValue(value);
|
||||
else
|
||||
dynamic_cast<::SwitchButton*>(window)->SetValue(value);
|
||||
dynamic_cast<::DeviceSwitchButton*>(window)->SetValue(value); //y25
|
||||
}
|
||||
|
||||
bool CheckBox::GetValue()
|
||||
@@ -738,7 +738,7 @@ bool CheckBox::GetValue()
|
||||
if (wxGetApp().suppress_round_corners())
|
||||
return dynamic_cast<::CheckBox*>(window)->GetValue();
|
||||
|
||||
return dynamic_cast<::SwitchButton*>(window)->GetValue();
|
||||
return dynamic_cast<::DeviceSwitchButton*>(window)->GetValue(); //y25
|
||||
}
|
||||
|
||||
void CheckBox::BUILD() {
|
||||
@@ -831,7 +831,7 @@ void CheckBox::msw_rescale()
|
||||
void CheckBox::sys_color_changed()
|
||||
{
|
||||
Field::sys_color_changed();
|
||||
if (auto switch_btn = dynamic_cast<::SwitchButton*>(window))
|
||||
if (auto switch_btn = dynamic_cast<::DeviceSwitchButton*>(window)) //y25
|
||||
switch_btn->SysColorChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
#include "WipeTowerDialog.hpp"
|
||||
|
||||
//y25
|
||||
#include "SyncBoxInfoDialog.hpp"
|
||||
|
||||
#include "Tab.hpp"
|
||||
|
||||
using Slic3r::Preset;
|
||||
using Slic3r::GUI::format_wxstr;
|
||||
|
||||
@@ -303,12 +308,54 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent)
|
||||
m_og_filament->append_line(line);
|
||||
m_og_filament->activate();
|
||||
|
||||
//y25
|
||||
m_og_sync = std::make_shared<ConfigOptionsGroup>(parent, "");
|
||||
DynamicPrintConfig* printer_config = &wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
||||
|
||||
m_og_sync->set_config(printer_config);
|
||||
m_og_sync->hide_labels();
|
||||
auto add_sync_btn = [this](wxWindow* parent) {
|
||||
|
||||
//y26
|
||||
auto sync_btn = new wxButton(parent, wxID_ANY, _L("Syn filament info from the box"), wxDefaultPosition, wxSize(200, 30), wxBU_EXACTFIT);
|
||||
wxGetApp().UpdateDarkUI(sync_btn, true);
|
||||
|
||||
sync_btn->SetToolTip(_L("Click the sync button to synchronize the Box information to the filament column."));
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(sync_btn, 0, wxALIGN_CENTER_VERTICAL);
|
||||
sync_btn->Bind(wxEVT_BUTTON, [parent](wxCommandEvent& e){
|
||||
//y25
|
||||
std::string ph_host = "";
|
||||
bool has_select_printer = wxGetApp().preset_bundle->physical_printers.has_selection();
|
||||
if (has_select_printer) {
|
||||
PhysicalPrinter& ph_printer = wxGetApp().preset_bundle->physical_printers.get_selected_printer();
|
||||
ph_host = ph_printer.config.opt_string("print_host");
|
||||
}
|
||||
|
||||
GetBoxInfoDialog dlg(wxGetApp().plater());
|
||||
if(ph_host.empty()){
|
||||
dlg.ShowModal();
|
||||
}
|
||||
else{
|
||||
dlg.synchronize_by_ip(ph_host);
|
||||
}
|
||||
});
|
||||
return sizer;
|
||||
};
|
||||
line = Line { "", "" };
|
||||
line.append_only_widget(add_sync_btn);
|
||||
m_og_sync->append_line(line);
|
||||
m_og_sync->activate();
|
||||
|
||||
m_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_sizer->Add(m_og_fff->sizer, 0, wxEXPAND);
|
||||
|
||||
//Y26
|
||||
m_sizer->Add(m_og_filament->sizer, 0, wxEXPAND);
|
||||
m_sizer->Add(m_og_sla->sizer, 0, wxEXPAND);
|
||||
|
||||
//y25
|
||||
m_sizer->Add(m_og_sync->sizer, 0, wxEXPAND);
|
||||
}
|
||||
|
||||
void FreqChangedParams::msw_rescale()
|
||||
@@ -339,7 +386,8 @@ void FreqChangedParams::Show(bool is_fff) const
|
||||
//Y26
|
||||
m_og_filament->Show(is_fff);
|
||||
m_og_sla->Show(!is_fff);
|
||||
|
||||
//y25
|
||||
m_og_sync->Show(is_fff);
|
||||
// correct showing of the FreqChangedParams sizer when m_wiping_dialog_button is hidden
|
||||
if (is_fff && !is_wdb_shown)
|
||||
m_wiping_dialog_button->Hide();
|
||||
|
||||
@@ -24,6 +24,8 @@ class FreqChangedParams
|
||||
|
||||
//Y26
|
||||
std::shared_ptr<ConfigOptionsGroup> m_og_filament;
|
||||
//y25
|
||||
std::shared_ptr<ConfigOptionsGroup> m_og_sync;
|
||||
std::shared_ptr<ConfigOptionsGroup> m_og_fff;
|
||||
std::shared_ptr<ConfigOptionsGroup> m_og_sla;
|
||||
|
||||
|
||||
@@ -1473,7 +1473,8 @@ bool GLCanvas3D::check_volumes_outside_state(GLVolumeCollection& volumes, ModelI
|
||||
//B52
|
||||
for (unsigned int vol_idx : volumes_idxs) {
|
||||
GLVolume* volume = volumes.volumes[vol_idx];
|
||||
if (!volume->is_modifier && (volume->shader_outside_printer_detection_enabled || (!volume->is_wipe_tower() && volume->composite_id.volume_id >= 0))) {
|
||||
//y25
|
||||
if (!volume->is_modifier && (volume->shader_outside_printer_detection_enabled && (!volume->is_wipe_tower() && volume->composite_id.volume_id >= 0))) {
|
||||
BuildVolume::ObjectState state;
|
||||
int bed_idx = -1;
|
||||
if (volume_below(*volume))
|
||||
|
||||
@@ -880,8 +880,21 @@ void GLGizmoSlaSupports::draw_island_config() {
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("head radius %.2f mm", unscale<float>(sample_config.head_radius));
|
||||
|
||||
bool exist_change = false;
|
||||
// copied from SLAPrint::Steps::support_points()
|
||||
const SLAPrintObject *po = m_c->selection_info()->print_object();
|
||||
const SLAPrintObjectConfig &cfg = po->config();
|
||||
float head_diameter = (cfg.support_tree_type == sla::SupportTreeType::Branching) ?
|
||||
float(cfg.branchingsupport_head_front_diameter):
|
||||
float(cfg.support_head_front_diameter); // SupportTreeType::Organic
|
||||
std::string button_title = "apply " + std::to_string(head_diameter);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(button_title.c_str())) {
|
||||
float density_relative = float(cfg.support_points_density_relative / 100.f);
|
||||
sample_config = sla::SampleConfigFactory::apply_density(
|
||||
sla::SampleConfigFactory::create(head_diameter), density_relative);
|
||||
}
|
||||
|
||||
bool exist_change = false;
|
||||
if (float max_for_one = unscale<float>(sample_config.max_length_for_one_support_point); // [in mm]
|
||||
ImGui::InputFloat("One support", &max_for_one, .1f, 1.f, "%.2f mm")) {
|
||||
sample_config.max_length_for_one_support_point = scale_(max_for_one);
|
||||
@@ -1457,7 +1470,7 @@ SlaGizmoHelpDialog::SlaGizmoHelpDialog()
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
const wxString ctrl = GUI::shortkey_ctrl_prefix();
|
||||
const wxString alt = GUI::shortkey_alt_prefix();
|
||||
|
||||
const wxString shift = wxString("Shift+");
|
||||
|
||||
// fonts
|
||||
const wxFont& font = wxGetApp().small_font();
|
||||
@@ -1484,9 +1497,9 @@ SlaGizmoHelpDialog::SlaGizmoHelpDialog()
|
||||
shortcuts.push_back(std::make_pair(_L("Left click"), _L("Add point")));
|
||||
shortcuts.push_back(std::make_pair(_L("Right click"), _L("Remove point")));
|
||||
shortcuts.push_back(std::make_pair(_L("Drag"), _L("Move point")));
|
||||
shortcuts.push_back(std::make_pair(ctrl+_L("Left click"), _L("Add point to selection")));
|
||||
shortcuts.push_back(std::make_pair(shift+_L("Left click"), _L("Add point to selection")));
|
||||
shortcuts.push_back(std::make_pair(alt+_L("Left click"), _L("Remove point from selection")));
|
||||
shortcuts.push_back(std::make_pair(wxString("Shift+")+_L("Drag"), _L("Select by rectangle")));
|
||||
shortcuts.push_back(std::make_pair(shift+_L("Drag"), _L("Select by rectangle")));
|
||||
shortcuts.push_back(std::make_pair(alt+_(L("Drag")), _L("Deselect by rectangle")));
|
||||
shortcuts.push_back(std::make_pair(ctrl+"A", _L("Select all points")));
|
||||
shortcuts.push_back(std::make_pair("Delete", _L("Remove selected points")));
|
||||
|
||||
259
src/slic3r/GUI/LoadStepDialog.cpp
Normal file
259
src/slic3r/GUI/LoadStepDialog.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
///|/ Copyright (c) Prusa Research 2018 - 2023 Vojtěch Bubník @bubnikv, Lukáš Matěna @lukasmatena, Oleksandra Iushchenko @YuSanka, Enrico Turri @enricoturri1966, Tomáš Mészáros @tamasmeszaros, David Kocík @kocikdav, Lukáš Hejl @hejllukas, Pavel Mikuš @Godrak, Filip Sykala @Jony01, Vojtěch Král @vojtechkral
|
||||
///|/ Copyright (c) 2022 Michael Kirsch
|
||||
///|/ Copyright (c) 2021 Boleslaw Ciesielski
|
||||
///|/ Copyright (c) 2019 John Drake @foxox
|
||||
///|/
|
||||
///|/ ported from lib/Slic3r/GUI/Plater.pm:
|
||||
///|/ Copyright (c) Prusa Research 2016 - 2019 Vojtěch Bubník @bubnikv, Vojtěch Král @vojtechkral, Enrico Turri @enricoturri1966, Oleksandra Iushchenko @YuSanka, Lukáš Matěna @lukasmatena, Tomáš Mészáros @tamasmeszaros
|
||||
///|/ Copyright (c) 2018 Martin Loidl @LoidlM
|
||||
///|/ Copyright (c) 2017 Matthias Gazzari @qtux
|
||||
///|/ Copyright (c) Slic3r 2012 - 2016 Alessandro Ranellucci @alranel
|
||||
///|/ Copyright (c) 2017 Joseph Lenox @lordofhyphens
|
||||
///|/ Copyright (c) 2015 Daren Schwenke
|
||||
///|/ Copyright (c) 2014 Mark Hindess
|
||||
///|/ Copyright (c) 2012 Mike Sheldrake @mesheldrake
|
||||
///|/ Copyright (c) 2012 Henrik Brix Andersen @henrikbrixandersen
|
||||
///|/ Copyright (c) 2012 Sam Wong
|
||||
///|/
|
||||
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
|
||||
#include "LoadStepDialog.hpp"
|
||||
#include <wx/window.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/radiobut.h>
|
||||
#include <wx/slider.h>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
#include "format.hpp"
|
||||
#include "MsgDialog.hpp"
|
||||
#include "Widgets/CheckBox.hpp"
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
static std::vector<std::pair<std::string, PrecisionParams>> default_step_import_params = {
|
||||
{"Low" , {0.005, 1. }},
|
||||
{"Medium" , {0.003, 0.5 }},
|
||||
{"High" , {0.001, 0.25}},
|
||||
};
|
||||
|
||||
LoadStepDialog::LoadStepDialog(wxWindow* parent, const std::string& filename, double linear_precision, double angle_precision, bool multiple_loading)
|
||||
: DPIDialog(parent, wxID_ANY, format_wxstr(_L("STEP import quality (%1%)"), filename), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER),
|
||||
m_params({ linear_precision, angle_precision })
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
wxGetApp().UpdateDarkUI(this);
|
||||
#else
|
||||
//SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
#endif
|
||||
const wxFont& font = wxGetApp().normal_font();
|
||||
SetFont(font);
|
||||
|
||||
// Call your custom function manually after constructing base
|
||||
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); // Get the sizer
|
||||
|
||||
add_params(main_sizer);
|
||||
|
||||
main_sizer->Add(new StaticLine(this), 0, wxEXPAND | wxLEFT | wxRIGHT, em_unit());
|
||||
|
||||
wxBoxSizer* bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_remember_chb = new ::CheckBox(this, _L("Remember my choice"));
|
||||
|
||||
bottom_sizer->Add(m_remember_chb, 0, wxEXPAND | wxRIGHT, 5);
|
||||
bottom_sizer->AddStretchSpacer();
|
||||
|
||||
auto buttons_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
|
||||
|
||||
if (multiple_loading) {
|
||||
auto apply_btn = new wxButton(this, wxID_APPLY, _L("Apply to all"));
|
||||
apply_btn->Bind(wxEVT_BUTTON, [this](wxEvent&) {
|
||||
m_apply_to_all = true;
|
||||
EndModal(wxID_OK);
|
||||
});
|
||||
buttons_sizer->Insert(0, apply_btn, 0, wxRIGHT, 5);
|
||||
}
|
||||
|
||||
bottom_sizer->Add(buttons_sizer, 0, wxEXPAND | wxLEFT, 5);
|
||||
main_sizer->Add(bottom_sizer, 0, wxEXPAND | wxALL, 10);
|
||||
|
||||
SetSizer(main_sizer);
|
||||
main_sizer->SetSizeHints(this);
|
||||
|
||||
enable_customs(!m_default);
|
||||
|
||||
// Update DarkUi just for buttons
|
||||
wxGetApp().UpdateDlgDarkUI(this, true);
|
||||
|
||||
}
|
||||
|
||||
void LoadStepDialog::add_params(wxSizer* sizer)
|
||||
{
|
||||
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
main_sizer->Add(new wxStaticText(this, wxID_ANY, _L("Select requested quality of the mesh after import: ")));
|
||||
|
||||
// add radio buttons for selection default parameters
|
||||
|
||||
for (const auto& [name, params] : default_step_import_params) {
|
||||
wxRadioButton* radio_def = new wxRadioButton(this, wxID_ANY, format_wxstr("%1%", _(name)));
|
||||
radio_def->Bind(wxEVT_RADIOBUTTON, [params_copy = params, this](wxEvent&) {
|
||||
m_params.linear = params_copy.linear;
|
||||
m_params.angle = params_copy.angle;
|
||||
|
||||
enable_customs(false);
|
||||
});
|
||||
bool is_selected = m_params.linear == params.linear && m_params.angle == params.angle;
|
||||
radio_def->SetValue(is_selected);
|
||||
|
||||
m_default |= is_selected;
|
||||
|
||||
main_sizer->Add(radio_def, 0, wxLEFT | wxTOP, em_unit());
|
||||
}
|
||||
|
||||
// add radio buttons for set custom parameters
|
||||
|
||||
wxRadioButton* radio_custom = new wxRadioButton(this, wxID_ANY, _L("Custom"));
|
||||
radio_custom->Bind(wxEVT_RADIOBUTTON, [&, this](wxEvent&) {
|
||||
enable_customs(true);
|
||||
#ifdef __linux__
|
||||
this->Fit();
|
||||
#endif // __linux__
|
||||
m_params.linear = string_to_double_decimal_point(m_linear_precision_val->GetValue().ToStdString());
|
||||
m_params.angle = string_to_double_decimal_point(m_angle_precision_val->GetValue().ToStdString());
|
||||
});
|
||||
|
||||
main_sizer->Add(radio_custom, 0, wxLEFT | wxTOP, em_unit());
|
||||
radio_custom->SetValue(!m_default);
|
||||
|
||||
long slyder_style = wxSL_HORIZONTAL | wxSL_TICKS;
|
||||
long text_ctrl_style = wxTE_PROCESS_ENTER;
|
||||
#ifdef _WIN32
|
||||
text_ctrl_style |= wxBORDER_SIMPLE;
|
||||
#endif
|
||||
|
||||
const wxSize def_slider_size = wxSize(15 * em_unit(), wxDefaultCoord);
|
||||
const wxSize def_editor_size = wxSize(5 * em_unit(), wxDefaultCoord);
|
||||
|
||||
const int hgap = 5;
|
||||
wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(4, em_unit(), hgap);
|
||||
grid_sizer->SetFlexibleDirection(wxBOTH);
|
||||
grid_sizer->AddGrowableCol(1, 1);
|
||||
grid_sizer->AddGrowableRow(0, 1);
|
||||
grid_sizer->AddGrowableRow(1, 1);
|
||||
|
||||
wxBoxSizer* labels_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
{
|
||||
const wxString left_text = _L("Lower quality");
|
||||
const int left_text_gap = std::max(GetTextExtent(_L("Linear precision")).x, GetTextExtent(_L("Angle precision")).x) + 4 * hgap - GetTextExtent(left_text).x * 0.5;
|
||||
const wxString right_text = _L("Higher quality");
|
||||
const int right_text_gap = GetTextExtent(_L("mm")).x + def_editor_size.x + 4 * hgap - GetTextExtent(right_text).x * 0.5;
|
||||
labels_sizer->Add(new wxStaticText(this, wxID_ANY, left_text), 0, wxLEFT, left_text_gap);
|
||||
labels_sizer->Add(new wxStaticText(this, wxID_ANY, wxEmptyString), 1, wxEXPAND);
|
||||
labels_sizer->Add(new wxStaticText(this, wxID_ANY, right_text), 0, wxRIGHT, right_text_gap);
|
||||
}
|
||||
|
||||
auto high_vals = std::find_if(default_step_import_params.begin(), default_step_import_params.end(),
|
||||
[](const std::pair<std::string, PrecisionParams>& val) { return val.first == "High"; });
|
||||
auto low_vals = std::find_if(default_step_import_params.begin(), default_step_import_params.end(),
|
||||
[](const std::pair<std::string, PrecisionParams>& val) { return val.first == "Low"; });
|
||||
assert(high_vals != default_step_import_params.end() && low_vals != default_step_import_params.end());
|
||||
|
||||
m_linear_precision_sl.init(high_vals->second.linear, low_vals->second.linear, 0.001);
|
||||
m_angle_precision_sl.init(high_vals->second.angle, low_vals->second.angle, 0.01);
|
||||
|
||||
auto process_value_change = [](double& precision, wxTextCtrl* text_ctrl, wxSlider* slider, const SliderHelper& sl_helper) -> void {
|
||||
wxString str_val = text_ctrl->GetValue();
|
||||
double val = string_to_double_decimal_point(str_val.ToStdString());
|
||||
precision = sl_helper.adjust_to_region(val);
|
||||
slider->SetValue(sl_helper.get_pos(precision));
|
||||
|
||||
if (wxString str_precision = format_wxstr("%1%", precision); str_precision != str_val)
|
||||
text_ctrl->SetValue(str_precision);
|
||||
};
|
||||
|
||||
auto tooltip = [](const SliderHelper& sl_helper) -> wxString {
|
||||
// TRN %n% contain min, max and step values respectively
|
||||
return format_wxstr(_L("Set value from the range [%1%; %2%] with %3% step"),
|
||||
sl_helper.min_val, sl_helper.max_val, sl_helper.val_step);
|
||||
};
|
||||
|
||||
// Add "Linear precision"
|
||||
|
||||
m_linear_precision_slider = new wxSlider(this, wxID_ANY, m_linear_precision_sl.get_pos(m_params.linear), m_linear_precision_sl.beg_sl_pos, m_linear_precision_sl.end_sl_pos, wxDefaultPosition, def_slider_size, slyder_style);
|
||||
m_linear_precision_slider->SetTickFreq(1);
|
||||
m_linear_precision_slider->Bind(wxEVT_SLIDER, [this](wxCommandEvent e) {
|
||||
m_params.linear = m_linear_precision_sl.get_value(m_linear_precision_slider->GetValue());
|
||||
m_linear_precision_val->SetValue(format_wxstr("%1%", m_params.linear));
|
||||
});
|
||||
|
||||
m_linear_precision_val = new wxTextCtrl(this, wxID_ANY, format_wxstr("%1%", m_linear_precision_sl.adjust_to_region(m_params.linear)), wxDefaultPosition, def_editor_size, text_ctrl_style);
|
||||
m_linear_precision_val->SetToolTip(tooltip(m_linear_precision_sl));
|
||||
|
||||
m_linear_precision_val->Bind(wxEVT_TEXT_ENTER, [process_value_change, this](wxCommandEvent& e) {
|
||||
process_value_change(m_params.linear, m_linear_precision_val, m_linear_precision_slider, m_linear_precision_sl);
|
||||
});
|
||||
m_linear_precision_val->Bind(wxEVT_KILL_FOCUS, [process_value_change, this](wxFocusEvent& e) {
|
||||
process_value_change(m_params.linear, m_linear_precision_val, m_linear_precision_slider, m_linear_precision_sl);
|
||||
e.Skip();
|
||||
});
|
||||
|
||||
grid_sizer->Add(new wxStaticText(this, wxID_ANY, _L("Linear precision") + ": "), 0, wxALIGN_CENTER_VERTICAL);
|
||||
grid_sizer->Add(m_linear_precision_slider, 1, wxEXPAND);
|
||||
grid_sizer->Add(m_linear_precision_val, 0, wxALIGN_CENTER_VERTICAL);
|
||||
grid_sizer->Add(new wxStaticText(this, wxID_ANY, _L("mm")), 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
// Add "Angle precision"
|
||||
|
||||
m_angle_precision_slider = new wxSlider(this, wxID_ANY, m_angle_precision_sl.get_pos(m_params.angle), m_angle_precision_sl.beg_sl_pos, m_angle_precision_sl.end_sl_pos, wxDefaultPosition, def_slider_size, slyder_style);
|
||||
m_angle_precision_slider->SetTickFreq(5);
|
||||
m_angle_precision_slider->Bind(wxEVT_SLIDER, [this](wxCommandEvent e) {
|
||||
m_params.angle = m_angle_precision_sl.get_value(m_angle_precision_slider->GetValue());
|
||||
m_angle_precision_val->SetValue(format_wxstr("%1%", m_params.angle));
|
||||
});
|
||||
|
||||
m_angle_precision_val = new wxTextCtrl(this, wxID_ANY, format_wxstr("%1%", m_angle_precision_sl.adjust_to_region(m_params.angle)), wxDefaultPosition, def_editor_size, text_ctrl_style);
|
||||
m_angle_precision_val->SetToolTip(tooltip(m_angle_precision_sl));
|
||||
|
||||
m_angle_precision_val->Bind(wxEVT_TEXT_ENTER, [process_value_change, this](wxCommandEvent& e) {
|
||||
process_value_change(m_params.angle, m_angle_precision_val, m_angle_precision_slider, m_angle_precision_sl);
|
||||
});
|
||||
m_angle_precision_val->Bind(wxEVT_KILL_FOCUS, [process_value_change, this](wxFocusEvent& e) {
|
||||
process_value_change(m_params.angle, m_angle_precision_val, m_angle_precision_slider, m_angle_precision_sl);
|
||||
e.Skip();
|
||||
});
|
||||
|
||||
grid_sizer->Add(new wxStaticText(this, wxID_ANY, _L("Angle precision") + ": "), 0, wxALIGN_CENTER_VERTICAL);
|
||||
grid_sizer->Add(m_angle_precision_slider, 1, wxEXPAND);
|
||||
grid_sizer->Add(m_angle_precision_val, 0, wxALIGN_CENTER_VERTICAL);
|
||||
grid_sizer->Add(new wxStaticText(this, wxID_ANY, _L("°")), 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
m_custom_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_custom_sizer->Add(labels_sizer, 0, wxEXPAND | wxBOTTOM | wxTOP, em_unit());
|
||||
m_custom_sizer->Add(grid_sizer, 1, wxEXPAND);
|
||||
|
||||
main_sizer->Add(m_custom_sizer, 1, wxEXPAND | wxLEFT, 3 * em_unit());
|
||||
sizer->Add(main_sizer, 1, wxEXPAND | wxALL, em_unit());
|
||||
}
|
||||
|
||||
void LoadStepDialog::enable_customs(bool enable)
|
||||
{
|
||||
m_linear_precision_slider->Enable(enable);
|
||||
m_linear_precision_val->Enable(enable);
|
||||
m_angle_precision_slider->Enable(enable);
|
||||
m_angle_precision_val->Enable(enable);
|
||||
}
|
||||
|
||||
bool LoadStepDialog::IsCheckBoxChecked()
|
||||
{
|
||||
return m_remember_chb && m_remember_chb->GetValue();
|
||||
}
|
||||
|
||||
bool LoadStepDialog::IsApplyToAllClicked()
|
||||
{
|
||||
return m_apply_to_all;
|
||||
}
|
||||
|
||||
} // namespace Slic3r::GUI
|
||||
100
src/slic3r/GUI/LoadStepDialog.hpp
Normal file
100
src/slic3r/GUI/LoadStepDialog.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
///|/ Copyright (c) Prusa Research 2018 - 2025 Oleksandra Iushchenko @YuSanka
|
||||
///|/
|
||||
///|/ PrusaSlicer is released under the terms of the AGPLv3 or higher
|
||||
///|/
|
||||
|
||||
#ifndef slic3r_LoadStepDialog_hpp_
|
||||
#define slic3r_LoadStepDialog_hpp_
|
||||
|
||||
#include <string>
|
||||
#include <wx/dialog.h>
|
||||
#include "GUI_Utils.hpp"
|
||||
|
||||
class wxBoxSizer;
|
||||
class wxTextCtrl;
|
||||
class wxSlider;
|
||||
class CheckBox;
|
||||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
struct PrecisionParams
|
||||
{
|
||||
double linear;
|
||||
double angle;
|
||||
};
|
||||
|
||||
struct SliderHelper
|
||||
{
|
||||
double min_val;
|
||||
double max_val;
|
||||
double val_step;
|
||||
int beg_sl_pos;
|
||||
int end_sl_pos;
|
||||
|
||||
void init(double min, double max, double step, int beg_pos = 1) {
|
||||
assert(val_step != 0.);
|
||||
min_val = min;
|
||||
max_val = max;
|
||||
val_step = step;
|
||||
|
||||
beg_sl_pos = beg_pos;
|
||||
end_sl_pos = beg_sl_pos + int(double(max_val - min_val) / val_step);
|
||||
}
|
||||
|
||||
double get_value(int pos) const {
|
||||
return max_val - val_step * (pos - beg_sl_pos);
|
||||
}
|
||||
|
||||
int get_pos(double value) const {
|
||||
return beg_sl_pos + int((max_val - value) / val_step);
|
||||
}
|
||||
|
||||
double adjust_to_region(double value) const {
|
||||
return std::max(std::min(value, max_val), min_val);
|
||||
}
|
||||
};
|
||||
|
||||
class LoadStepDialog : public DPIDialog
|
||||
{
|
||||
public:
|
||||
LoadStepDialog(wxWindow* parent, const std::string& filename, double linear_precision, double angle_precision, bool multiple_loading);
|
||||
~LoadStepDialog() = default;
|
||||
|
||||
bool IsCheckBoxChecked();
|
||||
bool IsApplyToAllClicked();
|
||||
|
||||
double get_linear_precision() { return m_params.linear; }
|
||||
double get_angle_precision() { return m_params.angle; }
|
||||
|
||||
protected:
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override {}
|
||||
void on_sys_color_changed() override {};
|
||||
|
||||
|
||||
private:
|
||||
void add_params(wxSizer* sizer);
|
||||
void enable_customs(bool enable);
|
||||
|
||||
private:
|
||||
PrecisionParams m_params;
|
||||
|
||||
::CheckBox* m_remember_chb { nullptr };
|
||||
|
||||
wxTextCtrl* m_linear_precision_val { nullptr };
|
||||
wxTextCtrl* m_angle_precision_val { nullptr };
|
||||
|
||||
wxSlider* m_linear_precision_slider { nullptr };
|
||||
wxSlider* m_angle_precision_slider { nullptr };
|
||||
|
||||
wxBoxSizer* m_custom_sizer { nullptr };
|
||||
|
||||
bool m_default { false };
|
||||
bool m_apply_to_all { false };
|
||||
|
||||
SliderHelper m_linear_precision_sl;
|
||||
SliderHelper m_angle_precision_sl;
|
||||
};
|
||||
|
||||
} // namespace Slic3r::GUI
|
||||
|
||||
#endif
|
||||
@@ -1128,6 +1128,11 @@ void NotificationManager::URLDownloadWithPrintablesLinkNotification::render_text
|
||||
}
|
||||
|
||||
//------URLDownloadNotification----------------
|
||||
void NotificationManager::URLDownloadNotification::set_filename(const std::string& filename_line)
|
||||
{
|
||||
m_text1 = filename_line;
|
||||
init();
|
||||
}
|
||||
|
||||
void NotificationManager::URLDownloadNotification::render_close_button(const float win_size_x, const float win_size_y, const float win_pos_x, const float win_pos_y)
|
||||
{
|
||||
@@ -2642,6 +2647,19 @@ void NotificationManager::set_download_URL_progress(size_t id, float percentage)
|
||||
}
|
||||
}
|
||||
}
|
||||
void NotificationManager::set_download_URL_filename(size_t id, const std::string& filename)
|
||||
{
|
||||
for (std::unique_ptr<PopNotification>& notification : m_pop_notifications) {
|
||||
if (notification->get_type() == NotificationType::URLDownload) {
|
||||
URLDownloadNotification* ntf = dynamic_cast<URLDownloadNotification*>(notification.get());
|
||||
if (ntf->get_download_id() != id)
|
||||
continue;
|
||||
ntf->set_filename(_u8L("Download") + ": " + filename);
|
||||
wxGetApp().plater()->get_current_canvas3D()->schedule_extra_frame(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NotificationManager::set_download_URL_paused(size_t id)
|
||||
{
|
||||
|
||||
@@ -256,6 +256,7 @@ public:
|
||||
void set_download_URL_paused(size_t id);
|
||||
void set_download_URL_canceled(size_t id);
|
||||
void set_download_URL_error(size_t id, const std::string& text);
|
||||
void set_download_URL_filename(size_t id, const std::string& filename);
|
||||
// slicing progress
|
||||
void init_slicing_progress_notification(std::function<bool()> cancel_callback);
|
||||
void set_slicing_progress_began();
|
||||
@@ -563,6 +564,7 @@ private:
|
||||
void set_paused(bool paused) { m_download_paused = paused; }
|
||||
void set_error_message(const std::string& message) { m_error_message = message; }
|
||||
bool compare_text(const std::string& text) const override { return false; };
|
||||
void set_filename(const std::string& filename_line);
|
||||
protected:
|
||||
void render_close_button(const float win_size_x, const float win_size_y,
|
||||
const float win_pos_x, const float win_pos_y) override;
|
||||
|
||||
@@ -405,6 +405,14 @@ void OptionsGroup::activate_line(Line& line)
|
||||
}
|
||||
}
|
||||
|
||||
//y25
|
||||
if (!line.get_only_widgets().empty()){
|
||||
for (auto only_widget : line.get_only_widgets()) {
|
||||
sizer->Add(only_widget(this->ctrl_parent()), 0, wxEXPAND);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const std::vector<Option>& option_set = line.get_options();
|
||||
bool is_legend_line = option_set.front().opt.gui_type == ConfigOptionDef::GUIType::legend;
|
||||
|
||||
|
||||
@@ -73,6 +73,12 @@ public:
|
||||
void append_widget(const widget_t widget) {
|
||||
m_extra_widgets.push_back(widget);
|
||||
}
|
||||
|
||||
//y25
|
||||
void append_only_widget(const widget_t widget) {
|
||||
only_widgets.push_back(widget);
|
||||
}
|
||||
|
||||
Line(wxString label, wxString tooltip) :
|
||||
label(_(label)), label_tooltip(_(tooltip)) {}
|
||||
Line() : m_is_separator(true) {}
|
||||
@@ -90,9 +96,14 @@ public:
|
||||
const std::vector<widget_t>& get_extra_widgets() const {return m_extra_widgets;}
|
||||
const std::vector<Option>& get_options() const { return m_options; }
|
||||
|
||||
//y25
|
||||
const std::vector<widget_t>& get_only_widgets() const {return only_widgets;}
|
||||
|
||||
private:
|
||||
std::vector<Option> m_options;//! {std::vector<Option>()};
|
||||
std::vector<widget_t> m_extra_widgets;//! {std::vector<widget_t>()};
|
||||
//y25
|
||||
std::vector<widget_t> only_widgets;//{std::vector<widget_t>()};
|
||||
};
|
||||
|
||||
using column_t = std::function<wxWindow*(wxWindow* parent, const Line&)>;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <string>
|
||||
#include <regex>
|
||||
#include <future>
|
||||
#include <utility>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/nowide/cstdio.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
@@ -119,6 +120,7 @@
|
||||
#include "ConfigWizardWebViewPage.hpp"
|
||||
#include "PresetArchiveDatabase.hpp"
|
||||
#include "BulkExportDialog.hpp"
|
||||
#include "LoadStepDialog.hpp"
|
||||
|
||||
#include "libslic3r/ArrangeHelper.hpp"
|
||||
|
||||
@@ -315,6 +317,7 @@ struct Plater::priv
|
||||
static const std::regex pattern_qidi;
|
||||
static const std::regex pattern_zip;
|
||||
static const std::regex pattern_printRequest;
|
||||
static const std::regex pattern_step;
|
||||
|
||||
//y20
|
||||
std::vector<ThumbnailData> thumbnails;
|
||||
@@ -609,11 +612,13 @@ private:
|
||||
bool show_warning_dialog { false };
|
||||
};
|
||||
|
||||
// FIXME: Some of the regex patterns are wrong (missing [.] before file extension).
|
||||
const std::regex Plater::priv::pattern_bundle(".*[.](amf|amf[.]xml|3mf)", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_3mf(".*3mf", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_any_amf(".*[.](amf|amf[.]xml|zip[.]amf)", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_zip(".*zip", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_printRequest(".*printRequest", std::regex::icase);
|
||||
const std::regex Plater::priv::pattern_step(".*[.](step|stp)", std::regex::icase);
|
||||
|
||||
Plater::priv::priv(Plater* q, MainFrame* main_frame)
|
||||
: q(q)
|
||||
@@ -1287,6 +1292,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
int answer_convert_from_meters = wxOK_DEFAULT;
|
||||
int answer_convert_from_imperial_units = wxOK_DEFAULT;
|
||||
int answer_consider_as_multi_part_objects = wxOK_DEFAULT;
|
||||
bool apply_step_import_parameters_to_all { false };
|
||||
|
||||
bool in_temp = false;
|
||||
const fs::path temp_path = wxStandardPaths::Get().GetTempDir().utf8_str().data();
|
||||
@@ -1302,7 +1308,26 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
const auto &path = input_files[i];
|
||||
#endif // _WIN32
|
||||
in_temp = (path.parent_path() == temp_path);
|
||||
const auto filename = path.filename();
|
||||
const boost::filesystem::path filename = path.filename();
|
||||
|
||||
const bool type_step = std::regex_match(path.string(), pattern_step);
|
||||
if (type_step && !apply_step_import_parameters_to_all &&
|
||||
wxGetApp().app_config->get_bool("show_step_import_parameters")) {
|
||||
|
||||
double linear_precision = string_to_double_decimal_point(wxGetApp().app_config->get("linear_precision"));
|
||||
double angle_precision = string_to_double_decimal_point(wxGetApp().app_config->get("angle_precision"));
|
||||
|
||||
LoadStepDialog dlg(q, filename.string(), linear_precision, angle_precision, (input_files_size - i) > 1);
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
wxGetApp().app_config->set("linear_precision", float_to_string_decimal_point(dlg.get_linear_precision()));
|
||||
wxGetApp().app_config->set("angle_precision", float_to_string_decimal_point(dlg.get_angle_precision()));
|
||||
if (dlg.IsCheckBoxChecked())
|
||||
wxGetApp().app_config->set("show_step_import_parameters", "0");
|
||||
apply_step_import_parameters_to_all = dlg.IsApplyToAllClicked();
|
||||
} else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (progress_dlg) {
|
||||
progress_dlg->Update(static_cast<int>(100.0f * static_cast<float>(i) / static_cast<float>(input_files.size())), _L("Loading file") + ": " + from_path(filename));
|
||||
progress_dlg->Fit();
|
||||
@@ -1350,7 +1375,14 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
|
||||
model = FileReader::load_model_with_config(path.string(), &config_loaded, &config_substitutions, qidislicer_generator_version, FileReader::LoadAttribute::CheckVersion, &load_stats);
|
||||
}
|
||||
else if (load_model) {
|
||||
model = FileReader::load_model(path.string(), FileReader::LoadAttributes{}, &load_stats);
|
||||
if (type_step) {
|
||||
double linear_precision = string_to_double_decimal_point(wxGetApp().app_config->get("linear_precision"));
|
||||
double angle_precision = string_to_double_decimal_point(wxGetApp().app_config->get("angle_precision"));
|
||||
model = FileReader::load_model(path.string(), FileReader::LoadAttributes{}, &load_stats,
|
||||
std::make_pair(linear_precision, angle_precision));
|
||||
}
|
||||
else
|
||||
model = FileReader::load_model(path.string(), FileReader::LoadAttributes{}, &load_stats);
|
||||
}
|
||||
} catch (const ConfigurationError &e) {
|
||||
std::string message = GUI::format(_L("Failed loading file \"%1%\" due to an invalid configuration."), filename.string()) + "\n\n" + e.what();
|
||||
@@ -7363,9 +7395,62 @@ void Plater::send_gcode()
|
||||
only_link = true;
|
||||
}
|
||||
max_send_number = std::stoi(wxGetApp().app_config->get("max_send"));
|
||||
|
||||
std::string selected_printer_host = "";
|
||||
bool has_select_printer = wxGetApp().preset_bundle->physical_printers.has_selection();
|
||||
if (has_select_printer) {
|
||||
PhysicalPrinter& ph_printer = wxGetApp().preset_bundle->physical_printers.get_selected_printer();
|
||||
selected_printer_host = ph_printer.config.opt_string("print_host");
|
||||
}
|
||||
|
||||
std::string sync_ip = box_msg.box_list_printer_ip;
|
||||
|
||||
bool has_diff = false;
|
||||
|
||||
if(sync_ip.empty()){
|
||||
;
|
||||
}
|
||||
else if (selected_printer_host != sync_ip && !selected_printer_host.empty()){
|
||||
WarningDialog(this, _L("Please note that the printer of the synchronous BOX does not match the currently selected printer.")).ShowModal();
|
||||
}
|
||||
#if QDT_RELEASE_TO_PUBLIC
|
||||
else{
|
||||
QIDINetwork qidi;
|
||||
wxString msg = "";
|
||||
GUI::Box_info filament_info;
|
||||
filament_info = qidi.get_box_info(msg, sync_ip);
|
||||
GUI::Box_info cur_box_info;
|
||||
cur_box_info = get_cur_box_info();
|
||||
|
||||
if (filament_info.filament_index != cur_box_info.filament_index
|
||||
|| filament_info.filament_vendor != cur_box_info.filament_vendor
|
||||
|| filament_info.filament_color_index != cur_box_info.filament_color_index
|
||||
|| filament_info.slot_state != cur_box_info.slot_state
|
||||
|| filament_info.slot_id != cur_box_info.slot_id
|
||||
|| filament_info.box_count != cur_box_info.box_count
|
||||
|| filament_info.auto_reload_detect != cur_box_info.auto_reload_detect) {
|
||||
has_diff = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if(has_diff){
|
||||
WarningDialog(this, _L("The BOX information has been updated. Please resynchronize.")).ShowModal();
|
||||
}
|
||||
|
||||
//B61 //y20
|
||||
PrintHostSendDialog dlg(default_output_file, PrintHostPostUploadAction::StartPrint, groups, storage_paths, storage_names, this, only_link);
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
|
||||
//y25
|
||||
std::vector<int> activate_slot;
|
||||
for (auto& temp_fila : wxGetApp().preset_bundle->filament_box_list) {
|
||||
auto& dnyconfig = temp_fila.second;
|
||||
std::string sold_id_t = dnyconfig.opt_string("slot_id", 0u);
|
||||
activate_slot.push_back(std::stoi(sold_id_t));
|
||||
}
|
||||
|
||||
|
||||
//y16
|
||||
bool is_jump = false;
|
||||
|
||||
@@ -7426,6 +7511,20 @@ void Plater::send_gcode()
|
||||
|
||||
//m_time_p = upload_job.create_time + seconds_to_add;
|
||||
|
||||
//y25
|
||||
if (!activate_slot.empty() && upload_job.upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
|
||||
for (int i = 0; i < activate_slot.size(); i++) {
|
||||
wxString check_status_msg = "";
|
||||
wxString command = wxString::Format(
|
||||
"SAVE_VARIABLE VARIABLE=value_t%d VALUE=\\\"'slot%d'\\\"",
|
||||
i,
|
||||
activate_slot[i]
|
||||
);
|
||||
bool success = upload_job.printhost->send_command_to_printer(check_status_msg, command);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
p->export_gcode(fs::path(), false, std::move(upload_job));
|
||||
|
||||
UploadCount++;
|
||||
@@ -7468,6 +7567,19 @@ void Plater::send_gcode()
|
||||
return;
|
||||
}
|
||||
|
||||
//y25
|
||||
if (!activate_slot.empty() && upload_job.upload_data.post_action == PrintHostPostUploadAction::StartPrint) {
|
||||
for (int i = 0; i < activate_slot.size(); i++) {
|
||||
wxString check_status_msg = "";
|
||||
wxString command = wxString::Format(
|
||||
"SAVE_VARIABLE VARIABLE=value_t%d VALUE=\\\"'slot%d'\\\"",
|
||||
i,
|
||||
activate_slot[i]
|
||||
);
|
||||
bool success = upload_job.printhost->send_command_to_printer(check_status_msg, command);
|
||||
}
|
||||
}
|
||||
|
||||
p->export_gcode(fs::path(), false, std::move(upload_job));
|
||||
UploadCount++;
|
||||
|
||||
@@ -7563,8 +7675,18 @@ bool Plater::update_filament_colors_in_full_config()
|
||||
std::vector<std::string> filament_colors;
|
||||
filament_colors.reserve(extruders_filaments.size());
|
||||
|
||||
for (const auto& extr_filaments : extruders_filaments)
|
||||
filament_colors.push_back(filaments.find_preset(extr_filaments.get_selected_preset_name(), true)->config.opt_string("filament_colour", (unsigned)0));
|
||||
//y25
|
||||
if(wxGetApp().preset_bundle->filament_box_list.empty()){
|
||||
for (const auto& extr_filaments : extruders_filaments)
|
||||
filament_colors.push_back(filaments.find_preset(extr_filaments.get_selected_preset_name(), true)->config.opt_string("filament_colour", (unsigned)0));
|
||||
}
|
||||
else{
|
||||
for(auto& fila : wxGetApp().preset_bundle->filament_box_list){
|
||||
auto& tray = fila.second;
|
||||
std::string color = tray.opt_string("filament_colour", 0u);
|
||||
filament_colors.push_back(color);
|
||||
}
|
||||
}
|
||||
|
||||
p->config->option<ConfigOptionStrings>("filament_colour")->values = filament_colors;
|
||||
return true;
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
#include "slic3r/GUI/Camera.hpp"
|
||||
#include "slic3r/Utils/PrintHost.hpp"
|
||||
|
||||
#if QDT_RELEASE_TO_PUBLIC
|
||||
#include "../QIDI/QIDINetwork.hpp"
|
||||
#endif
|
||||
|
||||
class wxString;
|
||||
|
||||
namespace Slic3r {
|
||||
@@ -55,6 +59,19 @@ class UserAccount;
|
||||
class PresetArchiveDatabase;
|
||||
enum class ArrangeSelectionMode;
|
||||
|
||||
//y25
|
||||
struct Box_msg {
|
||||
std::vector<int> slot_state;
|
||||
std::vector<int> slot_id;
|
||||
std::vector<std::string> filament_id;
|
||||
std::vector<std::string> filament_colors;
|
||||
std::vector<std::string> filament_type;
|
||||
std::string box_list_preset_name;
|
||||
std::string box_list_printer_ip;
|
||||
int box_count = 0;
|
||||
int auto_reload_detect = 0;
|
||||
};
|
||||
|
||||
class Plater: public wxPanel
|
||||
{
|
||||
public:
|
||||
@@ -475,6 +492,14 @@ public:
|
||||
m_sending_interval = 0;
|
||||
};
|
||||
|
||||
//y25
|
||||
Box_msg box_msg;
|
||||
|
||||
#if QDT_RELEASE_TO_PUBLIC
|
||||
GUI::Box_info current_box_info;
|
||||
GUI::Box_info get_cur_box_info() { return current_box_info; };
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::optional<fs_path> get_default_output_file();
|
||||
std::optional<wxString> check_output_path_has_error(const boost::filesystem::path& path) const;
|
||||
|
||||
@@ -127,7 +127,7 @@ void PreferencesDialog::show(const std::string& highlight_opt_key /*= std::strin
|
||||
downloader->set_path_name(app_config->get("url_downloader_dest"));
|
||||
downloader->allow(!app_config->has("downloader_url_registered") || app_config->get_bool("downloader_url_registered"));
|
||||
|
||||
for (const std::string opt_key : {"suppress_hyperlinks", "downloader_url_registered", "show_login_button"})
|
||||
for (const std::string opt_key : {"suppress_hyperlinks", "downloader_url_registered", "show_login_button", "show_step_import_parameters"})
|
||||
m_optgroup_other->set_value(opt_key, app_config->get_bool(opt_key));
|
||||
// by default "Log in" button is visible
|
||||
if (!app_config->has("show_login_button"))
|
||||
@@ -621,6 +621,11 @@ void PreferencesDialog::build()
|
||||
// "If disabled, the descriptions of configuration parameters in settings tabs will work as hyperlinks."),
|
||||
app_config->get_bool("suppress_hyperlinks"));
|
||||
|
||||
append_bool_option(m_optgroup_other, "show_step_import_parameters",
|
||||
L("Show STEP file import parameters"),
|
||||
L("If enabled, PrusaSlicer will show a dialog with quality selection when importing a STEP file."),
|
||||
app_config->get_bool("show_step_import_parameters"));
|
||||
|
||||
append_bool_option(m_optgroup_other, "show_login_button",
|
||||
L("Show \"Log in\" button in application top bar"),
|
||||
L("If enabled, QIDISlicer will show up \"Log in\" button in application top bar."),
|
||||
|
||||
@@ -1155,8 +1155,10 @@ void PlaterPresetComboBox::update()
|
||||
tooltip = from_u8(preset.name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
system_presets.push_back({ get_preset_name(preset), get_preset_name(preset).Lower(), bmp });
|
||||
|
||||
if (is_selected) {
|
||||
selected_user_preset = get_preset_name(preset);
|
||||
tooltip = from_u8(preset.name);
|
||||
@@ -1333,19 +1335,22 @@ void TabPresetComboBox::OnSelect(wxCommandEvent &evt)
|
||||
auto selected_item = evt.GetSelection();
|
||||
|
||||
auto marker = reinterpret_cast<Marker>(this->GetClientData(selected_item));
|
||||
if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX) {
|
||||
this->SetSelection(m_last_selected);
|
||||
if (marker == LABEL_ITEM_WIZARD_PRINTERS)
|
||||
wxTheApp->CallAfter([this]() {
|
||||
run_wizard(ConfigWizard::SP_PRINTERS);
|
||||
|
||||
// update combobox if its parent is a PhysicalPrinterDialog
|
||||
PhysicalPrinterDialog* parent = dynamic_cast<PhysicalPrinterDialog*>(this->GetParent());
|
||||
if (parent != nullptr)
|
||||
update();
|
||||
});
|
||||
}
|
||||
else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) {
|
||||
//y26
|
||||
//if (marker >= LABEL_ITEM_DISABLED && marker < LABEL_ITEM_MAX) {
|
||||
// this->SetSelection(m_last_selected);
|
||||
// if (marker == LABEL_ITEM_WIZARD_PRINTERS)
|
||||
// wxTheApp->CallAfter([this]() {
|
||||
// run_wizard(ConfigWizard::SP_PRINTERS);
|
||||
|
||||
// // update combobox if its parent is a PhysicalPrinterDialog
|
||||
// PhysicalPrinterDialog* parent = dynamic_cast<PhysicalPrinterDialog*>(this->GetParent());
|
||||
// if (parent != nullptr)
|
||||
// update();
|
||||
// });
|
||||
//}
|
||||
//else if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) {
|
||||
if (on_selection_changed && (m_last_selected != selected_item || m_collection->current_is_dirty())) {
|
||||
m_last_selected = selected_item;
|
||||
on_selection_changed(selected_item);
|
||||
}
|
||||
@@ -1431,7 +1436,23 @@ void TabPresetComboBox::update()
|
||||
selected = get_preset_name(preset);
|
||||
}
|
||||
} else {
|
||||
system_presets.push_back({get_preset_name(preset), get_preset_name(preset).Lower(), bmp, is_enabled});
|
||||
//y25
|
||||
if (m_type == Preset::TYPE_FILAMENT && !m_preset_bundle->filament_box_list.empty()) {
|
||||
system_presets.push_back({ get_preset_name(preset), get_preset_name(preset).Lower(), bmp });
|
||||
std::string preset_filament_id = preset.config.opt_string("filament_id", 0u);
|
||||
for (auto& entry : m_preset_bundle->filament_box_list) {
|
||||
auto& tray = entry.second;
|
||||
|
||||
std::string filament_id = tray.opt_string("filament_id", 0u);
|
||||
if (preset_filament_id == filament_id) {
|
||||
std::string box_preset_name = into_u8(get_preset_name(preset));
|
||||
tray.set_key_value("preset_name", new ConfigOptionStrings{ box_preset_name });
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
system_presets.push_back({ get_preset_name(preset), get_preset_name(preset).Lower(), bmp });
|
||||
|
||||
if (i == idx_selected)
|
||||
selected = get_preset_name(preset);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,9 @@ PrinterWebView::PrinterWebView(wxWindow *parent) : wxPanel(parent, wxID_ANY, wxD
|
||||
|
||||
titlePanel->SetSizer(buttonSizer);
|
||||
|
||||
toggleBar = new SwitchButton(menuPanel);
|
||||
//y25
|
||||
toggleBar = new DeviceSwitchButton(menuPanel);
|
||||
|
||||
toggleBar->SetSize(327);
|
||||
toggleBar->SetMaxSize({em_unit(this) * 40, -1});
|
||||
//y3
|
||||
|
||||
@@ -178,7 +178,7 @@ private:
|
||||
DeviceButton * refresh_button;
|
||||
DeviceButton * login_button;
|
||||
bool m_isloginin;
|
||||
SwitchButton * toggleBar;
|
||||
DeviceSwitchButton * toggleBar; //y25
|
||||
wxStaticBitmap * staticBitmap;
|
||||
//y3
|
||||
wxString m_ip;
|
||||
|
||||
365
src/slic3r/GUI/SyncBoxInfoDialog.cpp
Normal file
365
src/slic3r/GUI/SyncBoxInfoDialog.cpp
Normal file
@@ -0,0 +1,365 @@
|
||||
|
||||
#include "SyncBoxInfoDialog.hpp"
|
||||
|
||||
#include "MainFrame.hpp"
|
||||
#include "Widgets/ComboBox.hpp"
|
||||
#include "Widgets/Label.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "Tab.hpp"
|
||||
|
||||
#include "libslic3r/Utils.hpp"
|
||||
|
||||
//y25
|
||||
using namespace Slic3r;
|
||||
using namespace Slic3r::GUI;
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
GetBoxInfoDialog::GetBoxInfoDialog(Plater* plater)
|
||||
: DPIDialog(static_cast<wxWindow*>(wxGetApp().mainframe), wxID_ANY, _L("Sync Box information"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX)
|
||||
, m_plater(plater)
|
||||
{
|
||||
SetFont(wxGetApp().normal_font());
|
||||
|
||||
std::string icon_path = (boost::format("%1%/icons/QIDISlicer.ico") % resources_dir()).str();
|
||||
SetIcon(wxIcon(icon_path.c_str(), wxBITMAP_TYPE_ICO));
|
||||
|
||||
Freeze();
|
||||
SetBackgroundColour(m_colour_def_color);
|
||||
|
||||
m_sizer_main = new wxBoxSizer(wxVERTICAL);
|
||||
m_sizer_main->SetMinSize(wxSize(0, -1));
|
||||
|
||||
wxPanel* m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
|
||||
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
|
||||
|
||||
wxStaticText* m_tips_text = new wxStaticText(this, wxID_ANY, _L("Please select the printer in the list to get box info."), wxDefaultPosition, wxSize(-1, -1), 0);
|
||||
|
||||
wxBoxSizer *m_sizer_printer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_stext_printer_title = new wxStaticText(this, wxID_ANY, _L("Printer"), wxDefaultPosition, wxSize(-1, -1), 0);
|
||||
m_stext_printer_title->SetFont(::Label::Head_14);
|
||||
m_stext_printer_title->Wrap(-1);
|
||||
m_stext_printer_title->SetForegroundColour(m_colour_bold_color);
|
||||
m_stext_printer_title->SetBackgroundColour(m_colour_def_color);
|
||||
|
||||
m_comboBox_printer = new ::ComboBox(this, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(250), 20), 0, nullptr, wxCB_READONLY);
|
||||
m_sizer_printer->Add(m_stext_printer_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
m_sizer_printer->Add(0, 0, 0, wxEXPAND | wxALIGN_CENTER | wxLEFT, FromDIP(12));
|
||||
m_sizer_printer->Add(m_comboBox_printer, 1, wxEXPAND | wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
|
||||
wxPanel* switch_button_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxTAB_TRAVERSAL | wxBU_RIGHT);
|
||||
wxBoxSizer* sizer_switch_area = new wxBoxSizer(wxHORIZONTAL);
|
||||
switch_button_panel->SetBackgroundColour((wxColour("#FFFFFF")));
|
||||
m_switch_button = new SwitchButton(switch_button_panel);
|
||||
m_switch_button->SetMaxSize(wxSize(100, 100));
|
||||
m_switch_button->SetLabels(_L("Local"), _L("Link"));
|
||||
m_switch_button->SetValue(m_isNetMode);
|
||||
m_switch_button->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent& evt) {
|
||||
bool is_checked = evt.GetInt();
|
||||
m_switch_button->SetValue(is_checked);
|
||||
m_isNetMode = is_checked;
|
||||
m_comboBox_printer->SetValue("");
|
||||
m_comboBox_printer->Clear();
|
||||
m_printer_ip.clear();
|
||||
PresetBundle& preset_bundle = *wxGetApp().preset_bundle;
|
||||
PhysicalPrinterCollection& ph_printers = wxGetApp().preset_bundle->physical_printers;
|
||||
std::string preset_typename = NormalizeVendor(preset_bundle.printers.get_edited_preset().name);
|
||||
if (!m_isNetMode){
|
||||
for (PhysicalPrinterCollection::ConstIterator it = ph_printers.begin(); it != ph_printers.end(); ++it) {
|
||||
std::string printer_preset = (it->config.opt_string("preset_name"));
|
||||
std::string printer_name = it->name;
|
||||
if (preset_typename.find(NormalizeVendor(printer_preset)) != std::string::npos) {
|
||||
m_comboBox_printer->Append(from_u8(printer_name));
|
||||
m_printer_ip.push_back((it->config.opt_string("print_host")));
|
||||
}
|
||||
}
|
||||
m_comboBox_printer->SetSelection(0);
|
||||
}
|
||||
#if QDT_RELEASE_TO_PUBLIC
|
||||
else{
|
||||
if (wxGetApp().app_config->get("user_token") != ""){
|
||||
auto m_devices = wxGetApp().get_devices();
|
||||
for (const auto& device : m_devices) {
|
||||
if (preset_typename.find(NormalizeVendor(device.machine_type)) != std::string::npos)
|
||||
{
|
||||
m_comboBox_printer->Append(from_u8(device.device_name));
|
||||
m_printer_ip.push_back(device.url);
|
||||
}
|
||||
}
|
||||
m_comboBox_printer->SetSelection(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (m_comboBox_printer->GetValue().empty()){
|
||||
m_button_sync->Disable();
|
||||
}
|
||||
else {
|
||||
m_button_sync->Enable();
|
||||
}
|
||||
});
|
||||
sizer_switch_area->Add(m_switch_button, 0, wxALIGN_CENTER);
|
||||
switch_button_panel->SetSizer(sizer_switch_area);
|
||||
switch_button_panel->Layout();
|
||||
m_sizer_printer->Add(switch_button_panel, 0, wxALL | wxALIGN_CENTER, FromDIP(5));
|
||||
|
||||
wxBoxSizer* m_sizer_btn = new wxBoxSizer(wxHORIZONTAL);
|
||||
btn_bg_enable = StateColor(
|
||||
std::pair<wxColour, int>(wxColour(95, 82, 253), StateColor::Pressed),
|
||||
std::pair<wxColour, int>(wxColour(129, 150, 255), StateColor::Hovered),
|
||||
std::pair<wxColour, int>(wxColour(68, 121, 251), StateColor::Normal));
|
||||
|
||||
m_button_sync = new wxButton(this, wxID_ANY, _L("Sync"), wxDefaultPosition, wxSize(60, 25), wxBU_EXACTFIT);
|
||||
wxGetApp().UpdateDarkUI(m_button_sync, true);
|
||||
m_button_sync->Bind(wxEVT_BUTTON, &GetBoxInfoDialog::synchronization, this);
|
||||
|
||||
m_button_cancel = new wxButton(this, wxID_ANY, _L("Cancel"), wxDefaultPosition, wxSize(60, 25), wxBU_EXACTFIT);
|
||||
wxGetApp().UpdateDarkUI(m_button_cancel, true);
|
||||
m_button_cancel->Bind(wxEVT_BUTTON, &GetBoxInfoDialog::cancel, this);
|
||||
|
||||
m_sizer_btn->AddStretchSpacer();
|
||||
m_sizer_btn->Add(m_button_sync, 0, wxALIGN_RIGHT | wxALL, FromDIP(5));
|
||||
m_sizer_btn->Add(m_button_cancel, 0, wxALIGN_RIGHT | wxALL, FromDIP(5));
|
||||
|
||||
m_sizer_main->Add(m_line_top, 0, wxEXPAND | wxTOP, FromDIP(0));
|
||||
m_sizer_main->AddSpacer(FromDIP(10));
|
||||
m_sizer_main->Add(m_tips_text, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20));
|
||||
m_sizer_main->AddSpacer(FromDIP(15));
|
||||
m_sizer_main->Add(m_sizer_printer, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20));
|
||||
m_sizer_main->AddSpacer(FromDIP(25));
|
||||
m_sizer_main->Add(m_sizer_btn, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(20));
|
||||
m_sizer_main->AddSpacer(FromDIP(10));
|
||||
|
||||
SetSizer(m_sizer_main);
|
||||
|
||||
init_printer_combox();
|
||||
Layout();
|
||||
Fit();
|
||||
Thaw();
|
||||
Centre(wxBOTH);
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
}
|
||||
|
||||
GetBoxInfoDialog::~GetBoxInfoDialog() {}
|
||||
|
||||
void GetBoxInfoDialog::init_printer_combox()
|
||||
{
|
||||
m_isNetMode = wxGetApp().app_config->get("machine_list_net") == "1";
|
||||
m_switch_button->SetValue(m_isNetMode);
|
||||
wxCommandEvent event(wxEVT_TOGGLEBUTTON, m_switch_button->GetId());
|
||||
event.SetEventObject(m_switch_button);
|
||||
event.SetInt(m_switch_button->GetValue());
|
||||
m_switch_button->GetEventHandler()->ProcessEvent(event);
|
||||
}
|
||||
|
||||
void GetBoxInfoDialog::on_dpi_changed(const wxRect &suggested_rect)
|
||||
{
|
||||
Fit();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void GetBoxInfoDialog::synchronization(wxCommandEvent &event)
|
||||
{
|
||||
#if QDT_RELEASE_TO_PUBLIC
|
||||
int selected_idx = m_comboBox_printer->GetSelection();
|
||||
std::string printer_ip = m_printer_ip[selected_idx];
|
||||
|
||||
QIDINetwork qidi;
|
||||
wxString msg = "";
|
||||
bool has_box = qidi.get_box_state(msg, printer_ip);
|
||||
if (!has_box) {
|
||||
WarningDialog(this, _L("This Printer has not connect the box, please check.")).ShowModal();
|
||||
}
|
||||
else {
|
||||
//Get Box_info
|
||||
GUI::Box_info filament_info;
|
||||
filament_info = qidi.get_box_info(msg, printer_ip);
|
||||
m_plater->current_box_info = filament_info;
|
||||
qidi.get_color_filament_str(msg, filament_info, printer_ip);
|
||||
generate_filament_id(filament_info);
|
||||
syn_box_info = std::move(filament_info);
|
||||
update_filament_info(filament_info);
|
||||
|
||||
sync_box_list();
|
||||
|
||||
if(m_isNetMode)
|
||||
wxGetApp().app_config->set("machine_list_net", "1");
|
||||
else
|
||||
wxGetApp().app_config->set("machine_list_net", "0");
|
||||
this->EndModal(wxID_OK);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GetBoxInfoDialog::synchronize_by_ip(std::string ip)
|
||||
{
|
||||
#if QDT_RELEASE_TO_PUBLIC
|
||||
m_sync_printer_ip = ip;
|
||||
|
||||
QIDINetwork qidi;
|
||||
wxString msg = "";
|
||||
bool has_box = qidi.get_box_state(msg, m_sync_printer_ip);
|
||||
if (!has_box) {
|
||||
WarningDialog(this, _L("This Printer has not connect the box, please check.")).ShowModal();
|
||||
}
|
||||
else {
|
||||
//Get Box_info
|
||||
GUI::Box_info filament_info;
|
||||
filament_info = qidi.get_box_info(msg, m_sync_printer_ip);
|
||||
m_plater->current_box_info = filament_info;
|
||||
qidi.get_color_filament_str(msg, filament_info, m_sync_printer_ip);
|
||||
generate_filament_id(filament_info);
|
||||
syn_box_info = filament_info;
|
||||
update_filament_info(filament_info);
|
||||
|
||||
sync_box_list();
|
||||
|
||||
if(m_isNetMode)
|
||||
wxGetApp().app_config->set("machine_list_net", "1");
|
||||
else
|
||||
wxGetApp().app_config->set("machine_list_net", "0");
|
||||
this->EndModal(wxID_OK);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GetBoxInfoDialog::generate_filament_id(GUI::Box_info& machine_filament_info)
|
||||
{
|
||||
std::string filament_id = "QD";
|
||||
std::string box_id = wxGetApp().preset_bundle->printers.get_selected_preset().config.opt_string("box_id");
|
||||
filament_id = filament_id + "_" + box_id;
|
||||
|
||||
for(int i = 0; i < machine_filament_info.box_count * 4; i++){
|
||||
if (machine_filament_info.slot_state[i] == 0)
|
||||
continue;
|
||||
std::string temp_filament_id = filament_id;
|
||||
temp_filament_id = temp_filament_id + "_" + std::to_string(machine_filament_info.filament_vendor[i]);
|
||||
temp_filament_id = temp_filament_id + "_" + std::to_string(machine_filament_info.filament_index[i]);
|
||||
machine_filament_info.filament_id[i] = temp_filament_id;
|
||||
}
|
||||
|
||||
if(machine_filament_info.slot_state.back() != 0)
|
||||
{
|
||||
std::string temp_ext_filament_id = filament_id;
|
||||
temp_ext_filament_id = temp_ext_filament_id + "_" + std::to_string(machine_filament_info.filament_vendor.back());
|
||||
temp_ext_filament_id = temp_ext_filament_id + "_" + std::to_string(machine_filament_info.filament_index.back());
|
||||
machine_filament_info.filament_id.back() = temp_ext_filament_id;
|
||||
}
|
||||
}
|
||||
|
||||
void GetBoxInfoDialog::update_filament_info(GUI::Box_info& machine_filament_info)
|
||||
{
|
||||
m_plater->box_msg.slot_state = std::move(machine_filament_info.slot_state);
|
||||
m_plater->box_msg.filament_id = std::move(machine_filament_info.filament_id);
|
||||
m_plater->box_msg.filament_colors = std::move(machine_filament_info.filament_colors);
|
||||
m_plater->box_msg.box_count = std::move(machine_filament_info.box_count);
|
||||
m_plater->box_msg.filament_type = std::move(machine_filament_info.filament_type);
|
||||
m_plater->box_msg.slot_id = std::move(machine_filament_info.slot_id);
|
||||
m_plater->box_msg.auto_reload_detect = std::move(machine_filament_info.auto_reload_detect);
|
||||
PresetBundle &preset_bundle = *wxGetApp().preset_bundle;
|
||||
std::string preset_name_box = NormalizeVendor(preset_bundle.printers.get_edited_preset().name);
|
||||
m_plater->box_msg.box_list_preset_name = preset_name_box;
|
||||
|
||||
m_plater->box_msg.box_list_printer_ip = m_sync_printer_ip;
|
||||
}
|
||||
|
||||
void GetBoxInfoDialog::cancel(wxCommandEvent &event)
|
||||
{
|
||||
this->EndModal(wxID_CANCEL);
|
||||
}
|
||||
|
||||
std::string GetBoxInfoDialog::NormalizeVendor(const std::string& str)
|
||||
{
|
||||
std::string normalized;
|
||||
for (char c : str) {
|
||||
if (std::isalnum(c)) {
|
||||
normalized += std::tolower(c);
|
||||
}
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
void GetBoxInfoDialog::sync_box_list(){
|
||||
load_box_list();
|
||||
|
||||
Tab* tab_print = wxGetApp().get_tab(Preset::TYPE_PRINT);
|
||||
Tab* tab_printer = wxGetApp().get_tab(Preset::TYPE_PRINTER);
|
||||
|
||||
DynamicPrintConfig new_config_printer = wxGetApp().preset_bundle->printers.get_edited_preset().config;
|
||||
DynamicPrintConfig new_config_prints = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||
ConfigOptionFloats* nozzle_config = new ConfigOptionFloats();
|
||||
//y26
|
||||
for (int i = 0; i < wxGetApp().preset_bundle->filament_box_list.size(); i++) {
|
||||
nozzle_config->values.push_back(new_config_printer.opt_float("nozzle_diameter", 0u));
|
||||
}
|
||||
new_config_printer.set_key_value("nozzle_diameter", nozzle_config);
|
||||
new_config_printer.set_key_value("single_extruder_multi_material", new ConfigOptionBool(true));
|
||||
|
||||
new_config_prints.set_key_value("wipe_tower", new ConfigOptionBool(true));
|
||||
|
||||
tab_print->load_config(new_config_prints);
|
||||
tab_printer->load_config(new_config_printer);
|
||||
|
||||
wxGetApp().load_current_presets();
|
||||
|
||||
int idx = 0;
|
||||
for (auto& entry : wxGetApp().preset_bundle->filament_box_list) {
|
||||
auto& tray = entry.second;
|
||||
std::string preset_name = "";
|
||||
//y26
|
||||
if(tray.has("preset_name"))
|
||||
preset_name = tray.opt_string("preset_name", 0u);
|
||||
else {
|
||||
std::string printer_preset_name = wxGetApp().preset_bundle->physical_printers.get_selected_printer_preset_name();
|
||||
preset_name = "Generic PLA @" + printer_preset_name;
|
||||
}
|
||||
wxGetApp().preset_bundle->set_filament_preset(idx, preset_name);
|
||||
dynamic_cast<TabFilament*>(wxGetApp().get_tab(Preset::TYPE_FILAMENT))->set_active_extruder(idx);
|
||||
idx++;
|
||||
}
|
||||
wxGetApp().sidebar().update_all_filament_comboboxes();
|
||||
|
||||
std::vector<std::string> colors;
|
||||
for (auto& filament : wxGetApp().preset_bundle->filament_box_list) {
|
||||
auto info = filament.second;
|
||||
std::string color = info.opt_string("filament_colour", 0u);
|
||||
colors.push_back(color);
|
||||
}
|
||||
DynamicPrintConfig cfg_new = *wxGetApp().get_tab(Preset::TYPE_PRINTER)->get_config();
|
||||
cfg_new.set_key_value("extruder_colour", new ConfigOptionStrings(colors));
|
||||
|
||||
wxGetApp().get_tab(Preset::TYPE_PRINTER)->load_config(cfg_new);
|
||||
wxGetApp().plater()->on_config_change(cfg_new);
|
||||
}
|
||||
|
||||
void GetBoxInfoDialog::load_box_list(){
|
||||
std::map<int, DynamicPrintConfig> filament_box_list;
|
||||
char n = 'A';
|
||||
char t = 0;
|
||||
int count = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
count++;
|
||||
if (syn_box_info.slot_state[i] == 0)
|
||||
continue;
|
||||
DynamicPrintConfig tray_config;
|
||||
tray_config.set_key_value("filament_id", new ConfigOptionStrings{ syn_box_info.filament_id[i] });
|
||||
tray_config.set_key_value("tag_uid", new ConfigOptionStrings{ "" }); //clear
|
||||
tray_config.set_key_value("filament_type", new ConfigOptionStrings{syn_box_info.filament_type[i]}); //clear
|
||||
tray_config.set_key_value("slot_state", new ConfigOptionStrings{std::to_string(syn_box_info.slot_state[i])});
|
||||
tray_config.set_key_value("slot_id", new ConfigOptionStrings{ std::to_string(syn_box_info.slot_id[i]) });
|
||||
int group = i / 4 + 1;
|
||||
char suffix = 'A' + (i % 4);
|
||||
//std::string tray_name = "1" + std::string(1, 'A' + i);
|
||||
std::string tray_name = std::to_string(group) + suffix;
|
||||
tray_config.set_key_value("tray_name", new ConfigOptionStrings{ tray_name }); //1A 1B 1C
|
||||
tray_config.set_key_value("filament_colour", new ConfigOptionStrings{ into_u8(wxColour(syn_box_info.filament_colors[i]).GetAsString(wxC2S_HTML_SYNTAX)) });//filament_color
|
||||
tray_config.set_key_value("filament_exist", new ConfigOptionBools{ true }); //default
|
||||
|
||||
// tray_config.set_key_value("filament_multi_colors", new ConfigOptionStrings{});
|
||||
// tray_config.opt<ConfigOptionStrings>("filament_multi_colors")->values.push_back(into_u8(wxColour(syn_box_info.filament_colors[i]).GetAsString(wxC2S_HTML_SYNTAX)));
|
||||
filament_box_list.emplace('A' + i, std::move(tray_config));
|
||||
}
|
||||
|
||||
wxGetApp().preset_bundle->filament_box_list = filament_box_list;
|
||||
}
|
||||
|
||||
}} // namespace Slic3r
|
||||
59
src/slic3r/GUI/SyncBoxInfoDialog.hpp
Normal file
59
src/slic3r/GUI/SyncBoxInfoDialog.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
#ifndef _SyncBoxInfoDialog_H_
|
||||
#define _SyncBoxInfoDialog_H_
|
||||
|
||||
#include "GUI.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "Plater.hpp"
|
||||
#include "Widgets/Button.hpp"
|
||||
#include "Widgets/SwitchButton.hpp"
|
||||
#include "Widgets/ComboBox.hpp"
|
||||
#include "MainFrame.hpp"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
#endif
|
||||
|
||||
|
||||
//y25
|
||||
namespace Slic3r{
|
||||
namespace GUI{
|
||||
|
||||
class GetBoxInfoDialog : public DPIDialog
|
||||
{
|
||||
public:
|
||||
GetBoxInfoDialog(Plater* plater = nullptr);
|
||||
~GetBoxInfoDialog();
|
||||
void synchronization(wxCommandEvent &event);
|
||||
void synchronize_by_ip(std::string ip);
|
||||
void cancel(wxCommandEvent &event);
|
||||
void on_dpi_changed(const wxRect& suggested_rect) override;
|
||||
void init_printer_combox();
|
||||
std::string NormalizeVendor(const std::string& str);
|
||||
void generate_filament_id(GUI::Box_info& machine_filament_info);
|
||||
void update_filament_info(GUI::Box_info& machine_filament_info);
|
||||
void sync_box_list();
|
||||
void load_box_list();
|
||||
|
||||
std::vector<std::string> m_printer_ip;
|
||||
|
||||
private:
|
||||
Plater* m_plater{ nullptr };
|
||||
wxBoxSizer* m_sizer_main;
|
||||
wxStaticText* m_stext_printer_title;
|
||||
ComboBox* m_comboBox_printer;
|
||||
StateColor btn_bg_enable;
|
||||
wxButton* m_button_sync;
|
||||
wxButton* m_button_cancel;
|
||||
wxColour m_colour_def_color{ wxColour(255, 255, 255) };
|
||||
wxColour m_colour_bold_color{ wxColour(38, 46, 48) };
|
||||
SwitchButton* m_switch_button;
|
||||
bool m_isNetMode;
|
||||
GUI::Box_info syn_box_info;
|
||||
std::string m_sync_printer_ip;
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
#endif
|
||||
@@ -1464,17 +1464,17 @@ void TabPrint::build()
|
||||
|
||||
optgroup = page->new_optgroup(L("Advanced"));
|
||||
optgroup->append_single_option_line("seam_position", category_path + "seam-position");
|
||||
optgroup->append_single_option_line("seam_gap_distance", category_path + "seam-gap-distance");
|
||||
optgroup->append_single_option_line("staggered_inner_seams", category_path + "staggered-inner-seams");
|
||||
optgroup->append_single_option_line("seam_gap_distance", "print-settings/scarf-seam");
|
||||
optgroup->append_single_option_line("staggered_inner_seams", "print-settings/scarf-seam");
|
||||
|
||||
const std::string scarf_seam_path{"seam-position_151069#"};
|
||||
optgroup->append_single_option_line("scarf_seam_placement", scarf_seam_path + "scarf-joint-placement");
|
||||
optgroup->append_single_option_line("scarf_seam_only_on_smooth", scarf_seam_path + "scarf-joint-only-on-smooth-perimeters");
|
||||
optgroup->append_single_option_line("scarf_seam_start_height", scarf_seam_path + "scarf-start-height");
|
||||
optgroup->append_single_option_line("scarf_seam_entire_loop", scarf_seam_path + "scarf-joint-around-entire-perimeter");
|
||||
optgroup->append_single_option_line("scarf_seam_length", scarf_seam_path + "scarf-joint-length");
|
||||
optgroup->append_single_option_line("scarf_seam_max_segment_length", scarf_seam_path + "max-scarf-joint-segment-length");
|
||||
optgroup->append_single_option_line("scarf_seam_on_inner_perimeters", scarf_seam_path + "scarf-joint-on-inner-perimeters");
|
||||
optgroup->append_single_option_line("scarf_seam_placement", "print-settings/scarf-seam");
|
||||
optgroup->append_single_option_line("scarf_seam_only_on_smooth", "print-settings/scarf-seam");
|
||||
optgroup->append_single_option_line("scarf_seam_start_height", "print-settings/scarf-seam");
|
||||
optgroup->append_single_option_line("scarf_seam_entire_loop", "print-settings/scarf-seam");
|
||||
optgroup->append_single_option_line("scarf_seam_length", "print-settings/scarf-seam");
|
||||
optgroup->append_single_option_line("scarf_seam_max_segment_length", "print-settings/scarf-seam");
|
||||
optgroup->append_single_option_line("scarf_seam_on_inner_perimeters", "print-settings/scarf-seam");
|
||||
|
||||
optgroup->append_single_option_line("external_perimeters_first", category_path + "external-perimeters-first");
|
||||
optgroup->append_single_option_line("gap_fill_enabled", category_path + "fill-gaps");
|
||||
@@ -2250,6 +2250,8 @@ void TabFilament::build()
|
||||
Line line = { L("Nozzle"), "" };
|
||||
line.append_option(optgroup->get_option("first_layer_temperature"));
|
||||
line.append_option(optgroup->get_option("temperature"));
|
||||
//Y30
|
||||
line.append_option(optgroup->get_option("filament_flush_temp"));
|
||||
optgroup->append_line(line);
|
||||
|
||||
line = { L("Bed"), "" };
|
||||
@@ -2266,6 +2268,9 @@ void TabFilament::build()
|
||||
line.append_option(optgroup->get_option("chamber_minimal_temperature"));
|
||||
optgroup->append_line(line);
|
||||
|
||||
//Y30
|
||||
optgroup->append_single_option_line("box_temperature");
|
||||
|
||||
page = add_options_page(L("Cooling"), "cooling");
|
||||
std::string category_path = "filament-settings/cooling#";
|
||||
optgroup = page->new_optgroup(L("Enable"));
|
||||
@@ -2541,6 +2546,9 @@ void TabFilament::toggle_options()
|
||||
new_conf.set_key_value("chamber_minimal_temperature", new ConfigOptionInts{0});
|
||||
load_config(new_conf);
|
||||
}
|
||||
//Y30
|
||||
bool box_temp = printer_config->opt_bool("box_temperature_control");
|
||||
toggle_option("box_temperature", box_temp);
|
||||
}
|
||||
|
||||
void TabFilament::update()
|
||||
@@ -2940,6 +2948,8 @@ void TabPrinter::build_fff()
|
||||
optgroup->append_single_option_line("chamber_fan");
|
||||
optgroup->append_single_option_line("chamber_temperature_control");
|
||||
optgroup->append_single_option_line("wipe_device");
|
||||
//Y30
|
||||
optgroup->append_single_option_line("box_temperature_control");
|
||||
|
||||
const int gcode_field_height = 15; // 150
|
||||
const int notes_field_height = 25; // 250
|
||||
@@ -4207,6 +4217,11 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr
|
||||
else
|
||||
wxGetApp().get_tab(presets->type())->cache_config_diff(selected_options);
|
||||
}
|
||||
|
||||
//y25
|
||||
if (!wxGetApp().preset_bundle->filament_box_list.empty()) {
|
||||
wxGetApp().preset_bundle->filament_box_list.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2,20 +2,27 @@
|
||||
|
||||
#include "../wxExtensions.hpp"
|
||||
#include "../../Utils/MacDarkMode.hpp"
|
||||
#include "StaticBox.hpp"
|
||||
#include "Label.hpp"
|
||||
|
||||
#include <wx/dcgraph.h>
|
||||
#include <wx/dcmemory.h>
|
||||
#include <wx/dcclient.h>
|
||||
|
||||
//B64
|
||||
SwitchButton::SwitchButton(wxWindow* parent, const wxString& name, wxWindowID id)
|
||||
: BitmapToggleButton(parent, name, id)
|
||||
, m_on(this, "toggle_on", 28, 16)
|
||||
, m_off(this, "toggle_off", 28, 16)
|
||||
, text_color(std::pair{ 0x4479FB, (int) StateColor::Checked}, std::pair{0x6B6B6B, (int) StateColor::Normal})
|
||||
, track_color(0x333337)
|
||||
, thumb_color(std::pair{0x4479FB, (int) StateColor::Checked}, std::pair{0x333337, (int) StateColor::Normal})
|
||||
//y25
|
||||
wxDEFINE_EVENT(wxCUSTOMEVT_SWITCH_POS, wxCommandEvent);
|
||||
|
||||
SwitchButton::SwitchButton(wxWindow* parent, wxWindowID id)
|
||||
: wxBitmapToggleButton(parent, id, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxBU_EXACTFIT)
|
||||
, m_on(this, "toggle_on", 16)
|
||||
, m_off(this, "toggle_off", 16)
|
||||
, text_color(std::pair{0xfffffe, (int) StateColor::Checked}, std::pair{0x6B6B6B, (int) StateColor::Normal})
|
||||
, track_color(0xD9D9D9)
|
||||
, thumb_color(std::pair{0x4479FB, (int) StateColor::Checked}, std::pair{0xD9D9D9, (int) StateColor::Normal}) // y96
|
||||
{
|
||||
SetBackgroundColour(StaticBox::GetParentBackgroundColor(parent));
|
||||
Bind(wxEVT_TOGGLEBUTTON, [this](auto& e) { update(); e.Skip(); });
|
||||
SetFont(Label::Body_12);
|
||||
Rescale();
|
||||
}
|
||||
|
||||
@@ -31,6 +38,11 @@ void SwitchButton::SetTextColor(StateColor const& color)
|
||||
text_color = color;
|
||||
}
|
||||
|
||||
void SwitchButton::SetTextColor2(StateColor const &color)
|
||||
{
|
||||
text_color2 = color;
|
||||
}
|
||||
|
||||
void SwitchButton::SetTrackColor(StateColor const& color)
|
||||
{
|
||||
track_color = color;
|
||||
@@ -48,7 +60,315 @@ void SwitchButton::SetValue(bool value)
|
||||
update();
|
||||
}
|
||||
|
||||
void SwitchButton::SetSize(int size)
|
||||
void SwitchButton::Rescale()
|
||||
{
|
||||
if (!labels[0].IsEmpty()) {
|
||||
SetBackgroundColour(StaticBox::GetParentBackgroundColor(GetParent()));
|
||||
#ifdef __WXOSX__
|
||||
auto scale = Slic3r::GUI::mac_max_scaling_factor();
|
||||
int BS = (int) scale;
|
||||
#else
|
||||
constexpr int BS = 1;
|
||||
#endif
|
||||
wxSize thumbSize;
|
||||
wxSize trackSize;
|
||||
wxClientDC dc(this);
|
||||
#ifdef __WXOSX__
|
||||
dc.SetFont(dc.GetFont().Scaled(scale));
|
||||
#endif
|
||||
wxSize textSize[2];
|
||||
{
|
||||
textSize[0] = dc.GetTextExtent(labels[0]);
|
||||
textSize[1] = dc.GetTextExtent(labels[1]);
|
||||
}
|
||||
float fontScale = 0;
|
||||
{
|
||||
thumbSize = textSize[0];
|
||||
auto size = textSize[1];
|
||||
if (size.x > thumbSize.x) thumbSize.x = size.x;
|
||||
else size.x = thumbSize.x;
|
||||
thumbSize.x += BS * 12;
|
||||
thumbSize.y += BS * 6;
|
||||
trackSize.x = thumbSize.x + size.x + BS * 10;
|
||||
trackSize.y = thumbSize.y + BS * 2;
|
||||
auto maxWidth = GetMaxWidth();
|
||||
#ifdef __WXOSX__
|
||||
maxWidth *= scale;
|
||||
#endif
|
||||
if (trackSize.x > maxWidth) {
|
||||
fontScale = float(maxWidth) / trackSize.x;
|
||||
thumbSize.x -= (trackSize.x - maxWidth) / 2;
|
||||
trackSize.x = maxWidth;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
wxMemoryDC memdc(&dc);
|
||||
#ifdef __WXMSW__
|
||||
wxBitmap bmp(trackSize.x, trackSize.y);
|
||||
memdc.SelectObject(bmp);
|
||||
memdc.SetBackground(wxBrush(GetBackgroundColour()));
|
||||
memdc.Clear();
|
||||
#else
|
||||
wxImage image(trackSize);
|
||||
image.InitAlpha();
|
||||
memset(image.GetAlpha(), 0, trackSize.GetWidth() * trackSize.GetHeight());
|
||||
wxBitmap bmp(std::move(image));
|
||||
memdc.SelectObject(bmp);
|
||||
#endif
|
||||
memdc.SetFont(dc.GetFont());
|
||||
if (fontScale) {
|
||||
memdc.SetFont(dc.GetFont().Scaled(fontScale));
|
||||
textSize[0] = memdc.GetTextExtent(labels[0]);
|
||||
textSize[1] = memdc.GetTextExtent(labels[1]);
|
||||
}
|
||||
auto state = i == 0 ? StateColor::Enabled : (StateColor::Checked | StateColor::Enabled);
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
wxGCDC dc2(memdc);
|
||||
#else
|
||||
wxDC &dc2(memdc);
|
||||
#endif
|
||||
dc2.SetBrush(wxBrush(track_color.colorForStates(state)));
|
||||
dc2.SetPen(wxPen(track_color.colorForStates(state)));
|
||||
dc2.DrawRoundedRectangle(wxRect({0, 0}, trackSize), trackSize.y / 2);
|
||||
dc2.SetBrush(wxBrush(thumb_color.colorForStates(StateColor::Checked | StateColor::Enabled)));
|
||||
dc2.SetPen(wxPen(thumb_color.colorForStates(StateColor::Checked | StateColor::Enabled)));
|
||||
dc2.DrawRoundedRectangle(wxRect({ i == 0 ? BS : (trackSize.x - thumbSize.x - BS), BS}, thumbSize), thumbSize.y / 2);
|
||||
}
|
||||
memdc.SetTextForeground(text_color.colorForStates(state ^ StateColor::Checked));
|
||||
auto text_y = BS + (thumbSize.y - textSize[0].y) / 2;
|
||||
#ifdef __APPLE__
|
||||
if (Slic3r::is_mac_version_15()) {
|
||||
text_y -= FromDIP(2);
|
||||
}
|
||||
#endif
|
||||
memdc.DrawText(labels[0], {BS + (thumbSize.x - textSize[0].x) / 2, text_y});
|
||||
memdc.SetTextForeground(text_color2.count() == 0 ? text_color.colorForStates(state) : text_color2.colorForStates(state));
|
||||
auto text_y_1 = BS + (thumbSize.y - textSize[1].y) / 2;
|
||||
#ifdef __APPLE__
|
||||
if (Slic3r::is_mac_version_15()) {
|
||||
text_y_1 -= FromDIP(2);
|
||||
}
|
||||
#endif
|
||||
memdc.DrawText(labels[1], {trackSize.x - thumbSize.x - BS + (thumbSize.x - textSize[1].x) / 2, text_y_1});
|
||||
memdc.SelectObject(wxNullBitmap);
|
||||
#ifdef __WXOSX__
|
||||
bmp = wxBitmap(bmp.ConvertToImage(), -1, scale);
|
||||
#endif
|
||||
(i == 0 ? m_off : m_on).SetBitmap(bmp);
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void SwitchButton::update()
|
||||
{
|
||||
SetBitmap((GetValue() ? m_on : m_off).bmp());
|
||||
}
|
||||
|
||||
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()) {
|
||||
switch_left = false;
|
||||
switch_right = false;
|
||||
} else {
|
||||
if (target == "left") {
|
||||
switch_left = true;
|
||||
switch_right = false;
|
||||
} else if (target == "right") {
|
||||
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(68, 121, 251))) : 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);
|
||||
|
||||
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(68, 121, 251)));
|
||||
} 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);
|
||||
}
|
||||
|
||||
void SwitchBoard::Enable()
|
||||
{
|
||||
if (is_enable == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
is_enable = true;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void SwitchBoard::Disable()
|
||||
{
|
||||
if (is_enable == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
is_enable = false;
|
||||
Refresh();
|
||||
}
|
||||
|
||||
//B64
|
||||
DeviceSwitchButton::DeviceSwitchButton(wxWindow* parent, const wxString& name, wxWindowID id)
|
||||
: BitmapToggleButton(parent, name, id)
|
||||
, m_on(this, "toggle_on", 28, 16)
|
||||
, m_off(this, "toggle_off", 28, 16)
|
||||
, text_color(std::pair{ 0x4479FB, (int) StateColor::Checked}, std::pair{0x6B6B6B, (int) StateColor::Normal})
|
||||
, track_color(0x333337)
|
||||
, thumb_color(std::pair{0x4479FB, (int) StateColor::Checked}, std::pair{0x333337, (int) StateColor::Normal})
|
||||
{
|
||||
Rescale();
|
||||
}
|
||||
|
||||
void DeviceSwitchButton::SetLabels(wxString const& lbl_on, wxString const& lbl_off)
|
||||
{
|
||||
labels[0] = lbl_on;
|
||||
labels[1] = lbl_off;
|
||||
Rescale();
|
||||
}
|
||||
|
||||
void DeviceSwitchButton::SetTextColor(StateColor const& color)
|
||||
{
|
||||
text_color = color;
|
||||
}
|
||||
|
||||
void DeviceSwitchButton::SetTrackColor(StateColor const& color)
|
||||
{
|
||||
track_color = color;
|
||||
}
|
||||
|
||||
void DeviceSwitchButton::SetThumbColor(StateColor const& color)
|
||||
{
|
||||
thumb_color = color;
|
||||
}
|
||||
|
||||
void DeviceSwitchButton::SetValue(bool value)
|
||||
{
|
||||
if (value != GetValue())
|
||||
wxBitmapToggleButton::SetValue(value);
|
||||
update();
|
||||
}
|
||||
|
||||
void DeviceSwitchButton::SetSize(int size)
|
||||
{
|
||||
m_size = size;
|
||||
update();
|
||||
@@ -56,7 +376,7 @@ void SwitchButton::SetSize(int size)
|
||||
}
|
||||
|
||||
//B64
|
||||
void SwitchButton::Rescale()
|
||||
void DeviceSwitchButton::Rescale()
|
||||
{
|
||||
if (!labels[0].IsEmpty()) {
|
||||
#ifdef __WXOSX__
|
||||
@@ -138,7 +458,7 @@ void SwitchButton::Rescale()
|
||||
update();
|
||||
}
|
||||
|
||||
void SwitchButton::SysColorChange()
|
||||
void DeviceSwitchButton::SysColorChange()
|
||||
{
|
||||
m_on.sys_color_changed();
|
||||
m_off.sys_color_changed();
|
||||
@@ -146,7 +466,7 @@ void SwitchButton::SysColorChange()
|
||||
update();
|
||||
}
|
||||
|
||||
void SwitchButton::update()
|
||||
void DeviceSwitchButton::update()
|
||||
{
|
||||
SetBitmap((GetValue() ? m_on : m_off).bmp());
|
||||
update_size();
|
||||
|
||||
@@ -6,11 +6,83 @@
|
||||
|
||||
#include "BitmapToggleButton.hpp"
|
||||
|
||||
class SwitchButton : public BitmapToggleButton
|
||||
//y25
|
||||
wxDECLARE_EVENT(wxCUSTOMEVT_SWITCH_POS, wxCommandEvent);
|
||||
class SwitchButton : public wxBitmapToggleButton
|
||||
{
|
||||
public:
|
||||
SwitchButton(wxWindow * parent = NULL, wxWindowID id = wxID_ANY);
|
||||
|
||||
public:
|
||||
void SetLabels(wxString const & lbl_on, wxString const & lbl_off);
|
||||
|
||||
void SetTextColor(StateColor const &color);
|
||||
|
||||
void SetTextColor2(StateColor const &color);
|
||||
|
||||
void SetTrackColor(StateColor const &color);
|
||||
|
||||
void SetThumbColor(StateColor const &color);
|
||||
|
||||
void SetValue(bool value) override;
|
||||
|
||||
void Rescale();
|
||||
|
||||
|
||||
protected:
|
||||
void update();
|
||||
|
||||
private:
|
||||
ScalableBitmap m_on;
|
||||
ScalableBitmap m_off;
|
||||
|
||||
wxString labels[2];
|
||||
StateColor text_color;
|
||||
StateColor text_color2;
|
||||
StateColor track_color;
|
||||
StateColor thumb_color;
|
||||
};
|
||||
|
||||
class SwitchBoard : public wxWindow
|
||||
{
|
||||
public:
|
||||
SwitchBoard(wxWindow *parent = NULL, wxString leftL = "", wxString right = "", wxSize size = wxDefaultSize);
|
||||
wxString leftLabel;
|
||||
wxString rightLabel;
|
||||
|
||||
void updateState(wxString target);
|
||||
|
||||
bool switch_left{false};
|
||||
bool switch_right{false};
|
||||
bool is_enable {true};
|
||||
|
||||
void* client_data = nullptr;/*MachineObject* in StatusPanel*/
|
||||
|
||||
public:
|
||||
void Enable();
|
||||
void Disable();
|
||||
bool IsEnabled(){return is_enable;};
|
||||
|
||||
void SetClientData(void* data) { client_data = data; };
|
||||
void* GetClientData() { return client_data; };
|
||||
|
||||
void SetAutoDisableWhenSwitch() { auto_disable_when_switch = true; };
|
||||
|
||||
protected:
|
||||
void paintEvent(wxPaintEvent& evt);
|
||||
void render(wxDC& dc);
|
||||
void doRender(wxDC& dc);
|
||||
void on_left_down(wxMouseEvent& evt);
|
||||
|
||||
private:
|
||||
bool auto_disable_when_switch = false;
|
||||
};
|
||||
|
||||
class DeviceSwitchButton : public BitmapToggleButton
|
||||
{
|
||||
public:
|
||||
//B64
|
||||
SwitchButton(wxWindow * parent = NULL, const wxString& name = wxEmptyString, wxWindowID id = wxID_ANY);
|
||||
DeviceSwitchButton(wxWindow * parent = NULL, const wxString& name = wxEmptyString, wxWindowID id = wxID_ANY);
|
||||
|
||||
public:
|
||||
void SetLabels(wxString const & lbl_on, wxString const & lbl_off);
|
||||
|
||||
@@ -283,7 +283,6 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
||||
for (size_t j = 0; j < m_number_of_extruders; ++j) {
|
||||
if (i != j) {
|
||||
double def_val = m_printer_purging_volume * m_filament_purging_multipliers[j] / 100.;
|
||||
edit_boxes[j][i]->SetValue(wxString("") << int(def_val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,8 @@ public:
|
||||
std::vector<float> read_matrix_values();
|
||||
void format_sizer(wxSizer* sizer, wxPanel* page, wxGridSizer* grid_sizer, const wxString& table_title, int table_lshift=0);
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
std::vector<std::vector<wxTextCtrl*>> edit_boxes;
|
||||
std::vector<wxColour> m_colours;
|
||||
unsigned int m_number_of_extruders = 0;
|
||||
|
||||
Reference in New Issue
Block a user