diff --git a/resources/icons/down_half_circle.png b/resources/icons/down_half_circle.png new file mode 100644 index 000000000..84aba5c3c Binary files /dev/null and b/resources/icons/down_half_circle.png differ diff --git a/resources/icons/left_half_circle.png b/resources/icons/left_half_circle.png new file mode 100644 index 000000000..c1e8d3a9c Binary files /dev/null and b/resources/icons/left_half_circle.png differ diff --git a/resources/icons/right_half_circle.png b/resources/icons/right_half_circle.png new file mode 100644 index 000000000..9f182b0b4 Binary files /dev/null and b/resources/icons/right_half_circle.png differ diff --git a/resources/icons/up_half_circle.png b/resources/icons/up_half_circle.png new file mode 100644 index 000000000..9eea07fda Binary files /dev/null and b/resources/icons/up_half_circle.png differ diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index e50c7220a..67be47987 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1057,7 +1057,8 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl sizer->AddSpacer(5); sizer->Add(slider_h, 0, wxEXPAND | wxLEFT, 20); sizer->AddSpacer(5); - PrusaDoubleSlider* slider_v = new PrusaDoubleSlider(parent, wxID_ANY, 50, 70, 0, 100, wxDefaultPosition, wxSize(wxDefaultSize.x ,150), wxSL_VERTICAL); + PrusaDoubleSlider* slider_v = new PrusaDoubleSlider(parent, wxID_ANY, 5, 7, 0, 10, wxDefaultPosition, wxSize(wxDefaultSize.x ,150), wxSL_VERTICAL); + slider_v->SetKoefForLabels(0.15); sizer->AddSpacer(5); sizer->Add(slider_v, 0, wxLEFT, 20); sizer->AddSpacer(5); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 710d91b49..3ba0d3886 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -6,6 +6,7 @@ #include #include #include +#include const unsigned int wxCheckListBoxComboPopup::DefaultWidth = 200; const unsigned int wxCheckListBoxComboPopup::DefaultHeight = 200; @@ -761,7 +762,7 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, long style, const wxValidator& val, const wxString& name) : - wxControl(parent, id, pos, size, wxBORDER_NONE), + wxControl(parent, id, pos, size, wxWANTS_CHARS | wxBORDER_NONE), m_lower_value(lowerValue), m_higher_value (higherValue), m_min_value(minValue), m_max_value(maxValue), m_style(style) @@ -784,8 +785,10 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, Bind(wxEVT_LEFT_DOWN, &PrusaDoubleSlider::OnLeftDown, this); Bind(wxEVT_MOTION, &PrusaDoubleSlider::OnMotion, this); Bind(wxEVT_LEFT_UP, &PrusaDoubleSlider::OnLeftUp, this); - Bind(wxEVT_LEAVE_WINDOW,&PrusaDoubleSlider::OnLeftUp, this); Bind(wxEVT_MOUSEWHEEL, &PrusaDoubleSlider::OnWheel, this); + Bind(wxEVT_ENTER_WINDOW,&PrusaDoubleSlider::OnEnterWin, this); + Bind(wxEVT_LEAVE_WINDOW,&PrusaDoubleSlider::OnLeaveWin, this); + Bind(wxEVT_KEY_DOWN, &PrusaDoubleSlider::OnKeyDown, this); // control's view variables SLIDER_MARGIN = 2 + (style == wxSL_HORIZONTAL ? m_thumb_higher.GetWidth() : m_thumb_higher.GetHeight()); @@ -865,9 +868,22 @@ void PrusaDoubleSlider::get_lower_and_higher_position(int& lower_pos, int& highe } } -void PrusaDoubleSlider::OnPaint(wxPaintEvent& event) +void PrusaDoubleSlider::draw_focus_rect() +{ + if (!m_is_focused) + return; + const wxSize sz = GetSize(); + wxPaintDC dc(this); + const wxPen pen = wxPen(wxColour(128, 128, 10), 1, wxPENSTYLE_DOT); + dc.SetPen(pen); + dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxBRUSHSTYLE_TRANSPARENT)); + dc.DrawRectangle(2, 2, sz.x - 4, sz.y - 4); +} + +void PrusaDoubleSlider::render() { SetBackgroundColour(GetParent()->GetBackgroundColour()); + draw_focus_rect(); wxPaintDC dc(this); int width, height; @@ -888,6 +904,21 @@ void PrusaDoubleSlider::OnPaint(wxPaintEvent& event) draw_higher_thumb(dc, pos); } +void PrusaDoubleSlider::draw_info_line(wxDC& dc, const wxPoint& pos, const wxSize& thumb_size, const SelectedSlider selection) +{ + if (m_selection == selection) { + dc.SetPen(DARK_ORANGE_PEN); + is_horizontal() ? dc.DrawLine(pos.x, pos.y - thumb_size.y, pos.x, pos.y + thumb_size.y): + dc.DrawLine(pos.x - thumb_size.x, pos.y-1, pos.x + thumb_size.x, pos.y-1); + } +} + +wxString PrusaDoubleSlider::get_label(const int value) +{ + return m_label_koef == 1.0 ? wxString::Format("%d", value) : + wxNumberFormatter::ToString(m_label_koef*value, 2, wxNumberFormatter::Style_None); +} + void PrusaDoubleSlider::draw_lower_thumb(wxDC& dc, const wxPoint& pos) { // Draw thumb @@ -902,13 +933,16 @@ void PrusaDoubleSlider::draw_lower_thumb(wxDC& dc, const wxPoint& pos) y_draw = pos.y; } dc.DrawBitmap(m_thumb_lower, x_draw, y_draw); + // Draw info_line + draw_info_line(dc, pos, thumb_size, ssLower); // Draw thumb text wxCoord text_width, text_height; - dc.GetTextExtent(wxString::Format("%d", m_lower_value), &text_width, &text_height); + wxString label = get_label(m_lower_value); + dc.GetTextExtent(label, &text_width, &text_height); wxPoint text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + thumb_size.x) : - wxPoint(pos.x + thumb_size.y, pos.y - 1 - text_height); - dc.DrawText(wxString::Format("%d", m_lower_value), text_pos); + wxPoint(pos.x + thumb_size.x+1, pos.y - 0.5*text_height - 1); + dc.DrawText(label, text_pos); // Update thumb rect m_rect_lower_thumb = wxRect(x_draw, y_draw, thumb_size.x, thumb_size.y); @@ -928,13 +962,16 @@ void PrusaDoubleSlider::draw_higher_thumb(wxDC& dc, const wxPoint& pos) y_draw = pos.y - thumb_size.y; } dc.DrawBitmap(m_thumb_higher, x_draw, y_draw); + // Draw info_line + draw_info_line(dc, pos, thumb_size, ssHigher); // Draw thumb text wxCoord text_width, text_height; - dc.GetTextExtent(wxString::Format("%d", m_higher_value), &text_width, &text_height); - wxPoint text_pos = is_horizontal() ? wxPoint(pos.x - text_width-1, pos.y - thumb_size.x - text_height) : - wxPoint(pos.x - text_width-1 - thumb_size.y, pos.y + 1); - dc.DrawText(wxString::Format("%d", m_higher_value), text_pos); + wxString label = get_label(m_higher_value); + dc.GetTextExtent(label, &text_width, &text_height); + wxPoint text_pos = is_horizontal() ? wxPoint(pos.x - text_width-1, pos.y - thumb_size.x - text_height) : + wxPoint(pos.x - text_width - 1 - thumb_size.x, pos.y - 0.5*text_height + 1); + dc.DrawText(label, text_pos); // Update thumb rect m_rect_higher_thumb = wxRect(x_draw, y_draw, thumb_size.x, thumb_size.y); @@ -1033,6 +1070,9 @@ void PrusaDoubleSlider::OnMotion(wxMouseEvent& event) void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event) { m_is_left_down = false; + m_selection = ssUndef; + Refresh(); + Update(); event.Skip(); wxCommandEvent e(wxEVT_SCROLL_CHANGED); @@ -1040,18 +1080,29 @@ void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event) ProcessWindowEvent(e); } -void PrusaDoubleSlider::OnWheel(wxMouseEvent& event) +void PrusaDoubleSlider::OnEnterWin(wxMouseEvent& event) { - wxClientDC dc(this); - wxPoint pos = event.GetLogicalPosition(dc); - detect_selected_slider(pos, true); + m_is_focused = true; + Refresh(); + Update(); + event.Skip(); +} - if (m_selection == ssUndef) - return; +void PrusaDoubleSlider::OnLeaveWin(wxMouseEvent& event) +{ + m_is_focused = false; + OnLeftUp(event); +} - int delta = event.GetWheelRotation() > 0 ? -1 : 1; +// "condition" have to be true for: +// - value increase (if wxSL_VERTICAL) +// - value decrease (if wxSL_HORIZONTAL) +void PrusaDoubleSlider::move_current_thumb(const bool condition) +{ + int delta = condition ? -1 : 1; if (is_horizontal()) delta *= -1; + if (m_selection == ssLower) { m_lower_value -= delta; correct_lower_value(); @@ -1067,4 +1118,38 @@ void PrusaDoubleSlider::OnWheel(wxMouseEvent& event) e.SetEventObject(this); ProcessWindowEvent(e); } + +void PrusaDoubleSlider::OnWheel(wxMouseEvent& event) +{ + wxClientDC dc(this); + wxPoint pos = event.GetLogicalPosition(dc); + detect_selected_slider(pos, true); + + if (m_selection == ssUndef) + return; + + move_current_thumb(event.GetWheelRotation() > 0); +} + +void PrusaDoubleSlider::OnKeyDown(wxKeyEvent &event) +{ + if (is_horizontal()) + { + if (event.GetKeyCode() == WXK_LEFT || event.GetKeyCode() == WXK_RIGHT) + move_current_thumb(event.GetKeyCode() == WXK_LEFT); + else if (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_DOWN){ + m_selection = event.GetKeyCode() == WXK_UP ? ssHigher : ssLower; + Refresh(); + } + } + else { + if (event.GetKeyCode() == WXK_LEFT || event.GetKeyCode() == WXK_RIGHT) { + m_selection = event.GetKeyCode() == WXK_LEFT ? ssHigher : ssLower; + Refresh(); + } + else if (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_DOWN) + move_current_thumb(event.GetKeyCode() == WXK_UP); + } +} + // ***************************************************************************** diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 584882d96..59d27e448 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -525,27 +525,37 @@ public: } void SetLowerValue(int lower_val); void SetHigherValue(int higher_val); + void SetKoefForLabels(float koef){ m_label_koef = koef;} wxSize DoGetBestSize(){ return wxDefaultSize; } - void OnPaint(wxPaintEvent& event); + void OnPaint(wxPaintEvent& ){ render();} void OnLeftDown(wxMouseEvent& event); void OnMotion(wxMouseEvent& event); void OnLeftUp(wxMouseEvent& event); + void OnEnterWin(wxMouseEvent& event); + void OnLeaveWin(wxMouseEvent& event); void OnWheel(wxMouseEvent& event); + void OnKeyDown(wxKeyEvent &event); protected: + + void render(); + void draw_info_line(wxDC& dc, const wxPoint& pos, const wxSize& thumb_size, SelectedSlider selection); + wxString get_label(const int value); void correct_lower_value(); void correct_higher_value(); void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos); double get_scroll_step(); void get_lower_and_higher_position(int& lower_pos, int& higher_pos); - void draw_lower_thumb (wxDC& dc, const wxPoint& pos); + void draw_focus_rect(); + void draw_lower_thumb(wxDC& dc, const wxPoint& pos); void draw_higher_thumb(wxDC& dc, const wxPoint& pos); int position_to_value(wxDC& dc, const wxCoord x, const wxCoord y); void detect_selected_slider(const wxPoint& pt, const bool is_mouse_wheel = false); bool is_point_in_rect(const wxPoint& pt, const wxRect& rect); bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } + void move_current_thumb(const bool condition); private: int m_min_value; @@ -556,10 +566,12 @@ private: wxBitmap m_thumb_lower; SelectedSlider m_selection; bool m_is_left_down = false; + bool m_is_focused = false; wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb; long m_style; + float m_label_koef = 1.0; // control's view variables wxCoord SLIDER_MARGIN; // margin around slider