First implementations for an extension of color change feature :

Added context menu for "plus" button on DoubleSlider
This commit is contained in:
YuSanka 2019-10-09 09:28:50 +02:00
parent 47a8b49f8b
commit 8cdcac6ad8
3 changed files with 192 additions and 27 deletions

View File

@ -583,6 +583,25 @@ void Preview::create_double_slider()
m_slider = new DoubleSlider(this, wxID_ANY, 0, 0, 0, 100); m_slider = new DoubleSlider(this, wxID_ANY, 0, 0, 0, 100);
m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0);
/*
auto extruder_selector = new wxComboBox(this, wxID_ANY);
extruder_selector->Append("Whole print");
int extruder_cnt = wxGetApp().extruders_edited_cnt();
int i = 0;
while (i < extruder_cnt)
{
i++;
extruder_selector->Append(wxString::Format("Extruder %d", i));
}
extruder_selector->SetSelection(0);
auto sizer = new wxBoxSizer(wxVERTICAL);
sizer->Add(extruder_selector, 0, wxEXPAND, 0);
sizer->Add(m_slider, 1, wxEXPAND, 0);
m_double_slider_sizer->Add(sizer, 0, wxEXPAND, 0);
*/
// sizer, m_canvas_widget // sizer, m_canvas_widget
m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_double_slider_from_canvas, this); m_canvas_widget->Bind(wxEVT_KEY_DOWN, &Preview::update_double_slider_from_canvas, this);

View File

@ -2451,10 +2451,16 @@ std::vector<double> 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 (int tick : m_ticks) { // #ys_FIXME_COLOR
if (tick > val_size) // for (int tick : m_ticks) {
// if (tick > val_size)
// break;
// values.push_back(m_values[tick]);
// }
for (const TICK_CODE& tick : m_ticks_) {
if (tick.tick > val_size)
break; break;
values.push_back(m_values[tick]); values.push_back(m_values[tick.tick]);
} }
return values; return values;
@ -2465,19 +2471,36 @@ void DoubleSlider::SetTicksValues(const std::vector<double>& heights)
if (m_values.empty()) if (m_values.empty())
return; return;
const bool was_empty = m_ticks.empty(); // #ys_FIXME_COLOR
// const bool was_empty = m_ticks.empty();
//
// m_ticks.clear();
// for (auto h : heights) {
// auto it = std::lower_bound(m_values.begin(), m_values.end(), h - epsilon());
//
// if (it == m_values.end())
// continue;
//
// m_ticks.insert(it-m_values.begin());
// }
//
// 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
// wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
m_ticks.clear(); const bool was_empty = m_ticks_.empty();
m_ticks_.clear();
for (auto h : heights) { for (auto h : heights) {
auto it = std::lower_bound(m_values.begin(), m_values.end(), h - epsilon()); auto it = std::lower_bound(m_values.begin(), m_values.end(), h - epsilon());
if (it == m_values.end()) if (it == m_values.end())
continue; continue;
m_ticks.insert(it-m_values.begin()); m_ticks_.insert(it-m_values.begin());
} }
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));
} }
@ -2552,7 +2575,10 @@ 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) != m_ticks.end()) // #ys_FIXME_COLOR
// if (m_ticks.find(tick) != m_ticks.end())
// icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp();
if (m_ticks_.find(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;
@ -2695,9 +2721,13 @@ 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) // #ys_FIXME_COLOR
// for (auto tick : m_ticks)
for (auto tick : m_ticks_)
{ {
const wxCoord pos = get_position_from_value(tick); // #ys_FIXME_COLOR
// const wxCoord pos = get_position_from_value(tick);
const wxCoord pos = get_position_from_value(tick.tick);
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*/);
@ -2727,7 +2757,9 @@ void DoubleSlider::draw_colored_band(wxDC& dc)
main_band.SetBottom(height - SLIDER_MARGIN + 1); main_band.SetBottom(height - SLIDER_MARGIN + 1);
} }
if (m_ticks.empty()) { // #ys_FIXME_COLOR
// if (m_ticks.empty()) {
if (m_ticks_.empty()) {
dc.SetPen(GetParent()->GetBackgroundColour()); dc.SetPen(GetParent()->GetBackgroundColour());
dc.SetBrush(GetParent()->GetBackgroundColour()); dc.SetBrush(GetParent()->GetBackgroundColour());
dc.DrawRectangle(main_band); dc.DrawRectangle(main_band);
@ -2743,11 +2775,15 @@ void DoubleSlider::draw_colored_band(wxDC& dc)
dc.DrawRectangle(main_band); dc.DrawRectangle(main_band);
size_t i = 1; size_t i = 1;
for (auto tick : m_ticks) // #ys_FIXME_COLOR
// for (auto tick : m_ticks)
for (auto tick : m_ticks_)
{ {
if (i == colors_cnt) if (i == colors_cnt)
i = 0; i = 0;
const wxCoord pos = get_position_from_value(tick); // #ys_FIXME_COLOR
//const wxCoord pos = get_position_from_value(tick);
const wxCoord pos = get_position_from_value(tick.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);
@ -2780,7 +2816,9 @@ 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) // #ys_FIXME_COLOR
// 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;
@ -2832,16 +2870,24 @@ 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) { // #ys_FIXME_COLOR
const wxCoord pos = get_position_from_value(tick); // for (auto tick : m_ticks) {
for (auto tick : m_ticks_) {
// #ys_FIXME_COLOR
// const wxCoord pos = get_position_from_value(tick);
const wxCoord pos = get_position_from_value(tick.tick);
if (is_horizontal()) { if (is_horizontal()) {
if (pos - 4 <= pt.x && pt.x <= pos + 4) if (pos - 4 <= pt.x && pt.x <= pos + 4)
return tick; // #ys_FIXME_COLOR
// return tick;
return tick.tick;
} }
else { else {
if (pos - 4 <= pt.y && pt.y <= pos + 4) if (pos - 4 <= pt.y && pt.y <= pos + 4)
return tick; // #ys_FIXME_COLOR
// return tick;
return tick.tick;
} }
} }
return -1; return -1;
@ -2893,7 +2939,9 @@ 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(); // #ys_FIXME_COLOR
// m_ticks.clear();
m_ticks_.clear();
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
} }
else else
@ -2960,7 +3008,9 @@ 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);
is_revert_icon_focused = !m_ticks.empty() && is_point_in_rect(pos, m_rect_revert_icon); // #ys_FIXME_COLOR
// is_revert_icon_focused = !m_ticks.empty() && is_point_in_rect(pos, m_rect_revert_icon);
is_revert_icon_focused = !m_ticks_.empty() && is_point_in_rect(pos, m_rect_revert_icon);
} }
else if (m_is_left_down || m_is_right_down) { else if (m_is_left_down || m_is_right_down) {
if (m_selection == ssLower) { if (m_selection == ssLower) {
@ -2975,6 +3025,7 @@ void DoubleSlider::OnMotion(wxMouseEvent& event)
correct_higher_value(); correct_higher_value();
action = (current_value != m_higher_value); action = (current_value != m_higher_value);
} }
if (m_is_right_down) m_is_mouse_move = true;
} }
Refresh(); Refresh();
Update(); Update();
@ -3051,16 +3102,29 @@ 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;
// #ys_FIXME_COLOR
// if (action == taOnIcon) {
// if (!m_ticks.insert(tick).second)
// m_ticks.erase(tick);
// }
// else {
// const auto it = m_ticks.find(tick);
// if (it == m_ticks.end() && action == taAdd)
// m_ticks.insert(tick);
// else if (it != m_ticks.end() && action == taDel)
// m_ticks.erase(tick);
// }
if (action == taOnIcon) { if (action == taOnIcon) {
if (!m_ticks.insert(tick).second) if (!m_ticks_.insert(TICK_CODE(tick)).second)
m_ticks.erase(tick); m_ticks_.erase(TICK_CODE(tick));
} }
else { else {
const auto it = m_ticks.find(tick); const auto it = m_ticks_.find(tick);
if (it == m_ticks.end() && action == taAdd) if (it == m_ticks_.end() && action == taAdd)
m_ticks.insert(tick); m_ticks_.insert(tick);
else if (it != m_ticks.end() && action == taDel) else if (it != m_ticks_.end() && action == taDel)
m_ticks.erase(tick); m_ticks_.erase(tick);
} }
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
@ -3140,6 +3204,22 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event)
this->CaptureMouse(); this->CaptureMouse();
const wxClientDC dc(this); const wxClientDC dc(this);
wxPoint pos = event.GetLogicalPosition(dc);
if (is_point_in_rect(pos, m_rect_tick_action) && m_is_enabled_tick_manipulation)
{
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
// if on this Y doesn't exist tick
// #ys_FIXME_COLOR
// if (m_ticks.find(tick) == m_ticks.end())
if (m_ticks_.find(tick) == m_ticks_.end())
{
// show context menu on OnRightUp()
m_show_context_menu = true;
return;
}
}
detect_selected_slider(event.GetLogicalPosition(dc)); detect_selected_slider(event.GetLogicalPosition(dc));
if (!m_selection) if (!m_selection)
return; return;
@ -3149,6 +3229,7 @@ void DoubleSlider::OnRightDown(wxMouseEvent& event)
else else
m_lower_value = m_higher_value; m_lower_value = m_higher_value;
// set slider to "one layer" mode
m_is_right_down = m_is_one_layer = true; m_is_right_down = m_is_one_layer = true;
Refresh(); Refresh();
@ -3163,11 +3244,55 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event)
this->ReleaseMouse(); this->ReleaseMouse();
m_is_right_down = m_is_one_layer = false; m_is_right_down = m_is_one_layer = false;
if (m_show_context_menu) {
wxMenu menu;
append_menu_item(&menu, wxID_ANY, _(L("Add color change")) + " (M600)", "",
[this](wxCommandEvent&) { add_code("M600"); }, "colorchange_add_off.png", &menu);
append_menu_item(&menu, wxID_ANY, _(L("Add pause SD print")) + " (M25)", "",
[this](wxCommandEvent&) { add_code("M25"); }, "pause_add.png", &menu);
append_menu_item(&menu, wxID_ANY, _(L("Add custom G-code")), "",
[this](wxCommandEvent&) { add_code(""); }, "add_gcode", &menu);
Slic3r::GUI::wxGetApp().plater()->PopupMenu(&menu);
m_show_context_menu = false;
}
Refresh(); Refresh();
Update(); Update();
event.Skip(); event.Skip();
} }
void DoubleSlider::add_code(std::string code)
{
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
// if on this Y doesn't exist tick
if (m_ticks_.find(tick) == m_ticks_.end())
{
if (code.empty())
{
wxString msg_text = from_u8(_utf8(L("Enter custom G-code used on current layer"))) + " :";
wxString msg_header = from_u8((boost::format(_utf8(L("Custom Gcode on current layer (%1% mm)."))) % m_values[tick]).str());
// get custom gcode
wxString custom_code = wxGetTextFromUser(msg_text, msg_header);
if (custom_code.IsEmpty())
return;
code = custom_code.c_str();
}
m_ticks_.insert(TICK_CODE(tick, code));
wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED));
Refresh();
Update();
}
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// LockButton // LockButton

View File

@ -821,6 +821,7 @@ 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);
protected: protected:
@ -884,6 +885,7 @@ private:
bool m_is_action_icon_focesed = false; bool m_is_action_icon_focesed = false;
bool m_is_one_layer_icon_focesed = false; bool m_is_one_layer_icon_focesed = false;
bool m_is_enabled_tick_manipulation = true; bool m_is_enabled_tick_manipulation = true;
bool m_show_context_menu = false;
wxRect m_rect_lower_thumb; wxRect m_rect_lower_thumb;
wxRect m_rect_higher_thumb; wxRect m_rect_higher_thumb;
@ -912,6 +914,25 @@ private:
std::vector<wxPen*> m_segm_pens; std::vector<wxPen*> m_segm_pens;
std::set<int> m_ticks; std::set<int> m_ticks;
std::vector<double> m_values; std::vector<double> m_values;
struct TICK_CODE
{
TICK_CODE(int tick):tick(tick), gcode("M600"), extruder(0) {}
TICK_CODE(int tick, const std::string& code) :
tick(tick), gcode(code), extruder(0) {}
TICK_CODE(int tick, int extruder) :
tick(tick), gcode("M600"), extruder(extruder) {}
TICK_CODE(int tick, const std::string& code, int extruder) :
tick(tick), gcode(code), extruder(extruder) {}
bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; }
int tick;
std::string gcode;
int extruder;
};
std::set<TICK_CODE> m_ticks_;
}; };