Implemented check of color change event respecting to mode

+ unresolved ticks are marked with error_tick icon
 + some code refactoring
This commit is contained in:
YuSanka 2020-01-20 15:08:19 +01:00
parent 858e936e52
commit 6eaf48ebd8
3 changed files with 391 additions and 252 deletions

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
<g id="error_tick">
<path fill="#808080" d="M8,1.85l5.29,3.53V7v3.62L8,14.15l-5.29-3.53V7V5.38L8,1.85 M8,1L2,5v2v4l6,4l6-4V7V5L8,1L8,1z"/>
<path fill="none" stroke="#ED6B21" stroke-linecap="round" stroke-width="2" d="M8 4 L8 9" />
<circle fill="#ED6B21" cx="8" cy="12" r="1"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 640 B

View File

@ -2325,7 +2325,7 @@ DoubleSlider::DoubleSlider( wxWindow *parent,
m_cog_icon_dim = int((float)m_bmp_cog.bmp().GetSize().x / scale_factor); m_cog_icon_dim = int((float)m_bmp_cog.bmp().GetSize().x / scale_factor);
m_selection = ssUndef; m_selection = ssUndef;
m_pause_print_msg = _utf8(L("Place bearings in slots and resume")); m_ticks.set_pause_print_msg(_utf8(L("Place bearings in slots and resume")));
// slider events // slider events
Bind(wxEVT_PAINT, &DoubleSlider::OnPaint, this); Bind(wxEVT_PAINT, &DoubleSlider::OnPaint, this);
@ -2539,13 +2539,13 @@ Slic3r::Model::CustomGCodeInfo DoubleSlider::GetTicksValues() const
const int val_size = m_values.size(); const int val_size = m_values.size();
if (!m_values.empty()) if (!m_values.empty())
for (const TICK_CODE& tick : m_ticks) { for (const TICK_CODE& tick : m_ticks.ticks) {
if (tick.tick > val_size) if (tick.tick > val_size)
break; break;
values.emplace_back(t_custom_code{m_values[tick.tick], tick.gcode, tick.extruder, tick.color}); values.emplace_back(t_custom_code{m_values[tick.tick], tick.gcode, tick.extruder, tick.color});
} }
custom_gcode_per_print_z.mode = m_mode; custom_gcode_per_print_z.mode = m_force_mode_apply ? m_mode : m_ticks.mode;
return custom_gcode_per_print_z; return custom_gcode_per_print_z;
} }
@ -2554,13 +2554,13 @@ void DoubleSlider::SetTicksValues(const Slic3r::Model::CustomGCodeInfo& custom_g
{ {
if (m_values.empty()) if (m_values.empty())
{ {
m_ticks_mode = m_mode; m_ticks.mode = m_mode;
return; return;
} }
const bool was_empty = m_ticks.empty(); const bool was_empty = m_ticks.empty();
m_ticks.clear(); m_ticks.ticks.clear();
const std::vector<t_custom_code>& heights = custom_gcode_per_print_z.gcodes; const std::vector<t_custom_code>& heights = custom_gcode_per_print_z.gcodes;
for (auto h : heights) { for (auto h : heights) {
auto it = std::lower_bound(m_values.begin(), m_values.end(), h.print_z - epsilon()); auto it = std::lower_bound(m_values.begin(), m_values.end(), h.print_z - epsilon());
@ -2568,14 +2568,14 @@ void DoubleSlider::SetTicksValues(const Slic3r::Model::CustomGCodeInfo& custom_g
if (it == m_values.end()) if (it == m_values.end())
continue; continue;
m_ticks.emplace(TICK_CODE{int(it-m_values.begin()), h.gcode, h.extruder, h.color}); m_ticks.ticks.emplace(TICK_CODE{int(it-m_values.begin()), h.gcode, h.extruder, h.color});
} }
if (!was_empty && m_ticks.empty()) if (!was_empty && m_ticks.empty())
// Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one // Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one
post_ticks_changed_event(); post_ticks_changed_event();
m_ticks_mode = custom_gcode_per_print_z.mode; m_ticks.mode = custom_gcode_per_print_z.mode;
Refresh(); Refresh();
Update(); Update();
@ -2649,7 +2649,7 @@ void DoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoin
return; return;
wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp(); wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp();
if (m_ticks.find(TICK_CODE{tick}) != m_ticks.end()) if (m_ticks.ticks.find(TICK_CODE{tick}) != m_ticks.ticks.end())
icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp(); icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp();
wxCoord x_draw, y_draw; wxCoord x_draw, y_draw;
@ -2792,7 +2792,7 @@ void DoubleSlider::draw_ticks(wxDC& dc)
int height, width; int height, width;
get_size(&width, &height); get_size(&width, &height);
const wxCoord mid = is_horizontal() ? 0.5*height : 0.5*width; const wxCoord mid = is_horizontal() ? 0.5*height : 0.5*width;
for (auto tick : m_ticks) for (auto tick : m_ticks.ticks)
{ {
const wxCoord pos = get_position_from_value(tick.tick); const wxCoord pos = get_position_from_value(tick.tick);
@ -2801,11 +2801,23 @@ void DoubleSlider::draw_ticks(wxDC& dc)
is_horizontal() ? dc.DrawLine(pos, mid+14, pos, mid+9) : is_horizontal() ? dc.DrawLine(pos, mid+14, pos, mid+9) :
dc.DrawLine(mid + 14, pos/* - 1*/, mid + 9, pos/* - 1*/); dc.DrawLine(mid + 14, pos/* - 1*/, mid + 9, pos/* - 1*/);
wxBitmap icon = wxNullBitmap;
// Draw icon for "Pause print" or "Custom Gcode" // Draw icon for "Pause print" or "Custom Gcode"
if (tick.gcode != Slic3r::ColorChangeCode && tick.gcode != Slic3r::ToolChangeCode) if (tick.gcode != Slic3r::ColorChangeCode && tick.gcode != Slic3r::ToolChangeCode)
icon = create_scaled_bitmap(this, tick.gcode == Slic3r::PausePrintCode ? "pause_print" : "edit_gcode");
else
{ {
wxBitmap icon = create_scaled_bitmap(this, tick.gcode == Slic3r::PausePrintCode ? "pause_print" : "edit_gcode"); if ((tick.gcode == Slic3r::ColorChangeCode && (
(m_ticks.mode == t_mode::SingleExtruder && m_mode == t_mode::MultiExtruder ) ||
(m_ticks.mode == t_mode::MultiExtruder && m_mode == t_mode::SingleExtruder) )) ||
(tick.gcode == Slic3r::ToolChangeCode &&
(m_ticks.mode == t_mode::MultiAsSingle && m_mode != t_mode::MultiAsSingle ) ))
icon = create_scaled_bitmap(this, "error_tick");
}
if (!icon.IsNull())
{
wxCoord x_draw, y_draw; 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() ? 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; is_horizontal() ? y_draw = mid + 22 : x_draw = mid + m_thumb_size.x + 3;
@ -2820,7 +2832,7 @@ std::string DoubleSlider::get_color_for_tool_change_tick(std::set<TICK_CODE>::co
const int current_extruder = it->extruder == 0 ? std::max<int>(m_only_extruder, 1) : it->extruder; const int current_extruder = it->extruder == 0 ? std::max<int>(m_only_extruder, 1) : it->extruder;
auto it_n = it; auto it_n = it;
while (it_n != m_ticks.begin()) { while (it_n != m_ticks.ticks.begin()) {
--it_n; --it_n;
if (it_n->gcode == Slic3r::ColorChangeCode && it_n->extruder == current_extruder) if (it_n->gcode == Slic3r::ColorChangeCode && it_n->extruder == current_extruder)
return it_n->color; return it_n->color;
@ -2834,7 +2846,7 @@ std::string DoubleSlider::get_color_for_color_change_tick(std::set<TICK_CODE>::c
const int def_extruder = std::max<int>(1, m_only_extruder); const int def_extruder = std::max<int>(1, m_only_extruder);
auto it_n = it; auto it_n = it;
bool is_tool_change = false; bool is_tool_change = false;
while (it_n != m_ticks.begin()) { while (it_n != m_ticks.ticks.begin()) {
--it_n; --it_n;
if (it_n->gcode == Slic3r::ToolChangeCode) { if (it_n->gcode == Slic3r::ToolChangeCode) {
is_tool_change = true; is_tool_change = true;
@ -2881,9 +2893,9 @@ void DoubleSlider::draw_colored_band(wxDC& dc)
const int default_color_idx = m_mode==t_mode::MultiAsSingle ? std::max<int>(m_only_extruder - 1, 0) : 0; const int default_color_idx = m_mode==t_mode::MultiAsSingle ? std::max<int>(m_only_extruder - 1, 0) : 0;
draw_band(dc, wxColour(Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config()[default_color_idx]), main_band); draw_band(dc, wxColour(Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config()[default_color_idx]), main_band);
std::set<TICK_CODE>::const_iterator tick_it = m_ticks.begin(); std::set<TICK_CODE>::const_iterator tick_it = m_ticks.ticks.begin();
while (tick_it != m_ticks.end()) while (tick_it != m_ticks.ticks.end())
{ {
if ( (m_mode == t_mode::SingleExtruder && tick_it->gcode == Slic3r::ColorChangeCode ) || if ( (m_mode == t_mode::SingleExtruder && tick_it->gcode == Slic3r::ColorChangeCode ) ||
(m_mode == t_mode::MultiAsSingle && (tick_it->gcode == Slic3r::ToolChangeCode || tick_it->gcode == Slic3r::ColorChangeCode)) ) (m_mode == t_mode::MultiAsSingle && (tick_it->gcode == Slic3r::ToolChangeCode || tick_it->gcode == Slic3r::ColorChangeCode)) )
@ -2993,7 +3005,7 @@ bool DoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect)
int DoubleSlider::is_point_near_tick(const wxPoint& pt) int DoubleSlider::is_point_near_tick(const wxPoint& pt)
{ {
for (auto tick : m_ticks) { for (auto tick : m_ticks.ticks) {
const wxCoord pos = get_position_from_value(tick.tick); const wxCoord pos = get_position_from_value(tick.tick);
if (is_horizontal()) { if (is_horizontal()) {
@ -3030,8 +3042,13 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event)
wxClientDC dc(this); wxClientDC dc(this);
wxPoint pos = event.GetLogicalPosition(dc); wxPoint pos = event.GetLogicalPosition(dc);
if (is_point_in_rect(pos, m_rect_tick_action) && m_is_enabled_tick_manipulation) { if (is_point_in_rect(pos, m_rect_tick_action) && m_is_enabled_tick_manipulation)
action_tick(taOnIcon); {
const auto it = m_ticks.ticks.find(TICK_CODE{ m_selection == ssLower ? m_lower_value : m_higher_value });
if (it == m_ticks.ticks.end())
m_force_add_tick = true;
else
m_force_delete_tick = true;
return; return;
} }
@ -3054,12 +3071,13 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event)
m_selection == ssLower ? correct_lower_value() : correct_higher_value(); m_selection == ssLower ? correct_lower_value() : correct_higher_value();
if (!m_selection) m_selection = ssHigher; if (!m_selection) m_selection = ssHigher;
m_ticks.clear(); m_ticks.ticks.clear();
post_ticks_changed_event(); post_ticks_changed_event();
} }
else if (is_point_in_rect(pos, m_rect_cog_icon) && m_mode == t_mode::MultiExtruder) { else if (is_point_in_rect(pos, m_rect_cog_icon) && m_mode == t_mode::MultiExtruder) {
// show dialog for set extruder sequence // show dialog for set extruder sequence
m_edit_extruder_sequence = true; m_force_edit_extruder_sequence = true;
return;
} }
else else
detect_selected_slider(pos); detect_selected_slider(pos);
@ -3127,8 +3145,8 @@ wxString DoubleSlider::get_tooltip(IconFocus icon_focus)
else if (m_is_action_icon_focesed) else if (m_is_action_icon_focesed)
{ {
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
const auto tick_code_it = m_ticks.find(TICK_CODE{tick}); const auto tick_code_it = m_ticks.ticks.find(TICK_CODE{tick});
tooltip = tick_code_it == m_ticks.end() ? (m_mode == t_mode::MultiAsSingle ? tooltip = tick_code_it == m_ticks.ticks.end() ? (m_mode == t_mode::MultiAsSingle ?
_(L("For add change extruder use left mouse button click")) : _(L("For add change extruder use left mouse button click")) :
_(L("For add color change use left mouse button click")) ) + "\n" + _(L("For add color change use left mouse button click")) ) + "\n" +
_(L("For add another code use right mouse button click")) : _(L("For add another code use right mouse button click")) :
@ -3211,10 +3229,8 @@ void DoubleSlider::append_change_extruder_menu_item(wxMenu* menu)
if (m_mode == t_mode::MultiAsSingle) if (m_mode == t_mode::MultiAsSingle)
append_menu_item(change_extruder_menu, wxID_ANY, item_name, "", append_menu_item(change_extruder_menu, wxID_ANY, item_name, "",
[this, i](wxCommandEvent&) { change_extruder(i); }, "", menu, [this, i](wxCommandEvent&) { add_code_as_tick(Slic3r::ToolChangeCode, i); }, "", menu,
[is_active_extruder]() { return !is_active_extruder; }, Slic3r::GUI::wxGetApp().plater()); [is_active_extruder]() { return !is_active_extruder; }, Slic3r::GUI::wxGetApp().plater());
// append_menu_radio_item(change_extruder_menu, wxID_ANY, item_name, "",
// [this, i](wxCommandEvent&) { change_extruder(i); }, menu)->Check(i == initial_extruder);
} }
const wxString change_extruder_menu_name = m_mode == t_mode::MultiAsSingle ? _(L("Change extruder")) : _(L("Change extruder (N/A)")); const wxString change_extruder_menu_name = m_mode == t_mode::MultiAsSingle ? _(L("Change extruder")) : _(L("Change extruder (N/A)"));
@ -3245,13 +3261,13 @@ void DoubleSlider::append_add_color_change_menu_item(wxMenu* menu)
(is_used_extruder ? " (" + _(L("used")) + ")" : ""); (is_used_extruder ? " (" + _(L("used")) + ")" : "");
append_menu_item(add_color_change_menu, wxID_ANY, item_name, "", append_menu_item(add_color_change_menu, wxID_ANY, item_name, "",
[this, i](wxCommandEvent&) { add_code(Slic3r::ColorChangeCode, i); }, "", menu, [this, i](wxCommandEvent&) { add_code_as_tick(Slic3r::ColorChangeCode, i); }, "", menu,
[is_used_extruder]() { return is_used_extruder; }, Slic3r::GUI::wxGetApp().plater()); [is_used_extruder]() { return is_used_extruder; }, Slic3r::GUI::wxGetApp().plater());
} }
const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % Slic3r::ColorChangeCode).str()); const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % Slic3r::ColorChangeCode).str());
wxMenuItem* add_color_change_menu_item = menu->AppendSubMenu(add_color_change_menu, menu_name, ""); wxMenuItem* add_color_change_menu_item = menu->AppendSubMenu(add_color_change_menu, menu_name, "");
add_color_change_menu_item->SetBitmap(create_scaled_bitmap(nullptr, "colorchange_add_m")); add_color_change_menu_item->SetBitmap(create_scaled_bitmap(this, "colorchange_add_m"));
} }
} }
@ -3262,28 +3278,21 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event)
this->ReleaseMouse(); this->ReleaseMouse();
m_is_left_down = false; m_is_left_down = false;
if (m_show_context_menu) if (m_force_delete_tick)
{ {
if (m_mode == t_mode::SingleExtruder) delete_current_tick();
add_code(Slic3r::ColorChangeCode); m_force_delete_tick = false;
else
{
wxMenu menu;
if (m_mode == t_mode::MultiAsSingle)
append_change_extruder_menu_item(&menu);
else
append_add_color_change_menu_item(&menu);
Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu);
}
m_show_context_menu = false;
} }
else
if (m_edit_extruder_sequence) { if (m_force_add_tick)
{
add_current_tick();
m_force_add_tick = false;
}
else
if (m_force_edit_extruder_sequence) {
edit_extruder_sequence(); edit_extruder_sequence();
m_edit_extruder_sequence = false; m_force_edit_extruder_sequence = false;
} }
Refresh(); Refresh();
@ -3329,45 +3338,6 @@ void DoubleSlider::move_current_thumb(const bool condition)
ProcessWindowEvent(e); ProcessWindowEvent(e);
} }
void DoubleSlider::action_tick(const TicksAction action)
{
if (m_selection == ssUndef)
return;
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
const auto it = m_ticks.find(TICK_CODE{tick});
if (it != m_ticks.end()) // erase this tick
{
if (action == taAdd)
return;
m_ticks.erase(TICK_CODE{tick});
post_ticks_changed_event(it->gcode);
Refresh();
Update();
return;
}
if (action == taDel)
return;
if (action == taAdd)
{
// OnChar() is called immediately after OnKeyDown(), which can cause call of add_code() twice.
// To avoid this case we should suppress second add_code() call.
if (m_suppress_add_code)
return;
m_suppress_add_code = true;
if (m_mode == t_mode::SingleExtruder) // if (m_mode != t_mode::MultiExtruder)
add_code(Slic3r::ColorChangeCode);
m_suppress_add_code = false;
return;
}
m_show_context_menu = true;
}
void DoubleSlider::OnWheel(wxMouseEvent& event) void DoubleSlider::OnWheel(wxMouseEvent& event)
{ {
// Set nearest to the mouse thumb as a selected, if there is not selected thumb // Set nearest to the mouse thumb as a selected, if there is not selected thumb
@ -3391,10 +3361,18 @@ void DoubleSlider::OnWheel(wxMouseEvent& event)
void DoubleSlider::OnKeyDown(wxKeyEvent &event) void DoubleSlider::OnKeyDown(wxKeyEvent &event)
{ {
const int key = event.GetKeyCode(); const int key = event.GetKeyCode();
if (key == WXK_NUMPAD_ADD) if (key == WXK_NUMPAD_ADD) {
action_tick(taAdd); // OnChar() is called immediately after OnKeyDown(), which can cause call of add_tick() twice.
else if (key == 390 || key == WXK_DELETE || key == WXK_BACK) // To avoid this case we should suppress second add_tick() call.
action_tick(taDel); m_ticks.suppress_plus(true);
add_current_tick(true);
}
else if (key == 390 || key == WXK_DELETE || key == WXK_BACK) {
// OnChar() is called immediately after OnKeyDown(), which can cause call of delete_tick() twice.
// To avoid this case we should suppress second delete_tick() call.
m_ticks.suppress_minus(true);
delete_current_tick();
}
else if (is_horizontal()) else if (is_horizontal())
{ {
if (key == WXK_LEFT || key == WXK_RIGHT) if (key == WXK_LEFT || key == WXK_RIGHT)
@ -3428,10 +3406,14 @@ void DoubleSlider::OnKeyUp(wxKeyEvent &event)
void DoubleSlider::OnChar(wxKeyEvent& event) void DoubleSlider::OnChar(wxKeyEvent& event)
{ {
const int key = event.GetKeyCode(); const int key = event.GetKeyCode();
if (key == '+') if (key == '+' && !m_ticks.suppressed_plus()) {
action_tick(taAdd); add_current_tick(true);
else if (key == '-') m_ticks.suppress_plus(false);
action_tick(taDel); }
else if (key == '-' && !m_ticks.suppressed_minus()) {
delete_current_tick();
m_ticks.suppress_minus(false);
}
} }
void DoubleSlider::OnRightDown(wxMouseEvent& event) void DoubleSlider::OnRightDown(wxMouseEvent& event)
@ -3446,8 +3428,8 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event)
{ {
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
// if on this Z doesn't exist tick // if on this Z doesn't exist tick
auto it = m_ticks.find(TICK_CODE{ tick }); auto it = m_ticks.ticks.find(TICK_CODE{ tick });
if (it == m_ticks.end()) if (it == m_ticks.ticks.end())
{ {
// show context menu on OnRightUp() // show context menu on OnRightUp()
m_show_context_menu = true; m_show_context_menu = true;
@ -3484,8 +3466,8 @@ int DoubleSlider::get_extruder_for_tick(int tick)
if (m_ticks.empty()) if (m_ticks.empty())
return default_initial_extruder; return default_initial_extruder;
auto it = m_ticks.lower_bound(TICK_CODE{tick}); auto it = m_ticks.ticks.lower_bound(TICK_CODE{tick});
while (it != m_ticks.begin()) { while (it != m_ticks.ticks.begin()) {
--it; --it;
if(it->gcode == Slic3r::ToolChangeCode) if(it->gcode == Slic3r::ToolChangeCode)
return it->extruder; return it->extruder;
@ -3522,16 +3504,17 @@ std::set<int> DoubleSlider::get_used_extruders_for_tick(int tick)
return {default_initial_extruder}; return {default_initial_extruder};
std::set<int> used_extruders; std::set<int> used_extruders;
auto it_start = m_ticks.lower_bound(TICK_CODE{tick}); const std::set<TICK_CODE>& ticks = m_ticks.ticks;
auto it_start = ticks.lower_bound(TICK_CODE{tick});
auto it = it_start; auto it = it_start;
if (it == m_ticks.begin() && it->gcode == Slic3r::ToolChangeCode) { if (it == ticks.begin() && it->gcode == Slic3r::ToolChangeCode) {
used_extruders.emplace(it->extruder); used_extruders.emplace(it->extruder);
if (tick < it->tick) if (tick < it->tick)
used_extruders.emplace(default_initial_extruder); used_extruders.emplace(default_initial_extruder);
} }
while (it != m_ticks.begin()) { while (it != ticks.begin()) {
--it; --it;
if(it->gcode == Slic3r::ToolChangeCode) if(it->gcode == Slic3r::ToolChangeCode)
{ {
@ -3540,11 +3523,11 @@ std::set<int> DoubleSlider::get_used_extruders_for_tick(int tick)
} }
} }
if (it == m_ticks.begin() && used_extruders.empty()) if (it == ticks.begin() && used_extruders.empty())
used_extruders.emplace(default_initial_extruder); used_extruders.emplace(default_initial_extruder);
it = it_start; it = it_start;
while (it != m_ticks.end()) { while (it != ticks.end()) {
if(it->gcode == Slic3r::ToolChangeCode) if(it->gcode == Slic3r::ToolChangeCode)
used_extruders.emplace(it->extruder); used_extruders.emplace(it->extruder);
++it; ++it;
@ -3565,7 +3548,7 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event)
if (m_mode == t_mode::SingleExtruder) if (m_mode == t_mode::SingleExtruder)
append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "", append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "",
[this](wxCommandEvent&) { add_code(Slic3r::ColorChangeCode); }, "colorchange_add_m", &menu, [this](wxCommandEvent&) { add_code_as_tick(Slic3r::ColorChangeCode); }, "colorchange_add_m", &menu,
[](){return true;}, this); [](){return true;}, this);
else else
{ {
@ -3574,11 +3557,11 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event)
} }
append_menu_item(&menu, wxID_ANY, _(L("Add pause print")) + " (M601)", "", append_menu_item(&menu, wxID_ANY, _(L("Add pause print")) + " (M601)", "",
[this](wxCommandEvent&) { add_code(Slic3r::PausePrintCode); }, "pause_print", &menu, [this](wxCommandEvent&) { add_code_as_tick(Slic3r::PausePrintCode); }, "pause_print", &menu,
[]() {return true; }, this); []() {return true; }, this);
append_menu_item(&menu, wxID_ANY, _(L("Add custom G-code")), "", append_menu_item(&menu, wxID_ANY, _(L("Add custom G-code")), "",
[this](wxCommandEvent&) { add_code(""); }, "edit_gcode", &menu, [this](wxCommandEvent&) { add_code_as_tick(""); }, "edit_gcode", &menu,
[]() {return true; }, this); []() {return true; }, this);
Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu);
@ -3588,7 +3571,7 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event)
else if (m_show_edit_menu) { else if (m_show_edit_menu) {
wxMenu menu; wxMenu menu;
std::set<TICK_CODE>::iterator it = m_ticks.find(TICK_CODE{ m_selection == ssLower ? m_lower_value : m_higher_value }); std::set<TICK_CODE>::iterator it = m_ticks.ticks.find(TICK_CODE{ m_selection == ssLower ? m_lower_value : m_higher_value });
const bool is_color_change = it->gcode == Slic3r::ColorChangeCode; const bool is_color_change = it->gcode == Slic3r::ColorChangeCode;
append_menu_item(&menu, wxID_ANY, it->gcode == Slic3r::ColorChangeCode ? _(L("Edit color")) : append_menu_item(&menu, wxID_ANY, it->gcode == Slic3r::ColorChangeCode ? _(L("Edit color")) :
@ -3599,7 +3582,7 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event)
append_menu_item(&menu, wxID_ANY, it->gcode == Slic3r::ColorChangeCode ? _(L("Delete color change")) : append_menu_item(&menu, wxID_ANY, it->gcode == Slic3r::ColorChangeCode ? _(L("Delete color change")) :
it->gcode == Slic3r::PausePrintCode ? _(L("Delete pause print")) : it->gcode == Slic3r::PausePrintCode ? _(L("Delete pause print")) :
_(L("Delete custom G-code")), "", _(L("Delete custom G-code")), "",
[this](wxCommandEvent&) { action_tick(taDel); }, "colorchange_del_f", &menu); [this](wxCommandEvent&) { delete_current_tick();}, "colorchange_del_f", &menu);
Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu);
@ -3656,123 +3639,100 @@ static std::string get_pause_print_msg(const std::string& msg_in, double height)
return into_u8(dlg.GetValue()); return into_u8(dlg.GetValue());
} }
void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/) void DoubleSlider::add_code_as_tick(std::string code, int selected_extruder/* = -1*/)
{ {
if (m_selection == ssUndef)
return;
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
// if on this Z doesn't exist tick
auto it = m_ticks.find(TICK_CODE{ tick }); if (m_ticks.ticks.find(TICK_CODE{ tick }) != m_ticks.ticks.end() || // if on this Z doesn't exist tick
if (it != m_ticks.end()) !check_ticks_changed_event(code))
return; return;
std::string color;
const int extruder = selected_extruder > 0 ? selected_extruder : std::max<int>(1, m_only_extruder); const int extruder = selected_extruder > 0 ? selected_extruder : std::max<int>(1, m_only_extruder);
if (code == Slic3r::ColorChangeCode) if (!m_ticks.add_tick(tick, code, extruder, m_values[tick]))
{ return;
std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config();
if (m_ticks.empty())
color = colors[extruder-1];
else
{
auto before_tick_it = std::lower_bound(m_ticks.begin(), m_ticks.end(), TICK_CODE{ tick });
while (before_tick_it != m_ticks.begin()) {
--before_tick_it;
if (before_tick_it->gcode == Slic3r::ColorChangeCode && before_tick_it->extruder == extruder) {
color = before_tick_it->color;
break;
}
}
if (color.empty())
color = colors[extruder-1];
}
color = get_new_color(color);
if (color.empty())
return;
}
else if (code == Slic3r::PausePrintCode)
{
/* PausePrintCode doesn't need a color, so
* this field is used for save a short message shown on Printer display
* */
color = get_pause_print_msg(m_pause_print_msg, m_values[tick]);
if (color.empty())
return;
m_pause_print_msg = color;
}
else if (code.empty())
{
code = get_custom_code(m_custom_gcode, m_values[tick]);
if (code.empty())
return;
m_custom_gcode = code;
}
m_ticks.emplace(TICK_CODE{tick, code, extruder, color});
post_ticks_changed_event(code); post_ticks_changed_event(code);
Refresh(); }
Update();
void DoubleSlider::add_current_tick(bool call_from_keyboard /*= false*/)
{
if (m_selection == ssUndef)
return;
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
auto it = m_ticks.ticks.find(TICK_CODE{ tick });
if (it != m_ticks.ticks.end() || // this tick is already exist
!check_ticks_changed_event(m_mode == t_mode::MultiAsSingle ? Slic3r::ToolChangeCode : Slic3r::ColorChangeCode))
return;
if (m_mode == t_mode::SingleExtruder)
add_code_as_tick(Slic3r::ColorChangeCode);
else
{
wxMenu menu;
if (m_mode == t_mode::MultiAsSingle)
append_change_extruder_menu_item(&menu);
else
append_add_color_change_menu_item(&menu);
wxPoint pos = wxDefaultPosition;
if (call_from_keyboard)
{
int width, height;
get_size(&width, &height);
const wxCoord coord = 0.75 * (is_horizontal() ? height : width);
this->GetPosition(&width, &height);
pos = is_horizontal() ?
wxPoint(get_position_from_value(tick), height + coord) :
wxPoint(width + coord, get_position_from_value(tick));
}
Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu, pos);
}
}
void DoubleSlider::delete_current_tick()
{
if (m_selection == ssUndef)
return;
auto it = m_ticks.ticks.find(TICK_CODE{ m_selection == ssLower ? m_lower_value : m_higher_value });
if (it != m_ticks.ticks.end())
{
if (!check_ticks_changed_event(it->gcode))
return;
const std::string code = it->gcode;
m_ticks.ticks.erase(it);
post_ticks_changed_event(code);
}
} }
void DoubleSlider::edit_tick() void DoubleSlider::edit_tick()
{ {
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
// if on this Z exists tick const std::set<TICK_CODE>::iterator it = m_ticks.ticks.find(TICK_CODE{ tick });
std::set<TICK_CODE>::iterator it = m_ticks.find(TICK_CODE{ tick });
if (it != m_ticks.end())
{
std::string edited_value;
if (it->gcode == Slic3r::ColorChangeCode)
edited_value = get_new_color(it->color);
else if (it->gcode == Slic3r::PausePrintCode)
edited_value = get_pause_print_msg(it->color, m_values[it->tick]);
else
edited_value = get_custom_code(it->gcode, m_values[it->tick]);
if (edited_value.empty()) if (it == m_ticks.ticks.end() || // if on this Z exists tick
return; !check_ticks_changed_event(it->gcode))
return;
TICK_CODE changed_tick = *it; const std::string code = it->gcode;
if (it->gcode == Slic3r::ColorChangeCode || it->gcode == Slic3r::PausePrintCode) { if (m_ticks.edit_tick(it, m_values[it->tick]))
if (it->color == edited_value) post_ticks_changed_event(code);
return;
changed_tick.color = edited_value;
}
else {
if (it->gcode == edited_value)
return;
changed_tick.gcode = edited_value;
}
m_ticks.erase(it);
m_ticks.emplace(changed_tick);
post_ticks_changed_event(changed_tick.gcode);
}
}
void DoubleSlider::change_extruder(int extruder)
{
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config();
// if on this Y doesn't exist tick
if (m_ticks.find(TICK_CODE{tick}) == m_ticks.end())
{
m_ticks.emplace(TICK_CODE{tick, Slic3r::ToolChangeCode, extruder, extruder == 0 ? "" : colors[extruder-1]});
post_ticks_changed_event(Slic3r::ToolChangeCode);
Refresh();
Update();
}
} }
void DoubleSlider::edit_extruder_sequence() void DoubleSlider::edit_extruder_sequence()
{ {
if (!check_ticks_changed_event(Slic3r::ToolChangeCode))
return;
Slic3r::GUI::ExtruderSequenceDialog dlg(m_extruders_sequence); Slic3r::GUI::ExtruderSequenceDialog dlg(m_extruders_sequence);
if (dlg.ShowModal() != wxID_OK) if (dlg.ShowModal() != wxID_OK)
return; return;
@ -3783,13 +3743,7 @@ void DoubleSlider::edit_extruder_sequence()
m_extruders_sequence = from_dlg_val; m_extruders_sequence = from_dlg_val;
auto it = m_ticks.begin(); m_ticks.erase_all_ticks_with_code(Slic3r::ToolChangeCode);
while (it != m_ticks.end()) {
if (it->gcode == Slic3r::ToolChangeCode)
it = m_ticks.erase(it);
else
++it;
}
int tick = 0; int tick = 0;
double value = 0.0; double value = 0.0;
@ -3800,8 +3754,8 @@ void DoubleSlider::edit_extruder_sequence()
while (tick <= m_max_value) while (tick <= m_max_value)
{ {
int cur_extruder = m_extruders_sequence.extruders[extruder]; const int cur_extruder = m_extruders_sequence.extruders[extruder];
m_ticks.emplace(TICK_CODE{tick, Slic3r::ToolChangeCode, cur_extruder + 1, colors[cur_extruder]}); m_ticks.ticks.emplace(TICK_CODE{tick, Slic3r::ToolChangeCode, cur_extruder + 1, colors[cur_extruder]});
extruder++; extruder++;
if (extruder == extr_cnt) if (extruder == extr_cnt)
@ -3825,40 +3779,183 @@ void DoubleSlider::edit_extruder_sequence()
void DoubleSlider::post_ticks_changed_event(const std::string& gcode /*= ""*/) void DoubleSlider::post_ticks_changed_event(const std::string& gcode /*= ""*/)
{ {
if ( m_ticks_mode == m_mode || m_force_mode_apply = (gcode.empty() || gcode == Slic3r::ColorChangeCode || gcode == Slic3r::ToolChangeCode);
(gcode != Slic3r::ColorChangeCode && gcode != Slic3r::ToolChangeCode) )
{
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
return;
}
if (m_ticks_mode == t_mode::SingleExtruder && m_mode == t_mode::MultiAsSingle)
{
}
if (m_ticks_mode == t_mode::SingleExtruder && m_mode == t_mode::MultiExtruder)
{
}
if (m_ticks_mode == t_mode::MultiAsSingle && m_mode == t_mode::SingleExtruder)
{
}
if (m_ticks_mode == t_mode::MultiAsSingle && m_mode == t_mode::MultiExtruder)
{
}
if (m_ticks_mode == t_mode::MultiExtruder && m_mode == t_mode::SingleExtruder)
{
}
if (m_ticks_mode == t_mode::MultiExtruder && m_mode == t_mode::MultiAsSingle)
{
}
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
} }
bool DoubleSlider::check_ticks_changed_event(const std::string& gcode)
{
if ( m_ticks.mode == m_mode ||
(gcode != Slic3r::ColorChangeCode && gcode != Slic3r::ToolChangeCode) ||
(m_ticks.mode == t_mode::SingleExtruder && m_mode == t_mode::MultiAsSingle) || // All ColorChanges will be applied for 1st extruder
(m_ticks.mode == t_mode::MultiExtruder && m_mode == t_mode::MultiAsSingle) ) // Just mark ColorChanges for all unused extruders
return true;
if ((m_ticks.mode == t_mode::SingleExtruder && m_mode == t_mode::MultiExtruder ) ||
(m_ticks.mode == t_mode::MultiExtruder && m_mode == t_mode::SingleExtruder) )
{
if (!m_ticks.has_tick_with_code(Slic3r::ColorChangeCode))
return true;
wxString message = (m_ticks.mode == t_mode::SingleExtruder ?
_(L("The last color change data was saved for a single extruder printer profile.")) :
_(L("The last color change data was saved for a multiple extruder printer profile."))
) + "\n" +
_(L("Your current changes will cause a deletion of all saved color changes.")) + "\n\n\t" +
_(L("Are you sure you want to continue?"));
wxMessageDialog msg(this, message, _(L("Notice")), wxYES_NO);
if (msg.ShowModal() == wxID_YES) {
m_ticks.erase_all_ticks_with_code(Slic3r::ColorChangeCode);
post_ticks_changed_event(Slic3r::ColorChangeCode);
}
return false;
}
// m_ticks_mode == t_mode::MultiAsSingle
if( m_ticks.has_tick_with_code(Slic3r::ToolChangeCode) )
{
wxString message = m_mode == t_mode::SingleExtruder ? (
_(L("The last color change data was saved for a multi extruder printing.")) + "\n\n" +
_(L("Select YES if you want to delete all saved tool changes, \n\t"
"NO if you want all tool changes switch to color changes, \n\t"
"or CANCEL for do nothing")) + "\n\n\t" +
_(L("Do you want to delete all saved tool changes?"))
) : ( // t_mode::MultiExtruder
_(L("The last color change data was saved for a multi extruder printing with tool changes for whole print.")) + "\n\n" +
_(L("Your current changes will cause a deletion of all saved tool changes.")) + "\n\n\t" +
_(L("Are you sure you want to continue?")) ) ;
wxMessageDialog msg(this, message, _(L("Notice")), wxYES_NO | (m_mode == t_mode::SingleExtruder ? wxCANCEL : 0));
const int answer = msg.ShowModal();
if (answer == wxID_YES) {
m_ticks.erase_all_ticks_with_code(Slic3r::ToolChangeCode);
post_ticks_changed_event(Slic3r::ToolChangeCode);
}
else if (m_mode == t_mode::SingleExtruder && answer == wxID_NO) {
m_ticks.switch_code(Slic3r::ToolChangeCode, Slic3r::ColorChangeCode);
post_ticks_changed_event(Slic3r::ColorChangeCode);
}
return false;
}
return true;
}
bool DoubleSlider::TICK_CODE_INFO::add_tick(const int tick, std::string& code, const int extruder, double print_z)
{
std::string color;
if (code.empty()) // custom Gcode
{
code = get_custom_code(custom_gcode, print_z);
if (code.empty())
return false;
custom_gcode = code;
}
else if (code == Slic3r::PausePrintCode)
{
/* PausePrintCode doesn't need a color, so
* this field is used for save a short message shown on Printer display
* */
color = get_pause_print_msg(pause_print_msg, print_z);
if (color.empty())
return false;
pause_print_msg = color;
}
else
{
std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config();
color = colors[extruder - 1];
if (code == Slic3r::ColorChangeCode)
{
if (!ticks.empty())
{
auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), TICK_CODE{ tick });
while (before_tick_it != ticks.begin()) {
--before_tick_it;
if (before_tick_it->gcode == Slic3r::ColorChangeCode && before_tick_it->extruder == extruder) {
color = before_tick_it->color;
break;
}
}
}
color = get_new_color(color);
if (color.empty())
return false;
}
}
ticks.emplace(TICK_CODE{ tick, code, extruder, color });
return true;
}
bool DoubleSlider::TICK_CODE_INFO::edit_tick(std::set<TICK_CODE>::iterator it, double print_z)
{
std::string edited_value;
if (it->gcode == Slic3r::ColorChangeCode)
edited_value = get_new_color(it->color);
else if (it->gcode == Slic3r::PausePrintCode)
edited_value = get_pause_print_msg(it->color, print_z);
else
edited_value = get_custom_code(it->gcode, print_z);
if (edited_value.empty())
return false;
TICK_CODE changed_tick = *it;
if (it->gcode == Slic3r::ColorChangeCode || it->gcode == Slic3r::PausePrintCode) {
if (it->color == edited_value)
return false;
changed_tick.color = edited_value;
}
else {
if (it->gcode == edited_value)
return false;
changed_tick.gcode = edited_value;
}
ticks.erase(it);
ticks.emplace(changed_tick);
return true;
}
void DoubleSlider::TICK_CODE_INFO::switch_code(const std::string& code_from, const std::string& code_to)
{
for (auto it{ ticks.begin() }, end{ ticks.end() }; it != end; )
if (it->gcode == code_from)
{
TICK_CODE tick = *it;
tick.gcode = code_to;
tick.extruder = 1;
ticks.erase(it);
it = ticks.emplace(tick).first;
}
else
++it;
}
void DoubleSlider::TICK_CODE_INFO::erase_all_ticks_with_code(const std::string& gcode)
{
for (auto it{ ticks.begin() }, end{ ticks.end() }; it != end; ) {
if (it->gcode == gcode)
it = ticks.erase(it);
else
++it;
}
}
bool DoubleSlider::TICK_CODE_INFO::has_tick_with_code(const std::string& gcode)
{
for (const TICK_CODE& tick : ticks)
if (tick.gcode == gcode)
return true;
return false;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// LockButton // LockButton

View File

@ -844,9 +844,13 @@ public:
void OnChar(wxKeyEvent &event); void OnChar(wxKeyEvent &event);
void OnRightDown(wxMouseEvent& event); void OnRightDown(wxMouseEvent& event);
void OnRightUp(wxMouseEvent& event); void OnRightUp(wxMouseEvent& event);
void add_code(std::string code, int selected_extruder = -1);
void add_code_as_tick(std::string code, int selected_extruder = -1);
// add default action for tick, when press "+"
void add_current_tick(bool call_from_keyboard = false);
// delete current tick, when press "-"
void delete_current_tick();
void edit_tick(); void edit_tick();
void change_extruder(int extruder);
void edit_extruder_sequence(); void edit_extruder_sequence();
struct TICK_CODE struct TICK_CODE
@ -882,7 +886,6 @@ protected:
void correct_lower_value(); void correct_lower_value();
void correct_higher_value(); void correct_higher_value();
void move_current_thumb(const bool condition); void move_current_thumb(const bool condition);
void action_tick(const TicksAction action);
void enter_window(wxMouseEvent& event, const bool enter); void enter_window(wxMouseEvent& event, const bool enter);
private: private:
@ -906,6 +909,7 @@ private:
std::set<int> get_used_extruders_for_tick(int tick); std::set<int> get_used_extruders_for_tick(int tick);
void post_ticks_changed_event(const std::string& gcode = ""); void post_ticks_changed_event(const std::string& gcode = "");
bool check_ticks_changed_event(const std::string& gcode);
void append_change_extruder_menu_item(wxMenu*); void append_change_extruder_menu_item(wxMenu*);
void append_add_color_change_menu_item(wxMenu*); void append_add_color_change_menu_item(wxMenu*);
@ -937,11 +941,11 @@ private:
bool m_is_enabled_tick_manipulation = true; bool m_is_enabled_tick_manipulation = true;
bool m_show_context_menu = false; bool m_show_context_menu = false;
bool m_show_edit_menu = false; bool m_show_edit_menu = false;
bool m_edit_extruder_sequence = false; bool m_force_edit_extruder_sequence = false;
bool m_suppress_add_code = false; bool m_force_mode_apply = true;
bool m_force_add_tick = false;
bool m_force_delete_tick = false;
t_mode m_mode = t_mode::SingleExtruder; t_mode m_mode = t_mode::SingleExtruder;
std::string m_custom_gcode = "";
std::string m_pause_print_msg;
int m_only_extruder = -1; int m_only_extruder = -1;
wxRect m_rect_lower_thumb; wxRect m_rect_lower_thumb;
@ -972,8 +976,34 @@ private:
std::vector<wxPen*> m_line_pens; std::vector<wxPen*> m_line_pens;
std::vector<wxPen*> m_segm_pens; std::vector<wxPen*> m_segm_pens;
std::vector<double> m_values; std::vector<double> m_values;
std::set<TICK_CODE> m_ticks;
t_mode m_ticks_mode; struct TICK_CODE_INFO
{
std::set<TICK_CODE> ticks;
t_mode mode = t_mode::SingleExtruder;
bool empty() const { return ticks.empty(); }
void set_pause_print_msg(const std::string& message) { pause_print_msg = message; }
bool add_tick (const int tick, std::string &code, int extruder, double print_z);
bool edit_tick (std::set<TICK_CODE>::iterator it, double print_z);
void switch_code(const std::string& code_from, const std::string& code_to);
void erase_all_ticks_with_code (const std::string& gcode);
bool has_tick_with_code (const std::string& gcode);
void suppress_plus (bool suppress) { m_suppress_plus = suppress;}
void suppress_minus(bool suppress) { m_suppress_minus = suppress;}
bool suppressed_plus () { return m_suppress_plus ; }
bool suppressed_minus() { return m_suppress_minus; }
private:
std::string custom_gcode = "";
std::string pause_print_msg = "";
bool m_suppress_plus = false;
bool m_suppress_minus = false;
}
m_ticks;
public: public:
struct ExtrudersSequence struct ExtrudersSequence