From 33ba6fe4c68fdcac277f1aeb712e3548a68e3901 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 18 Oct 2019 12:35:35 +0200 Subject: Implemented possibility to set extruder sequence for whole print --- src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/ExtruderSequenceDialog.cpp | 197 ++++++++++++++++++++++++++++++ src/slic3r/GUI/ExtruderSequenceDialog.hpp | 45 +++++++ src/slic3r/GUI/GUI_ObjectList.cpp | 16 +-- src/slic3r/GUI/GUI_Preview.cpp | 13 +- src/slic3r/GUI/GUI_Preview.hpp | 5 +- src/slic3r/GUI/Plater.cpp | 3 + src/slic3r/GUI/wxExtensions.cpp | 120 +++++++++++++++++- src/slic3r/GUI/wxExtensions.hpp | 73 ++++++++++- 9 files changed, 445 insertions(+), 29 deletions(-) create mode 100644 src/slic3r/GUI/ExtruderSequenceDialog.cpp create mode 100644 src/slic3r/GUI/ExtruderSequenceDialog.hpp (limited to 'src/slic3r') diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 17b76e629..253488cd4 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -105,6 +105,8 @@ set(SLIC3R_GUI_SOURCES GUI/Camera.hpp GUI/wxExtensions.cpp GUI/wxExtensions.hpp + GUI/ExtruderSequenceDialog.cpp + GUI/ExtruderSequenceDialog.hpp GUI/WipeTowerDialog.cpp GUI/WipeTowerDialog.hpp GUI/RammingChart.cpp diff --git a/src/slic3r/GUI/ExtruderSequenceDialog.cpp b/src/slic3r/GUI/ExtruderSequenceDialog.cpp new file mode 100644 index 000000000..408826957 --- /dev/null +++ b/src/slic3r/GUI/ExtruderSequenceDialog.cpp @@ -0,0 +1,197 @@ +#include "ExtruderSequenceDialog.hpp" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "GUI.hpp" +#include "GUI_App.hpp" +#include "I18N.hpp" +#include "OptionsGroup.hpp" + + +namespace Slic3r { +namespace GUI { + +ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequence& sequence) + : DPIDialog(NULL, wxID_ANY, wxString(SLIC3R_APP_NAME) + " - " + _(L("Set extruder sequence")), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER), + m_sequence(sequence) +{ + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + SetDoubleBuffered(true); + SetFont(wxGetApp().normal_font()); + + auto main_sizer = new wxBoxSizer(wxVERTICAL); + const int em = wxGetApp().em_unit(); + + m_bmp_del = ScalableBitmap(this, "remove_copies"); + m_bmp_add = ScalableBitmap(this, "add_copies"); + + auto option_sizer = new wxBoxSizer(wxVERTICAL); + + auto intervals_box = new wxStaticBox(this, wxID_ANY, _(L("Set extruder change for every"))+ " : "); + auto intervals_box_sizer = new wxStaticBoxSizer(intervals_box, wxVERTICAL); + + m_intervals_grid_sizer = new wxFlexGridSizer(3, 5, em); + + auto editor_sz = wxSize(4*em, wxDefaultCoord); + + wxRadioButton* rb_by_layers = new wxRadioButton(this, wxID_ANY, ""); + rb_by_layers->Bind(wxEVT_RADIOBUTTON, [this](wxEvent&) { m_sequence.is_mm_intervals = false; }); + + wxStaticText* st_by_layers = new wxStaticText(this, wxID_ANY, _(L("layers"))); + m_interval_by_layers = new wxTextCtrl(this, wxID_ANY, + wxString::Format("%d", m_sequence.interval_by_layers), + wxDefaultPosition, editor_sz); + m_interval_by_layers->Bind(wxEVT_TEXT, [this, rb_by_layers](wxEvent&) + { + wxString str = m_interval_by_layers->GetValue(); + if (str.IsEmpty()) { + m_interval_by_layers->SetValue(wxString::Format("%d", m_sequence.interval_by_layers)); + return; + } + + m_sequence.interval_by_layers = wxAtoi(str); + + m_sequence.is_mm_intervals = false; + rb_by_layers->SetValue(true); + }); + + m_intervals_grid_sizer->Add(rb_by_layers, 0, wxALIGN_CENTER_VERTICAL); + m_intervals_grid_sizer->Add(m_interval_by_layers,0, wxALIGN_CENTER_VERTICAL); + m_intervals_grid_sizer->Add(st_by_layers,0, wxALIGN_CENTER_VERTICAL); + + wxRadioButton* rb_by_mm = new wxRadioButton(this, wxID_ANY, ""); + rb_by_mm->Bind(wxEVT_RADIOBUTTON, [this](wxEvent&) { m_sequence.is_mm_intervals = true; }); + rb_by_mm->SetValue(m_sequence.is_mm_intervals); + + wxStaticText* st_by_mm = new wxStaticText(this, wxID_ANY, _(L("mm"))); + m_interval_by_mm = new wxTextCtrl(this, wxID_ANY, + double_to_string(sequence.interval_by_mm), + wxDefaultPosition, editor_sz); + m_interval_by_mm->Bind(wxEVT_TEXT, [this, rb_by_mm](wxEvent&) + { + wxString str = m_interval_by_mm->GetValue(); + if (str.IsEmpty()) { + m_interval_by_mm->SetValue(wxString::Format("%d", m_sequence.interval_by_mm)); + return; + } + + str.Replace(",", ".", false); + double val; + if (str == "." || !str.ToCDouble(&val)) + val = 0.0; + + m_sequence.interval_by_mm = val; + + m_sequence.is_mm_intervals = true; + rb_by_mm->SetValue(true); + }); + + m_intervals_grid_sizer->Add(rb_by_mm, 0, wxALIGN_CENTER_VERTICAL); + m_intervals_grid_sizer->Add(m_interval_by_mm,0, wxALIGN_CENTER_VERTICAL); + m_intervals_grid_sizer->Add(st_by_mm,0, wxALIGN_CENTER_VERTICAL); + + intervals_box_sizer->Add(m_intervals_grid_sizer, 0, wxLEFT, em); + option_sizer->Add(intervals_box_sizer, 0, wxEXPAND); + + + auto extruders_box = new wxStaticBox(this, wxID_ANY, _(L("Set extruder(tool) sequence"))+ " : "); + auto extruders_box_sizer = new wxStaticBoxSizer(extruders_box, wxVERTICAL); + + m_extruders_grid_sizer = new wxFlexGridSizer(3, 5, em); + + apply_extruder_sequence(); + + extruders_box_sizer->Add(m_extruders_grid_sizer, 0, wxALL, em); + option_sizer->Add(extruders_box_sizer, 0, wxEXPAND | wxTOP, em); + + main_sizer->Add(option_sizer, 0, wxEXPAND | wxALL, em); + + wxStdDialogButtonSizer* buttons = this->CreateStdDialogButtonSizer(wxOK | wxCANCEL); + main_sizer->Add(buttons, 0, wxEXPAND | wxRIGHT | wxBOTTOM, em); + + SetSizer(main_sizer); + main_sizer->SetSizeHints(this); +} + +void ExtruderSequenceDialog::apply_extruder_sequence() +{ + Freeze(); + m_extruders_grid_sizer->Clear(true); + + for (size_t extruder=0; extruder < m_sequence.extruders.size(); ++extruder) + { + wxBitmapComboBox* extruder_selector = nullptr; + apply_extruder_selector(&extruder_selector, this); + extruder_selector->SetSelection(m_sequence.extruders[extruder]); + + extruder_selector->Bind(wxEVT_COMBOBOX, [this, extruder_selector, extruder](wxCommandEvent& evt) + { + m_sequence.extruders[extruder] = extruder_selector->GetSelection(); + evt.StopPropagation(); + }); + + auto del_btn = new ScalableButton(this, wxID_ANY, m_bmp_del); + del_btn->SetToolTip(_(L("Remove extruder from sequence"))); + if (m_sequence.extruders.size()==1) + del_btn->Disable(); + + del_btn->Bind(wxEVT_BUTTON, [this, extruder](wxEvent&) { + m_sequence.delete_extruder(extruder); + apply_extruder_sequence(); + }); + + auto add_btn = new ScalableButton(this, wxID_ANY, m_bmp_add); + add_btn->SetToolTip(_(L("Add extruder to sequence"))); + + add_btn->Bind(wxEVT_BUTTON, [this, extruder](wxEvent&) { + m_sequence.add_extruder(extruder); + apply_extruder_sequence(); + }); + + m_extruders_grid_sizer->Add(extruder_selector); + m_extruders_grid_sizer->Add(del_btn); + m_extruders_grid_sizer->Add(add_btn); + } + + Fit(); + Refresh(); + + Thaw(); +} + +void ExtruderSequenceDialog::on_dpi_changed(const wxRect& suggested_rect) +{ + SetFont(wxGetApp().normal_font()); + + m_bmp_add.msw_rescale(); + m_bmp_del.msw_rescale(); + + const int em = em_unit(); + + m_intervals_grid_sizer->SetHGap(em); + m_intervals_grid_sizer->SetVGap(em); + m_extruders_grid_sizer->SetHGap(em); + m_extruders_grid_sizer->SetVGap(em); + + msw_buttons_rescale(this, em, { wxID_OK, wxID_CANCEL }); + + // wxSize size = get_size(); + // SetMinSize(size); + + Fit(); + Refresh(); +} + +} +} + + diff --git a/src/slic3r/GUI/ExtruderSequenceDialog.hpp b/src/slic3r/GUI/ExtruderSequenceDialog.hpp new file mode 100644 index 000000000..3efd9e3a2 --- /dev/null +++ b/src/slic3r/GUI/ExtruderSequenceDialog.hpp @@ -0,0 +1,45 @@ +#ifndef slic3r_GUI_ExtruderSequenceDialog_hpp_ +#define slic3r_GUI_ExtruderSequenceDialog_hpp_ + +#include "GUI_Utils.hpp" +#include "wxExtensions.hpp" + +class wxTextCtrl; +class wxFlexGridSizer; + +namespace Slic3r { +namespace GUI { + +// ---------------------------------------------------------------------------- +// ExtruderSequenceDialog: a node inside ObjectDataViewModel +// ---------------------------------------------------------------------------- + +class ExtruderSequenceDialog: public DPIDialog +{ + ScalableBitmap m_bmp_del; + ScalableBitmap m_bmp_add; + DoubleSlider::ExtrudersSequence m_sequence; + + wxTextCtrl* m_interval_by_layers {nullptr}; + wxTextCtrl* m_interval_by_mm {nullptr}; + + wxFlexGridSizer* m_intervals_grid_sizer {nullptr}; + wxFlexGridSizer* m_extruders_grid_sizer {nullptr}; +public: + ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequence& sequence); + + ~ExtruderSequenceDialog() {} + + DoubleSlider::ExtrudersSequence GetValue() { return m_sequence; } + +protected: + void apply_extruder_sequence(); + void on_dpi_changed(const wxRect& suggested_rect) override; + +}; + +} +} + + +#endif // slic3r_GUI_ExtruderSequenceDialog_hpp_ diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index dc48a218c..377c26e79 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -895,10 +895,12 @@ void ObjectList::extruder_editing() if (!item || !(m_objects_model->GetItemType(item) & (itVolume | itObject))) return; + // ! #ys Use ApplyExtruderSelector instead this code + /* std::vector icons = get_extruder_color_icons(); if (icons.empty()) return; - + */ const int column_width = GetColumn(colExtruder)->GetWidth() + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X) + 5; wxPoint pos = get_mouse_position_in_control(); @@ -906,6 +908,10 @@ void ObjectList::extruder_editing() pos.x = GetColumn(colName)->GetWidth() + GetColumn(colPrint)->GetWidth() + 5; pos.y -= GetTextExtent("m").y; + apply_extruder_selector(&m_extruder_editor, this, L("default"), pos, size); + + // ! #ys Use ApplyExtruderSelector instead this code + /* if (!m_extruder_editor) m_extruder_editor = new wxBitmapComboBox(this, wxID_ANY, wxEmptyString, pos, size, 0, nullptr, wxCB_READONLY); @@ -928,6 +934,7 @@ void ObjectList::extruder_editing() m_extruder_editor->Append(wxString::Format("%d", i), *bmp); ++i; } + */ m_extruder_editor->SetSelection(m_objects_model->GetExtruderNumber(item)); auto set_extruder = [this]() @@ -948,13 +955,6 @@ void ObjectList::extruder_editing() set_extruder(); evt.StopPropagation(); }); - /* - m_extruder_editor->Bind(wxEVT_KILL_FOCUS, [set_extruder](wxFocusEvent& evt) - { - set_extruder(); - evt.Skip(); - });*/ - } void ObjectList::copy() diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 91ffa4a5a..e462e7c1d 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -602,16 +602,7 @@ void Preview::update_view_type(bool slice_completed) void Preview::update_extruder_selector() { - m_extruder_selector->Clear(); - - m_extruder_selector->Append("Whole print"); - const int extruder_cnt = wxGetApp().extruders_edited_cnt(); - int i = 0; - while (i < extruder_cnt) - { - i++; - m_extruder_selector->Append(wxString::Format("Extruder %d", i)); - } + apply_extruder_selector(&m_extruder_selector, this, L("Whole print")); } void Preview::create_double_slider() @@ -620,7 +611,6 @@ void Preview::create_double_slider() // #ys_FIXME_COLOR // m_double_slider_sizer->Add(m_slider, 0, wxEXPAND, 0); - m_extruder_selector = new wxComboBox(this, wxID_ANY); update_extruder_selector(); m_extruder_selector->SetSelection(0); m_extruder_selector->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) @@ -628,6 +618,7 @@ void Preview::create_double_slider() m_slider->SetManipulationState(m_extruder_selector->GetSelection() == 0 ? DoubleSlider::msMultiExtruderWholePrint : DoubleSlider::msMultiExtruder); + evt.StopPropagation(); }); m_extruder_selector->Disable(); // temporary disabled to suppress extruder selection diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 574f827e2..64b8baa7f 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -13,6 +13,7 @@ class wxBoxSizer; class wxStaticText; class wxChoice; class wxComboCtrl; +class wxBitmapComboBox; class wxCheckBox; class DoubleSlider; @@ -102,8 +103,8 @@ class Preview : public wxPanel bool m_loaded; bool m_enabled; - DoubleSlider* m_slider {nullptr}; - wxComboBox* m_extruder_selector {nullptr}; + DoubleSlider* m_slider {nullptr}; + wxBitmapComboBox* m_extruder_selector {nullptr}; public: Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_toolbar, Model* model, DynamicPrintConfig* config, diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 477a0b242..1cbbfda5a 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -4981,6 +4981,9 @@ std::vector Plater::get_extruder_colors_from_plater_config() const return extruder_colors; extruder_colors = (config->option("extruder_colour"))->values; + if (!wxGetApp().plater()) + return extruder_colors; + const std::vector& filament_colours = (p->config->option("filament_colour"))->values; for (size_t i = 0; i < extruder_colors.size(); ++i) if (extruder_colors[i] == "" && i < filament_colours.size()) diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index a103e6e0d..4528a14cc 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -22,6 +22,7 @@ #include "I18N.hpp" #include "GUI_Utils.hpp" #include "PresetBundle.hpp" +#include "ExtruderSequenceDialog.hpp" #include "../Utils/MacDarkMode.hpp" using Slic3r::GUI::from_u8; @@ -449,7 +450,7 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, Slic3r::GUI::BitmapCache* m_bitmap_cache = nullptr; -/*static*/ std::vector get_extruder_color_icons() +std::vector get_extruder_color_icons() { // Create the bitmap with color bars. std::vector bmps; @@ -493,6 +494,42 @@ static wxBitmap get_extruder_color_icon(size_t extruder_idx) return *bmps[extruder_idx >= bmps.size() ? 0 : extruder_idx]; } +void apply_extruder_selector(wxBitmapComboBox** ctrl, + wxWindow* parent, + const std::string& first_item/* = ""*/, + wxPoint pos/* = wxDefaultPosition*/, + wxSize size/* = wxDefaultSize*/) +{ + std::vector icons = get_extruder_color_icons(); + if (icons.empty()) + return; + + if (!*ctrl) + *ctrl = new wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, pos, size, + 0, nullptr, wxCB_READONLY); + else + { + (*ctrl)->SetPosition(pos); + (*ctrl)->SetMinSize(size); + (*ctrl)->SetSize(size); + (*ctrl)->Clear(); + } + + int i = 0; + for (wxBitmap* bmp : icons) { + if (i == 0) { + if (!first_item.empty()) + (*ctrl)->Append(_(first_item), *bmp); + ++i; + } + + (*ctrl)->Append(wxString::Format("%d", i), *bmp); + ++i; + } + (*ctrl)->SetSelection(0); +} + + // ***************************************************************************** // ---------------------------------------------------------------------------- // ObjectDataViewModelNode @@ -2248,6 +2285,8 @@ DoubleSlider::DoubleSlider( wxWindow *parent, m_bmp_revert = ScalableBitmap(this, "undo"); m_revert_icon_dim = m_bmp_revert.bmp().GetSize().x; + m_bmp_cog = ScalableBitmap(this, "cog"); + m_cog_icon_dim = m_bmp_cog.bmp().GetSize().x; m_selection = ssUndef; @@ -2306,6 +2345,8 @@ void DoubleSlider::msw_rescale() m_bmp_revert.msw_rescale(); m_revert_icon_dim = m_bmp_revert.bmp().GetSize().x; + m_bmp_cog.msw_rescale(); + m_cog_icon_dim = m_bmp_cog.bmp().GetSize().x; SLIDER_MARGIN = 4 + Slic3r::GUI::wxGetApp().em_unit(); @@ -2610,6 +2651,9 @@ void DoubleSlider::render() //draw revert bitmap (if it's shown) draw_revert_icon(dc); + + //draw cog bitmap (if it's shown) + draw_cog_icon(dc); } void DoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end) @@ -2880,6 +2924,24 @@ void DoubleSlider::draw_revert_icon(wxDC& dc) m_rect_revert_icon = wxRect(x_draw, y_draw, m_revert_icon_dim, m_revert_icon_dim); } +void DoubleSlider::draw_cog_icon(wxDC& dc) +{ + if (m_state != msMultiExtruderWholePrint) + return; + + int width, height; + get_size(&width, &height); + + wxCoord x_draw, y_draw; + is_horizontal() ? x_draw = width-2 : x_draw = width - m_cog_icon_dim - 2; + is_horizontal() ? y_draw = height - m_cog_icon_dim - 2 : y_draw = height-2; + + dc.DrawBitmap(m_bmp_cog.bmp(), x_draw, y_draw); + + //update rect of the lock/unlock icon + m_rect_cog_icon = wxRect(x_draw, y_draw, m_cog_icon_dim, m_cog_icon_dim); +} + void DoubleSlider::update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection) { const wxRect& rect = wxRect(begin_x, begin_y, m_thumb_size.x, m_thumb_size.y); @@ -2990,6 +3052,46 @@ void DoubleSlider::OnLeftDown(wxMouseEvent& event) m_ticks_.clear(); wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); } + else if (is_point_in_rect(pos, m_rect_cog_icon) && m_state == msMultiExtruderWholePrint) { + // show dialog for set extruder sequence + Slic3r::GUI::ExtruderSequenceDialog dlg(m_extruders_sequence); + if (dlg.ShowModal() != wxID_OK) + return; + + m_extruders_sequence = dlg.GetValue(); + + m_ticks_.erase(std::remove_if(m_ticks_.begin(), m_ticks_.end(), + [](TICK_CODE tick) { return tick.gcode == "tool_change"; }), m_ticks_.end()); + + int tick = 0; + double value = 0.0; + int extruder = 0; + const int extr_cnt = m_extruders_sequence.extruders.size(); + + while (tick <= m_max_value) + { + m_ticks_.insert(TICK_CODE(tick, "tool_change", m_extruders_sequence.extruders[extruder]+1)); + + extruder++; + if (extruder == extr_cnt) + extruder = 0; + if (m_extruders_sequence.is_mm_intervals) + { + value += m_extruders_sequence.interval_by_mm; + auto it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon()); + + if (it == m_values.end()) + break; + + tick = it - m_values.begin(); + } + else + tick += m_extruders_sequence.interval_by_layers; + } + + // m_ticks_.clear(); + wxPostEvent(this->GetParent(), wxCommandEvent(wxCUSTOMEVT_TICKSCHANGED)); + } else detect_selected_slider(pos); @@ -3042,13 +3144,16 @@ void DoubleSlider::correct_higher_value() m_lower_value = m_higher_value; } -wxString DoubleSlider::get_tooltip(bool is_revert_icon_focused) +wxString DoubleSlider::get_tooltip(IconFocus icon_focus) { wxString tooltip(wxEmptyString); if (m_is_one_layer_icon_focesed) tooltip = _(L("One layer mode")); - if (is_revert_icon_focused) + + if (icon_focus == ifRevert) tooltip = _(L("Discard all custom changes")); + if (icon_focus == ifCog) + tooltip = _(L("Set extruder sequence for whole print")); else if (m_is_action_icon_focesed) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; @@ -3072,13 +3177,16 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) const wxPoint pos = event.GetLogicalPosition(dc); m_is_one_layer_icon_focesed = is_point_in_rect(pos, m_rect_one_layer_icon); - bool is_revert_icon_focused = false; + IconFocus icon_focus = ifNone; if (!m_is_left_down && !m_is_one_layer) { m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); // #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); + if (!m_ticks_.empty() && is_point_in_rect(pos, m_rect_revert_icon)) + icon_focus = ifRevert; + else if (is_point_in_rect(pos, m_rect_cog_icon)) + icon_focus = ifCog; } else if (m_is_left_down || m_is_right_down) { if (m_selection == ssLower) { @@ -3103,7 +3211,7 @@ void DoubleSlider::OnMotion(wxMouseEvent& event) // const wxString tooltip = m_is_one_layer_icon_focesed ? _(L("One layer mode")) : // m_is_action_icon_focesed ? _(L("Add/Del color change")) : // is_revert_icon_focused ? _(L("Discard all color changes")) : ""; - this->SetToolTip(get_tooltip(is_revert_icon_focused)); + this->SetToolTip(get_tooltip(icon_focus)); if (action) { diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index b7fd81db3..ce5e58a6a 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -49,6 +49,8 @@ wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, std::function cb, wxEvtHandler* event_handler); class wxDialog; +class wxBitmapComboBox; + void edit_tooltip(wxString& tooltip); void msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector& btn_ids); int em_unit(wxWindow* win); @@ -57,6 +59,11 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name, const int px_cnt = 16, const bool is_horizontal = false, const bool grayscale = false); std::vector get_extruder_color_icons(); +void apply_extruder_selector(wxBitmapComboBox** ctrl, + wxWindow* parent, + const std::string& first_item = "", + wxPoint pos = wxDefaultPosition, + wxSize size = wxDefaultSize); class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup { @@ -750,6 +757,11 @@ enum TicksAction{ class DoubleSlider : public wxControl { + enum IconFocus { + ifNone, + ifRevert, + ifCog + }; public: DoubleSlider( wxWindow *parent, @@ -806,7 +818,7 @@ public: EnableTickManipulation(false); } - static enum ManipulationState { + enum ManipulationState { msSingleExtruder, // single extruder printer preset is selected msMultiExtruder, // multiple extruder printer preset is selected msMultiExtruderWholePrint // multiple extruder printer preset is selected, and "Whole print" is selected @@ -850,6 +862,7 @@ protected: void draw_colored_band(wxDC& dc); void draw_one_layer_icon(wxDC& dc); void draw_revert_icon(wxDC& dc); + 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_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const; @@ -858,7 +871,7 @@ protected: void detect_selected_slider(const wxPoint& pt); void correct_lower_value(); void correct_higher_value(); - wxString get_tooltip(bool is_revert_icon_focused); + wxString get_tooltip(IconFocus icon_focus); void move_current_thumb(const bool condition); void action_tick(const TicksAction action); void enter_window(wxMouseEvent& event, const bool enter); @@ -893,6 +906,7 @@ private: ScalableBitmap m_bmp_one_layer_unlock_on; ScalableBitmap m_bmp_one_layer_unlock_off; ScalableBitmap m_bmp_revert; + ScalableBitmap m_bmp_cog; SelectedSlider m_selection; bool m_is_left_down = false; bool m_is_right_down = false; @@ -910,10 +924,12 @@ private: wxRect m_rect_tick_action; wxRect m_rect_one_layer_icon; wxRect m_rect_revert_icon; + wxRect m_rect_cog_icon; wxSize m_thumb_size; int m_tick_icon_dim; int m_lock_icon_dim; int m_revert_icon_dim; + int m_cog_icon_dim; long m_style; float m_label_koef = 1.0; @@ -945,6 +961,16 @@ private: bool operator<(const TICK_CODE& other) const { return other.tick > this->tick; } bool operator>(const TICK_CODE& other) const { return other.tick < this->tick; } + TICK_CODE operator=(const TICK_CODE& other) const { + TICK_CODE ret_val(other.tick, other.gcode, other.extruder); + return ret_val; + } + TICK_CODE& operator=(const TICK_CODE& other) { + this->tick = other.tick; + this->gcode = other.gcode; + this->extruder = other.extruder; + return *this; + } int tick; std::string gcode; @@ -952,6 +978,49 @@ private: }; std::set m_ticks_; + +public: + struct ExtrudersSequence + { + bool is_mm_intervals; + double interval_by_mm; + int interval_by_layers; + std::vector extruders; + + ExtrudersSequence() : + is_mm_intervals(true), + interval_by_mm(3.0), + interval_by_layers(10), + extruders({ 0 }) {} + + ExtrudersSequence(const ExtrudersSequence& other) : + is_mm_intervals(other.is_mm_intervals), + interval_by_mm(other.interval_by_mm), + interval_by_layers(other.interval_by_layers), + extruders(other.extruders) {} + + ExtrudersSequence& operator=(const ExtrudersSequence& other) { + this->is_mm_intervals = other.is_mm_intervals; + this->interval_by_mm = other.interval_by_mm; + this->interval_by_layers= other.interval_by_layers; + this->extruders = other.extruders; + + return *this; + } + + void add_extruder(size_t pos) + { + extruders.insert(extruders.begin() + pos+1, size_t(0)); + } + + void delete_extruder(size_t pos) + { + if (extruders.size() == 1) + return;// last item can't be deleted + extruders.erase(extruders.begin() + pos); + } + } + m_extruders_sequence; }; -- cgit v1.2.3