From def47f895901677477fcd57d3153e97c05dac6ca Mon Sep 17 00:00:00 2001 From: yw4z Date: Fri, 22 May 2026 14:04:03 +0300 Subject: [PATCH] Mode button fixes / improvements (#13795) * init * update thumb color --- src/slic3r/GUI/ParamsPanel.cpp | 8 ++ src/slic3r/GUI/Tab.hpp | 2 +- src/slic3r/GUI/Widgets/StateColor.cpp | 3 +- src/slic3r/GUI/Widgets/SwitchButton.cpp | 135 +++++++++++++++--------- src/slic3r/GUI/Widgets/SwitchButton.hpp | 6 ++ 5 files changed, 101 insertions(+), 53 deletions(-) diff --git a/src/slic3r/GUI/ParamsPanel.cpp b/src/slic3r/GUI/ParamsPanel.cpp index c694f8647f..d612b56298 100644 --- a/src/slic3r/GUI/ParamsPanel.cpp +++ b/src/slic3r/GUI/ParamsPanel.cpp @@ -664,6 +664,14 @@ void ParamsPanel::update_mode() sync_mode_view(m_mode_view); sync_mode_view(m_current_tab ? dynamic_cast(m_current_tab)->m_mode_view : nullptr); + + auto sync_mode_icon = [&](ScalableButton* mode_icon) { + if (mode_icon == nullptr) + return; + mode_icon->Show(app_mode != comDevelop); + }; + sync_mode_icon(m_mode_icon); + sync_mode_icon(m_current_tab ? dynamic_cast(m_current_tab)->m_mode_icon : nullptr); } void ParamsPanel::msw_rescale() diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index ec9cfb2db3..e654f6c43b 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -146,7 +146,6 @@ protected: //BBS: GUI refactor wxPanel* m_top_panel; - ScalableButton* m_mode_icon; // ORCA m_static_title replacement wxBoxSizer* m_main_sizer; wxBoxSizer* m_top_sizer; wxBoxSizer* m_top_left_sizer; @@ -307,6 +306,7 @@ public: int m_update_cnt = 0; ModeSwitchButton *m_mode_view = nullptr; + ScalableButton* m_mode_icon = nullptr; // ORCA m_static_title replacement SwitchButton *m_extruder_switch = nullptr; MultiSwitchButton *m_variant_combo = nullptr; diff --git a/src/slic3r/GUI/Widgets/StateColor.cpp b/src/slic3r/GUI/Widgets/StateColor.cpp index d400f53de6..2a9d91f59a 100644 --- a/src/slic3r/GUI/Widgets/StateColor.cpp +++ b/src/slic3r/GUI/Widgets/StateColor.cpp @@ -42,7 +42,8 @@ static std::map gDarkColors{ {"#D7E8DE", "#1F2B27"}, // rgb(215, 232, 222) Not Used anymore // Leftover from BBS {"#2B3436", "#808080"}, // rgb(43, 52, 54) Not Used anymore // Leftover from BBS. Was used as main fill color of icons {"#ABABAB", "#ABABAB"}, - {"#D9D9D9", "#2D2D32"}, // rgb(217, 217, 217) Sidebar > Toggle button track color + {"#D9D9D9", "#27272A"}, // rgb(217, 217, 217) Sidebar > Toggle button track color + {"#FFFEFE", "#D9D9D9"}, // rgb(255, 254, 254) Sidebar > Toggle button thumb color {"#EBF9F0", "#293F34"}, //{"#F0F0F0", "#4C4C54"}, // ORCA diff --git a/src/slic3r/GUI/Widgets/SwitchButton.cpp b/src/slic3r/GUI/Widgets/SwitchButton.cpp index 0ff70d4a77..60c9344077 100644 --- a/src/slic3r/GUI/Widgets/SwitchButton.cpp +++ b/src/slic3r/GUI/Widgets/SwitchButton.cpp @@ -220,14 +220,40 @@ void SwitchButton::update() ModeSwitchButton::ModeSwitchButton(wxWindow* parent, wxWindowID id) { background_color = StateColor( - std::make_pair(wxColour(0xF1, 0xF1, 0xF1), (int) StateColor::Disabled), - std::make_pair(wxColour(0xE3, 0xE3, 0xE3), (int) StateColor::Pressed), - std::make_pair(wxColour(0xD9, 0xD9, 0xD9), (int) StateColor::Normal)); + std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Disabled), + std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Normal) + ); border_color = StateColor( - std::make_pair(wxColour(0xEA, 0xEA, 0xEA), (int) StateColor::Disabled), - std::make_pair(wxColour(0xBC, 0xBC, 0xBC), (int) StateColor::Hovered), - std::make_pair(wxColour(0xC8, 0xC8, 0xC8), (int) StateColor::Focused), - std::make_pair(wxColour(0xCE, 0xCE, 0xCE), (int) StateColor::Normal)); + std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Disabled), + std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Hovered | ~StateColor::Focused), + std::make_pair(wxColour("#26A69A"), (int) StateColor::Focused), + std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Normal) + ); + track_background = StateColor( + std::make_pair(wxColour("#009688"), (int) StateColor::Disabled), + std::make_pair(wxColour("#009688"), (int) StateColor::Normal) + ); + track_border = StateColor( + std::make_pair(wxColour("#D9D9D9"), (int) StateColor::Disabled), + std::make_pair(wxColour("#009688"), (int) StateColor::Hovered | ~StateColor::Focused), + std::make_pair(wxColour("#26A69A"), (int) StateColor::Focused), + std::make_pair(wxColour("#009688"), (int) StateColor::Normal) + ); + dot_active = StateColor( + std::make_pair(wxColour("#FFFEFE"), (int) StateColor::Disabled), + std::make_pair(wxColour("#FFFEFE"), (int) StateColor::Normal) + ); + dot_dimmed = StateColor( + std::make_pair(wxColour("#EEEEEE"), (int) StateColor::Disabled), + std::make_pair(wxColour("#EEEEEE"), (int) StateColor::Normal) + ); + text_color = StateColor( + std::make_pair(wxColour("#6B6B6B"), (int) StateColor::Disabled), + std::make_pair(wxColour("#6B6B6B"), (int) StateColor::Normal) + ); + + state_handler.attach(std::vector{&dot_active, &dot_dimmed, &text_color}); + state_handler.update_binds(); StaticBox::Create(parent, id, wxDefaultPosition, wxDefaultSize, 0); SetBackgroundColour(StaticBox::GetParentBackgroundColor(parent)); @@ -263,7 +289,7 @@ void ModeSwitchButton::SelectAndNotify(int selection) void ModeSwitchButton::Rescale() { - const wxSize button_size = FromDIP(wxSize(48, 20)); + const wxSize button_size = FromDIP(wxSize(48, 18)); SetMinSize(button_size); SetMaxSize(button_size); SetSize(button_size); @@ -274,63 +300,70 @@ void ModeSwitchButton::Rescale() bool ModeSwitchButton::Enable(bool enable /* = true */) { const bool changed = StaticBox::Enable(enable); - if (changed) + if (changed){ + wxCommandEvent e(EVT_ENABLE_CHANGED); + e.SetEventObject(this); + GetEventHandler()->ProcessEvent(e); + m_enabled = enable; // IsEnabled() not works because variable changes after paint event Refresh(); + } return changed; } void ModeSwitchButton::doRender(wxDC& dc) { - dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(wxBrush(GetBackgroundColour())); - dc.DrawRectangle(GetClientRect()); - - const wxRect bounds = GetClientRect().Deflate(1); + const wxRect bounds = GetClientRect(); if (bounds.width <= 0 || bounds.height <= 0) return; - const int states = state_handler.states(); - const bool hovered = (states & StateHandler::Hovered) != 0; - const bool focused = (states & StateHandler::Focused) != 0; - const bool disabled = !IsEnabled(); - - const wxColour track_fill = disabled ? wxColour(0xD0, 0xD0, 0xD4) : - m_pressed ? wxColour(0x5A, 0x5D, 0x64) : wxColour(0x66, 0x69, 0x70); - const wxColour track_border = disabled ? wxColour(0xDD, 0xDD, 0xE0) : - focused ? wxColour("#009688") : - hovered ? wxColour(0x7A, 0x7D, 0x84) : wxColour(0x75, 0x78, 0x7F); - const wxColour active_fill = disabled ? wxColour(0x9E, 0xBE, 0xB9) : - m_pressed ? wxColour(0x00877B) : wxColour("#009688"); - const wxColour active_dot = disabled ? wxColour(0xEC, 0xF4, 0xF2) : wxColour(0xB7, 0xEB, 0xE3); - const wxColour inactive_dot = disabled ? wxColour(0xF2, 0xF2, 0xF4) : wxColour(0xB5, 0xB7, 0xBD); - const wxColour thumb_fill = disabled ? wxColour(0xFA, 0xFA, 0xFA) : *wxWHITE; - const wxColour thumb_border = disabled ? wxColour(0xE7, 0xE7, 0xEA) : wxColour(0xDD, 0xDF, 0xE3); - - dc.SetPen(wxPen(track_border, 1)); - dc.SetBrush(wxBrush(track_fill)); - dc.DrawRoundedRectangle(bounds, bounds.height / 2.0); - - const wxRect thumb = thumb_rect_for(m_selection); - const int fill_right = std::min(bounds.GetRight(), thumb.GetX() + thumb.GetWidth() / 2 + FromDIP(2)); - wxRect active(bounds.x, bounds.y, fill_right - bounds.x + 1, bounds.height); dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(wxBrush(active_fill)); - dc.DrawRoundedRectangle(active, bounds.height / 2.0); + dc.SetBrush(wxBrush(GetBackgroundColour())); + dc.DrawRectangle(bounds); - const int dot_radius = std::max(FromDIP(1), thumb.height / 7); - for (int idx = 0; idx < 3; ++idx) { - if (idx == m_selection) - continue; + int states = state_handler.states(); + double v_center = bounds.height / 2.0; - const wxRect slot = thumb_rect_for(idx); - const wxPoint center(slot.GetX() + slot.GetWidth() / 2, slot.GetY() + slot.GetHeight() / 2); - dc.SetBrush(wxBrush(idx < m_selection ? active_dot : inactive_dot)); - dc.DrawCircle(center, dot_radius); + // Background + dc.SetPen(wxPen(border_color.colorForStates(states), 1)); + dc.SetBrush(wxBrush(background_color.colorForStates(states))); + dc.DrawRoundedRectangle(bounds, v_center); + + if (m_enabled) { + double dot_dist = (bounds.width - bounds.height) * 0.50; + + // Track + dc.SetPen(wxPen(track_border.colorForStates(states), 1)); + dc.SetBrush(wxBrush(track_background.colorForStates(states))); + wxRect track_rc = bounds; + track_rc.width = int(v_center * 2.0 + dot_dist * m_selection); + dc.DrawRoundedRectangle(track_rc, v_center); + + // Dots + dc.SetPen(*wxTRANSPARENT_PEN); + for (int idx = 0; idx < 3; ++idx) { + dc.SetBrush(wxBrush((idx <= m_selection ? dot_active : dot_dimmed).colorForStates(states))); + dc.DrawCircle(wxPoint(v_center + dot_dist * idx, v_center), track_rc.height * (double)(idx == m_selection ? 0.32 : 0.16)); + } } + else { // Developer mode + wxString str = "DEV"; + int kerning = 3; // pixels between chars + dc.SetTextForeground(text_color.colorForStates(states)); - dc.SetPen(wxPen(thumb_border, 1)); - dc.SetBrush(wxBrush(thumb_fill)); - dc.DrawRoundedRectangle(thumb, thumb.height / 2.0); + wxCoord totalWidth = 0; + for (char c : str) + totalWidth += dc.GetTextExtent(wxString(c)).x + kerning; + totalWidth -= kerning; + + wxCoord x = bounds.x + (bounds.width - totalWidth) / 2; + wxCoord y = bounds.y + (bounds.height - dc.GetTextExtent(str).y) / 2 - 1; + + for (char c : str) { + wxString ch(c); + dc.DrawText(ch, x, y); + x += dc.GetTextExtent(ch).x + kerning; + } + } } void ModeSwitchButton::mouseDown(wxMouseEvent& event) diff --git a/src/slic3r/GUI/Widgets/SwitchButton.hpp b/src/slic3r/GUI/Widgets/SwitchButton.hpp index 301287460a..0884fa64aa 100644 --- a/src/slic3r/GUI/Widgets/SwitchButton.hpp +++ b/src/slic3r/GUI/Widgets/SwitchButton.hpp @@ -78,7 +78,13 @@ private: private: int m_selection { 0 }; bool m_pressed { false }; + bool m_enabled { true }; wxString m_tooltips[3]; + StateColor dot_active; + StateColor dot_dimmed; + StateColor text_color; + StateColor track_background; + StateColor track_border; }; class MultiSwitchButton : public StaticBox