mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-05-16 18:12:10 +00:00
ENH: refine ui logic with filament group
1. Add filament group pop up when slice 2. Add more filament modes in filament dialog 3. Add capsule button jira:NONE Signed-off-by: xun.zhang <xun.zhang@bambulab.com> Change-Id: I8bc3a2e08696e406b89e550a0335a1a36728ee65 (cherry picked from commit f1702a5c3604f685a3b35ea0e83d29bdbbd90f70)
This commit is contained in:
@@ -302,6 +302,18 @@ void AppConfig::set_defaults()
|
||||
set_bool("auto_calculate_when_filament_change", true);
|
||||
}
|
||||
|
||||
if (get("ignore_ext_filament_in_filament_map").empty()){
|
||||
set_bool("ignore_ext_filament_in_filament_map", false);
|
||||
}
|
||||
|
||||
if (get("pop_up_filament_map_mode").empty()){
|
||||
set_bool("pop_up_filament_map_mode", true);
|
||||
}
|
||||
|
||||
if (get("prefered_filament_map_mode").empty()){
|
||||
set("prefered_filament_map_mode",ConfigOptionEnum<FilamentMapMode>::get_enum_names()[FilamentMapMode::fmmAutoForFlush]);
|
||||
}
|
||||
|
||||
if (get("show_home_page").empty()) {
|
||||
set_bool("show_home_page", true);
|
||||
}
|
||||
|
||||
@@ -301,6 +301,10 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/Field.hpp
|
||||
GUI/DragDropPanel.cpp
|
||||
GUI/DragDropPanel.hpp
|
||||
GUI/CapsuleButton.cpp
|
||||
GUI/CapsuleButton.hpp
|
||||
GUI/FilamentMapPanel.cpp
|
||||
GUI/FilamentMapPanel.hpp
|
||||
GUI/FilamentMapDialog.cpp
|
||||
GUI/FilamentMapDialog.hpp
|
||||
GUI/FileArchiveDialog.cpp
|
||||
@@ -430,6 +434,8 @@ set(SLIC3R_GUI_SOURCES
|
||||
GUI/InstanceCheck.hpp
|
||||
GUI/Search.cpp
|
||||
GUI/Search.hpp
|
||||
GUI/FilamentGroupPopup.hpp
|
||||
GUI/FilamentGroupPopup.cpp
|
||||
GUI/NotificationManager.cpp
|
||||
GUI/NotificationManager.hpp
|
||||
GUI/UnsavedChangesDialog.cpp
|
||||
|
||||
117
src/slic3r/GUI/CapsuleButton.cpp
Normal file
117
src/slic3r/GUI/CapsuleButton.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "GUI_App.hpp"
|
||||
#include "CapsuleButton.hpp"
|
||||
#include "wx/graphics.h"
|
||||
#include "Widgets/Label.hpp"
|
||||
#include "wx/dcgraph.h"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
CapsuleButton::CapsuleButton(wxWindow *parent, wxWindowID id, const wxString &label, bool selected) : wxPanel(parent, id)
|
||||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
|
||||
m_hovered = false;
|
||||
m_selected = selected;
|
||||
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
std::string icon_name = selected ? "capsule_tag_on" : "capsule_tag_off";
|
||||
auto bmp = create_scaled_bitmap(icon_name, nullptr, FromDIP(16));
|
||||
|
||||
m_btn = new wxBitmapButton(this, wxID_ANY, bmp, wxDefaultPosition, wxDefaultSize, wxNO_BORDER);
|
||||
m_btn->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
m_label = new Label(this, label);
|
||||
|
||||
sizer->AddSpacer(FromDIP(8));
|
||||
sizer->Add(m_btn, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, FromDIP(6));
|
||||
sizer->AddSpacer(FromDIP(8));
|
||||
sizer->Add(m_label, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, FromDIP(6));
|
||||
sizer->AddSpacer(FromDIP(8));
|
||||
|
||||
SetSizer(sizer);
|
||||
Layout();
|
||||
Fit();
|
||||
|
||||
auto forward_click_to_parent = [this](auto &event) {
|
||||
wxCommandEvent click_event(wxEVT_BUTTON, GetId());
|
||||
click_event.SetEventObject(this);
|
||||
this->ProcessEvent(click_event);
|
||||
};
|
||||
|
||||
m_btn->Bind(wxEVT_LEFT_DOWN, forward_click_to_parent);
|
||||
m_label->Bind(wxEVT_LEFT_DOWN, forward_click_to_parent);
|
||||
this->Bind(wxEVT_LEFT_DOWN, forward_click_to_parent);
|
||||
|
||||
Bind(wxEVT_PAINT, &CapsuleButton::OnPaint, this);
|
||||
Bind(wxEVT_ENTER_WINDOW, &CapsuleButton::OnEnterWindow, this);
|
||||
Bind(wxEVT_LEAVE_WINDOW, &CapsuleButton::OnLeaveWindow, this);
|
||||
|
||||
GUI::wxGetApp().UpdateDarkUIWin(this);
|
||||
}
|
||||
void CapsuleButton::OnPaint(wxPaintEvent &event)
|
||||
{
|
||||
wxAutoBufferedPaintDC dc(this);
|
||||
wxGraphicsContext *gc = wxGraphicsContext::Create(dc);
|
||||
|
||||
if (gc) {
|
||||
dc.Clear();
|
||||
wxRect rect = GetClientRect();
|
||||
gc->SetBrush(wxTransparentColour);
|
||||
gc->DrawRoundedRectangle(0, 0, rect.width, rect.height, 0);
|
||||
wxColour bg_color = m_selected ? wxColour("#EBF9F0") : wxColour("#FFFFFF");
|
||||
wxColour border_color = m_hovered || m_selected ? wxColour("#00AE42") : wxColour("#CECECE");
|
||||
int cornerRadius = 5;
|
||||
gc->SetBrush(wxBrush(bg_color));
|
||||
gc->SetPen(wxPen(border_color, 2));
|
||||
gc->DrawRoundedRectangle(1, 1, rect.width - 2, rect.height - 2, cornerRadius);
|
||||
delete gc;
|
||||
}
|
||||
}
|
||||
void CapsuleButton::Select(bool selected)
|
||||
{
|
||||
m_selected = selected;
|
||||
UpdateStatus();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void CapsuleButton::OnEnterWindow(wxMouseEvent &event)
|
||||
{
|
||||
if (!m_hovered) {
|
||||
m_hovered = true;
|
||||
UpdateStatus();
|
||||
Refresh();
|
||||
}
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void CapsuleButton::OnLeaveWindow(wxMouseEvent &event)
|
||||
{
|
||||
if (m_hovered) {
|
||||
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
|
||||
if (this->GetClientRect().Contains(pos)) return;
|
||||
m_hovered = false;
|
||||
UpdateStatus();
|
||||
Refresh();
|
||||
}
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void CapsuleButton::UpdateStatus()
|
||||
{
|
||||
const wxColour selected_color = wxColour("#EBF9F0");
|
||||
const wxColour normal_color = wxColour("#FFFFFF");
|
||||
|
||||
std::string icon_name = m_selected ? "capsule_tag_on" : "capsule_tag_off";
|
||||
auto bmp = create_scaled_bitmap(icon_name, nullptr, FromDIP(16));
|
||||
m_btn->SetBitmap(bmp);
|
||||
|
||||
if (m_selected) {
|
||||
m_label->SetBackgroundColour(selected_color);
|
||||
m_btn->SetBackgroundColour(selected_color);
|
||||
} else {
|
||||
m_label->SetBackgroundColour(normal_color);
|
||||
m_btn->SetBackgroundColour(normal_color);
|
||||
}
|
||||
}
|
||||
}} // namespace Slic3r::GUI
|
||||
28
src/slic3r/GUI/CapsuleButton.hpp
Normal file
28
src/slic3r/GUI/CapsuleButton.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef CAPSULE_BUTTON_HPP
|
||||
#define CAPSULE_BUTTON_HPP
|
||||
|
||||
#include "GUI.hpp"
|
||||
#include "wxExtensions.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
class CapsuleButton : public wxPanel
|
||||
{
|
||||
public:
|
||||
CapsuleButton(wxWindow *parent, wxWindowID id, const wxString &label, bool selected);
|
||||
void Select(bool selected);
|
||||
protected:
|
||||
void OnPaint(wxPaintEvent &event);
|
||||
private:
|
||||
void OnEnterWindow(wxMouseEvent &event);
|
||||
void OnLeaveWindow(wxMouseEvent &event);
|
||||
void UpdateStatus();
|
||||
|
||||
wxBitmapButton *m_btn;
|
||||
Label *m_label;
|
||||
|
||||
bool m_hovered;
|
||||
bool m_selected;
|
||||
};
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
#endif
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "DragDropPanel.hpp"
|
||||
#include "Widgets/Label.hpp"
|
||||
#include <slic3r/GUI/wxExtensions.hpp>
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
@@ -9,6 +10,27 @@ struct CustomData
|
||||
unsigned char r, g, b;
|
||||
};
|
||||
|
||||
|
||||
wxColor Hex2Color(const std::string& str)
|
||||
{
|
||||
if (str.empty() || (str.length() != 9 && str.length() != 7) || str[0] != '#')
|
||||
throw std::invalid_argument("Invalid hex color format");
|
||||
|
||||
auto hexToByte = [](const std::string& hex)->unsigned char
|
||||
{
|
||||
unsigned int byte;
|
||||
std::istringstream(hex) >> std::hex >> byte;
|
||||
return static_cast<unsigned char>(byte);
|
||||
};
|
||||
auto r = hexToByte(str.substr(1, 2));
|
||||
auto g = hexToByte(str.substr(3, 2));
|
||||
auto b = hexToByte(str.substr(5, 2));
|
||||
unsigned char a = 255;
|
||||
if (str.size() == 9)
|
||||
a = hexToByte(str.substr(7, 2));
|
||||
return wxColor(r, g, b, a);
|
||||
}
|
||||
|
||||
// Custom data object used to store information that needs to be backed up during drag and drop
|
||||
class ColorDataObject : public wxCustomDataObject
|
||||
{
|
||||
@@ -150,21 +172,24 @@ DragDropPanel::DragDropPanel(wxWindow *parent, const wxString &label, bool is_au
|
||||
auto title_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
title_panel->SetSizer(title_sizer);
|
||||
|
||||
wxStaticText *staticText = new wxStaticText(this, wxID_ANY, label);
|
||||
staticText->SetBackgroundColour(0xEEEEEE);
|
||||
title_sizer->Add(staticText, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
Label* static_text = new Label(this, label);
|
||||
static_text->SetFont(Label::Head_13);
|
||||
static_text->SetBackgroundColour(0xEEEEEE);
|
||||
|
||||
title_sizer->Add(static_text, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
||||
|
||||
m_sizer->Add(title_panel, 0, wxEXPAND);
|
||||
m_sizer->AddSpacer(20);
|
||||
|
||||
m_grid_item_sizer = new wxGridSizer(0, 5, FromDIP(10), 0); // row = 0, col = 3, 10 10 is space
|
||||
m_sizer->Add(m_grid_item_sizer);
|
||||
m_grid_item_sizer = new wxGridSizer(0, 6, FromDIP(5),FromDIP(5)); // row = 0, col = 3, 10 10 is space
|
||||
m_sizer->Add(m_grid_item_sizer, 1, wxEXPAND);
|
||||
|
||||
// set droptarget
|
||||
auto drop_target = new ColorDropTarget(this);
|
||||
SetDropTarget(drop_target);
|
||||
|
||||
SetSizer(m_sizer);
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
||||
@@ -172,7 +197,7 @@ void DragDropPanel::AddColorBlock(const wxColour &color, int filament_id, bool u
|
||||
{
|
||||
ColorPanel *panel = new ColorPanel(this, color, filament_id);
|
||||
panel->SetMinSize(wxSize(FromDIP(32), FromDIP(40)));
|
||||
m_grid_item_sizer->Add(panel, 0, wxALIGN_CENTER | wxLEFT, FromDIP(10));
|
||||
m_grid_item_sizer->Add(panel, 0, wxALIGN_CENTER);
|
||||
m_filament_blocks.push_back(panel);
|
||||
if (update_ui) {
|
||||
m_filament_blocks.front()->Refresh(); // FIX BUG: STUDIO-8467
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
wxColor Hex2Color(const std::string& str);
|
||||
|
||||
class ColorPanel;
|
||||
class DragDropPanel : public wxPanel
|
||||
{
|
||||
|
||||
318
src/slic3r/GUI/FilamentGroupPopup.cpp
Normal file
318
src/slic3r/GUI/FilamentGroupPopup.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
#include "FilamentGroupPopup.hpp"
|
||||
#include "FilamentMapDialog.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "MsgDialog.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "wx/dcgraph.h"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
static const wxString AutoForFlushLabel = _L("Filament-Saving Mode");
|
||||
static const wxString AutoForMatchLabel = _L("Convenient Mode");
|
||||
static const wxString ManualLabel = _L("Manual Mode");
|
||||
|
||||
static const wxString AutoForFlushDesp = _L("(Arrage after slicing)");
|
||||
static const wxString AutoForMatchDesp = _L("(Arrange before slicing)");
|
||||
static const wxString ManualDesp = "";
|
||||
|
||||
static const wxString AutoForFlushDetail = _L("Disregrad the filaments in AMS. Optimize filament usage "
|
||||
"by calculating the best allocation for the left and right "
|
||||
"nozzles. Arrange the filaments according on the printer according to "
|
||||
"the slicing results.");
|
||||
static const wxString AutoForMatchDetail = _L("Based on the current filaments in the AMS, allocate the "
|
||||
"filaments to the left and right nozzles.");
|
||||
static const wxString ManualDetail = _L("Mannully allocate the filaments for the left and right nozzles.");
|
||||
|
||||
static bool is_multi_extruder()
|
||||
{
|
||||
const auto &preset_bundle = wxGetApp().preset_bundle;
|
||||
const auto &full_config = preset_bundle->full_config();
|
||||
const auto nozzle_diameters = full_config.option<ConfigOptionFloatsNullable>("nozzle_diameter");
|
||||
return nozzle_diameters->size() > 1;
|
||||
}
|
||||
|
||||
FilamentMapMode get_prefered_map_mode()
|
||||
{
|
||||
const static std::map<std::string, int> enum_keys_map = ConfigOptionEnum<FilamentMapMode>::get_enum_values();
|
||||
auto &app_config = wxGetApp().app_config;
|
||||
std::string mode_str = app_config->get("prefered_filament_map_mode");
|
||||
auto iter = enum_keys_map.find(mode_str);
|
||||
if (iter == enum_keys_map.end()) {
|
||||
BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format("Could not get prefered_filament_map_mode from app config, use AutoForFlsuh mode");
|
||||
return FilamentMapMode::fmmAutoForFlush;
|
||||
}
|
||||
return FilamentMapMode(iter->second);
|
||||
}
|
||||
|
||||
static void set_prefered_map_mode(FilamentMapMode mode)
|
||||
{
|
||||
const static std::vector<std::string> enum_values = ConfigOptionEnum<FilamentMapMode>::get_enum_names();
|
||||
auto &app_config = wxGetApp().app_config;
|
||||
std::string mode_str;
|
||||
if (mode < enum_values.size()) mode_str = enum_values[mode];
|
||||
|
||||
if (mode_str.empty()) BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format("Set empty prefered_filament_map_mode to app config");
|
||||
app_config->set("prefered_filament_map_mode", mode_str);
|
||||
}
|
||||
|
||||
static bool get_pop_up_remind_flag()
|
||||
{
|
||||
auto &app_config = wxGetApp().app_config;
|
||||
return app_config->get_bool("pop_up_filament_map_mode");
|
||||
}
|
||||
|
||||
static void set_pop_up_remind_flag(bool remind)
|
||||
{
|
||||
auto &app_config = wxGetApp().app_config;
|
||||
app_config->set_bool("pop_up_filament_map_mode", remind);
|
||||
}
|
||||
|
||||
bool is_pop_up_required()
|
||||
{
|
||||
FilamentMapMode mode = get_prefered_map_mode();
|
||||
bool is_manual_mode_ = FilamentMapMode::fmmManual == mode;
|
||||
bool is_multi_extruder_ = is_multi_extruder();
|
||||
return is_multi_extruder_ && is_manual_mode_;
|
||||
}
|
||||
|
||||
FilamentGroupPopup::FilamentGroupPopup(wxWindow *parent) : PopupWindow(parent, wxBORDER_NONE)
|
||||
{
|
||||
wxBoxSizer *top_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
const int horizontal_margin = FromDIP(16);
|
||||
const int vertical_margin = FromDIP(15);
|
||||
const int vertical_padding = FromDIP(12);
|
||||
const int ratio_spacing = FromDIP(4);
|
||||
|
||||
const wxColor background_color = wxColor(255, 255, 255);
|
||||
SetBackgroundColour(background_color);
|
||||
|
||||
radio_btns.resize(ButtonType::btCount);
|
||||
button_labels.resize(ButtonType::btCount);
|
||||
button_desps.resize(ButtonType::btCount);
|
||||
detail_infos.resize(ButtonType::btCount);
|
||||
std::vector<wxString> btn_texts = {AutoForFlushLabel, AutoForMatchLabel, ManualLabel};
|
||||
std::vector<wxString> btn_desps = {AutoForFlushDesp, AutoForMatchDesp, ManualDesp};
|
||||
std::vector<wxString> mode_details = {AutoForFlushDetail, AutoForMatchDetail, ManualDetail};
|
||||
|
||||
top_sizer->AddSpacer(vertical_margin);
|
||||
|
||||
auto checked_bmp = create_scaled_bitmap("map_mode_on", nullptr, 16);
|
||||
auto unchecked_bmp = create_scaled_bitmap("map_mode_off", nullptr, 16);
|
||||
|
||||
for (size_t idx = 0; idx < ButtonType::btCount; ++idx) {
|
||||
wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
radio_btns[idx] = new wxBitmapButton(this, idx, unchecked_bmp, wxDefaultPosition, wxDefaultSize, wxNO_BORDER);
|
||||
radio_btns[idx]->SetBackgroundColour(background_color);
|
||||
|
||||
button_labels[idx] = new wxStaticText(this, wxID_ANY, btn_texts[idx]);
|
||||
button_labels[idx]->SetBackgroundColour(background_color);
|
||||
button_labels[idx]->SetForegroundColour(wxColor("#262E30"));
|
||||
button_labels[idx]->SetFont(Label::Head_14);
|
||||
|
||||
button_desps[idx] = new wxStaticText(this, wxID_ANY, btn_desps[idx]);
|
||||
button_desps[idx]->SetBackgroundColour(background_color);
|
||||
button_desps[idx]->SetForegroundColour(wxColor("#262E30"));
|
||||
button_desps[idx]->SetFont(Label::Body_14);
|
||||
|
||||
button_sizer->Add(radio_btns[idx], 0, wxALIGN_CENTER_VERTICAL);
|
||||
button_sizer->AddSpacer(ratio_spacing);
|
||||
button_sizer->Add(button_labels[idx], 0, wxALIGN_CENTER_VERTICAL);
|
||||
button_sizer->Add(button_desps[idx], 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
wxBoxSizer *label_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
detail_infos[idx] = new wxStaticText(this, wxID_ANY, mode_details[idx]);
|
||||
detail_infos[idx]->SetBackgroundColour(background_color);
|
||||
detail_infos[idx]->SetForegroundColour(wxColor("#6B6B6B"));
|
||||
detail_infos[idx]->SetFont(Label::Body_12);
|
||||
detail_infos[idx]->Wrap(FromDIP(320));
|
||||
|
||||
label_sizer->AddSpacer(radio_btns[idx]->GetRect().width + ratio_spacing);
|
||||
label_sizer->Add(detail_infos[idx], 1, wxEXPAND | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
top_sizer->Add(button_sizer, 0, wxLEFT | wxRIGHT, horizontal_margin);
|
||||
top_sizer->Add(label_sizer, 0, wxLEFT | wxRIGHT, horizontal_margin);
|
||||
top_sizer->AddSpacer(vertical_padding);
|
||||
|
||||
radio_btns[idx]->Bind(wxEVT_BUTTON, [this, idx](wxCommandEvent &event) {
|
||||
event.SetInt(idx);
|
||||
OnRadioBtn(event);
|
||||
});
|
||||
|
||||
radio_btns[idx]->Bind(wxEVT_ENTER_WINDOW, [this, idx](wxMouseEvent &) { UpdateButtonStatus(idx); });
|
||||
|
||||
radio_btns[idx]->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent &) { UpdateButtonStatus(); });
|
||||
|
||||
button_labels[idx]->Bind(wxEVT_LEFT_UP, [this, idx](wxMouseEvent &) {
|
||||
wxCommandEvent event;
|
||||
event.SetInt(idx);
|
||||
OnRadioBtn(event);
|
||||
});
|
||||
|
||||
button_labels[idx]->Bind(wxEVT_ENTER_WINDOW, [this, idx](wxMouseEvent &) { UpdateButtonStatus(idx); });
|
||||
button_labels[idx]->Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent &) { UpdateButtonStatus(); });
|
||||
}
|
||||
|
||||
{
|
||||
wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wiki_link = new wxStaticText(this, wxID_ANY, _L("More info on wiki"));
|
||||
wiki_link->SetBackgroundColour(background_color);
|
||||
wiki_link->SetForegroundColour(wxColor("#00AE42"));
|
||||
wiki_link->SetFont(Label::Body_12.Underlined());
|
||||
wiki_link->SetCursor(wxCursor(wxCURSOR_HAND));
|
||||
wiki_link->Bind(wxEVT_LEFT_DOWN, [](wxMouseEvent &) { wxLaunchDefaultBrowser("http//:example.com"); });
|
||||
|
||||
remind_checkbox = new wxCheckBox(this, wxID_ANY, _L("Don't remind me again"));
|
||||
remind_checkbox->SetBackgroundColour(background_color);
|
||||
remind_checkbox->SetForegroundColour(wxColor("#6B6B6B"));
|
||||
remind_checkbox->SetFont(Label::Body_12);
|
||||
remind_checkbox->Bind(wxEVT_CHECKBOX, &FilamentGroupPopup::OnRemindBtn, this);
|
||||
|
||||
button_sizer->Add(wiki_link, 0, wxLEFT, horizontal_margin);
|
||||
button_sizer->AddStretchSpacer();
|
||||
button_sizer->Add(remind_checkbox, 0, wxRIGHT, horizontal_margin);
|
||||
|
||||
top_sizer->Add(button_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, horizontal_margin);
|
||||
}
|
||||
|
||||
top_sizer->AddSpacer(vertical_margin);
|
||||
SetSizerAndFit(top_sizer);
|
||||
|
||||
m_mode = get_prefered_map_mode();
|
||||
m_timer = new wxTimer(this);
|
||||
|
||||
GUI::wxGetApp().UpdateDarkUIWin(this);
|
||||
|
||||
Bind(wxEVT_TIMER, &FilamentGroupPopup::OnTimer, this);
|
||||
Bind(wxEVT_ENTER_WINDOW, &FilamentGroupPopup::OnEnterWindow, this);
|
||||
Bind(wxEVT_LEAVE_WINDOW, &FilamentGroupPopup::OnLeaveWindow, this);
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::DrawRoundedCorner(int radius)
|
||||
{
|
||||
#ifdef __WIN32__
|
||||
HWND hwnd = GetHWND();
|
||||
if (hwnd) {
|
||||
HRGN hrgn = CreateRoundRectRgn(0, 0, GetRect().GetWidth(), GetRect().GetHeight(), radius, radius);
|
||||
SetWindowRgn(hwnd, hrgn, TRUE);
|
||||
|
||||
SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
|
||||
SetLayeredWindowAttributes(hwnd, 0, 0, LWA_COLORKEY);
|
||||
}
|
||||
#else
|
||||
wxClientDC dc(this);
|
||||
wxGraphicsContext *gc = wxGraphicsContext::Create(dc);
|
||||
if (gc) {
|
||||
gc->SetBrush(*wxWHITE_BRUSH);
|
||||
gc->SetPen(*wxTRANSPARENT_PEN);
|
||||
wxRect rect(0, 0, GetSize().GetWidth(), GetSize().GetHeight());
|
||||
wxGraphicsPath path = wxGraphicsRenderer::GetDefaultRenderer()->CreatePath();
|
||||
path.AddRoundedRectangle(0, 0, rect.width, rect.height, radius);
|
||||
gc->DrawPath(path);
|
||||
delete gc;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::Init(bool connect_status)
|
||||
{
|
||||
radio_btns[ButtonType::btForMatch]->Enable(connect_status);
|
||||
button_labels[ButtonType::btForMatch]->Enable(connect_status);
|
||||
|
||||
m_mode = get_prefered_map_mode();
|
||||
|
||||
wxCheckBoxState check_state = get_pop_up_remind_flag() ? wxCheckBoxState::wxCHK_UNCHECKED : wxCheckBoxState::wxCHK_CHECKED;
|
||||
remind_checkbox->Set3StateValue(check_state);
|
||||
|
||||
UpdateButtonStatus();
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::tryPopup(bool connect_status)
|
||||
{
|
||||
auto canPopup = [this]() {
|
||||
bool is_multi_extruder_ = is_multi_extruder();
|
||||
bool pop_up_flag = get_pop_up_remind_flag();
|
||||
return is_multi_extruder_ && pop_up_flag;
|
||||
};
|
||||
|
||||
if (canPopup()) {
|
||||
DrawRoundedCorner(16);
|
||||
Init(connect_status);
|
||||
ResetTimer();
|
||||
PopupWindow::Popup();
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::tryClose() { StartTimer(); }
|
||||
|
||||
void FilamentGroupPopup::StartTimer() { m_timer->StartOnce(300); }
|
||||
|
||||
void FilamentGroupPopup::ResetTimer()
|
||||
{
|
||||
if (m_timer->IsRunning()) { m_timer->Stop(); }
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::OnRadioBtn(wxCommandEvent &event)
|
||||
{
|
||||
m_mode = mode_list.at(event.GetInt());
|
||||
|
||||
set_prefered_map_mode(m_mode);
|
||||
|
||||
UpdateButtonStatus(m_mode);
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::OnRemindBtn(wxCommandEvent &event)
|
||||
{
|
||||
bool is_checked = remind_checkbox->IsChecked();
|
||||
set_pop_up_remind_flag(!is_checked);
|
||||
|
||||
if (is_checked) {
|
||||
MessageDialog dialog(nullptr, _L("No further pop up.You can go to \"Preferences\" to reopen the pop up."), _L("Tips"), wxICON_INFORMATION | wxOK);
|
||||
dialog.ShowModal();
|
||||
Dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::OnTimer(wxTimerEvent &event) { Dismiss(); }
|
||||
|
||||
void FilamentGroupPopup::OnLeaveWindow(wxMouseEvent &)
|
||||
{
|
||||
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
|
||||
if (this->GetClientRect().Contains(pos)) return;
|
||||
StartTimer();
|
||||
}
|
||||
|
||||
void FilamentGroupPopup::OnEnterWindow(wxMouseEvent &) { ResetTimer(); }
|
||||
|
||||
void FilamentGroupPopup::UpdateButtonStatus(int hover_idx)
|
||||
{
|
||||
auto checked_bmp = create_scaled_bitmap("map_mode_on", nullptr, 16);
|
||||
auto unchecked_bmp = create_scaled_bitmap("map_mode_off", nullptr, 16);
|
||||
auto checked_hover_bmp = create_scaled_bitmap("map_mode_on_hovered", nullptr);
|
||||
auto unchecked_hover_bmp = create_scaled_bitmap("map_mode_off_hovered", nullptr);
|
||||
|
||||
for (int i = 0; i < ButtonType::btCount; ++i) {
|
||||
// process checked and unchecked status
|
||||
if (mode_list.at(i) == m_mode) {
|
||||
if (i == hover_idx)
|
||||
radio_btns[i]->SetBitmap(checked_hover_bmp);
|
||||
else
|
||||
radio_btns[i]->SetBitmap(checked_bmp);
|
||||
button_labels[i]->SetFont(Label::Head_14);
|
||||
} else {
|
||||
if (i == hover_idx)
|
||||
radio_btns[i]->SetBitmap(unchecked_hover_bmp);
|
||||
else
|
||||
radio_btns[i]->SetBitmap(unchecked_bmp);
|
||||
button_labels[i]->SetFont(Label::Body_14);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_mode == FilamentMapMode::fmmAutoForMatch)
|
||||
remind_checkbox->Enable(false);
|
||||
else
|
||||
remind_checkbox->Enable(true);
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
54
src/slic3r/GUI/FilamentGroupPopup.hpp
Normal file
54
src/slic3r/GUI/FilamentGroupPopup.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef FILAMENT_GROUP_HOVER_HPP
|
||||
#define FILAMENT_GROUP_HOVER_HPP
|
||||
|
||||
#include <wx/graphics.h>
|
||||
#include <wx/hyperlink.h>
|
||||
#include "wxExtensions.hpp"
|
||||
#include "Widgets/PopupWindow.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
bool is_pop_up_required();
|
||||
FilamentMapMode get_prefered_map_mode();
|
||||
|
||||
class FilamentGroupPopup : public PopupWindow
|
||||
{
|
||||
public:
|
||||
FilamentGroupPopup(wxWindow *parent);
|
||||
void tryPopup(bool connect_status);
|
||||
void tryClose();
|
||||
|
||||
FilamentMapMode GetSelectedMode() const { return m_mode; }
|
||||
|
||||
private:
|
||||
void StartTimer();
|
||||
void ResetTimer();
|
||||
|
||||
void OnRadioBtn(wxCommandEvent &event);
|
||||
void OnLeaveWindow(wxMouseEvent &);
|
||||
void OnEnterWindow(wxMouseEvent &);
|
||||
void OnTimer(wxTimerEvent &event);
|
||||
void OnRemindBtn(wxCommandEvent &event);
|
||||
|
||||
void Init(bool connect_status);
|
||||
void UpdateButtonStatus(int hover_idx = -1);
|
||||
void DrawRoundedCorner(int radius);
|
||||
|
||||
private:
|
||||
enum ButtonType { btForFlush, btForMatch, btManual, btCount };
|
||||
|
||||
const std::vector<FilamentMapMode> mode_list = {fmmAutoForFlush, fmmAutoForMatch, fmmManual};
|
||||
|
||||
FilamentMapMode m_mode;
|
||||
wxTimer *m_timer;
|
||||
|
||||
std::vector<wxBitmapButton *> radio_btns;
|
||||
std::vector<wxStaticText *> button_labels;
|
||||
std::vector<wxStaticText *> button_desps;
|
||||
std::vector<wxStaticText *> detail_infos;
|
||||
|
||||
wxStaticText *wiki_link;
|
||||
wxCheckBox *remind_checkbox;
|
||||
};
|
||||
}} // namespace Slic3r::GUI
|
||||
#endif
|
||||
@@ -3,210 +3,118 @@
|
||||
#include "Widgets/Button.hpp"
|
||||
#include "Widgets/SwitchButton.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "CapsuleButton.hpp"
|
||||
#include "SelectMachine.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
const wxString manual_tips = _L("we will slice according to this grouping method:");
|
||||
|
||||
const wxString manual_below_tips = _L("Tips:\n"
|
||||
"You can drag the filaments to change which extruder they are assigned to.\n"
|
||||
"But your filament arrangement may not be the most filament-efficient.");
|
||||
|
||||
const wxString auto_tips = _L("Automatic filament grouping will be performed to reduce flushing consumption\n"
|
||||
"and filament changes during the slicing process.\n"
|
||||
"The recommended results will be displayed below after slicing:");
|
||||
|
||||
const wxString auto_tips_with_result = _L("Automatic filament grouping will be performed to reduce flushing consumption\n"
|
||||
"and filament changes during the slicing process.\n"
|
||||
"The recommended results are shown below:");
|
||||
|
||||
wxColour hex_to_color(const std::string &hex)
|
||||
{
|
||||
if ((hex.length() != 7 && hex.length() != 9) || hex[0] != '#') {
|
||||
throw std::invalid_argument("Invalid hex color format");
|
||||
}
|
||||
|
||||
unsigned int r, g, b, a = 255;
|
||||
std::stringstream ss;
|
||||
|
||||
// r
|
||||
ss << std::hex << hex.substr(1, 2);
|
||||
ss >> r;
|
||||
ss.clear();
|
||||
ss.str("");
|
||||
|
||||
// g
|
||||
ss << std::hex << hex.substr(3, 2);
|
||||
ss >> g;
|
||||
ss.clear();
|
||||
ss.str("");
|
||||
|
||||
// b
|
||||
ss << std::hex << hex.substr(5, 2);
|
||||
ss >> b;
|
||||
|
||||
// a
|
||||
if (hex.length() == 9) {
|
||||
ss.clear();
|
||||
ss.str("");
|
||||
ss << std::hex << hex.substr(7, 2);
|
||||
ss >> a;
|
||||
}
|
||||
|
||||
return wxColour(r, g, b, a);
|
||||
}
|
||||
|
||||
FilamentMapDialog::FilamentMapDialog(wxWindow *parent,
|
||||
const DynamicPrintConfig *config,
|
||||
const std::vector<int> &filament_map,
|
||||
const std::vector<int> &extruders,
|
||||
bool is_auto,
|
||||
bool has_auto_result
|
||||
)
|
||||
FilamentMapDialog::FilamentMapDialog(wxWindow *parent,
|
||||
const std::vector<std::string> &filament_color,
|
||||
const std::vector<int> &filament_map,
|
||||
const std::vector<int> &filaments,
|
||||
const FilamentMapMode mode,
|
||||
bool show_default)
|
||||
: wxDialog(parent, wxID_ANY, _L("Filament arrangement method of plate"), wxDefaultPosition, wxSize(2000, 1500))
|
||||
, m_config(config)
|
||||
, m_filament_color(filament_color)
|
||||
, m_filament_map(filament_map)
|
||||
, m_has_auto_result(has_auto_result)
|
||||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
||||
SetMinSize(wxSize(FromDIP(550), -1));
|
||||
SetMaxSize(wxSize(FromDIP(550), -1));
|
||||
|
||||
if (mode < fmmManual)
|
||||
m_page_type = PageType::ptAuto;
|
||||
else if (mode == fmmManual)
|
||||
m_page_type = PageType::ptManual;
|
||||
else
|
||||
m_page_type = PageType::ptDefault;
|
||||
|
||||
wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
main_sizer->AddSpacer(FromDIP(22));
|
||||
|
||||
m_mode_switch_btn = new SwitchButton(this);
|
||||
m_mode_switch_btn->SetMaxSize({em_unit(this) * 12, -1});
|
||||
m_mode_switch_btn->SetLabels(_L("Customize"), _L("Auto"));
|
||||
m_mode_switch_btn->Bind(wxEVT_TOGGLEBUTTON, &FilamentMapDialog::on_switch_mode, this);
|
||||
m_mode_switch_btn->SetValue(is_auto);
|
||||
main_sizer->Add(m_mode_switch_btn, 0, wxCENTER | wxALL, 10);
|
||||
wxBoxSizer *mode_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_tip_text = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
main_sizer->Add(m_tip_text, 0, wxALIGN_LEFT | wxLEFT, 15);
|
||||
m_auto_btn = new CapsuleButton(this, PageType::ptAuto, _L("Auto"), false);
|
||||
m_manual_btn = new CapsuleButton(this, PageType::ptManual, _L("Custom"), false);
|
||||
if (show_default)
|
||||
m_default_btn = new CapsuleButton(this, PageType::ptDefault, _L("Default"), true);
|
||||
else
|
||||
m_default_btn = nullptr;
|
||||
|
||||
m_extruder_panel_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
const int button_padding = FromDIP(2);
|
||||
mode_sizer->AddStretchSpacer();
|
||||
mode_sizer->Add(m_auto_btn, 1, wxALIGN_CENTER | wxLEFT | wxRIGHT, button_padding);
|
||||
mode_sizer->Add(m_manual_btn, 1, wxALIGN_CENTER | wxLEFT | wxRIGHT, button_padding);
|
||||
if (show_default) mode_sizer->Add(m_default_btn, 1, wxALIGN_CENTER | wxLEFT | wxRIGHT, button_padding);
|
||||
mode_sizer->AddStretchSpacer();
|
||||
|
||||
m_manual_left_panel = new DragDropPanel(this, wxT("Left nozzle:"), false);
|
||||
m_manual_right_panel = new DragDropPanel(this, wxT("Right nozzle:"), false);
|
||||
main_sizer->Add(mode_sizer, 0, wxEXPAND);
|
||||
main_sizer->AddSpacer(FromDIP(24));
|
||||
|
||||
std::vector<std::string> filament_color = config->option<ConfigOptionStrings>("filament_colour")->values;
|
||||
for (size_t i = 0; i < filament_map.size(); ++i) {
|
||||
auto iter = std::find(extruders.begin(), extruders.end(), i + 1);
|
||||
if (iter == extruders.end())
|
||||
continue;
|
||||
auto panel_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
FilamentMapMode default_auto_mode = (mode < FilamentMapMode::fmmManual ? mode : FilamentMapMode::fmmAutoForFlush);
|
||||
m_manual_map_panel = new FilamentMapManualPanel(this, m_filament_color, filaments, filament_map);
|
||||
m_auto_map_panel = new FilamentMapAutoPanel(this, default_auto_mode);
|
||||
if (show_default)
|
||||
m_default_map_panel = new FilamentMapDefaultPanel(this);
|
||||
else
|
||||
m_default_map_panel = nullptr;
|
||||
|
||||
if (filament_map[i] == 1) {
|
||||
m_manual_left_panel->AddColorBlock(hex_to_color(filament_color[i]), i + 1);
|
||||
}
|
||||
else if (filament_map[i] == 2) {
|
||||
m_manual_right_panel->AddColorBlock(hex_to_color(filament_color[i]), i + 1);
|
||||
}
|
||||
else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
panel_sizer->Add(m_manual_map_panel, 0, wxALIGN_CENTER | wxEXPAND);
|
||||
panel_sizer->Add(m_auto_map_panel, 0, wxALIGN_CENTER | wxEXPAND);
|
||||
if (show_default) panel_sizer->Add(m_default_map_panel, 0, wxALIGN_CENTER | wxEXPAND);
|
||||
main_sizer->Add(panel_sizer, 0, wxEXPAND);
|
||||
|
||||
m_switch_filament_btn = new ScalableButton(this, wxID_ANY, "switch_filament_maps");
|
||||
m_switch_filament_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_switch_filaments, this);
|
||||
m_switch_filament_btn->SetCanFocus(false);
|
||||
// just for placeholder for auto
|
||||
m_switch_filament_btn_auto = new ScalableButton(this, wxID_ANY, "switch_filament_maps");
|
||||
m_switch_filament_btn_auto->Enable(false);
|
||||
|
||||
m_extruder_panel_sizer->Add(m_manual_left_panel, 1, wxEXPAND | wxALL, 5);
|
||||
m_extruder_panel_sizer->Add(m_switch_filament_btn, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
|
||||
m_extruder_panel_sizer->Add(m_manual_right_panel, 1, wxEXPAND | wxALL, 5);
|
||||
m_manual_left_panel->Layout();
|
||||
m_manual_left_panel->Fit();
|
||||
m_manual_right_panel->Layout();
|
||||
m_manual_right_panel->Fit();
|
||||
|
||||
m_auto_left_panel = new DragDropPanel(this, wxT("Left nozzle:"), true);
|
||||
m_auto_right_panel = new DragDropPanel(this, wxT("Right nozzle:"), true);
|
||||
|
||||
for (size_t i = 0; i < filament_map.size(); ++i) {
|
||||
auto iter = std::find(extruders.begin(), extruders.end(), i + 1);
|
||||
if (iter == extruders.end()) continue;
|
||||
|
||||
if (filament_map[i] == 1) {
|
||||
m_auto_left_panel->AddColorBlock(hex_to_color(filament_color[i]), i + 1);
|
||||
} else if (filament_map[i] == 2) {
|
||||
m_auto_right_panel->AddColorBlock(hex_to_color(filament_color[i]), i + 1);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
m_extruder_panel_sizer->Add(m_auto_left_panel, 1, wxEXPAND | wxALL, 5);
|
||||
m_extruder_panel_sizer->Add(m_switch_filament_btn_auto, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
|
||||
m_extruder_panel_sizer->Add(m_auto_right_panel, 1, wxEXPAND | wxALL, 5);
|
||||
m_auto_left_panel->Layout();
|
||||
m_auto_left_panel->Fit();
|
||||
m_auto_right_panel->Layout();
|
||||
m_auto_right_panel->Fit();
|
||||
|
||||
main_sizer->Add(m_extruder_panel_sizer, 1, wxEXPAND | wxALL, 10);
|
||||
|
||||
m_below_tip_text = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
|
||||
m_below_tip_text->SetLabel(manual_below_tips);
|
||||
main_sizer->Add(m_below_tip_text, 0, wxALIGN_LEFT | wxLEFT, 15);
|
||||
|
||||
if (is_auto) {
|
||||
m_manual_left_panel->Hide();
|
||||
m_manual_right_panel->Hide();
|
||||
m_switch_filament_btn->Hide();
|
||||
m_below_tip_text->Hide();
|
||||
if (m_has_auto_result) {
|
||||
m_tip_text->SetLabel(auto_tips_with_result);
|
||||
}
|
||||
else {
|
||||
m_auto_left_panel->Hide();
|
||||
m_auto_right_panel->Hide();
|
||||
m_switch_filament_btn_auto->Hide();
|
||||
m_tip_text->SetLabel(auto_tips);
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_auto_left_panel->Hide();
|
||||
m_auto_right_panel->Hide();
|
||||
m_switch_filament_btn_auto->Hide();
|
||||
m_tip_text->SetLabel(manual_tips);
|
||||
m_below_tip_text->Show();
|
||||
}
|
||||
|
||||
wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
Button * ok_btn = new Button(this, _L("OK"));
|
||||
Button * cancel_btn = new Button(this, _L("Cancel"));
|
||||
button_sizer->Add(ok_btn, 0, wxALL, 5);
|
||||
button_sizer->Add(cancel_btn, 0, wxALL, 5);
|
||||
wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_ok_btn = new Button(this, _L("OK"));
|
||||
m_cancel_btn = new Button(this, _L("Cancel"));
|
||||
button_sizer->Add(m_ok_btn, 0, wxALL, 5);
|
||||
button_sizer->Add(m_cancel_btn, 0, wxALL, 5);
|
||||
main_sizer->Add(button_sizer, 0, wxALIGN_CENTER | wxALL, 10);
|
||||
|
||||
ok_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_ok, this);
|
||||
cancel_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_cancle, this);
|
||||
m_ok_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_ok, this);
|
||||
m_cancel_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_cancle, this);
|
||||
|
||||
m_auto_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_switch_mode, this);
|
||||
m_manual_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_switch_mode, this);
|
||||
if (show_default) m_default_btn->Bind(wxEVT_BUTTON, &FilamentMapDialog::on_switch_mode, this);
|
||||
|
||||
SetSizer(main_sizer);
|
||||
Layout();
|
||||
Fit();
|
||||
|
||||
CenterOnParent();
|
||||
GUI::wxGetApp().UpdateDarkUIWin(this);
|
||||
}
|
||||
|
||||
bool FilamentMapDialog::is_auto() const
|
||||
FilamentMapMode FilamentMapDialog::get_mode()
|
||||
{
|
||||
if (m_mode_switch_btn->GetValue()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (m_page_type == PageType::ptAuto)
|
||||
return m_auto_map_panel->GetMode();
|
||||
if (m_page_type == PageType::ptManual)
|
||||
return fmmManual;
|
||||
return fmmDefault;
|
||||
}
|
||||
|
||||
int FilamentMapDialog::ShowModal()
|
||||
{
|
||||
update_panel_status(m_page_type);
|
||||
return wxDialog::ShowModal();
|
||||
}
|
||||
|
||||
void FilamentMapDialog::on_ok(wxCommandEvent &event)
|
||||
{
|
||||
if (!is_auto()) {
|
||||
std::vector<int> left_filaments = m_manual_left_panel->GetAllFilaments();
|
||||
std::vector<int> right_filaments = m_manual_right_panel->GetAllFilaments();
|
||||
if (m_page_type == PageType::ptManual) {
|
||||
std::vector<int> left_filaments = m_manual_map_panel->GetLeftFilaments();
|
||||
std::vector<int> right_filaments = m_manual_map_panel->GetRightFilaments();
|
||||
|
||||
for (int i = 0; i < m_filament_map.size(); ++i) {
|
||||
if (std::find(left_filaments.begin(), left_filaments.end(), i + 1) != left_filaments.end()) {
|
||||
m_filament_map[i] = 1;
|
||||
} else if (std::find(right_filaments.begin(), right_filaments.end(), i + 1) != right_filaments.end()) {
|
||||
}
|
||||
else if (std::find(right_filaments.begin(), right_filaments.end(), i + 1) != right_filaments.end()) {
|
||||
m_filament_map[i] = 2;
|
||||
}
|
||||
}
|
||||
@@ -215,63 +123,62 @@ void FilamentMapDialog::on_ok(wxCommandEvent &event)
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
void FilamentMapDialog::on_cancle(wxCommandEvent &event)
|
||||
void FilamentMapDialog::on_cancle(wxCommandEvent &event) { EndModal(wxID_CANCEL); }
|
||||
|
||||
void FilamentMapDialog::update_panel_status(PageType page)
|
||||
{
|
||||
EndModal(wxID_CANCEL);
|
||||
if (page == PageType::ptDefault) {
|
||||
if (m_default_btn && m_default_map_panel) {
|
||||
m_default_btn->Select(true);
|
||||
m_default_map_panel->Show();
|
||||
}
|
||||
|
||||
m_manual_btn->Select(false);
|
||||
m_manual_map_panel->Hide();
|
||||
|
||||
m_auto_btn->Select(false);
|
||||
m_auto_map_panel->Hide();
|
||||
}
|
||||
if (page == PageType::ptManual) {
|
||||
if (m_default_btn && m_default_map_panel) {
|
||||
m_default_btn->Select(false);
|
||||
m_default_map_panel->Hide();
|
||||
}
|
||||
m_manual_btn->Select(true);
|
||||
m_manual_map_panel->Show();
|
||||
|
||||
m_auto_btn->Select(false);
|
||||
m_auto_map_panel->Hide();
|
||||
}
|
||||
if (page == PageType::ptAuto) {
|
||||
if (m_default_btn && m_default_map_panel) {
|
||||
m_default_btn->Select(false);
|
||||
m_default_map_panel->Hide();
|
||||
}
|
||||
m_manual_btn->Select(false);
|
||||
m_manual_map_panel->Hide();
|
||||
|
||||
m_auto_btn->Select(true);
|
||||
m_auto_map_panel->Show();
|
||||
}
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
||||
void FilamentMapDialog::on_switch_mode(wxCommandEvent &event)
|
||||
{
|
||||
bool value = dynamic_cast<SwitchButton *>(event.GetEventObject())->GetValue();
|
||||
if (value) { // auto
|
||||
m_manual_left_panel->Hide();
|
||||
m_manual_right_panel->Hide();
|
||||
m_switch_filament_btn->Hide();
|
||||
m_below_tip_text->Hide();
|
||||
if (m_has_auto_result) {
|
||||
m_auto_left_panel->Show();
|
||||
m_auto_right_panel->Show();
|
||||
m_switch_filament_btn_auto->Show();
|
||||
m_tip_text->SetLabel(auto_tips_with_result);
|
||||
}
|
||||
else {
|
||||
m_auto_left_panel->Hide();
|
||||
m_auto_right_panel->Hide();
|
||||
m_switch_filament_btn_auto->Hide();
|
||||
m_tip_text->SetLabel(auto_tips);
|
||||
}
|
||||
} else { // manual
|
||||
m_manual_left_panel->Show();
|
||||
m_manual_right_panel->Show();
|
||||
m_switch_filament_btn->Show();
|
||||
m_below_tip_text->Show();
|
||||
int win_id = event.GetId();
|
||||
m_page_type = PageType(win_id);
|
||||
|
||||
m_auto_left_panel->Hide();
|
||||
m_auto_right_panel->Hide();
|
||||
m_switch_filament_btn_auto->Hide();
|
||||
|
||||
m_tip_text->SetLabel(manual_tips);
|
||||
}
|
||||
Layout();
|
||||
Fit();
|
||||
update_panel_status(m_page_type);
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void FilamentMapDialog::on_switch_filaments(wxCommandEvent &event)
|
||||
void FilamentMapDialog::set_modal_btn_labels(const wxString &ok_label, const wxString &cancel_label)
|
||||
{
|
||||
std::vector<ColorPanel *> left_blocks = m_manual_left_panel->get_filament_blocks();
|
||||
std::vector<ColorPanel *> right_blocks = m_manual_right_panel->get_filament_blocks();
|
||||
|
||||
for (ColorPanel* block : left_blocks) {
|
||||
m_manual_right_panel->AddColorBlock(block->GetColor(), block->GetFilamentId(), false);
|
||||
m_manual_left_panel->RemoveColorBlock(block, false);
|
||||
}
|
||||
for (auto block : right_blocks) {
|
||||
m_manual_left_panel->AddColorBlock(block->GetColor(), block->GetFilamentId(), false);
|
||||
m_manual_right_panel->RemoveColorBlock(block, false);
|
||||
}
|
||||
Layout();
|
||||
Fit();
|
||||
m_ok_btn->SetLabel(ok_label);
|
||||
m_cancel_btn->SetLabel(cancel_label);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
#define slic3r_FilamentMapDialog_hpp_
|
||||
|
||||
#include "GUI.hpp"
|
||||
#include "FilamentMapPanel.hpp"
|
||||
#include <wx/simplebook.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/timer.h>
|
||||
#include <vector>
|
||||
#include "SelectMachine.hpp"
|
||||
#include "CapsuleButton.hpp"
|
||||
|
||||
class SwitchButton;
|
||||
class ScalableButton;
|
||||
@@ -17,42 +20,52 @@ class DynamicPrintConfig;
|
||||
|
||||
namespace GUI {
|
||||
class DragDropPanel;
|
||||
|
||||
class FilamentMapDialog : public wxDialog
|
||||
{
|
||||
enum PageType {
|
||||
ptAuto,
|
||||
ptManual,
|
||||
ptDefault
|
||||
};
|
||||
public:
|
||||
FilamentMapDialog(wxWindow *parent,
|
||||
const DynamicPrintConfig *config,
|
||||
const std::vector<std::string>& filament_color,
|
||||
const std::vector<int> &filament_map,
|
||||
const std::vector<int> &extruders,
|
||||
bool is_auto,
|
||||
bool has_auto_result
|
||||
const std::vector<int> &filaments,
|
||||
const FilamentMapMode mode,
|
||||
bool show_default=true
|
||||
);
|
||||
|
||||
bool is_auto() const;
|
||||
FilamentMapMode get_mode();
|
||||
const std::vector<int>& get_filament_maps() const { return m_filament_map; }
|
||||
|
||||
int ShowModal();
|
||||
void set_modal_btn_labels(const wxString& left_label, const wxString& right_label);
|
||||
private:
|
||||
void on_ok(wxCommandEvent &event);
|
||||
void on_cancle(wxCommandEvent &event);
|
||||
void on_switch_mode(wxCommandEvent &event);
|
||||
void on_switch_filaments(wxCommandEvent &event);
|
||||
|
||||
void update_panel_status(PageType page);
|
||||
|
||||
private:
|
||||
FilamentMapManualPanel* m_manual_map_panel;
|
||||
FilamentMapAutoPanel* m_auto_map_panel;
|
||||
FilamentMapDefaultPanel* m_default_map_panel;
|
||||
|
||||
CapsuleButton* m_auto_btn;
|
||||
CapsuleButton* m_manual_btn;
|
||||
CapsuleButton* m_default_btn;
|
||||
|
||||
Button* m_ok_btn;
|
||||
Button* m_cancel_btn;
|
||||
|
||||
PageType m_page_type;
|
||||
|
||||
private:
|
||||
wxStaticText * m_tip_text;
|
||||
wxStaticText * m_below_tip_text;
|
||||
SwitchButton * m_mode_switch_btn;
|
||||
wxBoxSizer * m_extruder_panel_sizer;
|
||||
DragDropPanel* m_manual_left_panel;
|
||||
DragDropPanel* m_manual_right_panel;
|
||||
DragDropPanel* m_auto_left_panel;
|
||||
DragDropPanel* m_auto_right_panel;
|
||||
ScalableButton* m_switch_filament_btn;
|
||||
ScalableButton* m_switch_filament_btn_auto; // for placeholder
|
||||
|
||||
private:
|
||||
const DynamicPrintConfig* m_config;
|
||||
std::vector<int> m_filament_map;
|
||||
bool m_has_auto_result;
|
||||
std::vector<std::string> m_filament_color;
|
||||
};
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
324
src/slic3r/GUI/FilamentMapPanel.cpp
Normal file
324
src/slic3r/GUI/FilamentMapPanel.cpp
Normal file
@@ -0,0 +1,324 @@
|
||||
#include "FilamentMapPanel.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "wx/graphics.h"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
FilamentMapManualPanel::FilamentMapManualPanel(wxWindow *parent,
|
||||
const std::vector<std::string> &color,
|
||||
const std::vector<int> &filament_list,
|
||||
const std::vector<int> &filament_map)
|
||||
: wxPanel(parent), m_filament_map(filament_map), m_filament_color(color), m_filament_list(filament_list)
|
||||
{
|
||||
SetBackgroundColour(wxColor(255, 255, 255));
|
||||
|
||||
auto top_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_description = new Label(this, _L("We will slice according to this grouping method:"));
|
||||
top_sizer->Add(m_description, 0, wxALIGN_LEFT | wxLEFT, FromDIP(15));
|
||||
top_sizer->AddSpacer(FromDIP(8));
|
||||
|
||||
auto drag_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_left_panel = new DragDropPanel(this, wxT("Left Nozzle:"), false);
|
||||
m_right_panel = new DragDropPanel(this, wxT("Right Nozzle:"), false);
|
||||
m_switch_btn = new ScalableButton(this, wxID_ANY, "switch_filament_maps");
|
||||
|
||||
for (size_t idx = 0; idx < m_filament_map.size(); ++idx) {
|
||||
auto iter = std::find(m_filament_list.begin(), m_filament_list.end(), idx + 1);
|
||||
if (iter == m_filament_list.end()) continue;
|
||||
wxColor color = Hex2Color(m_filament_color[idx]);
|
||||
if (m_filament_map[idx] == 1) {
|
||||
m_left_panel->AddColorBlock(color, idx + 1);
|
||||
} else {
|
||||
assert(m_filament_map[idx] == 2);
|
||||
m_right_panel->AddColorBlock(color, idx + 1);
|
||||
}
|
||||
}
|
||||
drag_sizer->Add(m_left_panel, 1, wxALIGN_CENTER | wxEXPAND | wxLEFT, FromDIP(20));
|
||||
drag_sizer->AddSpacer(FromDIP(7));
|
||||
drag_sizer->Add(m_switch_btn, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(1));
|
||||
drag_sizer->AddSpacer(FromDIP(7));
|
||||
drag_sizer->Add(m_right_panel, 1, wxALIGN_CENTER | wxEXPAND | wxRIGHT, FromDIP(20));
|
||||
|
||||
top_sizer->Add(drag_sizer, 0, wxALIGN_CENTER|wxEXPAND);
|
||||
|
||||
m_tips = new Label(this, _L("Tips: You can drag the filaments to change which extruder they are assigned to.\n"
|
||||
"But your filament arrangement may not be the most filament-efficient."));
|
||||
m_tips->SetFont(Label::Body_14);
|
||||
m_tips->SetForegroundColour(wxColour("#6B6B6B"));
|
||||
top_sizer->AddSpacer(FromDIP(8));
|
||||
top_sizer->Add(m_tips, 0, wxALIGN_LEFT | wxLEFT, FromDIP(15));
|
||||
|
||||
m_switch_btn->Bind(wxEVT_BUTTON, &FilamentMapManualPanel::OnSwitchFilament, this);
|
||||
|
||||
SetSizer(top_sizer);
|
||||
Layout();
|
||||
Fit();
|
||||
GUI::wxGetApp().UpdateDarkUIWin(this);
|
||||
}
|
||||
|
||||
void FilamentMapManualPanel::OnSwitchFilament(wxCommandEvent &)
|
||||
{
|
||||
auto left_blocks = m_left_panel->get_filament_blocks();
|
||||
auto right_blocks = m_right_panel->get_filament_blocks();
|
||||
|
||||
for (auto &block : left_blocks) {
|
||||
m_right_panel->AddColorBlock(block->GetColor(), block->GetFilamentId(), false);
|
||||
m_left_panel->RemoveColorBlock(block, false);
|
||||
}
|
||||
|
||||
for (auto &block : right_blocks) {
|
||||
m_left_panel->AddColorBlock(block->GetColor(), block->GetFilamentId(), false);
|
||||
m_right_panel->RemoveColorBlock(block, false);
|
||||
}
|
||||
|
||||
Layout();
|
||||
Fit();
|
||||
}
|
||||
|
||||
void FilamentMapManualPanel::Hide()
|
||||
{
|
||||
m_left_panel->Hide();
|
||||
m_right_panel->Hide();
|
||||
m_switch_btn->Hide();
|
||||
wxPanel::Hide();
|
||||
}
|
||||
|
||||
void FilamentMapManualPanel::Show()
|
||||
{
|
||||
m_left_panel->Show();
|
||||
m_right_panel->Show();
|
||||
m_switch_btn->Show();
|
||||
wxPanel::Show();
|
||||
}
|
||||
|
||||
GUI::FilamentMapBtnPanel::FilamentMapBtnPanel(wxWindow *parent, const wxString &label, const wxString &detail, const std::string &icon) : wxPanel(parent)
|
||||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
SetBackgroundStyle(wxBG_STYLE_PAINT);
|
||||
m_hover = false;
|
||||
|
||||
const int horizontal_margin = FromDIP(12);
|
||||
|
||||
auto sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
auto bmp = create_scaled_bitmap(icon, nullptr, 20);
|
||||
m_btn = new wxBitmapButton(this, wxID_ANY, bmp, wxDefaultPosition, wxDefaultSize, wxNO_BORDER);
|
||||
m_btn->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
m_label = new wxStaticText(this, wxID_ANY, label);
|
||||
m_label->SetFont(Label::Head_14);
|
||||
|
||||
auto label_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
label_sizer->AddStretchSpacer();
|
||||
label_sizer->Add(m_btn, 0, wxALIGN_CENTER|wxEXPAND);
|
||||
label_sizer->Add(m_label, 0, wxALIGN_CENTER|wxEXPAND);
|
||||
label_sizer->AddStretchSpacer();
|
||||
|
||||
sizer->AddSpacer(FromDIP(32));
|
||||
sizer->Add(label_sizer, 0, wxALIGN_CENTER | wxEXPAND);
|
||||
sizer->AddSpacer(FromDIP(24));
|
||||
|
||||
auto detail_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_detail = new Label(this, detail);
|
||||
m_detail->SetFont(Label::Body_12);
|
||||
m_detail->SetForegroundColour(wxColour("#6B6B6B"));
|
||||
m_detail->Wrap(FromDIP(180));
|
||||
|
||||
detail_sizer->AddStretchSpacer();
|
||||
detail_sizer->Add(m_detail, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, horizontal_margin);
|
||||
detail_sizer->AddStretchSpacer();
|
||||
|
||||
sizer->Add(detail_sizer, 0, wxALIGN_CENTER | wxEXPAND);
|
||||
sizer->AddSpacer(FromDIP(10));
|
||||
|
||||
SetSizer(sizer);
|
||||
Layout();
|
||||
Fit();
|
||||
|
||||
GUI::wxGetApp().UpdateDarkUIWin(this);
|
||||
|
||||
auto forward_click_to_parent = [this](wxMouseEvent &event) {
|
||||
wxCommandEvent click_event(wxEVT_LEFT_DOWN, GetId());
|
||||
click_event.SetEventObject(this);
|
||||
this->ProcessEvent(click_event);
|
||||
};
|
||||
|
||||
m_btn->Bind(wxEVT_LEFT_DOWN, forward_click_to_parent);
|
||||
m_label->Bind(wxEVT_LEFT_DOWN, forward_click_to_parent);
|
||||
m_detail->Bind(wxEVT_LEFT_DOWN, forward_click_to_parent);
|
||||
|
||||
Bind(wxEVT_PAINT, &FilamentMapBtnPanel::OnPaint, this);
|
||||
Bind(wxEVT_ENTER_WINDOW, &FilamentMapBtnPanel::OnEnterWindow, this);
|
||||
Bind(wxEVT_LEAVE_WINDOW, &FilamentMapBtnPanel::OnLeaveWindow, this);
|
||||
}
|
||||
|
||||
void FilamentMapBtnPanel::OnPaint(wxPaintEvent &event)
|
||||
{
|
||||
wxAutoBufferedPaintDC dc(this);
|
||||
wxGraphicsContext *gc = wxGraphicsContext::Create(dc);
|
||||
|
||||
if (gc) {
|
||||
dc.Clear();
|
||||
wxRect rect = GetClientRect();
|
||||
gc->SetBrush(wxTransparentColour);
|
||||
gc->DrawRoundedRectangle(0, 0, rect.width, rect.height, 0);
|
||||
wxColour bg_color = m_selected ? wxColour("#EBF9F0") : wxColour("#FFFFFF");
|
||||
wxColour border_color = m_hover || m_selected ? wxColour("#00AE42") : wxColour("#CECECE");
|
||||
int cornerRadius = 8;
|
||||
gc->SetBrush(wxBrush(bg_color));
|
||||
gc->SetPen(wxPen(border_color, 2));
|
||||
gc->DrawRoundedRectangle(1, 1, rect.width - 2, rect.height - 2, cornerRadius);
|
||||
delete gc;
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentMapBtnPanel::UpdateStatus()
|
||||
{
|
||||
const wxColour selected_color = wxColour("#EBF9F0");
|
||||
const wxColour normal_color = wxColour("#FFFFFF");
|
||||
if (m_selected) {
|
||||
m_btn->SetBackgroundColour(selected_color);
|
||||
m_label->SetBackgroundColour(selected_color);
|
||||
m_detail->SetBackgroundColour(selected_color);
|
||||
} else {
|
||||
m_btn->SetBackgroundColour(normal_color);
|
||||
m_label->SetBackgroundColour(normal_color);
|
||||
m_detail->SetBackgroundColour(normal_color);
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentMapBtnPanel::OnEnterWindow(wxMouseEvent &event)
|
||||
{
|
||||
if (!m_hover) {
|
||||
m_hover = true;
|
||||
UpdateStatus();
|
||||
Refresh();
|
||||
event.Skip();
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentMapBtnPanel::OnLeaveWindow(wxMouseEvent &event)
|
||||
{
|
||||
if (m_hover) {
|
||||
wxPoint pos = this->ScreenToClient(wxGetMousePosition());
|
||||
if (this->GetClientRect().Contains(pos)) return;
|
||||
m_hover = false;
|
||||
UpdateStatus();
|
||||
Refresh();
|
||||
event.Skip();
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentMapBtnPanel::Select(bool selected)
|
||||
{
|
||||
m_selected = selected;
|
||||
UpdateStatus();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
void GUI::FilamentMapBtnPanel::Hide()
|
||||
{
|
||||
m_btn->Hide();
|
||||
m_label->Hide();
|
||||
m_detail->Hide();
|
||||
wxPanel::Hide();
|
||||
}
|
||||
void GUI::FilamentMapBtnPanel::Show()
|
||||
{
|
||||
m_btn->Show();
|
||||
m_label->Show();
|
||||
m_detail->Show();
|
||||
wxPanel::Show();
|
||||
}
|
||||
|
||||
FilamentMapAutoPanel::FilamentMapAutoPanel(wxWindow *parent, FilamentMapMode mode) : wxPanel(parent)
|
||||
{
|
||||
static const wxString AutoForFlushDetail = _L("Disregrad the filaments in AMS. Optimize filament usage "
|
||||
"by calculating the best allocation for the left and right "
|
||||
"nozzles. Arrange the filaments according on the printer according to "
|
||||
"the slicing results.");
|
||||
static const wxString AutoForMatchDetail = _L("Based on the current filaments in the AMS, allocate the "
|
||||
"filaments to the left and right nozzles.");
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_flush_panel = new FilamentMapBtnPanel(this, _L("Material-Saving Mode"), AutoForFlushDetail, "flush_mode_panel_icon");
|
||||
m_match_panel = new FilamentMapBtnPanel(this, _L("Convenient Mode"), AutoForMatchDetail,"match_mode_panel_icon");
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
sizer->Add(m_flush_panel, 1, wxEXPAND);
|
||||
sizer->AddSpacer(FromDIP(12));
|
||||
sizer->Add(m_match_panel, 1, wxEXPAND);
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
m_flush_panel->Bind(wxEVT_LEFT_DOWN, [this](auto &event) { this->OnModeSwitch(FilamentMapMode::fmmAutoForFlush); });
|
||||
|
||||
m_match_panel->Bind(wxEVT_LEFT_DOWN, [this](auto &event) { this->OnModeSwitch(FilamentMapMode::fmmAutoForMatch); });
|
||||
|
||||
m_mode = mode;
|
||||
UpdateStatus();
|
||||
|
||||
SetSizerAndFit(sizer);
|
||||
Layout();
|
||||
GUI::wxGetApp().UpdateDarkUIWin(this);
|
||||
}
|
||||
void FilamentMapAutoPanel::Hide()
|
||||
{
|
||||
m_flush_panel->Hide();
|
||||
m_match_panel->Hide();
|
||||
wxPanel::Hide();
|
||||
}
|
||||
|
||||
void FilamentMapAutoPanel::Show()
|
||||
{
|
||||
m_flush_panel->Show();
|
||||
m_match_panel->Show();
|
||||
wxPanel::Show();
|
||||
}
|
||||
|
||||
void FilamentMapAutoPanel::UpdateStatus()
|
||||
{
|
||||
if (m_mode == fmmAutoForFlush) {
|
||||
m_flush_panel->Select(true);
|
||||
m_match_panel->Select(false);
|
||||
} else {
|
||||
m_flush_panel->Select(false);
|
||||
m_match_panel->Select(true);
|
||||
}
|
||||
}
|
||||
|
||||
void FilamentMapAutoPanel::OnModeSwitch(FilamentMapMode mode)
|
||||
{
|
||||
m_mode = mode;
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
FilamentMapDefaultPanel::FilamentMapDefaultPanel(wxWindow *parent) : wxPanel(parent)
|
||||
{
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_label = new Label(this, _L("The material allocation for the current disk follows the global settings."));
|
||||
m_label->SetFont(Label::Body_14);
|
||||
m_label->SetBackgroundColour(*wxWHITE);
|
||||
|
||||
sizer->AddStretchSpacer();
|
||||
sizer->Add(m_label, 1, wxEXPAND|wxALIGN_CENTER);
|
||||
sizer->AddStretchSpacer();
|
||||
|
||||
SetSizerAndFit(sizer);
|
||||
Layout();
|
||||
GUI::wxGetApp().UpdateDarkUIWin(this);
|
||||
}
|
||||
|
||||
void FilamentMapDefaultPanel::Hide()
|
||||
{
|
||||
m_label->Hide();
|
||||
wxPanel::Hide();
|
||||
}
|
||||
|
||||
void FilamentMapDefaultPanel::Show()
|
||||
{
|
||||
m_label->Show();
|
||||
wxPanel::Show();
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
89
src/slic3r/GUI/FilamentMapPanel.hpp
Normal file
89
src/slic3r/GUI/FilamentMapPanel.hpp
Normal file
@@ -0,0 +1,89 @@
|
||||
|
||||
#ifndef FILAMENT_MAP_PANEL_HPP
|
||||
#define FILAMENT_MAP_PANEL_HPP
|
||||
|
||||
#include "GUI.hpp"
|
||||
#include "DragDropPanel.hpp"
|
||||
#include "Widgets/SwitchButton.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
class FilamentMapManualPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
FilamentMapManualPanel(wxWindow *parent, const std::vector<std::string> &color, const std::vector<int> &filament_list, const std::vector<int> &filament_map);
|
||||
|
||||
std::vector<int> GetFilamentMaps() const { return m_filament_map; }
|
||||
std::vector<int> GetLeftFilaments() const { return m_left_panel->GetAllFilaments(); }
|
||||
std::vector<int> GetRightFilaments() const { return m_right_panel->GetAllFilaments(); }
|
||||
|
||||
void Hide();
|
||||
void Show();
|
||||
|
||||
private:
|
||||
void OnSwitchFilament(wxCommandEvent &);
|
||||
DragDropPanel *m_left_panel;
|
||||
DragDropPanel *m_right_panel;
|
||||
|
||||
Label *m_description;
|
||||
Label *m_tips;
|
||||
|
||||
ScalableButton *m_switch_btn;
|
||||
|
||||
std::vector<int> m_filament_map;
|
||||
std::vector<int> m_filament_list;
|
||||
std::vector<std::string> m_filament_color;
|
||||
};
|
||||
|
||||
class FilamentMapBtnPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
FilamentMapBtnPanel(wxWindow *parent, const wxString &label, const wxString &detail, const std::string &icon_path);
|
||||
void Hide();
|
||||
void Show();
|
||||
void Select(bool selected);
|
||||
protected:
|
||||
void OnPaint(wxPaintEvent &event);
|
||||
private:
|
||||
void OnEnterWindow(wxMouseEvent &event);
|
||||
void OnLeaveWindow(wxMouseEvent &evnet);
|
||||
|
||||
void UpdateStatus();
|
||||
|
||||
wxBitmapButton *m_btn;
|
||||
wxStaticText *m_label;
|
||||
Label *m_detail;
|
||||
bool m_hover{false};
|
||||
bool m_selected{false};
|
||||
};
|
||||
|
||||
class FilamentMapAutoPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
FilamentMapAutoPanel(wxWindow *parent, FilamentMapMode mode);
|
||||
void Hide();
|
||||
void Show();
|
||||
FilamentMapMode GetMode() const { return m_mode; }
|
||||
|
||||
private:
|
||||
void OnModeSwitch(FilamentMapMode mode);
|
||||
void UpdateStatus();
|
||||
|
||||
FilamentMapBtnPanel *m_flush_panel;
|
||||
FilamentMapBtnPanel *m_match_panel;
|
||||
FilamentMapMode m_mode;
|
||||
};
|
||||
|
||||
class FilamentMapDefaultPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
FilamentMapDefaultPanel(wxWindow *parent);
|
||||
void Hide();
|
||||
void Show();
|
||||
|
||||
private:
|
||||
Label *m_label;
|
||||
};
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
#endif
|
||||
@@ -4410,7 +4410,7 @@ void GCodeViewer::render_legend_color_arr_recommen(float window_padding)
|
||||
Plater *plater = wxGetApp().plater();
|
||||
wxCommandEvent evt(EVT_OPEN_FILAMENT_MAP_SETTINGS_DIALOG);
|
||||
evt.SetEventObject(plater);
|
||||
evt.SetInt(0b0010); //0010 means from gcode view, manual mode
|
||||
evt.SetInt(1); // 1 means from gcode viewer
|
||||
wxPostEvent(plater, evt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "ConfigWizard.hpp"
|
||||
#include "Widgets/WebView.hpp"
|
||||
#include "DailyTips.hpp"
|
||||
#include "FilamentMapDialog.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <dbt.h>
|
||||
@@ -1578,20 +1579,7 @@ wxBoxSizer* MainFrame::create_side_tools()
|
||||
|
||||
sizer->Layout();
|
||||
|
||||
// m_publish_btn->Bind(wxEVT_BUTTON, [this](auto& e) {
|
||||
// CallAfter([this] {
|
||||
// wxGetApp().open_publish_page_dialog();
|
||||
|
||||
// if (!wxGetApp().getAgent()) {
|
||||
// BOOST_LOG_TRIVIAL(info) << "publish: no agent";
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // record
|
||||
// json j;
|
||||
// NetworkAgent* agent = GUI::wxGetApp().getAgent();
|
||||
// });
|
||||
// });
|
||||
m_filament_group_popup = new FilamentGroupPopup(m_slice_btn);
|
||||
|
||||
m_slice_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event)
|
||||
{
|
||||
@@ -1602,14 +1590,62 @@ wxBoxSizer* MainFrame::create_side_tools()
|
||||
//this->m_plater->select_view_3D("Preview");
|
||||
m_plater->exit_gizmo();
|
||||
m_plater->update(true, true);
|
||||
if (m_slice_select == eSliceAll)
|
||||
wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SLICE_ALL));
|
||||
else
|
||||
wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SLICE_PLATE));
|
||||
|
||||
this->m_tabpanel->SetSelection(tpPreview);
|
||||
bool slice = true;
|
||||
|
||||
auto full_config = wxGetApp().preset_bundle->full_config();
|
||||
std::vector<int>g_filament_map = full_config.option<ConfigOptionInts>("filament_map")->values;
|
||||
FilamentMapMode g_filament_map_mode = get_prefered_map_mode();
|
||||
if (is_pop_up_required()) {
|
||||
auto filament_colors = full_config.option<ConfigOptionStrings>("filament_colour")->values;
|
||||
g_filament_map.resize(filament_colors.size());
|
||||
std::vector<int> filament_lists(filament_colors.size());
|
||||
std::iota(filament_lists.begin(), filament_lists.end(), 1);
|
||||
|
||||
FilamentMapDialog filament_dlg(this,
|
||||
filament_colors,
|
||||
g_filament_map,
|
||||
filament_lists,
|
||||
FilamentMapMode::fmmManual,
|
||||
false
|
||||
);
|
||||
auto ret = filament_dlg.ShowModal();
|
||||
if (ret == wxID_OK) {
|
||||
g_filament_map_mode = filament_dlg.get_mode();
|
||||
g_filament_map = filament_dlg.get_filament_maps();
|
||||
}
|
||||
else {
|
||||
slice = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (slice) {
|
||||
m_plater->set_global_filament_map_mode(g_filament_map_mode);
|
||||
if (g_filament_map_mode == FilamentMapMode::fmmManual)
|
||||
m_plater->set_global_filament_map(g_filament_map);
|
||||
if (m_slice_select == eSliceAll)
|
||||
wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SLICE_ALL));
|
||||
else
|
||||
wxPostEvent(m_plater, SimpleEvent(EVT_GLTOOLBAR_SLICE_PLATE));
|
||||
this->m_tabpanel->SetSelection(tpPreview);
|
||||
}
|
||||
});
|
||||
|
||||
m_slice_btn->Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent& event) {
|
||||
m_filament_group_popup->SetSize(wxSize(FromDIP(380),-1));
|
||||
wxPoint pos = m_slice_btn->ClientToScreen(wxPoint(0, 0));
|
||||
pos.y += m_slice_btn->GetRect().height * 1.25;
|
||||
pos.x -= (m_slice_option_btn->GetRect().width + m_filament_group_popup->GetRect().width * 0.6);
|
||||
|
||||
m_filament_group_popup->SetPosition(pos);
|
||||
m_filament_group_popup->tryPopup(m_plater->check_ams_status());
|
||||
});
|
||||
|
||||
m_slice_btn->Bind(wxEVT_LEAVE_WINDOW, [this](auto& event) {
|
||||
m_filament_group_popup->tryClose();
|
||||
});
|
||||
|
||||
|
||||
m_print_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event)
|
||||
{
|
||||
//this->m_plater->select_view_3D("Preview");
|
||||
@@ -3870,6 +3906,7 @@ void MainFrame::technology_changed()
|
||||
m_menubar->SetMenuLabel(id, pt == ptSLA ? _omitL("Material Settings") : _L("Filament Settings"));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Called after the Preferences dialog is closed and the program settings are saved.
|
||||
// Update the UI based on the current preferences.
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "UnsavedChangesDialog.hpp"
|
||||
#include "Widgets/SideButton.hpp"
|
||||
#include "Widgets/SideMenuPopup.hpp"
|
||||
#include "FilamentGroupPopup.hpp"
|
||||
|
||||
|
||||
#include <boost/property_tree/ptree_fwd.hpp>
|
||||
|
||||
@@ -338,6 +340,7 @@ public:
|
||||
|
||||
void technology_changed();
|
||||
|
||||
|
||||
//BBS
|
||||
void load_url(wxString url);
|
||||
void load_printer_url(wxString url, wxString apikey = "");
|
||||
@@ -393,6 +396,8 @@ public:
|
||||
SideButton* m_slice_option_btn{ nullptr };
|
||||
SideButton* m_print_btn{ nullptr };
|
||||
SideButton* m_print_option_btn{ nullptr };
|
||||
|
||||
FilamentGroupPopup* m_filament_group_popup{ nullptr };
|
||||
mutable bool m_slice_enable{ true };
|
||||
mutable bool m_print_enable{ true };
|
||||
bool get_enable_slice_status();
|
||||
|
||||
@@ -15322,9 +15322,9 @@ void Plater::open_platesettings_dialog(wxCommandEvent& evt) {
|
||||
void Plater::open_filament_map_setting_dialog(wxCommandEvent &evt)
|
||||
{
|
||||
PartPlate* curr_plate = p->partplate_list.get_curr_plate();
|
||||
int value = evt.GetInt();
|
||||
bool is_auto = value & 1; //0000 means manual, 0001 means auto
|
||||
bool need_slice = value & (1 << 1); //0010 means from gcode view, 0000 means not from gcode view
|
||||
int value = evt.GetInt(); //1 means from gcode view
|
||||
bool force_manual = value == 1; // If from gcode view, should display manual page
|
||||
bool need_slice = value ==1; // If from gcode view, should slice
|
||||
|
||||
const auto& project_config = wxGetApp().preset_bundle->project_config;
|
||||
auto filament_colors = config()->option<ConfigOptionStrings>("filament_colour")->values;
|
||||
@@ -15333,20 +15333,22 @@ void Plater::open_filament_map_setting_dialog(wxCommandEvent &evt)
|
||||
if (plate_filament_maps.size() != filament_colors.size()) // refine it later, save filament map to app config
|
||||
plate_filament_maps.resize(filament_colors.size(), 1);
|
||||
|
||||
FilamentMapMode display_mode = force_manual ? FilamentMapMode::fmmManual : plate_filament_map_mode;
|
||||
|
||||
FilamentMapDialog filament_dlg(this,
|
||||
config(),
|
||||
filament_colors,
|
||||
plate_filament_maps,
|
||||
curr_plate->get_extruders(true),
|
||||
plate_filament_map_mode < FilamentMapMode::fmmManual,
|
||||
false
|
||||
display_mode,
|
||||
true
|
||||
);
|
||||
|
||||
if (filament_dlg.ShowModal() == wxID_OK) {
|
||||
std::vector<int> new_filament_maps = filament_dlg.get_filament_maps();
|
||||
std::vector<int> old_filament_maps = plate_filament_maps;
|
||||
std::vector<int> old_filament_maps = curr_plate->get_filament_maps();
|
||||
|
||||
FilamentMapMode old_map_mode = plate_filament_map_mode;
|
||||
FilamentMapMode new_map_mode = filament_dlg.is_auto() ? fmmAutoForFlush : fmmManual;
|
||||
FilamentMapMode new_map_mode = filament_dlg.get_mode();
|
||||
|
||||
bool need_invalidate = (old_map_mode != new_map_mode ||
|
||||
old_filament_maps != new_filament_maps);
|
||||
@@ -15538,7 +15540,7 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi
|
||||
if (!ret) {
|
||||
PartPlate * curr_plate = p->partplate_list.get_curr_plate();
|
||||
wxCommandEvent evt(EVT_OPEN_FILAMENT_MAP_SETTINGS_DIALOG);
|
||||
evt.SetInt(curr_plate->get_filament_map_mode() < FilamentMapMode::fmmManual ? 1 : 0);
|
||||
evt.SetInt(0); // 0 means not from gcodeviewer
|
||||
evt.SetEventObject(this);
|
||||
wxPostEvent(this, evt);
|
||||
} else {
|
||||
|
||||
@@ -494,6 +494,7 @@ public:
|
||||
void on_filaments_delete(size_t extruders_count, size_t filament_id, int replace_filament_id = -1);
|
||||
// BBS
|
||||
void on_bed_type_change(BedType bed_type);
|
||||
|
||||
bool update_filament_colors_in_full_config();
|
||||
void config_change_notification(const DynamicPrintConfig &config, const std::string& key);
|
||||
void on_config_change(const DynamicPrintConfig &config);
|
||||
|
||||
@@ -1275,6 +1275,10 @@ wxWindow* PreferencesDialog::create_general_page()
|
||||
auto item_darkmode = create_item_darkmode_checkbox(_L("Enable Dark mode"), page,_L("Enable Dark mode"), 50, "dark_color_mode");
|
||||
#endif
|
||||
|
||||
auto title_filament_group = create_item_title(_L("Filament Group"), page, _L("Filament Group"));
|
||||
auto item_ignore_ext_filament = create_item_checkbox(_L("Ignore ext filament when auto grouping."), page, _L("Ignore ext filament when auto grouping"), 50, "ignore_ext_filament_when_group");
|
||||
auto item_pop_filament_group_mode = create_item_checkbox(_L("Pop up to select filament map mode."), page, _L("Pop up to select filament map mode"), 50, "pop_up_filament_map_mode");
|
||||
|
||||
auto title_develop_mode = create_item_title(_L("Develop mode"), page, _L("Develop mode"));
|
||||
auto item_develop_mode = create_item_checkbox(_L("Develop mode"), page, _L("Develop mode"), 50, "developer_mode");
|
||||
auto item_skip_ams_blacklist_check = create_item_checkbox(_L("Skip AMS blacklist check"), page, _L("Skip AMS blacklist check"), 50, "skip_ams_blacklist_check");
|
||||
@@ -1347,6 +1351,10 @@ wxWindow* PreferencesDialog::create_general_page()
|
||||
sizer_page->Add(item_darkmode, 0, wxEXPAND, FromDIP(3));
|
||||
#endif
|
||||
|
||||
sizer_page->Add(title_filament_group, 0, wxTOP | wxEXPAND, FromDIP(20));
|
||||
sizer_page->Add(item_ignore_ext_filament, 0, wxEXPAND, FromDIP(3));
|
||||
sizer_page->Add(item_pop_filament_group_mode, 0, wxEXPAND, FromDIP(3));
|
||||
|
||||
sizer_page->Add(title_develop_mode, 0, wxTOP | wxEXPAND, FromDIP(20));
|
||||
sizer_page->Add(item_develop_mode, 0, wxTOP, FromDIP(3));
|
||||
sizer_page->Add(item_skip_ams_blacklist_check, 0, wxTOP, FromDIP(3));
|
||||
|
||||
Reference in New Issue
Block a user