Improvements for Color paint widget (#13421)

* init

* fix build error

* Update GLGizmoMmuSegmentation.cpp

* Update GLGizmoMmuSegmentation.cpp

* Update GLGizmoMmuSegmentation.cpp

* fix popup positioning and add tooltip for remap info
This commit is contained in:
yw4z
2026-05-05 15:35:31 +03:00
committed by GitHub
parent b3482265e0
commit 1433521f98
2 changed files with 144 additions and 246 deletions

View File

@@ -115,9 +115,9 @@ bool GLGizmoMmuSegmentation::on_init()
m_desc["smart_fill_angle"] = _L("Smart fill angle");
m_desc["height_range"] = _L("Height range");
m_desc["toggle_wireframe"] = _L("Toggle Wireframe");
m_desc["perform_remap"] = _L("Remap filaments");
m_desc["perform_remap"] = _u8L("Remap filaments");
m_desc["remap"] = _L("Remap");
m_desc["cancel_remap"] = _L("Cancel");
m_desc["remap_reset"] = _L("Reset");
std::pair<wxString, wxString> paint_shortcut = {_L("Left mouse button"), m_desc["paint"]};
std::pair<wxString, wxString> erase_shortcut = {shift + _L("Left mouse button"), m_desc["erase"]};
@@ -304,10 +304,56 @@ void GLGizmoMmuSegmentation::render_tooltip_button(float x, float y)
GLGizmoUtils::render_tooltip_button(m_imgui, m_parent, get_shortcuts(), x, y);
}
// ORCA
bool GLGizmoMmuSegmentation::draw_color_button(int idx, std::string id_str, const ColorRGBA& color, ColorRGBA& map_color, bool active, float scale)
{
ImDrawList* draw_list = ImGui::GetWindowDrawList();
std::string label_id = std::to_string(idx) + id_str + std::to_string(idx);
ImVec2 pos = ImGui::GetCursorScreenPos();
ImVec2 size = ImVec2(27.f * scale, 27.f * scale);
ImVec4 color_vec = ImGuiWrapper::to_ImVec4(color);
ImU32 br_color = ImGui::ColorConvertFloat4ToU32(active ? ImGuiWrapper::COL_ORCA : m_is_dark_mode ? ImVec4(.35f, .35f, .35f, 1) : ImVec4(.85f, .85f, .85f, 1));
bool dark_tone = (0.299f * color.r() + 0.587f * color.g() + 0.114f * color.b()) < 0.51f; // matching values used by wxWidgets with clr.GetLuminance() < 0.51
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding , 7.f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding , ImVec2(0, 0));
ImGui::PushStyleColor(ImGuiCol_Text , dark_tone ? ImVec4(1,1,1,1) : ImVec4(0,0,0,1));
ImGui::PushStyleColor(ImGuiCol_Button , color_vec);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, color_vec);
ImGui::PushStyleColor(ImGuiCol_ButtonActive , color_vec);
bool clicked = ImGui::Button(label_id.c_str(), size);
ImGui::PopStyleVar(3);
ImGui::PopStyleColor(4);
auto drawBorder = [&](float d, float r, float t, ImU32 col) {
draw_list->AddRect({pos.x + d * scale, pos.y + d * scale}, {pos.x + size.x - d * scale , pos.y + size.y - d * scale}, col, r * scale, 0, t * scale);
};
drawBorder(1.5f, 3.f, 4.f, ImGui::ColorConvertFloat4ToU32(ImGui::GetStyleColorVec4(ImGuiCol_WindowBg)));
if(active)
drawBorder(.5f, 4.f , 2.f, br_color);
else
drawBorder(3.f, 2.5f, 1.f, br_color);
if (color != map_color){ // show mapped color as bubble if mapped
ImVec2 center = {pos.x + size.x - 3.f * scale, pos.y + 3.f * scale};
draw_list->AddCircleFilled(center, 6.f * scale, br_color, 16); // outer border for better visibility
draw_list->AddCircleFilled(center, 5.f * scale, ImGuiWrapper::to_ImU32(map_color), 16);
}
return clicked;
};
void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bottom_limit)
{
if (!m_c->selection_info()->model_object()) return;
float scale = m_parent.get_scale();
#ifdef WIN32
int dpi = get_dpi_for_window(wxGetApp().GetTopWindow());
scale *= (float) dpi / (float) DPI_DEFAULT;
#endif // WIN32
const float approx_height = m_imgui->scaled(22.0f);
y = std::min(y, bottom_limit - approx_height);
GizmoImguiSetNextWIndowPos(x, y, ImGuiCond_Always);
@@ -363,69 +409,67 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
const float drag_left_width = ImGui::GetStyle().WindowPadding.x + sliders_width - space_size;
const float max_tooltip_width = ImGui::GetFontSize() * 20.0f;
ImDrawList * draw_list = ImGui::GetWindowDrawList();
ImVec2 pos = ImGui::GetCursorScreenPos();
static float color_button_high = 25.0;
draw_list->AddRectFilled({pos.x - 10.0f, pos.y - 7.0f}, {pos.x + window_width + ImGui::GetFrameHeight(), pos.y + color_button_high}, ImGui::GetColorU32(ImGuiCol_FrameBgActive, 1.0f), 5.0f);
float color_button = ImGui::GetCursorPos().y;
m_imgui->text(m_desc.at("filaments"));
float start_pos_x = ImGui::GetCursorPos().x;
const ImVec2 max_label_size = ImGui::CalcTextSize("99", NULL, true);
const float item_spacing = m_imgui->scaled(0.8f);
size_t n_extruder_colors = std::min((size_t)EnforcerBlockerType::ExtruderMax, m_extruders_colors.size());
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(7.f * scale, 7.f * scale));
ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, 0); // removes extra space on tree node indentation
for (int extruder_idx = 0; extruder_idx < n_extruder_colors; extruder_idx++) {
const ColorRGBA &extruder_color = m_extruders_colors[extruder_idx];
ImVec4 color_vec = ImGuiWrapper::to_ImVec4(extruder_color);
std::string color_label = std::string("##extruder color ") + std::to_string(extruder_idx);
std::string item_text = std::to_string(extruder_idx + 1);
const ImVec2 label_size = ImGui::CalcTextSize(item_text.c_str(), NULL, true);
const ImVec2 button_size(max_label_size.x + m_imgui->scaled(0.5f),0.f);
if (extruder_idx % max_filament_items_per_line != 0)
ImGui::SameLine();
float button_offset = start_pos_x;
if (extruder_idx % max_filament_items_per_line != 0) {
button_offset += filament_item_width * (extruder_idx % max_filament_items_per_line);
ImGui::SameLine(button_offset);
if (draw_color_button(
extruder_idx + 1, // idx
"###extruder_color_", // button_id
m_extruders_colors[extruder_idx], // color
m_extruders_colors[extruder_idx], // mapped_color (not used in here)
m_selected_extruder_idx == extruder_idx, // is_active
scale
)){
m_selected_extruder_idx = extruder_idx;
}
// draw filament background
ImGuiColorEditFlags flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip;
if (m_selected_extruder_idx != extruder_idx) flags |= ImGuiColorEditFlags_NoBorder;
#ifdef __APPLE__
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA); // ORCA use orca color for selected filament border
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0);
bool color_picked = ImGui::ColorButton(color_label.c_str(), color_vec, flags, button_size);
ImGui::PopStyleVar(2);
ImGui::PopStyleColor(1);
#else
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA); // ORCA use orca color for selected filament border
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0);
bool color_picked = ImGui::ColorButton(color_label.c_str(), color_vec, flags, button_size);
ImGui::PopStyleVar(2);
ImGui::PopStyleColor(1);
#endif
color_button_high = ImGui::GetCursorPos().y - color_button - 2.0;
if (color_picked) { m_selected_extruder_idx = extruder_idx; }
if (extruder_idx < 16 && ImGui::IsItemHovered()) m_imgui->tooltip(_L("Shortcut Key ") + std::to_string(extruder_idx + 1), max_tooltip_width);
// draw filament id
float gray = 0.299 * extruder_color.r() + 0.587 * extruder_color.g() + 0.114 * extruder_color.b();
ImGui::SameLine(button_offset + (button_size.x - label_size.x) / 2.f);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, {10.0,15.0});
if (gray * 255.f < 80.f)
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 1.0f), "%s", item_text.c_str());
else
ImGui::TextColored(ImVec4(0.0f, 0.0f, 0.0f, 1.0f), "%s", item_text.c_str());
ImGui::PopStyleVar();
}
//ImGui::NewLine();
// ORCA: Remap filaments section (Border only, Title in border).
// Styled as a panel for visual grouping.
if (ImGui::TreeNodeEx(m_desc.at("perform_remap").c_str(), ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_FramePadding)){
render_filament_remap_ui(window_width, max_tooltip_width, scale);
bool has_mapping = false;
for (size_t i = 0; i < m_extruder_remap.size(); ++i){
if(m_extruder_remap[i] != i){
has_mapping = true;
break;
}
}
ImGui::Dummy(ImVec2(0,0));
// ORCA: Add Remap and Cancel buttons (outside the panel)
m_imgui->disabled_begin(!has_mapping); // disable when no mapping
if (m_imgui->button(m_desc.at("remap"))) {
this->remap_filament_assignments();
// Reset mapping to identity after apply
for (size_t i = 0; i < m_extruder_remap.size(); ++i) m_extruder_remap[i] = i;
}
m_imgui->disabled_end(/*m_is_unknown_font*/);
if (has_mapping){ // show only when it has mapping
ImGui::SameLine();
if (m_imgui->button(m_desc.at("remap_reset"))) {
// Reset mapping to identity
for (size_t i = 0; i < m_extruder_remap.size(); ++i) m_extruder_remap[i] = i;
}
}
//ImGui::Dummy(ImVec2(0.0f, 3.f * scale));
ImGui::TreePop();
}
ImGui::PopStyleVar(2); // IndentSpacing ItemSpacing
ImGui::Dummy(ImVec2(0.0f, ImGui::GetFontSize() * 0.1));
m_imgui->text(m_desc.at("tool_type"));
@@ -598,60 +642,6 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott
m_c->object_clipper()->set_position_by_ratio(clp_dist, true);
}
ImGui::Separator();
// ORCA: Remap filaments section (Border only, Title in border).
// Styled as a panel for visual grouping.
if (m_imgui->button(m_desc.at("perform_remap"))) {
m_show_remap_panel = !m_show_remap_panel;
}
if (m_show_remap_panel)
{
ImGui::Spacing();
ImDrawList* draw_list = ImGui::GetWindowDrawList();
std::string title = into_u8(m_desc.at("perform_remap"));
float available_width = ImGui::GetContentRegionAvail().x;
// ORCA: Draw Background filled (consistent with Filaments section)
// Use static to remember height from previous frame so we can draw it behind.
static float remap_panel_high = 40.0f;
ImVec2 p_bg_min = ImGui::GetCursorScreenPos();
// Adjust background position: slight negative offset to align with padding, width fills available
// height from static variable.
draw_list->AddRectFilled({p_bg_min.x - 10.0f, p_bg_min.y - 7.0f}, {p_bg_min.x + available_width + ImGui::GetFrameHeight(), p_bg_min.y + remap_panel_high}, ImGui::GetColorU32(ImGuiCol_FrameBgActive, 1.0f), 5.0f);
float start_y = ImGui::GetCursorPos().y;
// ORCA: Title as simple text - Removed as per request (redundant with button)
// m_imgui->text(title);
ImGui::BeginGroup();
// ORCA: Reduce vertical spacing within this group
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(m_imgui->scaled(0.4f), m_imgui->scaled(0.2f)));
render_filament_remap_ui(window_width, max_tooltip_width);
ImGui::PopStyleVar();
ImGui::EndGroup();
// ORCA: Update height for next frame fill
remap_panel_high = ImGui::GetCursorPos().y - start_y;
// ORCA: Add Remap and Cancel buttons (outside the panel)
ImGui::Spacing();
if (m_imgui->button(m_desc.at("remap"))) {
this->remap_filament_assignments();
// Reset mapping to identity after apply
for (size_t i = 0; i < m_extruder_remap.size(); ++i) m_extruder_remap[i] = i;
}
ImGui::SameLine();
if (m_imgui->button(m_desc.at("cancel_remap"))) {
// Reset mapping to identity
for (size_t i = 0; i < m_extruder_remap.size(); ++i) m_extruder_remap[i] = i;
}
}
ImGui::Separator();
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(6.0f, 10.0f));
@@ -1000,180 +990,85 @@ void GLGizmoMmuSegmentation::update_used_filaments()
}
}
void GLGizmoMmuSegmentation::render_filament_remap_ui(float window_width, float max_tooltip_width)
void GLGizmoMmuSegmentation::render_filament_remap_ui(float window_width, float max_tooltip_width, float scale)
{
size_t n_extr = std::min((size_t)EnforcerBlockerType::ExtruderMax, m_extruders_colors.size());
const ImVec2 max_label_size = ImGui::CalcTextSize("99", NULL, true);
const ImVec2 button_size(max_label_size.x + m_imgui->scaled(0.5f), 0.f);
int displayed_count = 0;
const int max_per_line = 8;
// ORCA: Use m_used_filaments to show only relevant source filaments
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(7.f * scale, 7.f * scale));
for (size_t src : m_used_filaments) {
if (src >= n_extr) continue;
const ColorRGBA &src_col = m_extruders_colors[src]; // keep for text contrast
const ColorRGBA &dst_col = m_extruders_colors[m_extruder_remap[src]];
// ORCA: Button now shows the SOURCE color (per maintainer request)
// This keeps the UI stable until "Remap" is clicked.
ImVec4 col_vec = ImGuiWrapper::to_ImVec4(src_col);
if (displayed_count > 0 && (displayed_count % max_per_line != 0))
ImGui::SameLine();
std::string btn_id = "##remap_src_" + std::to_string(src);
std::string pop_id = "popup_" + std::to_string(src);
ImGuiColorEditFlags flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoInputs |
ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoPicker |
ImGuiColorEditFlags_NoTooltip;
// ORCA: Show border ONLY if the popup is open (visual feedback for active selection)
// Decoupled from m_selected_extruder_idx to prevent unwanted selection highlights.
if (!ImGui::IsPopupOpen(pop_id.c_str()))
flags |= ImGuiColorEditFlags_NoBorder;
#ifdef __APPLE__
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0);
bool clicked = ImGui::ColorButton(btn_id.c_str(), col_vec, flags, button_size);
ImGui::PopStyleVar(2);
ImGui::PopStyleColor(1);
#else
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0);
bool clicked = ImGui::ColorButton(btn_id.c_str(), col_vec, flags, button_size);
ImGui::PopStyleVar(2);
ImGui::PopStyleColor(1);
#endif
// overlay destination number with proper contrast calculation
// ORCA: Text still shows DESTINATION index, but contrast is against SOURCE color now.
std::string dst_txt = std::to_string(m_extruder_remap[src] + 1);
float gray = 0.299f * src_col.r() + 0.587f * src_col.g() + 0.114f * src_col.b();
ImVec2 txt_sz = ImGui::CalcTextSize(dst_txt.c_str());
ImVec2 pos = ImGui::GetItemRectMin();
ImVec2 size = ImGui::GetItemRectSize();
if (gray * 255.f < 80.f)
ImGui::GetWindowDrawList()->AddText(
ImVec2(pos.x + (size.x - txt_sz.x) * 0.5f, pos.y + (size.y - txt_sz.y) * 0.5f),
IM_COL32(255,255,255,255), dst_txt.c_str());
else
ImGui::GetWindowDrawList()->AddText(
ImVec2(pos.x + (size.x - txt_sz.x) * 0.5f, pos.y + (size.y - txt_sz.y) * 0.5f),
IM_COL32(0,0,0,255), dst_txt.c_str());
bool src_clicked = draw_color_button(
(int)src + 1, // idx
"###remap_src_", // button_id
m_extruders_colors[src], // color
m_extruders_colors[m_extruder_remap[src]], // mapped_color (shows bubble if not matches with Color)
ImGui::IsPopupOpen(pop_id.c_str()), // is_active
scale
);
// ORCA: Show NEW color as a small triangle in the corner if remapped
if (src != m_extruder_remap[src]) {
float s = m_imgui->scaled(0.55f);
float offset = m_imgui->scaled(0.15f); // Inset to avoid rounded corner clipping
ImVec2 p = ImVec2(pos.x + offset, pos.y + offset);
// Contrast outline: White for dark backgrounds, Black for light backgrounds
// Use dst_col (new color) for outline contrast check? Or src_col?
// Usually outline is around the triangle (dst_col).
float dst_gray = 0.299f * dst_col.r() + 0.587f * dst_col.g() + 0.114f * dst_col.b();
ImU32 outline_col = (dst_gray * 255.f < 80.f) ? IM_COL32(255, 255, 255, 180) : IM_COL32(0, 0, 0, 180);
ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->AddTriangleFilled(
p,
ImVec2(p.x + s, p.y),
ImVec2(p.x, p.y + s),
ImGuiWrapper::to_ImU32(dst_col));
// ORCA: Add a thin outline for better contrast when colors are similar
draw_list->AddTriangle(
p,
ImVec2(p.x + s, p.y),
ImVec2(p.x, p.y + s),
outline_col,
0.5f);
}
// popup with possible destinations
if (clicked) {
if (src_clicked) {
// Calculate popup position centered below the current button
ImVec2 button_pos = ImGui::GetItemRectMin();
ImVec2 button_size = ImGui::GetItemRectSize();
ImVec2 popup_pos(button_pos.x + button_size.x * 0.5f, button_pos.y + button_size.y);
// Set popup styling BEFORE opening popup
// Ensure popup is within the main viewport bounds
int dst_count = (int)std::min(n_extr, (size_t)max_per_line);
float est_popup_w = button_size.x * dst_count
+ ImGui::GetStyle().ItemSpacing.x * (dst_count - 1)
+ ImGui::GetStyle().WindowPadding.x * 2.f;
ImGuiViewport* vp = ImGui::GetMainViewport();
float right_limit = vp->WorkPos.x + vp->WorkSize.x - est_popup_w * 0.5f; // pivot is 0.5 so subtract half
float centered_x = button_pos.x + button_size.x * 0.5f; // pivot 0.5 just needs center x
ImVec2 popup_pos(std::min(centered_x, right_limit), button_pos.y + button_size.y);
ImGui::SetNextWindowPos(popup_pos, ImGuiCond_Appearing, ImVec2(0.5f, -0.1f));
ImGui::SetNextWindowBgAlpha(1.0f); // Ensure full opacity
ImGui::OpenPopup(pop_id.c_str());
}
if (ImGui::IsItemHovered() && src != m_extruder_remap[src]) // show tooltip if it has mapping info
m_imgui->tooltip(std::to_string(src + 1) + " >> " + std::to_string(m_extruder_remap[src] + 1), max_tooltip_width);
// Apply popup styling before BeginPopup using standard Orca colors
ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 4.0f);
ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 1.0f);
// ORCA: Use FrameBgActive for consistency and to ensure visibility of white filaments
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGui::GetStyleColorVec4(ImGuiCol_FrameBgActive));
ImGui::PushStyleColor(ImGuiCol_Border, m_is_dark_mode ? ImVec4(0.5f, 0.5f, 0.5f, 1.0f) : ImVec4(0.6f, 0.6f, 0.6f, 1.0f));
ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding , 8.0f * scale);
ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 2.0f * scale); // thicker & colored border to prevent mixing with main window. Current ImGui version not supports shadows
ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
ImGui::PushStyleColor(ImGuiCol_Border , ImGui::ColorConvertFloat4ToU32(ImGuiWrapper::COL_ORCA));
if (ImGui::BeginPopup(pop_id.c_str())) {
m_imgui->text(_L("To:"));
for (int dst = 0; dst < (int)n_extr; ++dst) {
const ColorRGBA &dst_col_popup = m_extruders_colors[dst];
ImVec4 dst_vec = ImGuiWrapper::to_ImVec4(dst_col_popup);
if (dst > 0 && (dst % max_per_line != 0))
ImGui::SameLine();
std::string dst_btn = "##dst_" + std::to_string(src) + "_" + std::to_string(dst);
// Apply same styling to destination buttons
ImGuiColorEditFlags dst_flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoInputs |
ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoPicker |
ImGuiColorEditFlags_NoTooltip;
// Show border for currently selected destination filament
if (m_extruder_remap[src] != dst) dst_flags |= ImGuiColorEditFlags_NoBorder;
#ifdef __APPLE__
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0);
bool dst_clicked = ImGui::ColorButton(dst_btn.c_str(), dst_vec, dst_flags, button_size);
ImGui::PopStyleVar(2);
ImGui::PopStyleColor(1);
#else
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGuiWrapper::COL_ORCA);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 2.0);
bool dst_clicked = ImGui::ColorButton(dst_btn.c_str(), dst_vec, dst_flags, button_size);
ImGui::PopStyleVar(2);
ImGui::PopStyleColor(1);
#endif
// overlay destination number on popup buttons
std::string dst_num_txt = std::to_string(dst + 1);
float dst_gray = 0.299f * dst_col_popup.r() + 0.587f * dst_col_popup.g() + 0.114f * dst_col_popup.b();
ImVec2 dst_txt_sz = ImGui::CalcTextSize(dst_num_txt.c_str());
ImVec2 dst_pos = ImGui::GetItemRectMin();
ImVec2 dst_size = ImGui::GetItemRectSize();
if (dst_gray * 255.f < 80.f)
ImGui::GetWindowDrawList()->AddText(
ImVec2(dst_pos.x + (dst_size.x - dst_txt_sz.x) * 0.5f, dst_pos.y + (dst_size.y - dst_txt_sz.y) * 0.5f),
IM_COL32(255,255,255,255), dst_num_txt.c_str());
else
ImGui::GetWindowDrawList()->AddText(
ImVec2(dst_pos.x + (dst_size.x - dst_txt_sz.x) * 0.5f, dst_pos.y + (dst_size.y - dst_txt_sz.y) * 0.5f),
IM_COL32(0,0,0,255), dst_num_txt.c_str());
if (dst_clicked)
{
bool dst_clicked = draw_color_button(
dst + 1, // idx
"###remap_dst_", // button_id
m_extruders_colors[dst], // color
m_extruders_colors[dst], // mapped_color (non fuctional in here)
m_extruder_remap[src] == dst, // is_active
scale
);
if (dst_clicked) {
m_extruder_remap[src] = dst;
// update the source button color immediately
ImGui::CloseCurrentPopup();
}
}
ImGui::Dummy(ImVec2(0.0f, 2.f * scale));
ImGui::EndPopup();
}
@@ -1183,6 +1078,7 @@ void GLGizmoMmuSegmentation::render_filament_remap_ui(float window_width, float
displayed_count++;
}
ImGui::PopStyleVar(1); // ItemSpacing
}
void GLGizmoMmuSegmentation::remap_filament_assignments()

View File

@@ -114,7 +114,6 @@ protected:
bool m_detect_geometry_edge = true;
// Filament remap feature
bool m_show_remap_panel = false;
std::vector<size_t> m_extruder_remap; // index → target extruder index
// ORCA: Cache used filaments to filter UI
std::set<size_t> m_used_filaments; // Set of used filament indices (cached)
@@ -136,13 +135,16 @@ private:
void init_model_triangle_selectors();
// ORCA
bool draw_color_button(int idx, std::string id_str, const ColorRGBA& color, ColorRGBA& map_color, bool active, float scale);
// BBS
void update_triangle_selectors_colors();
void init_extruders_data();
// Filament remapping methods
void remap_filament_assignments();
void render_filament_remap_ui(float window_width, float max_tooltip_width);
void render_filament_remap_ui(float window_width, float max_tooltip_width, float scale);
// ORCA: Helper to update the cache of used filaments
void update_used_filaments();