Updated tooltips and context menus for 3 manipulation mode of DoubleSlider

+ Some code refactoring
This commit is contained in:
YuSanka 2020-01-09 16:38:59 +01:00
parent fb65e3152f
commit aed277089b
3 changed files with 220 additions and 116 deletions

View file

@ -694,9 +694,9 @@ void Preview::update_double_slider(const std::vector<double>& layers_z, bool kee
m_slider->EnableTickManipulation(color_print_enable); m_slider->EnableTickManipulation(color_print_enable);
// Detect and set manipulation mode for double slider // Detect and set manipulation mode for double slider
m_slider->SetManipulationState( wxGetApp().extruders_edited_cnt() == 1 ? DoubleSlider::msSingleExtruder : m_slider->SetManipulationMode( wxGetApp().extruders_edited_cnt() == 1 ? DoubleSlider::mmSingleExtruder :
wxGetApp().plater()->is_one_extruder_printed_model() ? DoubleSlider::msMultiAsSingle : wxGetApp().plater()->is_one_extruder_printed_model() ? DoubleSlider::mmMultiAsSingle :
DoubleSlider::msMultiExtruder); DoubleSlider::mmMultiExtruder);
} }
void Preview::reset_double_slider() void Preview::reset_double_slider()

View file

@ -2561,7 +2561,7 @@ std::vector<t_custom_code> 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) {
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});
@ -2575,19 +2575,19 @@ void DoubleSlider::SetTicksValues(const std::vector<t_custom_code>& heights)
if (m_values.empty()) if (m_values.empty())
return; return;
const bool was_empty = m_ticks_.empty(); const bool was_empty = m_ticks.empty();
m_ticks_.clear(); m_ticks.clear();
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());
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.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
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
@ -2638,11 +2638,6 @@ void DoubleSlider::render()
// draw line // draw line
draw_scroll_line(dc, lower_pos, higher_pos); draw_scroll_line(dc, lower_pos, higher_pos);
// //lower slider:
// draw_thumb(dc, lower_pos, ssLower);
// //higher slider:
// draw_thumb(dc, higher_pos, ssHigher);
//draw color print ticks //draw color print ticks
draw_ticks(dc); draw_ticks(dc);
@ -2668,7 +2663,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.find(TICK_CODE{tick}) != m_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;
@ -2811,7 +2806,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)
{ {
const wxCoord pos = get_position_from_value(tick.tick); const wxCoord pos = get_position_from_value(tick.tick);
@ -2834,6 +2829,96 @@ void DoubleSlider::draw_ticks(wxDC& dc)
} }
} }
bool DoubleSlider::get_color_for_tick(wxColour& color, std::set<TICK_CODE>::const_iterator tick_it, const std::vector<std::string>& colors) const
{
if (m_mode == mmMultiExtruder)
{
color = GetParent()->GetBackgroundColour();
return true;
}
const std::string& code = tick_it->gcode;
if ( code == Slic3r::PausePrintCode ||
(code != Slic3r::ColorChangeCode && code != Slic3r::ExtruderChangeCode) )
return false;
if (m_mode == mmSingleExtruder) {
if (code == Slic3r::ColorChangeCode) {
color = wxColour(tick_it->color);
return true;
}
return false;
}
const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt();
const int colors_cnt = colors.size();
auto get_m600_color_idx = [extruders_cnt, colors_cnt](const std::set<TICK_CODE>& ticks, std::set<TICK_CODE>::const_iterator it)
{
int shift = 0;
while (it != ticks.begin()) {
--it;
if (it->gcode == Slic3r::ColorChangeCode)
shift++;
}
if (extruders_cnt + shift >= colors_cnt)
return 0;
return extruders_cnt + shift;
};
auto get_color_idx_for_tool_change = [extruders_cnt, colors_cnt, get_m600_color_idx](const std::set<TICK_CODE>& ticks, std::set<TICK_CODE>::const_iterator it)
{
const int current_extruder = it->extruder == 0 ? 1 : it->extruder;
if (extruders_cnt == colors_cnt) // there is no one "M600"
return std::min<int>(extruders_cnt - 1, std::max<int>(current_extruder - 1, 0));
auto it_n = it;
while (it_n != ticks.begin()) {
--it_n;
if (it_n->gcode == Slic3r::ColorChangeCode && it_n->extruder == current_extruder)
return get_m600_color_idx(ticks, it_n);
}
return std::min<int>(extruders_cnt - 1, std::max<int>(current_extruder - 1, 0));
};
auto get_color_idx_for_color_change = [get_m600_color_idx](const std::set<TICK_CODE>& ticks, std::set<TICK_CODE>::const_iterator it)
{
auto it_n = it;
bool is_tool_change = false;
while (it_n != ticks.begin()) {
--it_n;
if (it_n->gcode == Slic3r::ExtruderChangeCode) {
is_tool_change = true;
if (it_n->extruder == it->extruder)
return get_m600_color_idx(ticks, it);
break;
}
}
if (!is_tool_change && it->extruder == 0) // use correct extruder number instead of 0
return get_m600_color_idx(ticks, it);
return -1;
};
// change tool (extruder)
if (code == Slic3r::ExtruderChangeCode)
color = wxColour(colors[get_color_idx_for_tool_change(m_ticks, tick_it)]);
// change color for current extruder
if (code == Slic3r::ColorChangeCode) {
const int color_idx = get_color_idx_for_color_change(m_ticks, tick_it);
if (color_idx < 0)
return false;
if (color_idx >= colors_cnt)
return false;
color = wxColour(colors[color_idx]);
}
return true;
}
void DoubleSlider::draw_colored_band(wxDC& dc) void DoubleSlider::draw_colored_band(wxDC& dc)
{ {
if (!m_is_enabled_tick_manipulation) if (!m_is_enabled_tick_manipulation)
@ -2856,29 +2941,40 @@ void DoubleSlider::draw_colored_band(wxDC& dc)
dc.DrawRectangle(band_rc); dc.DrawRectangle(band_rc);
}; };
const std::vector<std::string>& colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); const std::vector<std::string>& colors = Slic3r::GUI::wxGetApp().plater()->get_colors_for_color_print();
int colors_cnt = colors.size();
const wxColour bg_clr = GetParent()->GetBackgroundColour(); const wxColour bg_clr = GetParent()->GetBackgroundColour();
wxColour clr = m_ticks_.empty() ? bg_clr : wxColour(colors[0]); wxColour clr = m_ticks.empty() || m_mode == mmMultiExtruder ? bg_clr : wxColour(colors[0]);
draw_band(dc, clr, main_band); draw_band(dc, clr, main_band);
size_t i = 1; if (m_ticks.empty() || m_mode == mmMultiExtruder)
for (auto tick : m_ticks_) // don't color a band for MultiExtruder mode
{ return;
if ( (m_state != msMultiExtruder/*m_state == msSingleExtruder*/ && tick.gcode != Slic3r::ColorChangeCode) ||
(m_state == msMultiExtruder && tick.gcode != Slic3r::ExtruderChangeCode) )
continue;
const wxCoord pos = get_position_from_value(tick.tick); std::set<TICK_CODE>::const_iterator tick_it = m_ticks.begin();
while (tick_it != m_ticks.end())
{
if ( (m_mode == mmSingleExtruder && tick_it->gcode != Slic3r::ColorChangeCode ) ||
(m_mode == mmMultiAsSingle && !(tick_it->gcode == Slic3r::ExtruderChangeCode || tick_it->gcode == Slic3r::ColorChangeCode)) )
{
++tick_it;
continue;
}
const wxCoord pos = get_position_from_value(tick_it->tick);
is_horizontal() ? main_band.SetLeft(SLIDER_MARGIN + pos) : is_horizontal() ? main_band.SetLeft(SLIDER_MARGIN + pos) :
main_band.SetBottom(pos - 1); main_band.SetBottom(pos - 1);
clr = (m_state == msMultiExtruder && tick.color.empty()) ? bg_clr : if (!get_color_for_tick(clr, tick_it, colors))
m_state == msMultiExtruder ? wxColour(colors[std::min<int>(colors_cnt - 1, tick.extruder-1)]) : wxColour(tick.color); {
++tick_it;
continue;
}
draw_band(dc, clr, main_band); draw_band(dc, clr, main_band);
i++; ++tick_it;
} }
} }
@ -2903,7 +2999,7 @@ void DoubleSlider::draw_one_layer_icon(wxDC& dc)
void DoubleSlider::draw_revert_icon(wxDC& dc) void DoubleSlider::draw_revert_icon(wxDC& dc)
{ {
if (m_ticks_.empty() || !m_is_enabled_tick_manipulation) if (m_ticks.empty() || !m_is_enabled_tick_manipulation)
return; return;
int width, height; int width, height;
@ -2921,7 +3017,7 @@ void DoubleSlider::draw_revert_icon(wxDC& dc)
void DoubleSlider::draw_cog_icon(wxDC& dc) void DoubleSlider::draw_cog_icon(wxDC& dc)
{ {
if (m_state != msMultiExtruder) if (m_mode != mmMultiExtruder)
return; return;
int width, height; int width, height;
@ -2965,15 +3061,13 @@ void DoubleSlider::detect_selected_slider(const wxPoint& pt)
bool DoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect) bool DoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect)
{ {
if (rect.GetLeft() <= pt.x && pt.x <= rect.GetRight() && return rect.GetLeft() <= pt.x && pt.x <= rect.GetRight() &&
rect.GetTop() <= pt.y && pt.y <= rect.GetBottom()) rect.GetTop() <= pt.y && pt.y <= rect.GetBottom();
return true;
return false;
} }
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) {
const wxCoord pos = get_position_from_value(tick.tick); const wxCoord pos = get_position_from_value(tick.tick);
if (is_horizontal()) { if (is_horizontal()) {
@ -3034,10 +3128,10 @@ 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.clear();
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
} }
else if (is_point_in_rect(pos, m_rect_cog_icon) && m_state == msMultiExtruder) { else if (is_point_in_rect(pos, m_rect_cog_icon) && m_mode == mmMultiExtruder) {
// show dialog for set extruder sequence // show dialog for set extruder sequence
m_edit_extruder_sequence = true; m_edit_extruder_sequence = true;
} }
@ -3107,17 +3201,18 @@ 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.find(TICK_CODE{tick});
tooltip = tick_code_it == m_ticks_.end() ? (m_state == msSingleExtruder ? tooltip = tick_code_it == m_ticks.end() ? (m_mode == mmMultiAsSingle ?
_(L("For add color change use left mouse button click")) : _(L("For add change extruder use left mouse button click")) :
_(L("For add change extruder 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")) :
tick_code_it->gcode == Slic3r::ColorChangeCode ? ( m_state == msSingleExtruder ? tick_code_it->gcode == Slic3r::ColorChangeCode ? ( m_mode == mmSingleExtruder ?
_(L("For Delete color change use left mouse button click\n" _(L("For Delete color change use left mouse button click\n"
"For Edit color use right mouse button click")) : "For Edit color use right mouse button click")) :
from_u8((boost::format(_utf8(L("Delete color change for Extruder %1%"))) % tick_code_it->extruder).str()) ): from_u8((boost::format(_utf8(L("Delete color change for Extruder %1%"))) % tick_code_it->extruder).str()) ):
// tick_code_it->gcode == Slic3r::PausePrintCode ? _(L("Delete pause")) : tick_code_it->gcode == Slic3r::PausePrintCode ?
tick_code_it->gcode == Slic3r::ExtruderChangeCode ? _(L("Delete pause")) :
tick_code_it->gcode == Slic3r::ExtruderChangeCode ?
from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) : from_u8((boost::format(_utf8(L("Delete extruder change to \"%1%\""))) % tick_code_it->extruder).str()) :
from_u8((boost::format(_utf8(L("For Delete \"%1%\" code use left mouse button click\n" from_u8((boost::format(_utf8(L("For Delete \"%1%\" code use left mouse button click\n"
"For Edit \"%1%\" code use right mouse button click"))) % tick_code_it->gcode ).str()); "For Edit \"%1%\" code use right mouse button click"))) % tick_code_it->gcode ).str());
@ -3138,7 +3233,7 @@ void DoubleSlider::OnMotion(wxMouseEvent& event)
if (!m_is_left_down && !m_is_one_layer) { if (!m_is_left_down && !m_is_one_layer) {
m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action);
if (!m_ticks_.empty() && is_point_in_rect(pos, m_rect_revert_icon)) if (!m_ticks.empty() && is_point_in_rect(pos, m_rect_revert_icon))
icon_focus = ifRevert; icon_focus = ifRevert;
else if (is_point_in_rect(pos, m_rect_cog_icon)) else if (is_point_in_rect(pos, m_rect_cog_icon))
icon_focus = ifCog; icon_focus = ifCog;
@ -3182,7 +3277,7 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event)
if (m_show_context_menu) if (m_show_context_menu)
{ {
if (m_state == msSingleExtruder) if (m_mode == mmSingleExtruder)
add_code(Slic3r::ColorChangeCode); add_code(Slic3r::ColorChangeCode);
else else
{ {
@ -3194,7 +3289,7 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event)
wxString sub_menu_name = _(L("Change extruder")); wxString sub_menu_name = _(L("Change extruder"));
std::string menu_icon_name = "change_extruder"; std::string menu_icon_name = "change_extruder";
if (m_state == msMultiAsSingle) if (m_mode == mmMultiAsSingle)
{ {
int initial_extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); int initial_extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value);
if (initial_extruder == 0) if (initial_extruder == 0)
@ -3213,7 +3308,8 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event)
const wxString item_name = wxString::Format(_(L("Extruder %d")), i); const wxString item_name = wxString::Format(_(L("Extruder %d")), i);
append_menu_item(sub_menu, wxID_ANY, item_name, "", append_menu_item(sub_menu, wxID_ANY, item_name, "",
[this, i](wxCommandEvent&) { add_code(Slic3r::ColorChangeCode, i); }, "", &menu); [this, i](wxCommandEvent&) { add_code(Slic3r::ColorChangeCode, i); }, "", &menu,
[this]() {return true; }, this);
} }
sub_menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % Slic3r::ColorChangeCode).str()); sub_menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % Slic3r::ColorChangeCode).str());
@ -3285,13 +3381,13 @@ void DoubleSlider::action_tick(const TicksAction action)
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 it = m_ticks_.find(TICK_CODE{tick}); const auto it = m_ticks.find(TICK_CODE{tick});
if (it != m_ticks_.end()) // erase this tick if (it != m_ticks.end()) // erase this tick
{ {
if (action == taAdd) if (action == taAdd)
return; return;
m_ticks_.erase(TICK_CODE{tick}); m_ticks.erase(TICK_CODE{tick});
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
Refresh(); Refresh();
@ -3308,7 +3404,7 @@ void DoubleSlider::action_tick(const TicksAction action)
if (m_suppress_add_code) if (m_suppress_add_code)
return; return;
m_suppress_add_code = true; m_suppress_add_code = true;
if (m_state != msMultiExtruder) if (m_mode == mmSingleExtruder) // if (m_mode != mmMultiExtruder)
add_code(Slic3r::ColorChangeCode); add_code(Slic3r::ColorChangeCode);
m_suppress_add_code = false; m_suppress_add_code = false;
return; return;
@ -3395,8 +3491,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.find(TICK_CODE{ tick });
if (it == m_ticks_.end()) if (it == m_ticks.end())
{ {
// show context menu on OnRightUp() // show context menu on OnRightUp()
m_show_context_menu = true; m_show_context_menu = true;
@ -3429,11 +3525,11 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event)
int DoubleSlider::get_extruder_for_tick(int tick) int DoubleSlider::get_extruder_for_tick(int tick)
{ {
if (m_ticks_.empty()) if (m_ticks.empty())
return 0; return 0;
auto it = m_ticks_.lower_bound(TICK_CODE{tick}); auto it = m_ticks.lower_bound(TICK_CODE{tick});
while (it != m_ticks_.begin()) { while (it != m_ticks.begin()) {
--it; --it;
if(it->gcode == Slic3r::ExtruderChangeCode) if(it->gcode == Slic3r::ExtruderChangeCode)
return it->extruder; return it->extruder;
@ -3452,45 +3548,57 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event)
if (m_show_context_menu) { if (m_show_context_menu) {
wxMenu menu; wxMenu menu;
if (m_state == msMultiExtruder) if (m_mode == mmSingleExtruder)
append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "",
[this](wxCommandEvent&) { add_code(Slic3r::ColorChangeCode); }, "colorchange_add_m", &menu,
[](){return true;}, this);
else
{ {
const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt(); const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt();
if (extruders_cnt > 1) if (extruders_cnt > 1)
{ {
const int initial_extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); int initial_extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value);
if (initial_extruder == 0)
initial_extruder = 1;
wxMenu* change_extruder_menu = new wxMenu(); wxMenu* change_extruder_menu = new wxMenu();
wxMenu* add_color_change_menu = new wxMenu(); wxMenu* add_color_change_menu = new wxMenu();
for (int i = 0; i <= extruders_cnt; i++) { for (int i = 1; i <= extruders_cnt; i++) {
const wxString item_name = i == 0 ? _(L("Default")) : wxString::Format(_(L("Extruder %d")), i); const wxString item_name = wxString::Format(_(L("Extruder %d")), i);
if (m_mode == mmMultiAsSingle)
append_menu_radio_item(change_extruder_menu, wxID_ANY, item_name, "", append_menu_radio_item(change_extruder_menu, wxID_ANY, item_name, "",
[this, i](wxCommandEvent&) { change_extruder(i); }, &menu)->Check(i == initial_extruder); [this, i](wxCommandEvent&) { change_extruder(i); }, &menu)->Check(i == initial_extruder);
if (i==0) // don't use M600 for default extruder, if multimaterial print is selected
continue;
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(Slic3r::ColorChangeCode, i); }, "", &menu,
[](){return true;}, this);
} }
wxMenuItem* change_extruder_menu_item = menu.AppendSubMenu(change_extruder_menu, _(L("Change extruder")), _(L("Use another extruder"))); const wxString change_extruder_menu_name = m_mode == mmMultiAsSingle ? _(L("Change extruder")) : _(L("Change extruder (N/A)"));
wxMenuItem* change_extruder_menu_item = menu.AppendSubMenu(change_extruder_menu, change_extruder_menu_name, _(L("Use another extruder")));
change_extruder_menu_item->SetBitmap(create_scaled_bitmap(nullptr, "change_extruder")); change_extruder_menu_item->SetBitmap(create_scaled_bitmap(nullptr, "change_extruder"));
ManipulationMode mode = m_mode;
Slic3r::GUI::wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [this, mode, change_extruder_menu_item](wxUpdateUIEvent& evt) {
enable_menu_item(evt, [this](){return m_mode == mmMultiAsSingle;}, change_extruder_menu_item, this); },
change_extruder_menu_item->GetId());
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(nullptr, "colorchange_add_m"));
} }
} }
else
append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "",
[this](wxCommandEvent&) { add_code(Slic3r::ColorChangeCode); }, "colorchange_add_m", &menu);
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(Slic3r::PausePrintCode); }, "pause_print", &menu,
[]() {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(""); }, "edit_gcode", &menu,
[]() {return true; }, this);
Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu); Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu);
@ -3499,7 +3607,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.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")) :
@ -3571,17 +3679,17 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/)
{ {
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.find(TICK_CODE{ tick });
if (it == m_ticks_.end()) if (it == m_ticks.end())
{ {
std::string color = ""; std::string color = "";
if (code == Slic3r::ColorChangeCode) if (code == Slic3r::ColorChangeCode)
{ {
std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config();
if (m_state == msSingleExtruder && !m_ticks_.empty()) { if (m_mode == mmSingleExtruder && !m_ticks.empty()) {
auto before_tick_it = std::lower_bound(m_ticks_.begin(), m_ticks_.end(), TICK_CODE{ tick }); auto before_tick_it = std::lower_bound(m_ticks.begin(), m_ticks.end(), TICK_CODE{ tick });
while (before_tick_it != m_ticks_.begin()) { while (before_tick_it != m_ticks.begin()) {
--before_tick_it; --before_tick_it;
if (before_tick_it->gcode == Slic3r::ColorChangeCode) { if (before_tick_it->gcode == Slic3r::ColorChangeCode) {
color = before_tick_it->color; color = before_tick_it->color;
@ -3618,14 +3726,14 @@ void DoubleSlider::add_code(std::string code, int selected_extruder/* = -1*/)
} }
int extruder = 1; int extruder = 1;
if (m_state == msMultiExtruder) { if (m_mode != mmSingleExtruder) {
if (code == Slic3r::ColorChangeCode && selected_extruder >= 0) if (code == Slic3r::ColorChangeCode && selected_extruder >= 0)
extruder = selected_extruder; extruder = selected_extruder;
else else
extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value); extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value);
} }
m_ticks_.emplace(TICK_CODE{tick, code, extruder, color}); m_ticks.emplace(TICK_CODE{tick, code, extruder, color});
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
Refresh(); Refresh();
@ -3637,8 +3745,8 @@ 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 // if on this Z exists tick
std::set<TICK_CODE>::iterator it = m_ticks_.find(TICK_CODE{ tick }); std::set<TICK_CODE>::iterator it = m_ticks.find(TICK_CODE{ tick });
if (it != m_ticks_.end()) if (it != m_ticks.end())
{ {
std::string edited_value; std::string edited_value;
if (it->gcode == Slic3r::ColorChangeCode) if (it->gcode == Slic3r::ColorChangeCode)
@ -3663,8 +3771,8 @@ void DoubleSlider::edit_tick()
changed_tick.gcode = edited_value; changed_tick.gcode = edited_value;
} }
m_ticks_.erase(it); m_ticks.erase(it);
m_ticks_.emplace(changed_tick); m_ticks.emplace(changed_tick);
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
} }
@ -3677,9 +3785,9 @@ void DoubleSlider::change_extruder(int extruder)
std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config(); std::vector<std::string> colors = Slic3r::GUI::wxGetApp().plater()->get_extruder_colors_from_plater_config();
// if on this Y doesn't exist tick // if on this Y doesn't exist tick
if (m_ticks_.find(TICK_CODE{tick}) == m_ticks_.end()) if (m_ticks.find(TICK_CODE{tick}) == m_ticks.end())
{ {
m_ticks_.emplace(TICK_CODE{tick, Slic3r::ExtruderChangeCode, extruder, extruder == 0 ? "" : colors[extruder-1]}); m_ticks.emplace(TICK_CODE{tick, Slic3r::ExtruderChangeCode, extruder, extruder == 0 ? "" : colors[extruder-1]});
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
Refresh(); Refresh();
@ -3699,10 +3807,10 @@ void DoubleSlider::edit_extruder_sequence()
m_extruders_sequence = from_dlg_val; m_extruders_sequence = from_dlg_val;
auto it = m_ticks_.begin(); auto it = m_ticks.begin();
while (it != m_ticks_.end()) { while (it != m_ticks.end()) {
if (it->gcode == Slic3r::ExtruderChangeCode) if (it->gcode == Slic3r::ExtruderChangeCode)
it = m_ticks_.erase(it); it = m_ticks.erase(it);
else else
++it; ++it;
} }
@ -3717,7 +3825,7 @@ void DoubleSlider::edit_extruder_sequence()
while (tick <= m_max_value) while (tick <= m_max_value)
{ {
int cur_extruder = m_extruders_sequence.extruders[extruder]; int cur_extruder = m_extruders_sequence.extruders[extruder];
m_ticks_.emplace(TICK_CODE{tick, Slic3r::ExtruderChangeCode, cur_extruder + 1, colors[cur_extruder]}); m_ticks.emplace(TICK_CODE{tick, Slic3r::ExtruderChangeCode, cur_extruder + 1, colors[cur_extruder]});
extruder++; extruder++;
if (extruder == extr_cnt) if (extruder == extr_cnt)

View file

@ -821,20 +821,15 @@ public:
EnableTickManipulation(false); EnableTickManipulation(false);
} }
enum ManipulationState { enum ManipulationMode {
msSingleExtruder, // single extruder printer preset is selected mmSingleExtruder, // single extruder printer preset is selected
msMultiAsSingle, // multiple extruder printer preset is selected, but mmMultiAsSingle, // multiple extruder printer preset is selected, but
// this mode works just for Single extruder print // this mode works just for Single extruder print
// (For all print from objects settings is used just one extruder) // (For all print from objects settings is used just one extruder)
msMultiExtruder // multiple extruder printer preset is selected mmMultiExtruder // multiple extruder printer preset is selected
}; };
void SetManipulationState(ManipulationState state) { void SetManipulationMode(ManipulationMode mode) { m_mode = mode; }
m_state = state; ManipulationMode GetManipulationMode() const { return m_mode; }
}
void SetManipulationState(int extruders_cnt) {
m_state = extruders_cnt ==1 ? msSingleExtruder : msMultiExtruder;
}
ManipulationState GetManipulationState() const { return m_state; }
bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; }
bool is_one_layer() const { return m_is_one_layer; } bool is_one_layer() const { return m_is_one_layer; }
@ -860,6 +855,17 @@ public:
void change_extruder(int extruder); void change_extruder(int extruder);
void edit_extruder_sequence(); void edit_extruder_sequence();
struct TICK_CODE
{
bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; }
bool operator>(const TICK_CODE& other) const { return other.tick < this->tick; }
int tick = 0;
std::string gcode = Slic3r::ColorChangeCode;
int extruder = 0;
std::string color;
};
protected: protected:
void render(); void render();
@ -881,7 +887,6 @@ protected:
void detect_selected_slider(const wxPoint& pt); void detect_selected_slider(const wxPoint& pt);
void correct_lower_value(); void correct_lower_value();
void correct_higher_value(); void correct_higher_value();
wxString get_tooltip(IconFocus icon_focus);
void move_current_thumb(const bool condition); void move_current_thumb(const bool condition);
void action_tick(const TicksAction action); void action_tick(const TicksAction action);
void enter_window(wxMouseEvent& event, const bool enter); void enter_window(wxMouseEvent& event, const bool enter);
@ -897,6 +902,10 @@ protected:
wxSize get_size(); wxSize get_size();
void get_size(int *w, int *h); void get_size(int *w, int *h);
double get_double_value(const SelectedSlider& selection); double get_double_value(const SelectedSlider& selection);
wxString get_tooltip(IconFocus icon_focus);
bool get_color_for_tick( wxColour& color,
std::set<TICK_CODE>::const_iterator tick_it,
const std::vector<std::string>& colors) const;
private: private:
bool is_osx { false }; bool is_osx { false };
@ -929,7 +938,7 @@ private:
bool m_show_edit_menu = false; bool m_show_edit_menu = false;
bool m_edit_extruder_sequence = false; bool m_edit_extruder_sequence = false;
bool m_suppress_add_code = false; bool m_suppress_add_code = false;
ManipulationState m_state = msSingleExtruder; ManipulationMode m_mode = mmSingleExtruder;
std::string m_custom_gcode = ""; std::string m_custom_gcode = "";
std::string m_pause_print_msg; std::string m_pause_print_msg;
@ -960,21 +969,8 @@ 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::set<int> m_ticks;
std::vector<double> m_values; std::vector<double> m_values;
std::set<TICK_CODE> m_ticks;
struct TICK_CODE
{
bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; }
bool operator>(const TICK_CODE& other) const { return other.tick < this->tick; }
int tick = 0;
std::string gcode = Slic3r::ColorChangeCode;
int extruder = 0;
std::string color;
};
std::set<TICK_CODE> m_ticks_;
public: public:
struct ExtrudersSequence struct ExtrudersSequence