mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-22 19:26:08 +03:00
Compare commits
1 Commits
main
...
fix/bambu-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
367047f731 |
2
.github/workflows/build_all.yml
vendored
2
.github/workflows/build_all.yml
vendored
@@ -142,7 +142,7 @@ jobs:
|
||||
flatpak:
|
||||
name: "Flatpak"
|
||||
container:
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-50
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:gnome-49
|
||||
options: --privileged
|
||||
volumes:
|
||||
- /usr/local/lib/android:/usr/local/lib/android
|
||||
|
||||
@@ -199,22 +199,22 @@ echo -e "${GREEN}All required dependencies found${NC}"
|
||||
# Install runtime and SDK if requested
|
||||
if [[ "$INSTALL_RUNTIME" == true ]]; then
|
||||
echo -e "${YELLOW}Installing GNOME runtime and SDK...${NC}"
|
||||
flatpak install --user -y flathub org.gnome.Platform//50
|
||||
flatpak install --user -y flathub org.gnome.Sdk//50
|
||||
flatpak install --user -y flathub org.gnome.Platform//49
|
||||
flatpak install --user -y flathub org.gnome.Sdk//49
|
||||
fi
|
||||
|
||||
# Check if required runtime is available
|
||||
if ! flatpak info --user org.gnome.Platform//50 &> /dev/null; then
|
||||
echo -e "${RED}Error: GNOME Platform 50 runtime is not installed.${NC}"
|
||||
if ! flatpak info --user org.gnome.Platform//49 &> /dev/null; then
|
||||
echo -e "${RED}Error: GNOME Platform 49 runtime is not installed.${NC}"
|
||||
echo "Run with -i flag to install it automatically, or install manually:"
|
||||
echo "flatpak install --user flathub org.gnome.Platform//50"
|
||||
echo "flatpak install --user flathub org.gnome.Platform//49"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! flatpak info --user org.gnome.Sdk//50 &> /dev/null; then
|
||||
echo -e "${RED}Error: GNOME SDK 50 is not installed.${NC}"
|
||||
if ! flatpak info --user org.gnome.Sdk//49 &> /dev/null; then
|
||||
echo -e "${RED}Error: GNOME SDK 49 is not installed.${NC}"
|
||||
echo "Run with -i flag to install it automatically, or install manually:"
|
||||
echo "flatpak install --user flathub org.gnome.Sdk//50"
|
||||
echo "flatpak install --user flathub org.gnome.Sdk//49"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ ARCH="$(uname -m)"
|
||||
NO_DEBUG_INFO=false
|
||||
FORCE_PULL=false
|
||||
FORCE_CLEAN=true
|
||||
CONTAINER_IMAGE="ghcr.io/flathub-infra/flatpak-github-actions:gnome-50"
|
||||
CONTAINER_IMAGE="ghcr.io/flathub-infra/flatpak-github-actions:gnome-49"
|
||||
|
||||
normalize_arch() {
|
||||
case "$1" in
|
||||
@@ -142,16 +142,6 @@ fi
|
||||
|
||||
DOCKER_RUN_ARGS=(run --rm -i --privileged)
|
||||
|
||||
# When building from a git worktree, $PROJECT_ROOT/.git is a file pointing to the
|
||||
# main repo's git dir (outside $PROJECT_ROOT). The git commands and flatpak-builder
|
||||
# inside the container need that path to resolve, so bind-mount the common git dir
|
||||
# read-only at its original absolute path. No-op for a normal clone.
|
||||
GIT_COMMON_DIR="$(git -C "$PROJECT_ROOT" rev-parse --path-format=absolute --git-common-dir 2>/dev/null || true)"
|
||||
if [ -n "$GIT_COMMON_DIR" ] && [ "$GIT_COMMON_DIR" != "$PROJECT_ROOT/.git" ]; then
|
||||
echo " Git worktree detected; mounting common git dir read-only: $GIT_COMMON_DIR"
|
||||
DOCKER_RUN_ARGS+=(-v "$GIT_COMMON_DIR":"$GIT_COMMON_DIR":ro)
|
||||
fi
|
||||
|
||||
# Pass build parameters as env vars so the inner script doesn't need
|
||||
# variable expansion from the outer shell (avoids quoting issues).
|
||||
echo "=== Starting Flatpak build inside container ==="
|
||||
@@ -185,8 +175,8 @@ git config --global --add safe.directory '/src/.flatpak-builder/git/*'
|
||||
|
||||
# Install required SDK extensions (not pre-installed in the container image)
|
||||
flatpak install -y --noninteractive --arch="$BUILD_ARCH" flathub \
|
||||
org.gnome.Platform//50 \
|
||||
org.gnome.Sdk//50 \
|
||||
org.gnome.Platform//49 \
|
||||
org.gnome.Sdk//49 \
|
||||
org.freedesktop.Sdk.Extension.llvm21//25.08 || true
|
||||
|
||||
install_end=$(date +%s)
|
||||
|
||||
@@ -45,12 +45,6 @@
|
||||
<color type="primary" scheme_preference="dark">#00695C</color>
|
||||
</branding>
|
||||
<releases>
|
||||
<release version="2.4.0-dev" date="2026-05-22" type="development">
|
||||
<url type="details">https://github.com/OrcaSlicer/OrcaSlicer/releases/tag/nightly-builds</url>
|
||||
<description>
|
||||
<p>See the release page for detailed changelog.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="2.3.2" date="2025-03-23">
|
||||
<url type="details">https://github.com/OrcaSlicer/OrcaSlicer/releases/tag/v2.3.2</url>
|
||||
<description>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
app-id: com.orcaslicer.OrcaSlicer
|
||||
runtime: org.gnome.Platform
|
||||
runtime-version: "50"
|
||||
runtime-version: "49"
|
||||
sdk: org.gnome.Sdk
|
||||
sdk-extensions:
|
||||
- org.freedesktop.Sdk.Extension.llvm21
|
||||
@@ -115,9 +115,7 @@ modules:
|
||||
- -DwxUSE_ZLIB=sys
|
||||
- -DwxUSE_LIBJPEG=sys
|
||||
- -DwxUSE_LIBTIFF=OFF
|
||||
- -DwxUSE_LIBWEBP=builtin
|
||||
- -DwxUSE_EXPAT=sys
|
||||
- -DwxUSE_NANOSVG=OFF
|
||||
- -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld
|
||||
- -DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld
|
||||
- -DCMAKE_MODULE_LINKER_FLAGS=-fuse-ld=lld
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
sudo apt update
|
||||
sudo apt install build-essential flatpak flatpak-builder gnome-software-plugin-flatpak -y
|
||||
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
flatpak install flathub org.gnome.Platform//50 org.gnome.Sdk//50 org.freedesktop.Sdk.Extension.llvm21//25.08
|
||||
flatpak install flathub org.gnome.Platform//48 org.gnome.Sdk//48
|
||||
|
||||
|
||||
##
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
#include <csignal>
|
||||
|
||||
#if defined(__linux__) || defined(__LINUX__)
|
||||
#include <condition_variable>
|
||||
@@ -7460,13 +7459,6 @@ extern "C" {
|
||||
#else /* _MSC_VER */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
// Ignore SIGPIPE so a write to a closed socket (e.g. a dropped printer
|
||||
// network connection) returns EPIPE to the caller instead of terminating
|
||||
// the whole process. Without this, losing the printer link kills
|
||||
// OrcaSlicer with SIGPIPE (exit 141) and produces no crash report.
|
||||
std::signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
return CLI().run(argc, argv);
|
||||
}
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
@@ -864,10 +864,10 @@ std::string GCodeWriter::_spiral_travel_to_z(double z, const Vec2d &ij_offset, c
|
||||
// Determine number of segments based on Resolution
|
||||
// --------------------------------------------------------------------
|
||||
const double ref_resolution = 0.01; // reference resolution in mm
|
||||
const double ref_segments = 8.0; // reference number of segments at reference resolution
|
||||
const double ref_segments = 16.0; // reference number of segments at reference resolution
|
||||
|
||||
// number of linear segments to use for approximating the arc, clamp between 4 and 16
|
||||
const int segments = std::clamp(int(std::round(ref_segments * (ref_resolution / m_resolution))), 4, 16);
|
||||
// number of linear segments to use for approximating the arc, clamp between 4 and 24
|
||||
const int segments = std::clamp(int(std::round(ref_segments * (ref_resolution / m_resolution))), 4, 24);
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
const double px = m_pos(0) - m_x_offset; // take plate offset into consideration
|
||||
|
||||
@@ -581,6 +581,14 @@ void Preset::load_info(const std::string& file)
|
||||
catch (...) {
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: workaround for current info file convert, will remove it later
|
||||
if (this->updated_time == 0) {
|
||||
this->updated_time = (long long)Slic3r::Utils::get_current_time_utc();
|
||||
//this->sync_info = "update";
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("old info file, updated time to %1%") % this->updated_time;
|
||||
save_info();
|
||||
}
|
||||
}
|
||||
|
||||
void Preset::save_info(std::string file)
|
||||
@@ -2178,29 +2186,19 @@ bool PresetCollection::load_user_preset(std::string name, std::map<std::string,
|
||||
}
|
||||
}
|
||||
|
||||
// base_id is only required for presets inheriting from a parent. Root presets
|
||||
// with an empty "inherits" field intentionally have no base_id.
|
||||
std::string based_id;
|
||||
const auto base_id = preset_values.find(BBL_JSON_KEY_BASE_ID);
|
||||
if (base_id != preset_values.end()) {
|
||||
based_id = base_id->second;
|
||||
} else {
|
||||
const auto inherits_iter = preset_values.find(BBL_JSON_KEY_INHERITS);
|
||||
const bool preset_inherits_from_parent = inherits_iter != preset_values.end() && !inherits_iter->second.empty();
|
||||
if (preset_inherits_from_parent) {
|
||||
// This indicates that there is inherits exists but there is no base_id
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__
|
||||
<< boost::format("can not find base_id, not loading for user preset %1%") % canonical_name;
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
// base_id
|
||||
if (preset_values.find(BBL_JSON_KEY_BASE_ID) == preset_values.end()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format("can not find base_id, not loading for user preset %1%") % canonical_name;
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
std::string cloud_base_id = preset_values[BBL_JSON_KEY_BASE_ID];
|
||||
|
||||
//filament_id
|
||||
std::string cloud_filament_id;
|
||||
if ((m_type == Preset::TYPE_FILAMENT) && preset_values.find(BBL_JSON_KEY_FILAMENT_ID) != preset_values.end()) {
|
||||
cloud_filament_id = preset_values[BBL_JSON_KEY_FILAMENT_ID];
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << canonical_name << " filament_id: " << cloud_filament_id << " base_id: " << based_id;
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " " << canonical_name << " filament_id: " << cloud_filament_id << " base_id: " << cloud_base_id;
|
||||
}
|
||||
|
||||
DynamicPrintConfig new_config, cloud_config;
|
||||
@@ -2273,7 +2271,7 @@ bool PresetCollection::load_user_preset(std::string name, std::map<std::string,
|
||||
iter->version = cloud_version.value();
|
||||
iter->user_id = cloud_user_id;
|
||||
iter->setting_id = cloud_setting_id;
|
||||
iter->base_id = based_id;
|
||||
iter->base_id = cloud_base_id;
|
||||
iter->filament_id = cloud_filament_id;
|
||||
update_alias(*iter);
|
||||
//presets_loaded.emplace_back(*it->second);
|
||||
@@ -2292,7 +2290,7 @@ bool PresetCollection::load_user_preset(std::string name, std::map<std::string,
|
||||
preset.version = cloud_version.value();
|
||||
preset.user_id = cloud_user_id;
|
||||
preset.setting_id = cloud_setting_id;
|
||||
preset.base_id = based_id;
|
||||
preset.base_id = cloud_base_id;
|
||||
preset.filament_id = cloud_filament_id;
|
||||
update_alias(preset);
|
||||
|
||||
@@ -3653,22 +3651,20 @@ void PresetCollection::set_custom_preset_alias(Preset &preset)
|
||||
// For printers, there is nothing to remove
|
||||
// For prints AKA processes, the postfix should be kept
|
||||
// Alias should be set here, as the preset name may be augmented further later (i.e., prefixing relative path for bundles)
|
||||
std::string bare_preset_name = get_preset_bare_name(preset.name);
|
||||
std::string alias_name = bare_preset_name;
|
||||
|
||||
const bool is_root_filament_preset =
|
||||
m_type == Preset::Type::TYPE_FILAMENT &&
|
||||
preset.config.has(BBL_JSON_KEY_INHERITS) &&
|
||||
preset.config.option<ConfigOptionString>(BBL_JSON_KEY_INHERITS)->value.empty();
|
||||
if (is_root_filament_preset) {
|
||||
const size_t suffix_separator_pos = bare_preset_name.find_first_of("@");
|
||||
if (suffix_separator_pos != std::string::npos) {
|
||||
alias_name = bare_preset_name.substr(0, suffix_separator_pos);
|
||||
boost::trim_right(alias_name);
|
||||
if (alias_name.empty())
|
||||
alias_name = bare_preset_name;
|
||||
std::string alias_name;
|
||||
std::string preset_name = get_preset_bare_name(preset.name);
|
||||
if (m_type == Preset::Type::TYPE_FILAMENT && preset.config.has(BBL_JSON_KEY_INHERITS) && preset.config.option<ConfigOptionString>(BBL_JSON_KEY_INHERITS)->value.empty()) {
|
||||
if (alias_name.empty()) {
|
||||
size_t end_pos = preset_name.find_first_of("@");
|
||||
if (end_pos != std::string::npos) {
|
||||
alias_name = preset_name.substr(0, end_pos);
|
||||
boost::trim_right(alias_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
alias_name = preset_name;
|
||||
}
|
||||
|
||||
preset.alias = std::move(alias_name);
|
||||
m_map_alias_to_profile_name[preset.alias].push_back(preset.name);
|
||||
|
||||
@@ -606,24 +606,13 @@ VendorType PresetBundle::get_current_vendor_type()
|
||||
{
|
||||
auto t = VendorType::Unknown;
|
||||
auto config = &printers.get_edited_preset().config;
|
||||
const auto* printer_model = config->opt<ConfigOptionString>("printer_model");
|
||||
if (printer_model == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": printer_model is "
|
||||
<< (config->has("printer_model") ? "not a string" : "missing")
|
||||
<< ", vendor type is Unknown";
|
||||
return t;
|
||||
}
|
||||
|
||||
std::string vendor_name;
|
||||
for (const auto& vendor_profile : vendors) {
|
||||
for (const auto& vendor_model : vendor_profile.second.models) {
|
||||
if (vendor_model.name == printer_model->value) {
|
||||
for (auto vendor_profile : vendors) {
|
||||
for (auto vendor_model : vendor_profile.second.models)
|
||||
if (vendor_model.name == config->opt_string("printer_model")) {
|
||||
vendor_name = vendor_profile.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!vendor_name.empty())
|
||||
break;
|
||||
}
|
||||
if (!vendor_name.empty())
|
||||
{
|
||||
@@ -3790,17 +3779,7 @@ int PresetBundle::get_printer_extruder_count() const
|
||||
{
|
||||
const Preset& printer_preset = this->printers.get_edited_preset();
|
||||
|
||||
const auto* nozzle_diameter = printer_preset.config.option<ConfigOptionFloats>("nozzle_diameter");
|
||||
if (nozzle_diameter == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": nozzle_diameter is missing, using 1 extruder";
|
||||
return 1;
|
||||
}
|
||||
if (nozzle_diameter->values.empty()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": nozzle_diameter is empty, using 1 extruder";
|
||||
return 1;
|
||||
}
|
||||
|
||||
int count = int(nozzle_diameter->values.size());
|
||||
int count = printer_preset.config.option<ConfigOptionFloats>("nozzle_diameter")->values.size();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include "DevManager.h"
|
||||
#include "DevUtil.h"
|
||||
|
||||
@@ -154,15 +151,11 @@ namespace Slic3r
|
||||
{
|
||||
keep_alive();
|
||||
MachineObject* obj = this->get_selected_machine();
|
||||
if (!obj) {
|
||||
BOOST_LOG_TRIVIAL(warning) << "DeviceManager::check_pushing selected machine not found";
|
||||
return;
|
||||
}
|
||||
|
||||
std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
|
||||
auto internal = std::chrono::duration_cast<std::chrono::milliseconds>(start - obj->last_update_time);
|
||||
|
||||
if (!obj->is_support_mqtt_alive)
|
||||
if (obj && !obj->is_support_mqtt_alive)
|
||||
{
|
||||
if (internal.count() > TIMEOUT_FOR_STRAT && internal.count() < 1000 * 60 * 60 * 300)
|
||||
{
|
||||
@@ -923,33 +916,18 @@ namespace Slic3r
|
||||
const auto cloud_provider = Slic3r::GUI::wxGetApp().get_printer_cloud_provider();
|
||||
if (Slic3r::GUI::wxGetApp().is_user_login(cloud_provider))
|
||||
{
|
||||
try {
|
||||
m_manager->check_pushing();
|
||||
} catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DeviceManagerRefresher::on_timer check_pushing exception="
|
||||
<< e.what();
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DeviceManagerRefresher::on_timer check_pushing unknown exception";
|
||||
}
|
||||
|
||||
try {
|
||||
m_manager->check_pushing();
|
||||
try
|
||||
{
|
||||
agent->refresh_connection(cloud_provider);
|
||||
} catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DeviceManagerRefresher::on_timer refresh_connection exception="
|
||||
<< e.what();
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DeviceManagerRefresher::on_timer refresh_connection unknown exception";
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// certificate
|
||||
try {
|
||||
agent->install_device_cert(obj->get_dev_id(), obj->is_lan_mode_printer());
|
||||
} catch (const std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DeviceManagerRefresher::on_timer install_device_cert exception="
|
||||
<< e.what();
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << "DeviceManagerRefresher::on_timer install_device_cert unknown exception";
|
||||
}
|
||||
agent->install_device_cert(obj->get_dev_id(), obj->is_lan_mode_printer());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,7 +338,15 @@ void FilamentGroupPopup::OnRadioBtn(int idx)
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::OnTimer(wxTimerEvent &event) { Dismiss(); }
|
||||
void FilamentGroupPopup::OnTimer(wxTimerEvent&)
|
||||
{
|
||||
if (IsMouseInPopup()) {
|
||||
StartTimer();
|
||||
return;
|
||||
}
|
||||
|
||||
Dismiss();
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::Dismiss() {
|
||||
m_active = false;
|
||||
@@ -348,19 +356,22 @@ void FilamentGroupPopup::Dismiss() {
|
||||
|
||||
void FilamentGroupPopup::OnLeaveWindow(wxMouseEvent &)
|
||||
{
|
||||
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
|
||||
if (this->GetClientRect().Contains(pos)) return;
|
||||
if (this->GetScreenRect().Contains(wxGetMousePosition())) return;
|
||||
StartTimer();
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::OnEnterWindow(wxMouseEvent &)
|
||||
{
|
||||
// Ignore spurious ENTER synthesized by PopupWindow::OnMouseEvent2 on macOS.
|
||||
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
|
||||
if (!this->GetClientRect().Contains(pos)) return;
|
||||
if (!this->GetScreenRect().Contains(wxGetMousePosition())) return;
|
||||
ResetTimer();
|
||||
}
|
||||
|
||||
bool FilamentGroupPopup::IsMouseInPopup() const
|
||||
{
|
||||
return this->GetScreenRect().Contains(wxGetMousePosition());
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::UpdateButtonStatus(int hover_idx)
|
||||
{
|
||||
for (int i = 0; i < ButtonType::btCount; ++i) {
|
||||
@@ -394,4 +405,4 @@ void FilamentGroupPopup::UpdateButtonStatus(int hover_idx)
|
||||
Fit();
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
@@ -36,6 +36,7 @@ private:
|
||||
void OnEnterWindow(wxMouseEvent &);
|
||||
void OnTimer(wxTimerEvent &event);
|
||||
void Dismiss();
|
||||
bool IsMouseInPopup() const;
|
||||
|
||||
void CreateBmps();
|
||||
|
||||
|
||||
@@ -5851,20 +5851,16 @@ void GUI_App::reload_settings()
|
||||
return;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " cloud user preset number is: " << user_presets.size();
|
||||
auto refresh_synced_ui = [this, user_presets = std::move(user_presets)]() mutable {
|
||||
if (is_closing() || !preset_bundle || !app_config || !mainframe)
|
||||
return;
|
||||
|
||||
// Check the user presets for any system vendors that need to be installed
|
||||
for (auto data : user_presets) {
|
||||
if (!check_preset_parent_available(data))
|
||||
add_pending_vendor_preset(data);
|
||||
}
|
||||
load_pending_vendors();
|
||||
preset_bundle->load_user_presets(*app_config, user_presets, ForwardCompatibilitySubstitutionRule::Enable);
|
||||
preset_bundle->save_user_presets(*app_config, get_delete_cache_presets());
|
||||
|
||||
// Orca: settings changed, refresh ui to reflect the new preset values
|
||||
// Check the user presets for any system vendors that need to be installed
|
||||
for (auto data : user_presets) {
|
||||
if (!check_preset_parent_available(data))
|
||||
add_pending_vendor_preset(data);
|
||||
}
|
||||
load_pending_vendors();
|
||||
preset_bundle->load_user_presets(*app_config, user_presets, ForwardCompatibilitySubstitutionRule::Enable);
|
||||
preset_bundle->save_user_presets(*app_config, get_delete_cache_presets());
|
||||
// Orca: settings changed, refresh ui to reflect the new preset values
|
||||
auto refresh_synced_ui = [this] {
|
||||
mainframe->update_side_preset_ui();
|
||||
for (auto tab : tabs_list) {
|
||||
tab->reload_config();
|
||||
|
||||
@@ -664,14 +664,6 @@ void ParamsPanel::update_mode()
|
||||
|
||||
sync_mode_view(m_mode_view);
|
||||
sync_mode_view(m_current_tab ? dynamic_cast<Tab*>(m_current_tab)->m_mode_view : nullptr);
|
||||
|
||||
auto sync_mode_icon = [&](ScalableButton* mode_icon) {
|
||||
if (mode_icon == nullptr)
|
||||
return;
|
||||
mode_icon->Show(app_mode != comDevelop);
|
||||
};
|
||||
sync_mode_icon(m_mode_icon);
|
||||
sync_mode_icon(m_current_tab ? dynamic_cast<Tab*>(m_current_tab)->m_mode_icon : nullptr);
|
||||
}
|
||||
|
||||
void ParamsPanel::msw_rescale()
|
||||
|
||||
@@ -146,6 +146,7 @@ protected:
|
||||
|
||||
//BBS: GUI refactor
|
||||
wxPanel* m_top_panel;
|
||||
ScalableButton* m_mode_icon; // ORCA m_static_title replacement
|
||||
wxBoxSizer* m_main_sizer;
|
||||
wxBoxSizer* m_top_sizer;
|
||||
wxBoxSizer* m_top_left_sizer;
|
||||
@@ -306,7 +307,6 @@ public:
|
||||
int m_update_cnt = 0;
|
||||
|
||||
ModeSwitchButton *m_mode_view = nullptr;
|
||||
ScalableButton* m_mode_icon = nullptr; // ORCA m_static_title replacement
|
||||
SwitchButton *m_extruder_switch = nullptr;
|
||||
MultiSwitchButton *m_variant_combo = nullptr;
|
||||
|
||||
|
||||
@@ -42,8 +42,7 @@ static std::map<wxColour, wxColour> gDarkColors{
|
||||
{"#D7E8DE", "#1F2B27"}, // rgb(215, 232, 222) Not Used anymore // Leftover from BBS
|
||||
{"#2B3436", "#808080"}, // rgb(43, 52, 54) Not Used anymore // Leftover from BBS. Was used as main fill color of icons
|
||||
{"#ABABAB", "#ABABAB"},
|
||||
{"#D9D9D9", "#27272A"}, // rgb(217, 217, 217) Sidebar > Toggle button track color
|
||||
{"#FFFEFE", "#D9D9D9"}, // rgb(255, 254, 254) Sidebar > Toggle button thumb color
|
||||
{"#D9D9D9", "#2D2D32"}, // rgb(217, 217, 217) Sidebar > Toggle button track color
|
||||
{"#EBF9F0", "#293F34"},
|
||||
//{"#F0F0F0", "#4C4C54"},
|
||||
// ORCA
|
||||
|
||||
@@ -220,40 +220,14 @@ void SwitchButton::update()
|
||||
ModeSwitchButton::ModeSwitchButton(wxWindow* parent, wxWindowID id)
|
||||
{
|
||||
background_color = StateColor(
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Normal)
|
||||
);
|
||||
std::make_pair(wxColour(0xF1, 0xF1, 0xF1), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour(0xE3, 0xE3, 0xE3), (int) StateColor::Pressed),
|
||||
std::make_pair(wxColour(0xD9, 0xD9, 0xD9), (int) StateColor::Normal));
|
||||
border_color = StateColor(
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Hovered | ~StateColor::Focused),
|
||||
std::make_pair(wxColour("#26A69A"), (int) StateColor::Focused),
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Normal)
|
||||
);
|
||||
track_background = StateColor(
|
||||
std::make_pair(wxColour("#009688"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#009688"), (int) StateColor::Normal)
|
||||
);
|
||||
track_border = StateColor(
|
||||
std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#009688"), (int) StateColor::Hovered | ~StateColor::Focused),
|
||||
std::make_pair(wxColour("#26A69A"), (int) StateColor::Focused),
|
||||
std::make_pair(wxColour("#009688"), (int) StateColor::Normal)
|
||||
);
|
||||
dot_active = StateColor(
|
||||
std::make_pair(wxColour("#FFFEFE"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#FFFEFE"), (int) StateColor::Normal)
|
||||
);
|
||||
dot_dimmed = StateColor(
|
||||
std::make_pair(wxColour("#EEEEEE"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#EEEEEE"), (int) StateColor::Normal)
|
||||
);
|
||||
text_color = StateColor(
|
||||
std::make_pair(wxColour("#6B6B6B"), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour("#6B6B6B"), (int) StateColor::Normal)
|
||||
);
|
||||
|
||||
state_handler.attach(std::vector<StateColor const*>{&dot_active, &dot_dimmed, &text_color});
|
||||
state_handler.update_binds();
|
||||
std::make_pair(wxColour(0xEA, 0xEA, 0xEA), (int) StateColor::Disabled),
|
||||
std::make_pair(wxColour(0xBC, 0xBC, 0xBC), (int) StateColor::Hovered),
|
||||
std::make_pair(wxColour(0xC8, 0xC8, 0xC8), (int) StateColor::Focused),
|
||||
std::make_pair(wxColour(0xCE, 0xCE, 0xCE), (int) StateColor::Normal));
|
||||
|
||||
StaticBox::Create(parent, id, wxDefaultPosition, wxDefaultSize, 0);
|
||||
SetBackgroundColour(StaticBox::GetParentBackgroundColor(parent));
|
||||
@@ -289,7 +263,7 @@ void ModeSwitchButton::SelectAndNotify(int selection)
|
||||
|
||||
void ModeSwitchButton::Rescale()
|
||||
{
|
||||
const wxSize button_size = FromDIP(wxSize(48, 18));
|
||||
const wxSize button_size = FromDIP(wxSize(48, 20));
|
||||
SetMinSize(button_size);
|
||||
SetMaxSize(button_size);
|
||||
SetSize(button_size);
|
||||
@@ -300,70 +274,63 @@ void ModeSwitchButton::Rescale()
|
||||
bool ModeSwitchButton::Enable(bool enable /* = true */)
|
||||
{
|
||||
const bool changed = StaticBox::Enable(enable);
|
||||
if (changed){
|
||||
wxCommandEvent e(EVT_ENABLE_CHANGED);
|
||||
e.SetEventObject(this);
|
||||
GetEventHandler()->ProcessEvent(e);
|
||||
m_enabled = enable; // IsEnabled() not works because variable changes after paint event
|
||||
if (changed)
|
||||
Refresh();
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
void ModeSwitchButton::doRender(wxDC& dc)
|
||||
{
|
||||
const wxRect bounds = GetClientRect();
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(wxBrush(GetBackgroundColour()));
|
||||
dc.DrawRectangle(GetClientRect());
|
||||
|
||||
const wxRect bounds = GetClientRect().Deflate(1);
|
||||
if (bounds.width <= 0 || bounds.height <= 0)
|
||||
return;
|
||||
|
||||
const int states = state_handler.states();
|
||||
const bool hovered = (states & StateHandler::Hovered) != 0;
|
||||
const bool focused = (states & StateHandler::Focused) != 0;
|
||||
const bool disabled = !IsEnabled();
|
||||
|
||||
const wxColour track_fill = disabled ? wxColour(0xD0, 0xD0, 0xD4) :
|
||||
m_pressed ? wxColour(0x5A, 0x5D, 0x64) : wxColour(0x66, 0x69, 0x70);
|
||||
const wxColour track_border = disabled ? wxColour(0xDD, 0xDD, 0xE0) :
|
||||
focused ? wxColour("#009688") :
|
||||
hovered ? wxColour(0x7A, 0x7D, 0x84) : wxColour(0x75, 0x78, 0x7F);
|
||||
const wxColour active_fill = disabled ? wxColour(0x9E, 0xBE, 0xB9) :
|
||||
m_pressed ? wxColour(0x00877B) : wxColour("#009688");
|
||||
const wxColour active_dot = disabled ? wxColour(0xEC, 0xF4, 0xF2) : wxColour(0xB7, 0xEB, 0xE3);
|
||||
const wxColour inactive_dot = disabled ? wxColour(0xF2, 0xF2, 0xF4) : wxColour(0xB5, 0xB7, 0xBD);
|
||||
const wxColour thumb_fill = disabled ? wxColour(0xFA, 0xFA, 0xFA) : *wxWHITE;
|
||||
const wxColour thumb_border = disabled ? wxColour(0xE7, 0xE7, 0xEA) : wxColour(0xDD, 0xDF, 0xE3);
|
||||
|
||||
dc.SetPen(wxPen(track_border, 1));
|
||||
dc.SetBrush(wxBrush(track_fill));
|
||||
dc.DrawRoundedRectangle(bounds, bounds.height / 2.0);
|
||||
|
||||
const wxRect thumb = thumb_rect_for(m_selection);
|
||||
const int fill_right = std::min(bounds.GetRight(), thumb.GetX() + thumb.GetWidth() / 2 + FromDIP(2));
|
||||
wxRect active(bounds.x, bounds.y, fill_right - bounds.x + 1, bounds.height);
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(wxBrush(GetBackgroundColour()));
|
||||
dc.DrawRectangle(bounds);
|
||||
dc.SetBrush(wxBrush(active_fill));
|
||||
dc.DrawRoundedRectangle(active, bounds.height / 2.0);
|
||||
|
||||
int states = state_handler.states();
|
||||
double v_center = bounds.height / 2.0;
|
||||
const int dot_radius = std::max(FromDIP(1), thumb.height / 7);
|
||||
for (int idx = 0; idx < 3; ++idx) {
|
||||
if (idx == m_selection)
|
||||
continue;
|
||||
|
||||
// Background
|
||||
dc.SetPen(wxPen(border_color.colorForStates(states), 1));
|
||||
dc.SetBrush(wxBrush(background_color.colorForStates(states)));
|
||||
dc.DrawRoundedRectangle(bounds, v_center);
|
||||
|
||||
if (m_enabled) {
|
||||
double dot_dist = (bounds.width - bounds.height) * 0.50;
|
||||
|
||||
// Track
|
||||
dc.SetPen(wxPen(track_border.colorForStates(states), 1));
|
||||
dc.SetBrush(wxBrush(track_background.colorForStates(states)));
|
||||
wxRect track_rc = bounds;
|
||||
track_rc.width = int(v_center * 2.0 + dot_dist * m_selection);
|
||||
dc.DrawRoundedRectangle(track_rc, v_center);
|
||||
|
||||
// Dots
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
for (int idx = 0; idx < 3; ++idx) {
|
||||
dc.SetBrush(wxBrush((idx <= m_selection ? dot_active : dot_dimmed).colorForStates(states)));
|
||||
dc.DrawCircle(wxPoint(v_center + dot_dist * idx, v_center), track_rc.height * (double)(idx == m_selection ? 0.32 : 0.16));
|
||||
}
|
||||
const wxRect slot = thumb_rect_for(idx);
|
||||
const wxPoint center(slot.GetX() + slot.GetWidth() / 2, slot.GetY() + slot.GetHeight() / 2);
|
||||
dc.SetBrush(wxBrush(idx < m_selection ? active_dot : inactive_dot));
|
||||
dc.DrawCircle(center, dot_radius);
|
||||
}
|
||||
else { // Developer mode
|
||||
wxString str = "DEV";
|
||||
int kerning = 3; // pixels between chars
|
||||
dc.SetTextForeground(text_color.colorForStates(states));
|
||||
|
||||
wxCoord totalWidth = 0;
|
||||
for (char c : str)
|
||||
totalWidth += dc.GetTextExtent(wxString(c)).x + kerning;
|
||||
totalWidth -= kerning;
|
||||
|
||||
wxCoord x = bounds.x + (bounds.width - totalWidth) / 2;
|
||||
wxCoord y = bounds.y + (bounds.height - dc.GetTextExtent(str).y) / 2 - 1;
|
||||
|
||||
for (char c : str) {
|
||||
wxString ch(c);
|
||||
dc.DrawText(ch, x, y);
|
||||
x += dc.GetTextExtent(ch).x + kerning;
|
||||
}
|
||||
}
|
||||
dc.SetPen(wxPen(thumb_border, 1));
|
||||
dc.SetBrush(wxBrush(thumb_fill));
|
||||
dc.DrawRoundedRectangle(thumb, thumb.height / 2.0);
|
||||
}
|
||||
|
||||
void ModeSwitchButton::mouseDown(wxMouseEvent& event)
|
||||
|
||||
@@ -78,13 +78,7 @@ private:
|
||||
private:
|
||||
int m_selection { 0 };
|
||||
bool m_pressed { false };
|
||||
bool m_enabled { true };
|
||||
wxString m_tooltips[3];
|
||||
StateColor dot_active;
|
||||
StateColor dot_dimmed;
|
||||
StateColor text_color;
|
||||
StateColor track_background;
|
||||
StateColor track_border;
|
||||
};
|
||||
|
||||
class MultiSwitchButton : public StaticBox
|
||||
|
||||
@@ -100,33 +100,3 @@ TEST_CASE("Legacy bundle import without bundle metadata stays in the user preset
|
||||
CHECK(fs::equivalent(fs::path(imported->file).parent_path().parent_path(), user_root / PRESET_PRINT_NAME));
|
||||
}
|
||||
|
||||
TEST_CASE("Current vendor type tolerates missing printer model", "[Preset][Bundle]")
|
||||
{
|
||||
PresetBundle bundle;
|
||||
|
||||
VendorProfile orca_vendor("ORCA");
|
||||
VendorProfile::PrinterModel model;
|
||||
model.name = "Orca Test";
|
||||
orca_vendor.models.emplace_back(model);
|
||||
bundle.vendors.emplace("ORCA", std::move(orca_vendor));
|
||||
|
||||
bundle.printers.get_edited_preset().config.erase("printer_model");
|
||||
|
||||
CHECK(bundle.get_current_vendor_type() == VendorType::Unknown);
|
||||
}
|
||||
|
||||
TEST_CASE("Printer extruder count tolerates missing nozzle diameter", "[Preset][Bundle]")
|
||||
{
|
||||
PresetBundle bundle;
|
||||
DynamicPrintConfig& config = bundle.printers.get_edited_preset().config;
|
||||
|
||||
config.erase("nozzle_diameter");
|
||||
CHECK(bundle.get_printer_extruder_count() == 1);
|
||||
|
||||
config.set_key_value("nozzle_diameter", new ConfigOptionFloats());
|
||||
CHECK(bundle.get_printer_extruder_count() == 1);
|
||||
|
||||
config.set_key_value("nozzle_diameter", new ConfigOptionFloats({ 0.4, 0.6 }));
|
||||
CHECK(bundle.get_printer_extruder_count() == 2);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user