mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-05 14:51:06 +00:00
Use DPI-aware 20 DIP vertical scrolling for general-purpose GUI scroll areas. Keep list-based views aligned to their item height so one wheel increment follows the visible row rhythm. This makes Preferences and other dialogs scroll consistently across Windows DPI settings.
942 lines
40 KiB
C++
942 lines
40 KiB
C++
#include <algorithm>
|
|
#include <sstream>
|
|
//#include "libslic3r/FlushVolCalc.hpp"
|
|
#include "ObjColorDialog.hpp"
|
|
#include "BitmapCache.hpp"
|
|
#include "GUI.hpp"//for ICON_SIZE
|
|
#include "I18N.hpp"
|
|
#include "GUI_App.hpp"
|
|
#include "MsgDialog.hpp"
|
|
#include "Widgets/Button.hpp"
|
|
#include "MainFrame.hpp"
|
|
#include "libslic3r/Config.hpp"
|
|
#include "BitmapComboBox.hpp"
|
|
#include "Widgets/ComboBox.hpp"
|
|
#include "Widgets/DialogButtons.hpp"
|
|
#include <wx/sizer.h>
|
|
|
|
#include "libslic3r/ObjColorUtils.hpp"
|
|
#include "libslic3r/Model.hpp"
|
|
using namespace Slic3r;
|
|
using namespace Slic3r::GUI;
|
|
|
|
int objcolor_scale(const int val) { return val * Slic3r::GUI::wxGetApp().em_unit() / 10; }
|
|
int OBJCOLOR_ITEM_WIDTH() { return objcolor_scale(30); }
|
|
static const wxColour g_text_color = wxColour(107, 107, 107, 255);
|
|
static const wxColour g_undefined_color_in_obj = wxColour(0, 255, 0, 255);
|
|
const int HEADER_BORDER = 5;
|
|
const int CONTENT_BORDER = 3;
|
|
const int PANEL_WIDTH = 400;
|
|
const int COLOR_LABEL_WIDTH = 180;
|
|
const int IMAGE_SIZE_WIDTH = 300;
|
|
#define MIN_OBJCOLOR_DIALOG_WIDTH FromDIP(400)
|
|
#define FIX_SCROLL_HEIGTH FromDIP(400)
|
|
#define BTN_SIZE wxSize(FromDIP(58), FromDIP(24))
|
|
#define BTN_GAP FromDIP(15)
|
|
#define FIX_SCROLL_IMAGE_WIDTH FromDIP(270)
|
|
static void update_ui(wxWindow* window)
|
|
{
|
|
Slic3r::GUI::wxGetApp().UpdateDarkUI(window);
|
|
}
|
|
|
|
static const char g_min_cluster_color = 1;
|
|
static const char g_max_color = (int) EnforcerBlockerType::ExtruderMax;
|
|
|
|
wxBoxSizer* ObjColorDialog::create_btn_sizer(long flags,bool exist_error)
|
|
{
|
|
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
if (!exist_error) {
|
|
btn_sizer->AddSpacer(FromDIP(25));
|
|
auto *tips = new HyperLink(this, _L("Wiki Guide")); // ORCA
|
|
tips->SetURL("https://www.orcaslicer.com/wiki/import_export#obj");
|
|
btn_sizer->Add(tips, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
|
}
|
|
btn_sizer->AddStretchSpacer();
|
|
|
|
auto dlg_btns = new DialogButtons(this, {"OK", "Cancel"});
|
|
m_button_list[wxOK] = dlg_btns->GetOK();
|
|
m_button_list[wxCANCEL] = dlg_btns->GetCANCEL();
|
|
|
|
btn_sizer->Add(dlg_btns, 0, wxEXPAND);
|
|
return btn_sizer;
|
|
}
|
|
|
|
void ObjColorDialog::on_dpi_changed(const wxRect &suggested_rect)
|
|
{
|
|
m_panel_ObjColor->msw_rescale();
|
|
this->Refresh();
|
|
}
|
|
void ObjColorDialog::update_layout() {
|
|
m_main_sizer->Layout();
|
|
SetSizerAndFit(m_main_sizer);
|
|
}
|
|
|
|
bool ObjColorDialog::Show(bool show) {
|
|
if (m_panel_ObjColor->do_show(show)) {
|
|
return DPIDialog::Show(true);
|
|
} else {
|
|
return DPIDialog::Show(false);
|
|
}
|
|
};
|
|
|
|
ObjColorDialog::ObjColorDialog(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector<std::string> &extruder_colours, const bool semm)
|
|
: DPIDialog(parent ? parent : static_cast<wxWindow *>(wxGetApp().mainframe),
|
|
wxID_ANY,
|
|
_(L("OBJ file import color")),
|
|
wxDefaultPosition,
|
|
wxDefaultSize,
|
|
wxDEFAULT_DIALOG_STYLE /* | wxRESIZE_BORDER*/)
|
|
{
|
|
auto m_line_top = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 1));
|
|
m_line_top->SetBackgroundColour(wxColour(166, 169, 170));
|
|
|
|
this->SetBackgroundColour(*wxWHITE);
|
|
this->SetMinSize(wxSize(MIN_OBJCOLOR_DIALOG_WIDTH, -1));
|
|
|
|
m_main_sizer = new wxBoxSizer(wxVERTICAL);
|
|
m_main_sizer->Add(m_line_top, 0, wxEXPAND, 0);
|
|
// set min sizer width according to extruders count
|
|
auto sizer_width = (int) (2.8 * OBJCOLOR_ITEM_WIDTH());
|
|
sizer_width = sizer_width > MIN_OBJCOLOR_DIALOG_WIDTH ? sizer_width : MIN_OBJCOLOR_DIALOG_WIDTH;
|
|
m_main_sizer->SetMinSize(wxSize(sizer_width, -1));
|
|
bool some_face_no_color = false;
|
|
if (!in_out.deal_vertex_color) {
|
|
auto temp0 = in_out.input_colors.size();
|
|
auto temp1 = in_out.model->objects[0]->volumes[0]->mesh_ptr()->facets_count();
|
|
some_face_no_color = temp0 < temp1;
|
|
}
|
|
bool ok = in_out.lost_material_name.empty() && !some_face_no_color;
|
|
if (ok) {
|
|
m_panel_ObjColor = new ObjColorPanel(this, in_out, extruder_colours, semm);
|
|
m_panel_ObjColor->set_layout_callback([this]() { update_layout(); });
|
|
m_main_sizer->Add(m_panel_ObjColor, 1, wxEXPAND | wxALL, 0);
|
|
}
|
|
else {
|
|
wxBoxSizer * error_mtl_sizer = new wxBoxSizer(wxVERTICAL);
|
|
|
|
wxStaticText *error_mtl_title = new wxStaticText(this, wxID_ANY, _L("Some faces don't have color defined."));
|
|
if (!in_out.lost_material_name.empty()) {
|
|
error_mtl_title->SetLabel(_L("MTL file exist error, could not find the material:") + " " + in_out.lost_material_name + ".");
|
|
}
|
|
error_mtl_title->SetFont(Label::Head_12);
|
|
error_mtl_sizer->Add(error_mtl_title, 0, wxALIGN_LEFT | wxBOTTOM | wxTOP, FromDIP(5));
|
|
|
|
wxStaticText *tip_title = new wxStaticText(this, wxID_ANY, _L("Please check OBJ or MTL file."));
|
|
tip_title->SetFont(Label::Head_12);
|
|
error_mtl_sizer->Add(tip_title, 0, wxALIGN_LEFT | wxBOTTOM | wxTOP, FromDIP(5));
|
|
|
|
m_main_sizer->Add(error_mtl_sizer, 1, wxEXPAND | wxLEFT, FromDIP(25));
|
|
}
|
|
|
|
m_buttons_sizer = create_btn_sizer(wxOK | wxCANCEL, !ok);
|
|
if (!ok) {
|
|
m_button_list[wxCANCEL]->Hide();
|
|
m_button_list[wxOK]->Enable(true);
|
|
// ORCA no need to set colors again
|
|
} else {
|
|
m_button_list[wxOK]->Bind(wxEVT_UPDATE_UI, ([this](wxUpdateUIEvent &e) {
|
|
if (m_panel_ObjColor->is_ok() == m_button_list[wxOK]->IsEnabled()) { return; }
|
|
m_button_list[wxOK]->Enable(m_panel_ObjColor->is_ok());
|
|
// ORCA no need to set colors again
|
|
}));
|
|
}
|
|
m_main_sizer->Add(m_buttons_sizer, 0, wxBOTTOM | wxTOP | wxRIGHT | wxEXPAND, BTN_GAP);
|
|
SetSizer(m_main_sizer);
|
|
m_main_sizer->SetSizeHints(this);
|
|
|
|
if (this->FindWindowById(wxID_OK, this)) {
|
|
this->FindWindowById(wxID_OK, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {// if OK button is clicked..
|
|
if (!m_panel_ObjColor) {
|
|
EndModal(wxCANCEL);
|
|
return;
|
|
}
|
|
m_panel_ObjColor->clear_instance_and_revert_offset();
|
|
m_panel_ObjColor->send_new_filament_to_ui();
|
|
EndModal(wxID_OK);
|
|
}, wxID_OK);
|
|
}
|
|
if (this->FindWindowById(wxID_CANCEL, this)) {
|
|
update_ui(static_cast<wxButton*>(this->FindWindowById(wxID_CANCEL, this)));
|
|
this->FindWindowById(wxID_CANCEL, this)->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) {
|
|
if (m_panel_ObjColor) {
|
|
m_panel_ObjColor->cancel_paint_color();
|
|
}
|
|
EndModal(wxCANCEL);
|
|
});
|
|
}
|
|
this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent &e) {
|
|
if (m_panel_ObjColor) {
|
|
m_panel_ObjColor->cancel_paint_color();
|
|
}
|
|
EndModal(wxCANCEL);
|
|
});
|
|
|
|
wxGetApp().UpdateDlgDarkUI(this);
|
|
CenterOnParent();
|
|
}
|
|
|
|
// This panel contains all control widgets for both simple and advanced mode (these reside in separate sizers)
|
|
ObjColorPanel::ObjColorPanel(wxWindow *parent, Slic3r::ObjDialogInOut &in_out, const std::vector<std::string> &extruder_colours, const bool semm)
|
|
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize /*,wxBORDER_RAISED*/)
|
|
, m_obj_in_out(in_out)
|
|
, m_input_colors(in_out.input_colors)
|
|
, m_filament_ids(in_out.filament_ids)
|
|
, m_first_extruder_id(in_out.first_extruder_id)
|
|
, m_semm(semm)
|
|
{
|
|
if (in_out.input_colors.size() == 0) { return; }
|
|
for (const std::string& color : extruder_colours) {
|
|
m_colours.push_back(wxColor(color));
|
|
}
|
|
//deal input_colors
|
|
m_input_colors_size = in_out.input_colors.size();
|
|
for (size_t i = 0; i < in_out.input_colors.size(); i++) {
|
|
if (color_is_equal(in_out.input_colors[i], UNDEFINE_COLOR)) { // not define color range:0~1
|
|
in_out.input_colors[i] = convert_to_rgba(m_colours[0]);
|
|
}
|
|
}
|
|
if (in_out.is_single_color && in_out.input_colors.size() >= 1) {
|
|
m_cluster_colors_from_algo.emplace_back(in_out.input_colors[0]);
|
|
m_cluster_colours.emplace_back(convert_to_wxColour(in_out.input_colors[0]));
|
|
m_cluster_labels_from_algo.reserve(m_input_colors_size);
|
|
for (size_t i = 0; i < m_input_colors_size; i++) {
|
|
m_cluster_labels_from_algo.emplace_back(0);
|
|
}
|
|
m_cluster_map_filaments.resize(m_cluster_colors_from_algo.size());
|
|
m_new_add_colors.resize(m_cluster_map_filaments.size());
|
|
m_color_num_recommend = m_color_cluster_num_by_algo = m_cluster_colors_from_algo.size();
|
|
} else {//cluster deal
|
|
deal_algo(-1);
|
|
}
|
|
//end first cluster
|
|
//draw ui
|
|
auto sizer_width = FromDIP(300);
|
|
// Create two switched panels with their own sizers
|
|
m_sizer_simple = new wxBoxSizer(wxVERTICAL);
|
|
m_page_simple = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
|
m_page_simple->SetSizer(m_sizer_simple);
|
|
m_page_simple->SetBackgroundColour(*wxWHITE);
|
|
|
|
update_ui(m_page_simple);
|
|
// BBS
|
|
m_sizer_simple->AddSpacer(FromDIP(10));
|
|
// BBS: for tunning flush volumes
|
|
{
|
|
//color cluster results
|
|
wxBoxSizer * specify_cluster_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
wxStaticText *specify_color_cluster_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Specify number of colors:"));
|
|
specify_color_cluster_title->SetFont(Label::Head_14);
|
|
specify_cluster_sizer->Add(specify_color_cluster_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
|
|
|
m_color_cluster_num_by_user_ebox = new SpinInput(m_page_simple, "", wxEmptyString, wxDefaultPosition, wxSize(FromDIP(60), -1), wxTE_PROCESS_ENTER);
|
|
m_color_cluster_num_by_user_ebox->SetValue(std::to_string(m_color_cluster_num_by_algo).c_str());
|
|
m_color_cluster_num_by_user_ebox->SetToolTip(_L("Enter or click the adjustment button to modify number again"));
|
|
{//event
|
|
auto on_apply_color_cluster_text_modify = [this](wxEvent &e) {
|
|
int number = m_color_cluster_num_by_user_ebox->GetValue();
|
|
if (number > m_color_num_recommend || number < g_min_cluster_color) {
|
|
number = number < g_min_cluster_color ? g_min_cluster_color : m_color_num_recommend;
|
|
auto str = wxString::Format(("%d"), number);
|
|
m_color_cluster_num_by_user_ebox->SetValue(str);
|
|
// m_color_cluster_num_by_user_ebox->SetInsertionPointEnd();
|
|
}
|
|
if (m_last_cluster_num != number) {
|
|
wxBusyCursor busy;
|
|
deal_algo(number, true);
|
|
Layout();
|
|
Refresh();
|
|
Update();
|
|
m_last_cluster_num = number;
|
|
}
|
|
};
|
|
m_color_cluster_num_by_user_ebox->Bind(wxEVT_TEXT_ENTER, on_apply_color_cluster_text_modify);
|
|
m_color_cluster_num_by_user_ebox->Bind(wxEVT_SPINCTRL, on_apply_color_cluster_text_modify);
|
|
|
|
m_color_cluster_num_by_user_ebox->Bind(wxEVT_CHAR, [](wxKeyEvent &e) {
|
|
int keycode = e.GetKeyCode();
|
|
wxString input_char = wxString::Format("%c", keycode);
|
|
long value;
|
|
if (!input_char.ToLong(&value))
|
|
return;
|
|
e.Skip();
|
|
});
|
|
}
|
|
specify_cluster_sizer->AddSpacer(FromDIP(2));
|
|
specify_cluster_sizer->Add(m_color_cluster_num_by_user_ebox, 0, wxALIGN_CENTER | wxALL, 0);
|
|
specify_cluster_sizer->AddSpacer(FromDIP(15));
|
|
wxStaticText *recommend_color_cluster_title = new wxStaticText(m_page_simple, wxID_ANY, "(" + std::to_string(m_color_num_recommend) + " " + _L("Recommended ") + ")");
|
|
specify_cluster_sizer->Add(recommend_color_cluster_title, 0, wxALIGN_CENTER | wxALL, 0);
|
|
|
|
m_sizer_simple->Add(specify_cluster_sizer, 0, wxEXPAND | wxLEFT, FromDIP(20));
|
|
{//add combox
|
|
auto icon_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
auto plater = wxGetApp().plater();
|
|
{
|
|
auto mo = m_obj_in_out.model->objects[0];
|
|
mo->add_instance();
|
|
auto mv = mo->volumes[0];
|
|
m_thumbnail_offset = Slic3r::Vec3d::Zero();
|
|
auto box = mo->bounding_box_exact();
|
|
if (box.min.x() < 0 || box.min.y() < 0 || box.min.z() < 0) {
|
|
m_thumbnail_offset = Slic3r::Vec3d(box.min.x() < 0 ? -box.min.x() : 0, box.min.y() < 0 ? -box.min.y() : 0, box.min.z() < 0 ? -box.min.z() : 0);
|
|
mv->translate(m_thumbnail_offset);
|
|
}
|
|
}
|
|
|
|
wxStaticText *combox_title = new wxStaticText(m_page_simple, wxID_ANY, _L("view"));
|
|
auto cur_combox = new ComboBox(m_page_simple, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(FromDIP(100), -1), 0, NULL, wxCB_READONLY);
|
|
wxArrayString choices = get_all_camera_view_type();
|
|
for (size_t i = 0; i < choices.size(); i++) { cur_combox->Append(choices[i]); }
|
|
cur_combox->SetSelection(0);
|
|
cur_combox->Bind(wxEVT_COMBOBOX, [this](auto &e) {
|
|
set_view_angle_type(e.GetSelection());
|
|
Layout();
|
|
Fit();
|
|
});
|
|
// add image
|
|
wxImage image(IMAGE_SIZE_WIDTH, IMAGE_SIZE_WIDTH);
|
|
image.InitAlpha();
|
|
for (unsigned int r = 0; r < IMAGE_SIZE_WIDTH; ++r) {
|
|
for (unsigned int c = 0; c < IMAGE_SIZE_WIDTH; ++c) {
|
|
image.SetRGB((int) c, (int) r, 0, 255, 0);
|
|
image.SetAlpha((int) c, (int) r, 255);
|
|
}
|
|
}
|
|
m_image_button = new wxButton(m_page_simple, wxID_ANY, {}, wxDefaultPosition, wxSize(FromDIP(IMAGE_SIZE_WIDTH), FromDIP(IMAGE_SIZE_WIDTH)),
|
|
wxBORDER_NONE | wxBU_AUTODRAW);
|
|
m_image_button->SetBitmap(image);
|
|
m_image_button->SetCanFocus(false);
|
|
#ifdef __WXGTK__
|
|
RemoveButtonBorder(m_image_button);
|
|
#endif
|
|
icon_sizer->Add(m_image_button, 0, wxEXPAND | wxALL,
|
|
FromDIP(0)); // wxEXPAND | wxALL
|
|
cur_combox->Raise();//for mac
|
|
|
|
m_sizer_simple->Add(icon_sizer, FromDIP(0), wxALIGN_CENTER | wxALL, FromDIP(0));
|
|
auto view_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
view_sizer->Add(combox_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
|
view_sizer->Add(cur_combox , 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
|
m_sizer_simple->Add(view_sizer, 0, wxALIGN_RIGHT | wxRIGHT, FromDIP(20));
|
|
}
|
|
wxBoxSizer * current_filaments_title_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
wxStaticText *current_filaments_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Current filament colors"));
|
|
current_filaments_title->SetFont(Label::Head_14);
|
|
current_filaments_title_sizer->Add(current_filaments_title, 0, wxALIGN_CENTER | wxALL, FromDIP(5));
|
|
m_sizer_simple->Add(current_filaments_title_sizer, 0, wxEXPAND | wxLEFT, FromDIP(20));
|
|
int current_filament_row = 1;
|
|
int current_filament_col = 1;
|
|
const int one_row_max = 16;
|
|
if (m_colours.size() > 1) {
|
|
current_filament_row = (m_colours.size() - 1) / one_row_max + 1;
|
|
if (current_filament_row >= 2) {
|
|
current_filament_col = one_row_max;
|
|
} else {
|
|
current_filament_col = m_colours.size();
|
|
}
|
|
}
|
|
m_sizer_current_filaments = new wxBoxSizer(wxHORIZONTAL);
|
|
wxGridSizer *current_filaments_sizer = new wxGridSizer(current_filament_row, current_filament_col, FromDIP(5), FromDIP(7)); //(int rows, int cols, int vgap, int hgap );
|
|
for (size_t i = 0; i < m_colours.size(); i++) {
|
|
auto extruder_icon_sizer = create_extruder_icon_and_rgba_sizer(m_page_simple, i, m_colours[i]);
|
|
current_filaments_sizer->Add(extruder_icon_sizer, 0, wxALIGN_LEFT);
|
|
}
|
|
m_sizer_current_filaments->AddSpacer(FromDIP(1));
|
|
m_sizer_current_filaments->Add(current_filaments_sizer, 0, wxEXPAND);
|
|
m_sizer_current_filaments->AddStretchSpacer();
|
|
m_sizer_simple->Add(m_sizer_current_filaments, 0, wxEXPAND | wxLEFT, FromDIP(25));
|
|
//colors table title
|
|
wxBoxSizer * matching_title_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
matching_title_sizer->AddSpacer(FromDIP(25));
|
|
wxStaticText *matching_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Matching"));
|
|
matching_title->SetFont(Label::Head_14);
|
|
matching_title_sizer->Add(matching_title, 0, wxEXPAND , 0);
|
|
m_sizer_simple->Add(matching_title_sizer, 0, wxEXPAND | wxTOP, FromDIP(15));// wxTop has FromDIP(10) margin
|
|
//new color table
|
|
m_scrolledWindow = new wxScrolledWindow(m_page_simple, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
|
|
m_scrolledWindow->SetBackgroundColour(*wxWHITE);
|
|
m_scrolledWindow->SetScrollRate(0, FromDIP(20));
|
|
m_scrolledWindow->EnableScrolling(false, true);
|
|
m_scrolledWindow->ShowScrollbars(wxScrollbarVisibility::wxSHOW_SB_NEVER, wxScrollbarVisibility::wxSHOW_SB_DEFAULT);
|
|
draw_new_table();
|
|
|
|
m_sizer_simple->Add(m_scrolledWindow, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(15));
|
|
//buttons
|
|
wxBoxSizer *quick_set_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
quick_set_sizer->AddSpacer(FromDIP(25));
|
|
wxStaticText *quick_set_title = new wxStaticText(m_page_simple, wxID_ANY, _L("Quick set"));
|
|
quick_set_title->SetFont(Label::Head_12);
|
|
quick_set_sizer->Add(quick_set_title, 0, wxALIGN_CENTER | wxALL, 0);
|
|
quick_set_sizer->AddSpacer(FromDIP(10));
|
|
|
|
auto calc_approximate_match_btn_sizer = create_approximate_match_btn_sizer(m_page_simple);
|
|
auto calc_add_btn_sizer = create_add_btn_sizer(m_page_simple);
|
|
auto calc_reset_btn_sizer = create_reset_btn_sizer(m_page_simple);
|
|
quick_set_sizer->Add(calc_add_btn_sizer, 0, wxALIGN_CENTER | wxALL, 0);
|
|
quick_set_sizer->AddSpacer(FromDIP(10));
|
|
quick_set_sizer->Add(calc_approximate_match_btn_sizer, 0, wxALIGN_CENTER | wxALL, 0);
|
|
quick_set_sizer->AddSpacer(FromDIP(10));
|
|
quick_set_sizer->Add(calc_reset_btn_sizer, 0, wxALIGN_CENTER | wxALL, 0);
|
|
quick_set_sizer->AddSpacer(FromDIP(10));
|
|
m_sizer_simple->Add(quick_set_sizer, 0, wxEXPAND | wxTOP, FromDIP(10));
|
|
|
|
wxBoxSizer *warning_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
m_warning_text = new wxStaticText(m_page_simple, wxID_ANY, "");
|
|
m_warning_text->SetForegroundColour(wxColour(107, 107, 107, 100));
|
|
warning_sizer->Add(m_warning_text, 0, wxALIGN_CENTER | wxALL, 0);
|
|
m_sizer_simple->Add(warning_sizer, 0, wxEXPAND | wxLEFT, FromDIP(25));
|
|
|
|
m_sizer_simple->AddSpacer(15);
|
|
}
|
|
deal_default_strategy();
|
|
deal_thumbnail();
|
|
//page_simple//page_advanced
|
|
m_sizer = new wxBoxSizer(wxVERTICAL);
|
|
m_sizer->Add(m_page_simple, 0, wxEXPAND, 0);
|
|
|
|
m_sizer->SetSizeHints(this);
|
|
SetSizer(m_sizer);
|
|
this->Layout();
|
|
}
|
|
|
|
ObjColorPanel::~ObjColorPanel() {
|
|
}
|
|
|
|
void ObjColorPanel::msw_rescale()
|
|
{
|
|
for (unsigned int i = 0; i < m_extruder_icon_list.size(); ++i) {
|
|
auto bitmap = *get_extruder_color_icon(m_colours[i].GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(i + 1), FromDIP(16), FromDIP(16));
|
|
m_extruder_icon_list[i]->SetBitmap(bitmap);
|
|
}
|
|
/* for (unsigned int i = 0; i < m_color_cluster_icon_list.size(); ++i) {
|
|
auto bitmap = *get_extruder_color_icon(m_cluster_colours[i].GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(i + 1), FromDIP(16), FromDIP(16));
|
|
m_color_cluster_icon_list[i]->SetBitmap(bitmap);
|
|
}*/
|
|
}
|
|
|
|
bool ObjColorPanel::is_ok() {
|
|
for (auto item : m_result_icon_list) {
|
|
if (item->bitmap_combox->IsShown()) {
|
|
auto selection = item->bitmap_combox->GetSelection();
|
|
if (selection < 1) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void ObjColorPanel::send_new_filament_to_ui()
|
|
{
|
|
update_new_add_final_colors();
|
|
if (m_is_add_filament) {
|
|
for (auto c : m_new_add_final_colors) {
|
|
/*auto evt = new ColorEvent(EVT_ADD_CUSTOM_FILAMENT, c);
|
|
wxQueueEvent(wxGetApp().plater(), evt);*/
|
|
wxGetApp().sidebar().add_custom_filament(c);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ObjColorPanel::cancel_paint_color() {
|
|
m_filament_ids.clear();
|
|
auto mo = m_obj_in_out.model->objects[0];
|
|
mo->config.set("extruder", 1);
|
|
clear_instance_and_revert_offset();
|
|
auto mv = mo->volumes[0];
|
|
mv->mmu_segmentation_facets.reset();
|
|
mv->config.set("extruder", 1);
|
|
m_first_extruder_id = 1;
|
|
}
|
|
|
|
void ObjColorPanel::update_filament_ids()
|
|
{
|
|
//deal m_filament_ids
|
|
m_filament_ids.clear();
|
|
m_filament_ids.reserve(m_input_colors_size);
|
|
for (size_t i = 0; i < m_input_colors_size; i++) {
|
|
auto label = m_cluster_labels_from_algo[i];
|
|
if (m_cluster_map_filaments[label] > 0) {
|
|
m_filament_ids.emplace_back(m_cluster_map_filaments[label]);
|
|
} else {
|
|
m_filament_ids.emplace_back(1);//min filament_id is 1
|
|
}
|
|
}
|
|
m_first_extruder_id = m_cluster_map_filaments[0];
|
|
}
|
|
|
|
void ObjColorPanel::set_layout_callback(LayoutChanggeCallback callback) {
|
|
m_layout_callback = callback;
|
|
}
|
|
|
|
void ObjColorPanel::do_layout_callback() {
|
|
if (m_layout_callback) {
|
|
m_layout_callback();
|
|
}
|
|
}
|
|
|
|
wxBoxSizer *ObjColorPanel::create_approximate_match_btn_sizer(wxWindow *parent)
|
|
{
|
|
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
m_quick_approximate_match_btn = new Button(parent, _L("Color match"));
|
|
m_quick_approximate_match_btn->SetToolTip(_L("Approximate color matching."));
|
|
m_quick_approximate_match_btn->SetStyle(ButtonStyle::Regular, ButtonType::Window);
|
|
m_quick_approximate_match_btn->SetFocus();
|
|
btn_sizer->Add(m_quick_approximate_match_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 0);
|
|
m_quick_approximate_match_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
|
|
deal_approximate_match_btn();
|
|
deal_thumbnail();
|
|
});
|
|
return btn_sizer;
|
|
}
|
|
|
|
wxBoxSizer *ObjColorPanel::create_add_btn_sizer(wxWindow *parent)
|
|
{
|
|
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
m_quick_add_btn = new Button(parent, _L("Append"));
|
|
m_quick_add_btn->SetToolTip(_L("Append to existing filaments"));
|
|
auto cur_btn = m_quick_add_btn;
|
|
cur_btn->SetStyle(ButtonStyle::Regular, ButtonType::Window);
|
|
cur_btn->SetFocus();
|
|
btn_sizer->Add(cur_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 0);
|
|
cur_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
|
|
deal_add_btn();
|
|
deal_thumbnail();
|
|
});
|
|
m_quick_add_btn->Enable(m_semm); // only SEMM printer can add more colors
|
|
return btn_sizer;
|
|
}
|
|
|
|
wxBoxSizer *ObjColorPanel::create_reset_btn_sizer(wxWindow *parent)
|
|
{
|
|
auto btn_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
m_quick_reset_btn = new Button(parent, _L("Reset"));
|
|
m_quick_reset_btn->SetToolTip(_L("Reset mapped extruders."));
|
|
auto cur_btn = m_quick_reset_btn;
|
|
cur_btn->SetStyle(ButtonStyle::Regular, ButtonType::Window);
|
|
cur_btn->SetFocus();
|
|
btn_sizer->Add(cur_btn, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 0);
|
|
cur_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) {
|
|
deal_reset_btn();
|
|
deal_thumbnail();
|
|
});
|
|
return btn_sizer;
|
|
}
|
|
|
|
wxBoxSizer *ObjColorPanel::create_extruder_icon_and_rgba_sizer(wxWindow *parent, int id, const wxColour &color)
|
|
{
|
|
auto icon_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
wxButton *icon = new wxButton(parent, wxID_ANY, {}, wxDefaultPosition, FromDIP(wxSize(20,20)), wxBORDER_NONE | wxBU_AUTODRAW);
|
|
icon->SetBitmap(*get_extruder_color_icon(color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(id + 1), FromDIP(20), FromDIP(20)));
|
|
icon->SetCanFocus(false);
|
|
#ifdef __WXGTK__
|
|
RemoveButtonBorder(icon);
|
|
#endif
|
|
m_extruder_icon_list.emplace_back(icon);
|
|
icon_sizer->Add(icon, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0); // wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM
|
|
//icon_sizer->AddSpacer(FromDIP(5));
|
|
return icon_sizer;
|
|
}
|
|
|
|
std::string ObjColorPanel::get_color_str(const wxColour &color) {
|
|
std::string str = ("R:" + std::to_string(color.Red()) +
|
|
std::string(" G:") + std::to_string(color.Green()) +
|
|
std::string(" B:") + std::to_string(color.Blue()) +
|
|
std::string(" A:") + std::to_string(color.Alpha()));
|
|
return str;
|
|
}
|
|
|
|
ComboBox *ObjColorPanel::CreateEditorCtrl(wxWindow *parent, int id) // wxRect labelRect,, const wxVariant &value
|
|
{
|
|
std::vector<wxBitmap *> icons = get_extruder_color_icons();
|
|
const double em = Slic3r::GUI::wxGetApp().em_unit();
|
|
bool thin_icon = false;
|
|
const int icon_width = lround((thin_icon ? 2 : 4.4) * em);
|
|
const int icon_height = lround(2 * em);
|
|
m_combox_icon_width = icon_width;
|
|
m_combox_icon_height = icon_height;
|
|
|
|
icons.insert(icons.begin(), get_extruder_color_icon(g_undefined_color_in_obj.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), std::to_string(-1), icon_width, icon_height));
|
|
if (icons.empty())
|
|
return nullptr;
|
|
|
|
::ComboBox *c_editor = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, nullptr,
|
|
wxCB_READONLY | CB_NO_DROP_ICON | CB_NO_TEXT);
|
|
c_editor->SetMinSize(wxSize(icon_width + FromDIP(8), -1)); // match size with bitmap
|
|
c_editor->SetMaxSize(wxSize(icon_width + FromDIP(8), -1)); // match size with bitmap
|
|
c_editor->GetDropDown().SetUseContentWidth(false);
|
|
for (size_t i = 0; i < icons.size(); i++) {
|
|
c_editor->Append(wxString::Format("%d", i), *icons[i]);
|
|
if (i == 0) {
|
|
c_editor->SetItemTooltip(i, g_undefined_color_in_obj.GetAsString(wxC2S_HTML_SYNTAX));
|
|
} else {
|
|
c_editor->SetItemTooltip(i, m_colours[i-1].GetAsString(wxC2S_HTML_SYNTAX));
|
|
}
|
|
}
|
|
c_editor->SetSelection(0);
|
|
c_editor->SetName(wxString::Format("%d", id));
|
|
c_editor->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &evt) {
|
|
auto *com_box = static_cast<ComboBox *>(evt.GetEventObject());
|
|
int i = atoi(com_box->GetName().c_str());
|
|
if (i < m_cluster_map_filaments.size()) {
|
|
m_cluster_map_filaments[i] = com_box->GetSelection();
|
|
m_new_add_colors[i] = com_box->GetItemTooltip(com_box->GetSelection());
|
|
deal_thumbnail();
|
|
}
|
|
evt.StopPropagation();
|
|
});
|
|
return c_editor;
|
|
}
|
|
|
|
void ObjColorPanel::deal_approximate_match_btn()
|
|
{
|
|
m_warning_text->SetLabelText("");
|
|
if (m_result_icon_list.size() == 0) { return; }
|
|
auto map_count = m_result_icon_list[0]->bitmap_combox->GetCount() -1;
|
|
if (map_count < 1) { return; }
|
|
for (size_t i = 0; i < m_cluster_colours.size(); i++) {
|
|
auto c = m_cluster_colours[i];
|
|
std::vector<ColorDistValue> color_dists;
|
|
color_dists.resize(map_count);
|
|
for (size_t j = 0; j < map_count; j++) {
|
|
auto tip_color = m_result_icon_list[0]->bitmap_combox->GetItemTooltip(j+1);
|
|
wxColour candidate_c(tip_color);
|
|
color_dists[j].distance = calc_color_distance(c, candidate_c);
|
|
color_dists[j].id = j + 1;
|
|
}
|
|
std::sort(color_dists.begin(), color_dists.end(), [](ColorDistValue &a, ColorDistValue& b) {
|
|
return a.distance < b.distance;
|
|
});
|
|
auto new_index= color_dists[0].id;
|
|
m_result_icon_list[i]->bitmap_combox->SetSelection(new_index);
|
|
m_new_add_colors[i] = m_result_icon_list[i]->bitmap_combox->GetItemTooltip(new_index);
|
|
m_cluster_map_filaments[i] = new_index;
|
|
}
|
|
}
|
|
|
|
void ObjColorPanel::show_sizer(wxSizer *sizer, bool show)
|
|
{
|
|
wxSizerItemList items = sizer->GetChildren();
|
|
for (wxSizerItemList::iterator it = items.begin(); it != items.end(); ++it) {
|
|
wxSizerItem *item = *it;
|
|
if (wxWindow *window = item->GetWindow()) {
|
|
window->Show(show);
|
|
}
|
|
if (wxSizer *son_sizer = item->GetSizer()) {
|
|
show_sizer(son_sizer, show);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void ObjColorPanel::draw_new_table()
|
|
{
|
|
auto cluster_count = m_cluster_colours.size();
|
|
auto col = 3;
|
|
auto row = cluster_count / col;
|
|
auto remainder = cluster_count % col;
|
|
if (remainder > 0) {
|
|
row++;
|
|
}
|
|
int old_row = 0;
|
|
bool first_draw = false;
|
|
if (m_new_grid_sizer) {
|
|
old_row = m_new_grid_sizer->GetRows();
|
|
m_new_grid_sizer->SetRows(row);
|
|
}
|
|
else {
|
|
first_draw = true;
|
|
m_new_grid_sizer = new wxGridSizer(row, 1, 1, 3); //(int rows, int cols, int vgap, int hgap );
|
|
m_scrolledWindow->SetSizer(m_new_grid_sizer);
|
|
}
|
|
if (!first_draw) {
|
|
for (size_t i = old_row; i < row; i++) { show_sizer(m_row_sizer_list[i], true); }
|
|
for (size_t i = row; i < old_row; i++) { show_sizer(m_row_sizer_list[i], false); }
|
|
for (size_t i = 0; i < cluster_count; i++) { show_sizer(m_row_col_boxsizer_list[i], true); }
|
|
for (size_t i = cluster_count; i < m_color_num_recommend; i++) { show_sizer(m_row_col_boxsizer_list[i], false); }
|
|
for (size_t ii = 0; ii < row; ii++) {
|
|
for (size_t j = 0; j < col; j++) {
|
|
auto id = ii * col + j;
|
|
if (id >= cluster_count) {
|
|
break;
|
|
}
|
|
auto color = m_cluster_colours[id];
|
|
m_color_cluster_icon_list[id]->SetBitmap(*get_extruder_color_icon(color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), "", FromDIP(16), FromDIP(16)));
|
|
}
|
|
}
|
|
}
|
|
else {//first draw
|
|
for (size_t ii = 0; ii < row; ii++) {
|
|
wxPanel *row_panel = new wxPanel(m_scrolledWindow);
|
|
//row_panel->SetBackgroundColour(ii % 2 == 0 ? *wxWHITE : wxColour(238, 238, 238));
|
|
auto row_sizer = new wxGridSizer(1, col, 1, 1);
|
|
row_panel->SetSizer(row_sizer);
|
|
|
|
row_panel->SetMinSize(wxSize(FromDIP(PANEL_WIDTH), -1));
|
|
row_panel->SetMaxSize(wxSize(FromDIP(PANEL_WIDTH), -1));
|
|
for (size_t j = 0; j < col; j++) {
|
|
auto id = ii * col + j;
|
|
if (id >= cluster_count) {
|
|
break;
|
|
}
|
|
auto cluster_color_icon_sizer = create_color_icon_map_rgba_sizer(row_panel, id, m_cluster_colours[id]);
|
|
m_row_col_boxsizer_list.emplace_back(cluster_color_icon_sizer);
|
|
row_sizer->Add(cluster_color_icon_sizer, 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL, 0);
|
|
}
|
|
m_row_sizer_list.emplace_back(row_sizer);
|
|
m_new_grid_sizer->Add(row_panel, 0, wxALIGN_LEFT | wxALL, FromDIP(HEADER_BORDER));
|
|
}
|
|
}
|
|
m_new_grid_sizer->Layout();
|
|
auto height = m_new_grid_sizer->GetMinSize().GetY();
|
|
if (row <= 4 || height < FromDIP(185)) {
|
|
m_scrolledWindow->SetMinSize(wxSize(-1, height));
|
|
} else {
|
|
m_scrolledWindow->SetMinSize(wxSize(-1, FromDIP(185)));
|
|
m_scrolledWindow->SetMaxSize(wxSize(-1, FromDIP(185)));
|
|
}
|
|
m_scrolledWindow->FitInside();
|
|
if (!first_draw) {
|
|
do_layout_callback();
|
|
}
|
|
}
|
|
|
|
void ObjColorPanel::update_new_add_final_colors()
|
|
{
|
|
m_new_add_final_colors = m_new_add_colors;
|
|
if (!m_cluster_map_filaments.empty()) {
|
|
m_max_filament_index = *std::max_element(m_cluster_map_filaments.begin(), m_cluster_map_filaments.end());
|
|
} else {
|
|
m_max_filament_index = 0;
|
|
}
|
|
|
|
if (m_max_filament_index <= m_colours.size()) { // Fix 20240904
|
|
m_new_add_final_colors.clear();
|
|
}
|
|
else {
|
|
m_new_add_final_colors.resize(m_max_filament_index - m_colours.size());
|
|
for (int ii = m_colours.size() ; ii < m_max_filament_index; ii++) {
|
|
for (int j = 0; j < m_cluster_map_filaments.size(); j++) {
|
|
if (m_cluster_map_filaments[j] == (ii+ 1) && j < m_new_add_colors.size()) {
|
|
auto index = ii - m_colours.size();
|
|
if (index < m_new_add_final_colors.size()) {
|
|
m_new_add_final_colors[index] = m_new_add_colors[j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (m_new_add_final_colors.size() > 0) {
|
|
m_is_add_filament = true;
|
|
}
|
|
}
|
|
|
|
void ObjColorPanel::deal_algo(char cluster_number, bool redraw_ui)
|
|
{
|
|
if (m_last_cluster_number == cluster_number) {
|
|
return;
|
|
}
|
|
wxBusyCursor cursor;
|
|
m_last_cluster_number = cluster_number;
|
|
obj_color_deal_algo(m_input_colors, m_cluster_colors_from_algo, m_cluster_labels_from_algo, cluster_number,g_max_color);
|
|
|
|
m_cluster_colours.clear();
|
|
m_cluster_colours.reserve(m_cluster_colors_from_algo.size());
|
|
for (size_t i = 0; i < m_cluster_colors_from_algo.size(); i++) {
|
|
m_cluster_colours.emplace_back(convert_to_wxColour(m_cluster_colors_from_algo[i]));
|
|
}
|
|
if (m_cluster_colours.size() == 0) {
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",m_cluster_colours.size() = 0\n";
|
|
return;
|
|
}
|
|
m_cluster_map_filaments.resize(m_cluster_colors_from_algo.size());
|
|
m_new_add_colors.resize(m_cluster_map_filaments.size());
|
|
m_color_cluster_num_by_algo = m_cluster_colors_from_algo.size();
|
|
if (cluster_number == -1) {
|
|
m_color_num_recommend = m_color_cluster_num_by_algo;
|
|
}
|
|
//redraw ui
|
|
if (redraw_ui) {
|
|
deal_reset_btn();
|
|
draw_new_table();
|
|
deal_default_strategy();
|
|
deal_thumbnail();
|
|
}
|
|
}
|
|
|
|
void ObjColorPanel::deal_default_strategy()
|
|
{
|
|
bool is_exceed = deal_add_btn();
|
|
if (!is_exceed) {
|
|
deal_approximate_match_btn();
|
|
}
|
|
m_warning_text->SetLabelText(_L("Note") + ": " + _L("The color has been selected, you can choose OK \n to continue or manually adjust it."));
|
|
}
|
|
|
|
void ObjColorPanel::deal_thumbnail() {
|
|
update_filament_ids();
|
|
// generate model volume
|
|
if (m_obj_in_out.deal_vertex_color) {
|
|
if (m_obj_in_out.filament_ids.size() > 0) {
|
|
m_deal_thumbnail_flag = Model::obj_import_vertex_color_deal(m_obj_in_out.filament_ids, m_obj_in_out.first_extruder_id, m_obj_in_out.model);
|
|
}
|
|
} else {
|
|
if (m_obj_in_out.filament_ids.size() > 0) {
|
|
m_deal_thumbnail_flag = Model::obj_import_face_color_deal(m_obj_in_out.filament_ids, m_obj_in_out.first_extruder_id, m_obj_in_out.model);
|
|
}
|
|
}
|
|
generate_thumbnail();
|
|
}
|
|
|
|
void ObjColorPanel::generate_thumbnail()
|
|
{
|
|
if (m_deal_thumbnail_flag && m_obj_in_out.model->objects.size() == 1) {
|
|
std::vector<Slic3r::ColorRGBA> colors = GUI::wxGetApp().plater()->get_extruders_colors();
|
|
for (size_t i = 0; i < m_new_add_colors.size(); i++) {
|
|
Slic3r::ColorRGBA temp_color;
|
|
temp_color[0] = m_new_add_colors[i].Red() / 255.f;
|
|
temp_color[1] = m_new_add_colors[i].Green() / 255.f;
|
|
temp_color[2] = m_new_add_colors[i].Blue() / 255.f;
|
|
temp_color[3] = m_new_add_colors[i].Alpha() / 255.f;
|
|
colors.emplace_back(temp_color);
|
|
}
|
|
|
|
auto mo = m_obj_in_out.model->objects[0];
|
|
wxGetApp().plater()->update_obj_preview_thumbnail(mo, 0, 0, colors, (int) m_camera_view_angle_type);
|
|
// get thumbnail image
|
|
PartPlate *plate = wxGetApp().plater()->get_partplate_list().get_plate(0);
|
|
auto & data = plate->obj_preview_thumbnail_data;
|
|
if (data.is_valid()) {
|
|
wxImage image(data.width, data.height);
|
|
image.InitAlpha();
|
|
for (unsigned int r = 0; r < data.height; ++r) {
|
|
unsigned int rr = (data.height - 1 - r) * data.width;
|
|
for (unsigned int c = 0; c < data.width; ++c) {
|
|
unsigned char *px = (unsigned char *) data.pixels.data() + 4 * (rr + c);
|
|
image.SetRGB((int) c, (int) r, px[0], px[1], px[2]);
|
|
image.SetAlpha((int) c, (int) r, px[3]);
|
|
}
|
|
}
|
|
image = image.Rescale(FromDIP(IMAGE_SIZE_WIDTH), FromDIP(IMAGE_SIZE_WIDTH));
|
|
m_image_button->SetBitmap(image);
|
|
}
|
|
|
|
}
|
|
else {
|
|
#ifdef _WIN32
|
|
__debugbreak();
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void ObjColorPanel::set_view_angle_type(int value)
|
|
{
|
|
if (value >= 0) {
|
|
m_camera_view_angle_type = (Slic3r::GUI::Camera::ViewAngleType) value;
|
|
generate_thumbnail();
|
|
}
|
|
}
|
|
|
|
|
|
void ObjColorPanel::clear_instance_and_revert_offset()
|
|
{
|
|
auto mo = m_obj_in_out.model->objects[0];
|
|
mo->clear_instances();
|
|
auto mv = mo->volumes[0];
|
|
auto box = mo->bounding_box_exact();
|
|
if (!m_thumbnail_offset.isApprox(Slic3r::Vec3d::Zero())) {
|
|
mv->translate(-m_thumbnail_offset);
|
|
}
|
|
}
|
|
|
|
bool ObjColorPanel::do_show(bool show) {
|
|
if (show) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool ObjColorPanel::deal_add_btn()
|
|
{
|
|
if (!m_semm) { return false; }// only SEMM printer can add more colors
|
|
if (m_colours.size() > g_max_color) { return false; }
|
|
deal_reset_btn();
|
|
std::vector<wxBitmap *> new_icons;
|
|
auto new_color_size = m_cluster_colors_from_algo.size();
|
|
new_icons.reserve(new_color_size);
|
|
m_new_add_colors.clear();
|
|
m_new_add_colors.reserve(new_color_size);
|
|
int new_index = m_colours.size() + 1;
|
|
bool is_exceed = false;
|
|
for (size_t i = 0; i < new_color_size; i++) {
|
|
if (m_colours.size() + new_icons.size() >= g_max_color) {
|
|
is_exceed = true;
|
|
break;
|
|
}
|
|
wxColour cur_color = convert_to_wxColour(m_cluster_colors_from_algo[i]);
|
|
m_new_add_colors.emplace_back(cur_color);
|
|
new_icons.emplace_back(get_extruder_color_icon(cur_color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(),
|
|
std::to_string(new_index), m_combox_icon_width, m_combox_icon_height));
|
|
new_index++;
|
|
}
|
|
new_index = m_colours.size() + 1;
|
|
for (size_t i = 0; i < m_result_icon_list.size(); i++) {
|
|
auto item = m_result_icon_list[i];
|
|
for (size_t k = 0; k < new_icons.size(); k++) {
|
|
item->bitmap_combox->Append(wxString::Format("%d", item->bitmap_combox->GetCount()), *new_icons[k]);
|
|
item->bitmap_combox->SetItemTooltip(item->bitmap_combox->GetCount() -1,m_new_add_colors[k].GetAsString(wxC2S_HTML_SYNTAX));
|
|
}
|
|
item->bitmap_combox->SetSelection(new_index);
|
|
m_cluster_map_filaments[i] = new_index;
|
|
new_index++;
|
|
}
|
|
if (is_exceed) {
|
|
deal_approximate_match_btn();
|
|
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",Waring:The count of newly added and \n current extruders exceeds 32.";
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void ObjColorPanel::deal_reset_btn()
|
|
{
|
|
for (auto item : m_result_icon_list) {
|
|
// delete redundant bitmap
|
|
while (item->bitmap_combox->GetCount() > m_colours.size()+ 1) {
|
|
item->bitmap_combox->DeleteOneItem(item->bitmap_combox->GetCount() - 1);
|
|
}
|
|
item->bitmap_combox->SetSelection(0);
|
|
}
|
|
for (int i = 0; i < m_new_add_colors.size(); i++) {
|
|
m_new_add_colors[i] = g_undefined_color_in_obj;
|
|
}
|
|
m_warning_text->SetLabelText("");
|
|
}
|
|
|
|
wxBoxSizer *ObjColorPanel::create_color_icon_map_rgba_sizer(wxWindow *parent, int id, const wxColour &color)
|
|
{
|
|
auto icon_sizer = new wxBoxSizer(wxHORIZONTAL);
|
|
//icon_sizer->AddSpacer(FromDIP(40));
|
|
wxButton *icon = new wxButton(parent, wxID_ANY, {}, wxDefaultPosition, FromDIP(wxSize(20,20)), wxBORDER_NONE | wxBU_AUTODRAW);
|
|
icon->SetBitmap(*get_extruder_color_icon(color.GetAsString(wxC2S_HTML_SYNTAX).ToStdString(), "", FromDIP(20), FromDIP(20)));
|
|
icon->SetCanFocus(false);
|
|
#ifdef __WXGTK__
|
|
RemoveButtonBorder(icon);
|
|
#endif
|
|
m_color_cluster_icon_list.emplace_back(icon);
|
|
icon_sizer->Add(icon, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0); // wxALIGN_CENTER_VERTICAL | wxTOP | wxBOTTOM
|
|
icon_sizer->AddSpacer(FromDIP(10));
|
|
|
|
wxStaticText *map_text = new wxStaticText(parent, wxID_ANY, _L(u8"—> "));
|
|
map_text->SetFont(Label::Head_12);
|
|
icon_sizer->Add(map_text, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
|
|
|
|
for (size_t i = m_result_icon_list.size(); i < id + 1; i++) {
|
|
m_result_icon_list.emplace_back(new ButtonState());
|
|
}
|
|
m_result_icon_list[id]->bitmap_combox = CreateEditorCtrl(parent, id);
|
|
icon_sizer->Add(m_result_icon_list[id]->bitmap_combox, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 0);
|
|
return icon_sizer;
|
|
}
|