diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp index a17ba2fe5..e3932e5c8 100644 --- a/src/slic3r/GUI/DoubleSlider.cpp +++ b/src/slic3r/GUI/DoubleSlider.cpp @@ -401,6 +401,9 @@ void Control::render() //draw cog bitmap (if it's shown) draw_cog_icon(dc); + + //draw mouse position + draw_tick_on_mouse_position(dc); } void Control::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end) @@ -443,9 +446,68 @@ void Control::draw_info_line_with_icon(wxDC& dc, const wxPoint& pos, const Selec } } -wxString Control::get_label(const SelectedSlider& selection) const +void Control::draw_tick_on_mouse_position(wxDC& dc) { - const int value = selection == ssLower ? m_lower_value : m_higher_value; + if (!m_is_focused || m_moving_pos == wxDefaultPosition) + return; + + //calculate thumb position on slider line + int width, height; + get_size(&width, &height); + + int tick = get_tick_near_point(m_moving_pos); + if (tick == m_higher_value || tick == m_lower_value) + return ; + + auto draw_ticks = [this](wxDC& dc, wxPoint pos, int margin=0 ) + { + wxPoint pt_beg = is_horizontal() ? wxPoint(pos.x+margin, pos.y - m_thumb_size.y) : wxPoint(pos.x - m_thumb_size.x , pos.y+margin); + wxPoint pt_end = is_horizontal() ? wxPoint(pos.x+margin, pos.y + m_thumb_size.y) : wxPoint(pos.x - 0.5 * m_thumb_size.x + 1, pos.y+margin); + dc.DrawLine(pt_beg, pt_end); + + pt_beg = is_horizontal() ? wxPoint(pos.x + margin, pos.y - m_thumb_size.y) : wxPoint(pos.x + 0.5 * m_thumb_size.x, pos.y+margin); + pt_end = is_horizontal() ? wxPoint(pos.x + margin, pos.y + m_thumb_size.y) : wxPoint(pos.x + m_thumb_size.x + 1, pos.y+margin); + dc.DrawLine(pt_beg, pt_end); + }; + + auto draw_touch = [this](wxDC& dc, wxPoint pos, int margin, bool right_side ) + { + int mult = right_side ? 1 : -1; + wxPoint pt_beg = is_horizontal() ? wxPoint(pos.x - margin, pos.y + mult * m_thumb_size.y) : wxPoint(pos.x + mult * m_thumb_size.x, pos.y - margin); + wxPoint pt_end = is_horizontal() ? wxPoint(pos.x + margin, pos.y + mult * m_thumb_size.y) : wxPoint(pos.x + mult * m_thumb_size.x, pos.y + margin); + dc.DrawLine(pt_beg, pt_end); + }; + + if (tick > 0) // this tick exists and should be marked as a focused + { + wxCoord new_pos = get_position_from_value(tick); + const wxPoint pos = is_horizontal() ? wxPoint(new_pos, height * 0.5) : wxPoint(0.5 * width, new_pos); + + dc.SetPen(DARK_ORANGE_PEN); + + draw_ticks(dc, pos, -2); + draw_ticks(dc, pos, 2 ); + draw_touch(dc, pos, 2, true); + draw_touch(dc, pos, 2, false); + + return; + } + + tick = get_value_from_position(m_moving_pos); + if (tick >= m_max_value || tick <= m_min_value || tick == m_higher_value || tick == m_lower_value) + return; + + wxCoord new_pos = get_position_from_value(tick); + const wxPoint pos = is_horizontal() ? wxPoint(new_pos, height * 0.5) : wxPoint(0.5 * width, new_pos); + + //draw info line + dc.SetPen(LIGHT_GREY_PEN); + draw_ticks(dc, pos); +} + +wxString Control::get_label(int tick) const +{ + const int value = tick; if (m_label_koef == 1.0 && m_values.empty()) return wxString::Format("%d", value); @@ -458,22 +520,24 @@ wxString Control::get_label(const SelectedSlider& selection) const return wxString::Format("%s\n(%d)", str, m_values.empty() ? value : value+1); } -void Control::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const +void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_side/*=true*/) const { - if ( selection == ssUndef || - ((m_is_one_layer || m_higher_value==m_lower_value) && selection != m_selection) ) - return; wxCoord text_width, text_height; - const wxString label = get_label(selection); + const wxString label = get_label(tick); dc.GetMultiLineTextExtent(label, &text_width, &text_height); wxPoint text_pos; - if (selection ==ssLower) + if (right_side) text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + m_thumb_size.x) : - wxPoint(pos.x + m_thumb_size.x+1, pos.y - 0.5*text_height - 1); + wxPoint(pos.x + m_thumb_size.x+1, pos.y - 0.5*text_height - 1); else text_pos = is_horizontal() ? wxPoint(pos.x - text_width - 1, pos.y - m_thumb_size.x - text_height) : - wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5*text_height + 1); - dc.DrawText(label, text_pos); + wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5*text_height + 1); + dc.DrawText(label, text_pos); +} + +void Control::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const +{ + draw_tick_text(dc, pos, selection == ssLower ? m_lower_value : m_higher_value, selection == ssLower); } void Control::draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) @@ -564,16 +628,24 @@ void Control::draw_ticks(wxDC& dc) is_horizontal() ? dc.DrawLine(pos, mid+14, pos, mid+9) : dc.DrawLine(mid + 14, pos/* - 1*/, mid + 9, pos/* - 1*/); - wxBitmap icon = wxNullBitmap; + // if current tick if focused, we should to use a specific "focused" icon + bool focused_tick = m_moving_pos != wxDefaultPosition && tick.tick == get_tick_near_point(m_moving_pos); - // Draw icon for "Pause print" or "Custom Gcode" - if (tick.gcode != ColorChangeCode && tick.gcode != ToolChangeCode) - icon = create_scaled_bitmap(tick.gcode == PausePrintCode ? "pause_print" : "edit_gcode"); - else if (m_ticks.is_conflict_tick(tick, m_mode, m_only_extruder, m_values[tick.tick])) - icon = create_scaled_bitmap("error_tick"); + // get icon name if it is + std::string icon_name; + if (tick.gcode == ColorChangeCode || tick.gcode == ToolChangeCode) { + if (m_ticks.is_conflict_tick(tick, m_mode, m_only_extruder, m_values[tick.tick])) + icon_name = focused_tick ? "error_tick_f" : "error_tick"; + } + else if (tick.gcode == PausePrintCode) + icon_name = focused_tick ? "pause_print_f" : "pause_print"; + else + icon_name = focused_tick ? "edit_gcode_f" : "edit_gcode"; - if (!icon.IsNull()) + // Draw icon for "Pause print", "Custom Gcode" or conflict tick + if (!icon_name.empty()) { + wxBitmap icon = create_scaled_bitmap(icon_name); wxCoord x_draw, y_draw; is_horizontal() ? x_draw = pos - 0.5 * m_tick_icon_dim : y_draw = pos - 0.5 * m_tick_icon_dim; is_horizontal() ? y_draw = mid + 22 : x_draw = mid + m_thumb_size.x + 3; @@ -979,6 +1051,7 @@ void Control::OnMotion(wxMouseEvent& event) m_focus = fiTick; tick = get_tick_near_point(pos); } + m_moving_pos = pos; } else if (m_is_left_down || m_is_right_down) { if (m_selection == ssLower) { @@ -993,6 +1066,7 @@ void Control::OnMotion(wxMouseEvent& event) correct_higher_value(); action = (current_value != m_higher_value); } + m_moving_pos = wxDefaultPosition; } Refresh(); Update(); @@ -1361,58 +1435,70 @@ std::set TickCodeInfo::get_used_extruders_for_tick(int tick, int only_extru return used_extruders; } -void Control::get_add_menu(wxMenu* menu) +void Control::show_add_context_menu() { + wxMenu menu; + if (m_mode == t_mode::SingleExtruder) { - append_menu_item(menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", - [this](wxCommandEvent&) { add_code_as_tick(ColorChangeCode); }, "colorchange_add_m", menu); + append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", + [this](wxCommandEvent&) { add_code_as_tick(ColorChangeCode); }, "colorchange_add_m", &menu); UseDefaultColors(false); } else { - append_change_extruder_menu_item(menu); - append_add_color_change_menu_item(menu); + append_change_extruder_menu_item(&menu); + append_add_color_change_menu_item(&menu); } - append_menu_item(menu, wxID_ANY, _(L("Add pause print")) + " (M601)", "", - [this](wxCommandEvent&) { add_code_as_tick(PausePrintCode); }, "pause_print", menu); + append_menu_item(&menu, wxID_ANY, _(L("Add pause print")) + " (M601)", "", + [this](wxCommandEvent&) { add_code_as_tick(PausePrintCode); }, "pause_print", &menu); - append_menu_item(menu, wxID_ANY, _(L("Add custom G-code")), "", - [this](wxCommandEvent&) { add_code_as_tick(""); }, "edit_gcode", menu); + append_menu_item(&menu, wxID_ANY, _(L("Add custom G-code")), "", + [this](wxCommandEvent&) { add_code_as_tick(""); }, "edit_gcode", &menu); + + GUI::wxGetApp().plater()->PopupMenu(&menu); } -void Control::get_edit_menu(wxMenu* menu) +void Control::show_edit_context_menu() { + wxMenu menu; + std::set::iterator it = m_ticks.ticks.find(TickCode{ m_selection == ssLower ? m_lower_value : m_higher_value }); if (it->gcode == ToolChangeCode) { if (m_mode == t_mode::MultiAsSingle) - append_change_extruder_menu_item(menu); - append_add_color_change_menu_item(menu, true); + append_change_extruder_menu_item(&menu); + append_add_color_change_menu_item(&menu, true); } else - append_menu_item( menu, wxID_ANY, it->gcode == ColorChangeCode ? _(L("Edit color")) : + append_menu_item(&menu, wxID_ANY, it->gcode == ColorChangeCode ? _(L("Edit color")) : it->gcode == PausePrintCode ? _(L("Edit pause print message")) : _(L("Edit custom G-code")), "", - [this](wxCommandEvent&) { edit_tick(); }, "edit_uni", menu); + [this](wxCommandEvent&) { edit_tick(); }, "edit_uni", &menu); if (it->gcode == ColorChangeCode && m_mode == t_mode::MultiAsSingle) - append_change_extruder_menu_item(menu, true); + append_change_extruder_menu_item(&menu, true); - append_menu_item( menu, wxID_ANY, it->gcode == ColorChangeCode ? _(L("Delete color change")) : + append_menu_item(&menu, wxID_ANY, it->gcode == ColorChangeCode ? _(L("Delete color change")) : it->gcode == ToolChangeCode ? _(L("Delete tool change")) : it->gcode == PausePrintCode ? _(L("Delete pause print")) : _(L("Delete custom G-code")), "", - [this](wxCommandEvent&) { delete_current_tick();}, "colorchange_del_f", menu); + [this](wxCommandEvent&) { delete_current_tick();}, "colorchange_del_f", &menu); + + GUI::wxGetApp().plater()->PopupMenu(&menu); } -void Control::get_cog_icon_menu(wxMenu* menu) +void Control::show_cog_icon_context_menu() { - append_menu_item(menu, wxID_ANY, _(L("Jump to print Z")) + " (Shift+G)", "", - [this](wxCommandEvent&) { jump_to_print_z(); }, "", menu); + wxMenu menu; - append_menu_item(menu, wxID_ANY, _(L("Set extruder sequence for whole print")), "", - [this](wxCommandEvent&) { edit_extruder_sequence(); }, "", menu); + append_menu_item(&menu, wxID_ANY, _(L("Jump to print Z")) + " (Shift+G)", "", + [this](wxCommandEvent&) { jump_to_print_z(); }, "", &menu); + + append_menu_item(&menu, wxID_ANY, _(L("Set extruder sequence for whole print")), "", + [this](wxCommandEvent&) { edit_extruder_sequence(); }, "", &menu); + + GUI::wxGetApp().plater()->PopupMenu(&menu); } void Control::OnRightUp(wxMouseEvent& event) @@ -1429,19 +1515,12 @@ void Control::OnRightUp(wxMouseEvent& event) if (edited_tick >= 0) edit_tick(edited_tick); } - else - { - wxMenu menu; - - if (m_mouse == maAddMenu) - get_add_menu(&menu); - else if (m_mouse == maEditMenu) - get_edit_menu(&menu); - else if (m_mouse == maCogIconMenu) - get_cog_icon_menu(&menu); - - GUI::wxGetApp().plater()->PopupMenu(&menu); - } + else if (m_mouse == maAddMenu) + show_add_context_menu(); + else if (m_mouse == maEditMenu) + show_edit_context_menu(); + else if (m_mouse == maCogIconMenu) + show_cog_icon_context_menu(); Refresh(); Update(); @@ -1726,7 +1805,10 @@ void Control::edit_extruder_sequence() while (tick <= m_max_value) { const int cur_extruder = m_extruders_sequence.extruders[extruder]; - m_ticks.ticks.emplace(TickCode{tick, ToolChangeCode, cur_extruder + 1, colors[cur_extruder]}); + + bool meaningless_tick = value == 0.0 && cur_extruder == extruder; + if (!meaningless_tick) + m_ticks.ticks.emplace(TickCode{tick, ToolChangeCode, cur_extruder + 1, colors[cur_extruder]}); extruder++; if (extruder == extr_cnt) diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp index 78c568eb4..c6c85fe0e 100644 --- a/src/slic3r/GUI/DoubleSlider.hpp +++ b/src/slic3r/GUI/DoubleSlider.hpp @@ -235,9 +235,9 @@ public: void move_current_thumb_to_pos(wxPoint pos); void edit_extruder_sequence(); void jump_to_print_z(); - void get_add_menu(wxMenu *menu); - void get_edit_menu(wxMenu *menu); - void get_cog_icon_menu(wxMenu *menu); + void show_add_context_menu(); + void show_edit_context_menu(); + void show_cog_icon_context_menu(); ExtrudersSequence m_extruders_sequence; @@ -256,6 +256,8 @@ protected: void draw_cog_icon(wxDC &dc); void draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection); void draw_info_line_with_icon(wxDC& dc, const wxPoint& pos, SelectedSlider selection); + void draw_tick_on_mouse_position(wxDC &dc); + void draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, bool right_side = true) const; void draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const; void update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection); @@ -271,7 +273,7 @@ private: int get_tick_near_point(const wxPoint& pt); double get_scroll_step(); - wxString get_label(const SelectedSlider& selection) const; + wxString get_label(int tick) const; void get_lower_and_higher_position(int& lower_pos, int& higher_pos); int get_value_from_position(const wxCoord x, const wxCoord y); int get_value_from_position(const wxPoint pos) { return get_value_from_position(pos.x, pos.y); } @@ -329,6 +331,7 @@ private: MouseAction m_mouse = maNone; FocusedItem m_focus = fiNone; + wxPoint m_moving_pos = wxDefaultPosition; wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb;