From 0572a3299a61831dbd0a6308a4326673c9334c0f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 25 Apr 2018 13:25:34 +0200 Subject: [PATCH 001/119] First experiment with the wxCollapsiblePane --- lib/Slic3r/GUI/Plater.pm | 2 +- xs/src/slic3r/GUI/GUI.cpp | 30 ++++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 53176ccfe..7227d222c 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -403,7 +403,7 @@ sub new { } } - my $frequently_changed_parameters_sizer = Wx::BoxSizer->new(wxHORIZONTAL); + my $frequently_changed_parameters_sizer = Wx::BoxSizer->new(wxVERTICAL);#(wxHORIZONTAL); Slic3r::GUI::add_frequently_changed_parameters($self, $frequently_changed_parameters_sizer, $presets); my $object_info_sizer; diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index e85112008..beae2d524 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include "wxExtensions.hpp" @@ -638,8 +640,26 @@ wxString from_u8(const std::string &str) void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer) { + // Experiments with new UI + wxCollapsiblePane *collpane = new wxCollapsiblePane(parent, wxID_ANY, "Print settings:"); + collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, collpane](wxCommandEvent e){ + wxWindowUpdateLocker noUpdates(parent); + + parent->Layout(); + collpane->Refresh(); + })); + + // add the pane with a zero proportion value to the sizer which contains it + sizer->Add(collpane, 0, wxGROW | wxALL, 5); + // now add a test label in the collapsible pane using a sizer to layout it: + wxWindow *win = collpane->GetPane(); +#ifdef __WXMSW__ + collpane->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + win->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#endif //__WXMSW__ + DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config; - m_optgroup = std::make_shared(parent, "", config); + m_optgroup = std::make_shared(/*parent*/win, "", config); // const wxArrayInt& ar = preset_sizer->GetColWidths(); // m_optgroup->label_width = ar.IsEmpty() ? 100 : ar.front(); // doesn't work m_optgroup->m_on_change = [config](t_config_option_key opt_key, boost::any value){ @@ -755,7 +775,13 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl - sizer->Add(m_optgroup->sizer, 1, wxEXPAND | wxBOTTOM, 2); +// sizer->Add(m_optgroup->sizer, 1, wxEXPAND | wxBOTTOM, 2); + + + wxSizer *paneSz = new wxBoxSizer(wxVERTICAL); + paneSz->Add(m_optgroup->sizer, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); + win->SetSizer(paneSz); + paneSz->SetSizeHints(win); } ConfigOptionsGroup* get_optgroup() From 993294579d93ebda300c18e0d96b902c6b846a15 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 3 May 2018 13:27:20 +0200 Subject: [PATCH 002/119] Button's border and background aren't use on MSW. --- xs/src/slic3r/GUI/GUI.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 83d1e246e..2542c04c6 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -813,24 +813,24 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl wxCollapsiblePane *collpane = new wxCollapsiblePane(parent, wxID_ANY, "Print settings:"); collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, collpane](wxCommandEvent e){ wxWindowUpdateLocker noUpdates(parent); - parent->Layout(); collpane->Refresh(); })); // add the pane with a zero proportion value to the sizer which contains it - sizer->Add(collpane, 0, wxGROW | wxALL, 5); - // now add a test label in the collapsible pane using a sizer to layout it: + sizer->Add(collpane, 0, wxGROW | wxALL, 0); + wxWindow *win = collpane->GetPane(); #ifdef __WXMSW__ - collpane->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - win->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + wxColour& clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + collpane->GetControlWidget()->SetWindowStyleFlag(wxNO_BORDER); + collpane->GetControlWidget()->SetBackgroundColour(clr); + collpane->SetBackgroundColour(clr); + win->SetBackgroundColour(clr); #endif //__WXMSW__ DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config; - m_optgroup = std::make_shared(/*parent*/win, "", config); -// const wxArrayInt& ar = preset_sizer->GetColWidths(); -// m_optgroup->label_width = ar.IsEmpty() ? 100 : ar.front(); // doesn't work + m_optgroup = std::make_shared(win, "", config); m_optgroup->m_on_change = [config](t_config_option_key opt_key, boost::any value){ TabPrint* tab_print = nullptr; for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) { @@ -943,10 +943,6 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl m_optgroup->append_line(line); - -// sizer->Add(m_optgroup->sizer, 1, wxEXPAND | wxBOTTOM, 2); - - wxSizer *paneSz = new wxBoxSizer(wxVERTICAL); paneSz->Add(m_optgroup->sizer, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); win->SetSizer(paneSz); From db549e86095eace3df2befe2ccca2248a58426b0 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 4 May 2018 18:32:20 +0200 Subject: [PATCH 003/119] First experiments with ObjectsTreeList --- lib/Slic3r/GUI/Plater.pm | 4 +- xs/src/slic3r/GUI/GUI.cpp | 136 ++++++++- xs/src/slic3r/GUI/wxExtensions.cpp | 443 +++++++++++++++++++++++++++++ xs/src/slic3r/GUI/wxExtensions.hpp | 411 ++++++++++++++++++++++++++ 4 files changed, 992 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 603d97a2f..83a14f21a 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -72,7 +72,7 @@ sub new { }); # Initialize preview notebook - $self->{preview_notebook} = Wx::Notebook->new($self, -1, wxDefaultPosition, [335,335], wxNB_BOTTOM); + $self->{preview_notebook} = Wx::Notebook->new($self, -1, wxDefaultPosition, [-1,335], wxNB_BOTTOM); # Initialize handlers for canvases my $on_select_object = sub { @@ -485,6 +485,7 @@ sub new { $buttons_sizer->Add($self->{btn_export_gcode}, 0, wxALIGN_RIGHT, 0); my $right_sizer = Wx::BoxSizer->new(wxVERTICAL); + $right_sizer->SetMinSize([-1, 600]); $right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets; $right_sizer->Add($frequently_changed_parameters_sizer, 0, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5); @@ -522,6 +523,7 @@ sub new { } $self->update_ui_from_settings(); + $self->Layout; return $self; } diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 2542c04c6..0be77b6ba 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -812,6 +812,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl // Experiments with new UI wxCollapsiblePane *collpane = new wxCollapsiblePane(parent, wxID_ANY, "Print settings:"); collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, collpane](wxCommandEvent e){ + wxWindowUpdateLocker noUpdates_cp(collpane); wxWindowUpdateLocker noUpdates(parent); parent->Layout(); collpane->Refresh(); @@ -942,9 +943,142 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl }; m_optgroup->append_line(line); + auto common_sizer = new wxBoxSizer(wxVERTICAL); + common_sizer->Add(m_optgroup->sizer); + +// auto listctrl = new wxDataViewListCtrl(win, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); +// listctrl->AppendToggleColumn("Toggle"); +// listctrl->AppendTextColumn("Text"); +// wxVector data; +// data.push_back(wxVariant(true)); +// data.push_back(wxVariant("row 1")); +// listctrl->AppendItem(data); +// data.clear(); +// data.push_back(wxVariant(false)); +// data.push_back(wxVariant("row 3")); +// listctrl->AppendItem(data); +// data.clear(); +// data.push_back(wxVariant(false)); +// data.push_back(wxVariant("row 2")); +// listctrl->AppendItem(data); +// common_sizer->Add(listctrl, 0, wxEXPAND | wxALL, 1); + + // ********************************************************************************************** + auto objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); + wxSizer *objects_sz = new wxBoxSizer(wxVERTICAL); + objects_ctrl->SetMinSize(wxSize(-1, 200)); + objects_sz->Add(objects_ctrl, 1, wxGROW | wxALL, 5); + + auto objects_model = new MyObjectTreeModel; + objects_ctrl->AssociateModel(objects_model); +#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE + objects_ctrl->EnableDragSource(wxDF_UNICODETEXT); + objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT); +#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE + + // column 0 of the view control: + + wxDataViewTextRenderer *tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); + wxDataViewColumn *column00 = new wxDataViewColumn("Name", tr, 0, 150, wxALIGN_LEFT, + wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); + objects_ctrl->AppendColumn(column00); + + // column 1 of the view control: + + tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); + wxDataViewColumn *column01 = new wxDataViewColumn("Copy", tr, 1, 95, wxALIGN_CENTER_HORIZONTAL, + wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); + objects_ctrl->AppendColumn(column01); + + // column 2 of the view control: + + tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); + wxDataViewColumn *column02 = new wxDataViewColumn("Scale", tr, 2, 95, wxALIGN_CENTER_HORIZONTAL, + wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); + objects_ctrl->AppendColumn(column02); + + common_sizer->Add(objects_sz, 0, wxEXPAND | wxALL, 1); + + // ********************************************************************************************** +/* auto view_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); + wxSizer *PanelSz = new wxBoxSizer(wxVERTICAL); + view_ctrl->SetMinSize(wxSize(-1, 200)); + PanelSz->Add(view_ctrl, 1, wxGROW | wxALL, 5); + PanelSz->Add( new wxStaticText(win, wxID_ANY, "Most of the cells above are editable!"), 0, wxGROW | wxALL, 5); + + auto m_music_model = new MyMusicTreeModel; + view_ctrl->AssociateModel(m_music_model); + +#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE + view_ctrl->EnableDragSource(wxDF_UNICODETEXT); + view_ctrl->EnableDropTarget(wxDF_UNICODETEXT); +#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE + + // column 0 of the view control: + + tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); + wxDataViewColumn *column0 = + new wxDataViewColumn("title", tr, 0, 150, wxALIGN_LEFT, + wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); + view_ctrl->AppendColumn(column0); +#if 0 + // Call this and sorting is enabled + // immediately upon start up. + column0->SetAsSortKey(); +#endif + + // column 1 of the view control: + + tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_EDITABLE); + wxDataViewColumn *column1 = + new wxDataViewColumn("artist", tr, 1, 150, wxALIGN_LEFT, + wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE | + wxDATAVIEW_COL_RESIZABLE); + column1->SetMinWidth(100); // this column can't be resized to be smaller + view_ctrl->AppendColumn(column1); + + // column 2 of the view control: + + wxDataViewSpinRenderer *sr = + new wxDataViewSpinRenderer(0, 2010, wxDATAVIEW_CELL_EDITABLE, + wxALIGN_RIGHT | wxALIGN_CENTRE_VERTICAL); + wxDataViewColumn *column2 = + new wxDataViewColumn("year", sr, 2, 60, wxALIGN_LEFT, + wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE); + view_ctrl->AppendColumn(column2); + + // column 3 of the view control: + + wxArrayString choices; + choices.Add("good"); + choices.Add("bad"); + choices.Add("lousy"); + wxDataViewChoiceRenderer *c = + new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, + wxALIGN_RIGHT | wxALIGN_CENTRE_VERTICAL); + wxDataViewColumn *column3 = + new wxDataViewColumn("rating", c, 3, 100, wxALIGN_LEFT, + wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE); + view_ctrl->AppendColumn(column3); + + // column 4 of the view control: + + view_ctrl->AppendProgressColumn("popularity", 4, wxDATAVIEW_CELL_INERT, 80); + + // column 5 of the view control: + + MyCustomRenderer *cr = new MyCustomRenderer(wxDATAVIEW_CELL_ACTIVATABLE); + wxDataViewColumn *column5 = + new wxDataViewColumn("custom", cr, 5, -1, wxALIGN_LEFT, + wxDATAVIEW_COL_RESIZABLE); + view_ctrl->AppendColumn(column5); + + // ********************************************************************************************** + common_sizer->Add(PanelSz, 0, wxEXPAND | wxALL, 1); +*/ wxSizer *paneSz = new wxBoxSizer(wxVERTICAL); - paneSz->Add(m_optgroup->sizer, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); + paneSz->Add(common_sizer/*m_optgroup->sizer*/, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); win->SetSizer(paneSz); paneSz->SetSizeHints(win); } diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 8bc282474..9d691b1aa 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -165,3 +165,446 @@ void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& e auto selected = GetItemText(GetSelection()); cmb->SetText(selected); } + +// ***************************************************************************** +// ---------------------------------------------------------------------------- +// MyObjectTreeModel +// ---------------------------------------------------------------------------- + +MyObjectTreeModel::MyObjectTreeModel() +{ + auto root1 = new MyObjectTreeModelNode("Object1"); + m_objects.emplace(root1); + + auto root2 = new MyObjectTreeModelNode("Object2"); + m_objects.emplace(root2); + root2->Append(new MyObjectTreeModelNode(root2, "SubObject1")); + root2->Append(new MyObjectTreeModelNode(root2, "SubObject2")); + root2->Append(new MyObjectTreeModelNode(root2, "SubObject3")); + + auto root3 = new MyObjectTreeModelNode("Object3"); + m_objects.emplace(root3); + auto root4 = new MyObjectTreeModelNode("Object4"); + m_objects.emplace(root4); + root4->Append(new MyObjectTreeModelNode(root2, "SubObject1")); + root4->Append(new MyObjectTreeModelNode(root2, "SubObject2")); + root4->Append(new MyObjectTreeModelNode(root2, "SubObject3")); +} + +wxString MyObjectTreeModel::GetName(const wxDataViewItem &item) const +{ + MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return wxEmptyString; + + return node->m_name; +} + +wxString MyObjectTreeModel::GetCopyCnt(const wxDataViewItem &item) const +{ + MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return wxEmptyString; + + return node->m_copy; +} + +wxString MyObjectTreeModel::GetScale(const wxDataViewItem &item) const +{ + MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return wxEmptyString; + + return node->m_scale; +} + +// void MyObjectTreeModel::Delete(const wxDataViewItem &item) +// { +// +// } + +void MyObjectTreeModel::GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned int col) const +{ + wxASSERT(item.IsOk()); + + MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + switch (col) + { + case 0: + variant = node->m_name; + break; + case 1: + variant = node->m_copy; + break; + case 2: + variant = node->m_scale; + break; + default: + ;// wxLogError("MyMusicTreeModel::GetValue: wrong column %d", col); + } +} + +bool MyObjectTreeModel::SetValue(const wxVariant &variant, const wxDataViewItem &item, unsigned int col) +{ + wxASSERT(item.IsOk()); + + MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + switch (col) + { + case 0: + node->m_name = variant.GetString(); + return true; + case 1: + node->m_copy = variant.GetString(); + return true; + case 2: + node->m_scale = variant.GetString(); + return true; + + default:; + // wxLogError("MyObjectTreeModel::SetValue: wrong column"); + } + return false; +} + +// bool MyObjectTreeModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const +// { +// +// } + +wxDataViewItem MyObjectTreeModel::GetParent(const wxDataViewItem &item) const +{ + // the invisible root node has no parent + if (!item.IsOk()) + return wxDataViewItem(0); + + MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + + // objects nodes also has no parent + if (m_objects.find(node) != m_objects.end()) + return wxDataViewItem(0); + + return wxDataViewItem((void*)node->GetParent()); +} + +bool MyObjectTreeModel::IsContainer(const wxDataViewItem &item) const +{ + // the invisble root node can have children + if (!item.IsOk()) + return true; + + MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + return node->IsContainer(); +} + +unsigned int MyObjectTreeModel::GetChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const +{ + MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)parent.GetID(); + if (!node) + { + for (auto object: m_objects) + array.Add(wxDataViewItem((void*)object)); + return m_objects.size(); + } + + if (node->GetChildCount() == 0) + { + return 0; + } + + unsigned int count = node->GetChildren().GetCount(); + for (unsigned int pos = 0; pos < count; pos++) + { + MyObjectTreeModelNode *child = node->GetChildren().Item(pos); + array.Add(wxDataViewItem((void*)child)); + } + + return count; +} + +// ***************************************************************************** +// ---------------------------------------------------------------------------- +// MyMusicTreeModel +// ---------------------------------------------------------------------------- + +MyMusicTreeModel::MyMusicTreeModel() +{ + m_root = new MyMusicTreeModelNode(NULL, "");// , "My Music"); + + // setup pop music + m_pop = new MyMusicTreeModelNode(m_root, "Pop music"); + m_pop->Append( + new MyMusicTreeModelNode(m_pop, "You are not alone", "Michael Jackson", 1995)); + m_pop->Append( + new MyMusicTreeModelNode(m_pop, "Take a bow", "Madonna", 1994)); + m_root->Append(m_pop); + + // setup classical music + m_classical = new MyMusicTreeModelNode(m_root, "Classical music"); + m_ninth = new MyMusicTreeModelNode(m_classical, "Ninth symphony", + "Ludwig van Beethoven", 1824); + m_classical->Append(m_ninth); + m_classical->Append(new MyMusicTreeModelNode(m_classical, "German Requiem", + "Johannes Brahms", 1868)); + m_root->Append(m_classical); + + m_classicalMusicIsKnownToControl = false; +} + +wxString MyMusicTreeModel::GetTitle(const wxDataViewItem &item) const +{ + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return wxEmptyString; + + return node->m_title; +} + +wxString MyMusicTreeModel::GetArtist(const wxDataViewItem &item) const +{ + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return wxEmptyString; + + return node->m_artist; +} + +int MyMusicTreeModel::GetYear(const wxDataViewItem &item) const +{ + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return 2000; + + return node->m_year; +} + +void MyMusicTreeModel::AddToClassical(const wxString &title, const wxString &artist, + unsigned int year) +{ + if (!m_classical) + { + wxASSERT(m_root); + + // it was removed: restore it + m_classical = new MyMusicTreeModelNode(m_root, "Classical music"); + m_root->Append(m_classical); + + // notify control + wxDataViewItem child((void*)m_classical); + wxDataViewItem parent((void*)m_root); + ItemAdded(parent, child); + } + + // add to the classical music node a new node: + MyMusicTreeModelNode *child_node = + new MyMusicTreeModelNode(m_classical, title, artist, year); + m_classical->Append(child_node); + + // FIXME: what's m_classicalMusicIsKnownToControl for? + if (m_classicalMusicIsKnownToControl) + { + // notify control + wxDataViewItem child((void*)child_node); + wxDataViewItem parent((void*)m_classical); + ItemAdded(parent, child); + } +} + +void MyMusicTreeModel::Delete(const wxDataViewItem &item) +{ + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return; + + wxDataViewItem parent(node->GetParent()); + if (!parent.IsOk()) + { + wxASSERT(node == m_root); + + // don't make the control completely empty: + //wxLogError("Cannot remove the root item!"); + return; + } + + // is the node one of those we keep stored in special pointers? + if (node == m_pop) + m_pop = NULL; + else if (node == m_classical) + m_classical = NULL; + else if (node == m_ninth) + m_ninth = NULL; + + // first remove the node from the parent's array of children; + // NOTE: MyMusicTreeModelNodePtrArray is only an array of _pointers_ + // thus removing the node from it doesn't result in freeing it + node->GetParent()->GetChildren().Remove(node); + + // free the node + delete node; + + // notify control + ItemDeleted(parent, item); +} + +int MyMusicTreeModel::Compare(const wxDataViewItem &item1, const wxDataViewItem &item2, + unsigned int column, bool ascending) const +{ + wxASSERT(item1.IsOk() && item2.IsOk()); + // should never happen + + if (IsContainer(item1) && IsContainer(item2)) + { + wxVariant value1, value2; + GetValue(value1, item1, 0); + GetValue(value2, item2, 0); + + wxString str1 = value1.GetString(); + wxString str2 = value2.GetString(); + int res = str1.Cmp(str2); + if (res) return res; + + // items must be different + wxUIntPtr litem1 = (wxUIntPtr)item1.GetID(); + wxUIntPtr litem2 = (wxUIntPtr)item2.GetID(); + + return litem1 - litem2; + } + + return wxDataViewModel::Compare(item1, item2, column, ascending); +} + +void MyMusicTreeModel::GetValue(wxVariant &variant, + const wxDataViewItem &item, unsigned int col) const +{ + wxASSERT(item.IsOk()); + + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + switch (col) + { + case 0: + variant = node->m_title; + break; + case 1: + variant = node->m_artist; + break; + case 2: + variant = (long)node->m_year; + break; + case 3: + variant = node->m_quality; + break; + case 4: + variant = 80L; // all music is very 80% popular + break; + case 5: + if (GetYear(item) < 1900) + variant = "old"; + else + variant = "new"; + break; + + default: + ;// wxLogError("MyMusicTreeModel::GetValue: wrong column %d", col); + } +} + +bool MyMusicTreeModel::SetValue(const wxVariant &variant, + const wxDataViewItem &item, unsigned int col) +{ + wxASSERT(item.IsOk()); + + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + switch (col) + { + case 0: + node->m_title = variant.GetString(); + return true; + case 1: + node->m_artist = variant.GetString(); + return true; + case 2: + node->m_year = variant.GetLong(); + return true; + case 3: + node->m_quality = variant.GetString(); + return true; + + default:; +// wxLogError("MyMusicTreeModel::SetValue: wrong column"); + } + return false; +} + +bool MyMusicTreeModel::IsEnabled(const wxDataViewItem &item, + unsigned int col) const +{ + wxASSERT(item.IsOk()); + + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + + // disable Beethoven's ratings, his pieces can only be good + return !(col == 3 && node->m_artist.EndsWith("Beethoven")); +} + +wxDataViewItem MyMusicTreeModel::GetParent(const wxDataViewItem &item) const +{ + // the invisible root node has no parent + if (!item.IsOk()) + return wxDataViewItem(0); + + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + + // "MyMusic" also has no parent + if (node == m_root) + return wxDataViewItem(0); + + return wxDataViewItem((void*)node->GetParent()); +} + +bool MyMusicTreeModel::IsContainer(const wxDataViewItem &item) const +{ + // the invisble root node can have children + // (in our model always "MyMusic") + if (!item.IsOk()) + return true; + + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + return node->IsContainer(); +} + +unsigned int MyMusicTreeModel::GetChildren(const wxDataViewItem &parent, + wxDataViewItemArray &array) const +{ + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)parent.GetID(); + if (!node) + { + array.Add(wxDataViewItem((void*)m_root)); + return 1; + } + + if (node == m_classical) + { + MyMusicTreeModel *model = (MyMusicTreeModel*)(const MyMusicTreeModel*) this; + model->m_classicalMusicIsKnownToControl = true; + } + + if (node->GetChildCount() == 0) + { + return 0; + } + + unsigned int count = node->GetChildren().GetCount(); + for (unsigned int pos = 0; pos < count; pos++) + { + MyMusicTreeModelNode *child = node->GetChildren().Item(pos); + array.Add(wxDataViewItem((void*)child)); + } + + return count; +} + + +// ***************************************************************************** + + + diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index ed8bb9276..0ed27ab74 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -4,6 +4,9 @@ #include #include #include +#include +#include +#include class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup { @@ -50,4 +53,412 @@ public: void SetItemsCnt(int cnt) { m_cnt_open_items = cnt; } }; +// ***************************************************************************** +// ---------------------------------------------------------------------------- +// MyObjectTreeModelNode: a node inside MyObjectTreeModel +// ---------------------------------------------------------------------------- + +class MyObjectTreeModelNode; +WX_DEFINE_ARRAY_PTR(MyObjectTreeModelNode*, MyObjectTreeModelNodePtrArray); + +class MyObjectTreeModelNode +{ + MyObjectTreeModelNode* m_parent; + MyObjectTreeModelNodePtrArray m_children; +public: + MyObjectTreeModelNode( const wxString &name) { + m_parent = NULL; + m_name = name; + m_copy = "1"; + m_scale = "100%"; + } + + MyObjectTreeModelNode( MyObjectTreeModelNode* parent, + const wxString& sub_obj) { + m_parent = parent; + m_name = sub_obj; + m_copy = wxEmptyString; + m_scale = wxEmptyString; + } + + ~MyObjectTreeModelNode() + { + // free all our children nodes + size_t count = m_children.GetCount(); + for (size_t i = 0; i < count; i++) + { + MyObjectTreeModelNode *child = m_children[i]; + delete child; + } + } + + wxString m_name; + wxString m_copy; + wxString m_scale; + bool m_container = false; + + bool IsContainer() const + { + return m_container; + } + + MyObjectTreeModelNode* GetParent() + { + return m_parent; + } + MyObjectTreeModelNodePtrArray& GetChildren() + { + return m_children; + } + MyObjectTreeModelNode* GetNthChild(unsigned int n) + { + return m_children.Item(n); + } + void Insert(MyObjectTreeModelNode* child, unsigned int n) + { + m_children.Insert(child, n); + } + void Append(MyObjectTreeModelNode* child) + { + if (!m_container) + m_container = true; + m_children.Add(child); + } + unsigned int GetChildCount() const + { + return m_children.GetCount(); + } +}; + +// ---------------------------------------------------------------------------- +// MyObjectTreeModel +// ---------------------------------------------------------------------------- + +class MyObjectTreeModel :public wxDataViewModel +{ + std::set m_objects; +public: + MyObjectTreeModel(); + ~MyObjectTreeModel() + { + for (auto object : m_objects) + delete object; + } + + // helper method for wxLog + + wxString GetName(const wxDataViewItem &item) const; + wxString GetCopyCnt(const wxDataViewItem &item) const; + wxString GetScale(const wxDataViewItem &item) const; + + // helper methods to change the model + +// void AddToClassical(const wxString &title, const wxString &artist, +// unsigned int year); +// void Delete(const wxDataViewItem &item); + + virtual unsigned int GetColumnCount() const override { return 3;} + virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); } + + virtual void GetValue(wxVariant &variant, + const wxDataViewItem &item, unsigned int col) const override; + virtual bool SetValue(const wxVariant &variant, + const wxDataViewItem &item, unsigned int col) override; + +// virtual bool IsEnabled(const wxDataViewItem &item, +// unsigned int col) const override; + + virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override; + virtual bool IsContainer(const wxDataViewItem &item) const override; + virtual unsigned int GetChildren(const wxDataViewItem &parent, + wxDataViewItemArray &array) const override; +}; + + + + +// ***************************************************************************** +// ---------------------------------------------------------------------------- +// MyMusicTreeModelNode: a node inside MyMusicTreeModel +// ---------------------------------------------------------------------------- + +class MyMusicTreeModelNode; +WX_DEFINE_ARRAY_PTR(MyMusicTreeModelNode*, MyMusicTreeModelNodePtrArray); + +class MyMusicTreeModelNode +{ +public: + MyMusicTreeModelNode(MyMusicTreeModelNode* parent, + const wxString &title, const wxString &artist, + unsigned int year) + { + m_parent = parent; + + m_title = title; + m_artist = artist; + m_year = year; + m_quality = "good"; + + m_container = false; + } + + MyMusicTreeModelNode(MyMusicTreeModelNode* parent, + const wxString &branch) + { + m_parent = parent; + + m_title = branch; + m_year = -1; + + m_container = true; + } + + ~MyMusicTreeModelNode() + { + // free all our children nodes + size_t count = m_children.GetCount(); + for (size_t i = 0; i < count; i++) + { + MyMusicTreeModelNode *child = m_children[i]; + delete child; + } + } + + bool IsContainer() const + { + return m_container; + } + + MyMusicTreeModelNode* GetParent() + { + return m_parent; + } + MyMusicTreeModelNodePtrArray& GetChildren() + { + return m_children; + } + MyMusicTreeModelNode* GetNthChild(unsigned int n) + { + return m_children.Item(n); + } + void Insert(MyMusicTreeModelNode* child, unsigned int n) + { + m_children.Insert(child, n); + } + void Append(MyMusicTreeModelNode* child) + { + m_children.Add(child); + } + unsigned int GetChildCount() const + { + return m_children.GetCount(); + } + +public: // public to avoid getters/setters + wxString m_title; + wxString m_artist; + int m_year; + wxString m_quality; + + // TODO/FIXME: + // the GTK version of wxDVC (in particular wxDataViewCtrlInternal::ItemAdded) + // needs to know in advance if a node is or _will be_ a container. + // Thus implementing: + // bool IsContainer() const + // { return m_children.GetCount()>0; } + // doesn't work with wxGTK when MyMusicTreeModel::AddToClassical is called + // AND the classical node was removed (a new node temporary without children + // would be added to the control) + bool m_container; + +private: + MyMusicTreeModelNode *m_parent; + MyMusicTreeModelNodePtrArray m_children; +}; + + +// ---------------------------------------------------------------------------- +// MyMusicTreeModel +// ---------------------------------------------------------------------------- + +/* +Implement this data model +Title Artist Year Judgement +-------------------------------------------------------------------------- +1: My Music: +2: Pop music +3: You are not alone Michael Jackson 1995 good +4: Take a bow Madonna 1994 good +5: Classical music +6: Ninth Symphony Ludwig v. Beethoven 1824 good +7: German Requiem Johannes Brahms 1868 good +*/ + +class MyMusicTreeModel : public wxDataViewModel +{ +public: + MyMusicTreeModel(); + ~MyMusicTreeModel() + { + if (m_root) + delete m_root; + + } + + // helper method for wxLog + + wxString GetTitle(const wxDataViewItem &item) const; + wxString GetArtist(const wxDataViewItem &item) const; + int GetYear(const wxDataViewItem &item) const; + + // helper methods to change the model + + void AddToClassical(const wxString &title, const wxString &artist, + unsigned int year); + void Delete(const wxDataViewItem &item); + + wxDataViewItem GetNinthItem() const + { + return wxDataViewItem(m_ninth); + } + + // override sorting to always sort branches ascendingly + + int Compare(const wxDataViewItem &item1, const wxDataViewItem &item2, + unsigned int column, bool ascending) const override/*wxOVERRIDE*/; + + // implementation of base class virtuals to define model + + virtual unsigned int GetColumnCount() const override/*wxOVERRIDE*/ + { + return 6; + } + + virtual wxString GetColumnType(unsigned int col) const override/*wxOVERRIDE*/ + { + if (col == 2) + return wxT("long"); + + return wxT("string"); + } + + virtual void GetValue(wxVariant &variant, + const wxDataViewItem &item, unsigned int col) const override/*wxOVERRIDE*/; + virtual bool SetValue(const wxVariant &variant, + const wxDataViewItem &item, unsigned int col) override/*wxOVERRIDE*/; + + virtual bool IsEnabled(const wxDataViewItem &item, + unsigned int col) const override/*wxOVERRIDE*/; + + virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override/*wxOVERRIDE*/; + virtual bool IsContainer(const wxDataViewItem &item) const override/*wxOVERRIDE*/; + virtual unsigned int GetChildren(const wxDataViewItem &parent, + wxDataViewItemArray &array) const override/*wxOVERRIDE*/; + +private: + MyMusicTreeModelNode* m_root; + + // pointers to some "special" nodes of the tree: + MyMusicTreeModelNode* m_pop; + MyMusicTreeModelNode* m_classical; + MyMusicTreeModelNode* m_ninth; + + // ?? + bool m_classicalMusicIsKnownToControl; +}; + +// ---------------------------------------------------------------------------- +// MyCustomRenderer +// ---------------------------------------------------------------------------- + +class MyCustomRenderer : public wxDataViewCustomRenderer +{ +public: + // This renderer can be either activatable or editable, for demonstration + // purposes. In real programs, you should select whether the user should be + // able to activate or edit the cell and it doesn't make sense to switch + // between the two -- but this is just an example, so it doesn't stop us. + explicit MyCustomRenderer(wxDataViewCellMode mode) + : wxDataViewCustomRenderer("string", mode, wxALIGN_CENTER) + { } + + virtual bool Render(wxRect rect, wxDC *dc, int state) override/*wxOVERRIDE*/ + { + dc->SetBrush(*wxLIGHT_GREY_BRUSH); + dc->SetPen(*wxTRANSPARENT_PEN); + + rect.Deflate(2); + dc->DrawRoundedRectangle(rect, 5); + + RenderText(m_value, + 0, // no offset + wxRect(dc->GetTextExtent(m_value)).CentreIn(rect), + dc, + state); + return true; + } + + virtual bool ActivateCell(const wxRect& WXUNUSED(cell), + wxDataViewModel *WXUNUSED(model), + const wxDataViewItem &WXUNUSED(item), + unsigned int WXUNUSED(col), + const wxMouseEvent *mouseEvent) override/*wxOVERRIDE*/ + { + wxString position; + if (mouseEvent) + position = wxString::Format("via mouse at %d, %d", mouseEvent->m_x, mouseEvent->m_y); + else + position = "from keyboard"; +// wxLogMessage("MyCustomRenderer ActivateCell() %s", position); + return false; + } + + virtual wxSize GetSize() const override/*wxOVERRIDE*/ + { + return wxSize(60, 20); + } + + virtual bool SetValue(const wxVariant &value) override/*wxOVERRIDE*/ + { + m_value = value.GetString(); + return true; + } + + virtual bool GetValue(wxVariant &WXUNUSED(value)) const override/*wxOVERRIDE*/{ return true; } + + virtual bool HasEditorCtrl() const override/*wxOVERRIDE*/{ return true; } + + virtual wxWindow* + CreateEditorCtrl(wxWindow* parent, + wxRect labelRect, + const wxVariant& value) override/*wxOVERRIDE*/ + { + wxTextCtrl* text = new wxTextCtrl(parent, wxID_ANY, value, + labelRect.GetPosition(), + labelRect.GetSize(), + wxTE_PROCESS_ENTER); + text->SetInsertionPointEnd(); + + return text; + } + + virtual bool + GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& value) override/*wxOVERRIDE*/ + { + wxTextCtrl* text = wxDynamicCast(ctrl, wxTextCtrl); + if (!text) + return false; + + value = text->GetValue(); + + return true; + } + +private: + wxString m_value; +}; +// ***************************************************************************** + + + #endif // slic3r_GUI_wxExtensions_hpp_ From c07f347ff6cc952cf7cd8853cb89c6b5984d3272 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 9 May 2018 14:36:20 +0200 Subject: [PATCH 004/119] CollapsiblePanes are putted to ScrolledWindow --- xs/src/slic3r/GUI/GUI.cpp | 148 +++++++++++------------------ xs/src/slic3r/GUI/wxExtensions.cpp | 12 +-- xs/src/slic3r/GUI/wxExtensions.hpp | 6 +- 3 files changed, 65 insertions(+), 101 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 0be77b6ba..0e2893b57 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -809,17 +809,25 @@ wxString from_u8(const std::string &str) void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer) { + sizer->SetMinSize(-1, 300); + auto main_sizer = new wxBoxSizer(wxVERTICAL); + auto main_page = new wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + main_page->SetSizer(main_sizer); + main_page->SetScrollbars(1, 1, 1, 1); + sizer->Add(main_page, 1, wxEXPAND | wxALL, 1); + // Experiments with new UI - wxCollapsiblePane *collpane = new wxCollapsiblePane(parent, wxID_ANY, "Print settings:"); - collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, collpane](wxCommandEvent e){ + wxCollapsiblePane *collpane = new wxCollapsiblePane(main_page, wxID_ANY, "Frequently Changing Parameters:"); + collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, main_page, collpane](wxCommandEvent e){ wxWindowUpdateLocker noUpdates_cp(collpane); - wxWindowUpdateLocker noUpdates(parent); - parent->Layout(); + wxWindowUpdateLocker noUpdates(main_page); + parent->Layout(); + main_page->Layout(); collpane->Refresh(); })); // add the pane with a zero proportion value to the sizer which contains it - sizer->Add(collpane, 0, wxGROW | wxALL, 0); + main_sizer->Add(collpane, 0, wxGROW | wxALL, 0); wxWindow *win = collpane->GetPane(); #ifdef __WXMSW__ @@ -943,8 +951,36 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl }; m_optgroup->append_line(line); - auto common_sizer = new wxBoxSizer(wxVERTICAL); - common_sizer->Add(m_optgroup->sizer); + wxSizer *paneSz = new wxBoxSizer(wxVERTICAL); + paneSz->Add(m_optgroup->sizer, 1, wxGROW | wxEXPAND | /*wxBOTTOM*/wxALL, /*2*/5); + win->SetSizer(paneSz); + paneSz->SetSizeHints(win); + + + + + wxCollapsiblePane *collpane_objects = new wxCollapsiblePane(main_page, wxID_ANY, "Objects List:"); + collpane_objects->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, main_page, collpane_objects](wxCommandEvent e){ + wxWindowUpdateLocker noUpdates_cp(collpane_objects); + wxWindowUpdateLocker noUpdates(main_page); + parent->Layout(); + main_page->Layout(); + collpane_objects->Refresh(); + })); + + // add the pane with a zero proportion value to the sizer which contains it + main_sizer->Add(collpane_objects, 0, wxGROW | wxALL, 0); + + wxWindow *win_objects = collpane_objects->GetPane(); +#ifdef __WXMSW__ + collpane_objects->GetControlWidget()->SetWindowStyleFlag(wxNO_BORDER); + collpane_objects->GetControlWidget()->SetBackgroundColour(clr); + collpane_objects->SetBackgroundColour(clr); + win_objects->SetBackgroundColour(clr); +#endif //__WXMSW__ + +// auto common_sizer = new wxBoxSizer(wxVERTICAL); +// common_sizer->Add(m_optgroup->sizer); // auto listctrl = new wxDataViewListCtrl(win, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); // listctrl->AppendToggleColumn("Toggle"); @@ -964,9 +1000,10 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl // common_sizer->Add(listctrl, 0, wxEXPAND | wxALL, 1); // ********************************************************************************************** - auto objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); + auto objects_ctrl = new wxDataViewCtrl(win_objects, wxID_ANY, wxDefaultPosition, wxDefaultSize); wxSizer *objects_sz = new wxBoxSizer(wxVERTICAL); - objects_ctrl->SetMinSize(wxSize(-1, 200)); + objects_ctrl->SetBestFittingSize(wxSize(-1, 200)); +// objects_ctrl->SetMinSize(wxSize(-1, 200)); objects_sz->Add(objects_ctrl, 1, wxGROW | wxALL, 5); auto objects_model = new MyObjectTreeModel; @@ -979,108 +1016,31 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl // column 0 of the view control: wxDataViewTextRenderer *tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); - wxDataViewColumn *column00 = new wxDataViewColumn("Name", tr, 0, 150, wxALIGN_LEFT, + wxDataViewColumn *column00 = new wxDataViewColumn("Name", tr, 0, 140, wxALIGN_LEFT, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); objects_ctrl->AppendColumn(column00); // column 1 of the view control: tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); - wxDataViewColumn *column01 = new wxDataViewColumn("Copy", tr, 1, 95, wxALIGN_CENTER_HORIZONTAL, + wxDataViewColumn *column01 = new wxDataViewColumn("Copy", tr, 1, 75, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); objects_ctrl->AppendColumn(column01); // column 2 of the view control: tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); - wxDataViewColumn *column02 = new wxDataViewColumn("Scale", tr, 2, 95, wxALIGN_CENTER_HORIZONTAL, + wxDataViewColumn *column02 = new wxDataViewColumn("Scale", tr, 2, 80, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); objects_ctrl->AppendColumn(column02); - common_sizer->Add(objects_sz, 0, wxEXPAND | wxALL, 1); +// common_sizer->Add(objects_sz, 0, wxEXPAND | wxALL, 1); - // ********************************************************************************************** -/* auto view_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); - wxSizer *PanelSz = new wxBoxSizer(wxVERTICAL); - view_ctrl->SetMinSize(wxSize(-1, 200)); - PanelSz->Add(view_ctrl, 1, wxGROW | wxALL, 5); - PanelSz->Add( new wxStaticText(win, wxID_ANY, "Most of the cells above are editable!"), 0, wxGROW | wxALL, 5); - - auto m_music_model = new MyMusicTreeModel; - view_ctrl->AssociateModel(m_music_model); + wxSizer *paneSz_objects = new wxBoxSizer(wxVERTICAL); + paneSz_objects->Add(objects_sz, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); + win_objects->SetSizer(paneSz_objects); + paneSz_objects->SetSizeHints(win_objects); -#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE - view_ctrl->EnableDragSource(wxDF_UNICODETEXT); - view_ctrl->EnableDropTarget(wxDF_UNICODETEXT); -#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE - - // column 0 of the view control: - - tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); - wxDataViewColumn *column0 = - new wxDataViewColumn("title", tr, 0, 150, wxALIGN_LEFT, - wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); - view_ctrl->AppendColumn(column0); -#if 0 - // Call this and sorting is enabled - // immediately upon start up. - column0->SetAsSortKey(); -#endif - - // column 1 of the view control: - - tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_EDITABLE); - wxDataViewColumn *column1 = - new wxDataViewColumn("artist", tr, 1, 150, wxALIGN_LEFT, - wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE | - wxDATAVIEW_COL_RESIZABLE); - column1->SetMinWidth(100); // this column can't be resized to be smaller - view_ctrl->AppendColumn(column1); - - // column 2 of the view control: - - wxDataViewSpinRenderer *sr = - new wxDataViewSpinRenderer(0, 2010, wxDATAVIEW_CELL_EDITABLE, - wxALIGN_RIGHT | wxALIGN_CENTRE_VERTICAL); - wxDataViewColumn *column2 = - new wxDataViewColumn("year", sr, 2, 60, wxALIGN_LEFT, - wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE); - view_ctrl->AppendColumn(column2); - - // column 3 of the view control: - - wxArrayString choices; - choices.Add("good"); - choices.Add("bad"); - choices.Add("lousy"); - wxDataViewChoiceRenderer *c = - new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, - wxALIGN_RIGHT | wxALIGN_CENTRE_VERTICAL); - wxDataViewColumn *column3 = - new wxDataViewColumn("rating", c, 3, 100, wxALIGN_LEFT, - wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE); - view_ctrl->AppendColumn(column3); - - // column 4 of the view control: - - view_ctrl->AppendProgressColumn("popularity", 4, wxDATAVIEW_CELL_INERT, 80); - - // column 5 of the view control: - - MyCustomRenderer *cr = new MyCustomRenderer(wxDATAVIEW_CELL_ACTIVATABLE); - wxDataViewColumn *column5 = - new wxDataViewColumn("custom", cr, 5, -1, wxALIGN_LEFT, - wxDATAVIEW_COL_RESIZABLE); - view_ctrl->AppendColumn(column5); - - // ********************************************************************************************** - common_sizer->Add(PanelSz, 0, wxEXPAND | wxALL, 1); -*/ - - wxSizer *paneSz = new wxBoxSizer(wxVERTICAL); - paneSz->Add(common_sizer/*m_optgroup->sizer*/, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); - win->SetSizer(paneSz); - paneSz->SetSizeHints(win); } ConfigOptionsGroup* get_optgroup() diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 9d691b1aa..0fb335118 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -186,9 +186,9 @@ MyObjectTreeModel::MyObjectTreeModel() m_objects.emplace(root3); auto root4 = new MyObjectTreeModelNode("Object4"); m_objects.emplace(root4); - root4->Append(new MyObjectTreeModelNode(root2, "SubObject1")); - root4->Append(new MyObjectTreeModelNode(root2, "SubObject2")); - root4->Append(new MyObjectTreeModelNode(root2, "SubObject3")); + root4->Append(new MyObjectTreeModelNode(root4, "SubObject1")); + root4->Append(new MyObjectTreeModelNode(root4, "SubObject2")); + root4->Append(new MyObjectTreeModelNode(root4, "SubObject3")); } wxString MyObjectTreeModel::GetName(const wxDataViewItem &item) const @@ -200,7 +200,7 @@ wxString MyObjectTreeModel::GetName(const wxDataViewItem &item) const return node->m_name; } -wxString MyObjectTreeModel::GetCopyCnt(const wxDataViewItem &item) const +wxString MyObjectTreeModel::GetCopy(const wxDataViewItem &item) const { MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); if (!node) // happens if item.IsOk()==false @@ -302,8 +302,8 @@ unsigned int MyObjectTreeModel::GetChildren(const wxDataViewItem &parent, wxData MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)parent.GetID(); if (!node) { - for (auto object: m_objects) - array.Add(wxDataViewItem((void*)object)); + for (auto object : m_objects) + array.Add(wxDataViewItem((void*)object)); return m_objects.size(); } diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 0ed27ab74..6ebdbe8b2 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -148,7 +148,7 @@ public: // helper method for wxLog wxString GetName(const wxDataViewItem &item) const; - wxString GetCopyCnt(const wxDataViewItem &item) const; + wxString GetCopy(const wxDataViewItem &item) const; wxString GetScale(const wxDataViewItem &item) const; // helper methods to change the model @@ -172,6 +172,10 @@ public: virtual bool IsContainer(const wxDataViewItem &item) const override; virtual unsigned int GetChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const override; + + // Is the container just a header or an item with all columns + // In our case it is an item with all columns + virtual bool HasContainerColumns(const wxDataViewItem& WXUNUSED(item)) const override { return true; } }; From 2e7d623ee40489d437badee28c4b52ec62eaceed Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 10 May 2018 16:36:12 +0200 Subject: [PATCH 005/119] Created PrusaCollapsiblePane for CollapsiblePane view with disclosure triangles --- resources/icons/disclosure_triangle_close.png | Bin 0 -> 212 bytes resources/icons/disclosure_triangle_open.png | Bin 0 -> 210 bytes xs/src/slic3r/GUI/GUI.cpp | 83 ++++------- xs/src/slic3r/GUI/wxExtensions.cpp | 133 +++++++++++++++++- xs/src/slic3r/GUI/wxExtensions.hpp | 61 ++++++++ 5 files changed, 218 insertions(+), 59 deletions(-) create mode 100644 resources/icons/disclosure_triangle_close.png create mode 100644 resources/icons/disclosure_triangle_open.png diff --git a/resources/icons/disclosure_triangle_close.png b/resources/icons/disclosure_triangle_close.png new file mode 100644 index 0000000000000000000000000000000000000000..0660422c7f53ee6bc352d6ce790d653214b523e0 GIT binary patch literal 212 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!AwsV#}EtuWQjQo_U)UOd39CjnE<`Y1$*|` zaGp}(4+#s~$0~J+;prs42DTceNBSw!Or{U)Z?-8&GMKS+tWG;O=OouuHJ%lj2c~y* zbyck}_{fmOP&vzyVZ~3~o3k7n7PYucUE-sD-~ab%7 literal 0 HcmV?d00001 diff --git a/resources/icons/disclosure_triangle_open.png b/resources/icons/disclosure_triangle_open.png new file mode 100644 index 0000000000000000000000000000000000000000..81112f2a2610371930c4be6fcb173a2472c5e298 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!E{d-#}EtuWC_*~makvG`UI#|CR|+=dgkfV zr=FssqVF4i2=nnw@@84tnsu1Pf%WUusZ;Ma{;-!~>%8hX^&xwJ^FD=4wvC;ad6+%g zCajZWYmi#qz!vJXb4l}-Ehb?CZAI>kVFwN{Fl?CZW##C;`XA6r22WQ%mvv4FO#qAdd(main_page, 1, wxEXPAND | wxALL, 1); // Experiments with new UI - wxCollapsiblePane *collpane = new wxCollapsiblePane(main_page, wxID_ANY, "Frequently Changing Parameters:"); - collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, main_page, collpane](wxCommandEvent e){ - wxWindowUpdateLocker noUpdates_cp(collpane); - wxWindowUpdateLocker noUpdates(main_page); - parent->Layout(); - main_page->Layout(); - collpane->Refresh(); - })); + // *** Frequently Changing Parameters *** + auto* collpane = new PrusaCollapsiblePane(main_page, wxID_ANY, "Frequently Changing Parameters:"); // add the pane with a zero proportion value to the sizer which contains it main_sizer->Add(collpane, 0, wxGROW | wxALL, 0); wxWindow *win = collpane->GetPane(); -#ifdef __WXMSW__ - wxColour& clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - collpane->GetControlWidget()->SetWindowStyleFlag(wxNO_BORDER); - collpane->GetControlWidget()->SetBackgroundColour(clr); - collpane->SetBackgroundColour(clr); - win->SetBackgroundColour(clr); -#endif //__WXMSW__ DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config; m_optgroup = std::make_shared(win, "", config); @@ -952,57 +939,24 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl m_optgroup->append_line(line); wxSizer *paneSz = new wxBoxSizer(wxVERTICAL); - paneSz->Add(m_optgroup->sizer, 1, wxGROW | wxEXPAND | /*wxBOTTOM*/wxALL, /*2*/5); + paneSz->Add(m_optgroup->sizer, 1, wxGROW | wxEXPAND | wxLEFT | wxRIGHT, 5); win->SetSizer(paneSz); paneSz->SetSizeHints(win); - - wxCollapsiblePane *collpane_objects = new wxCollapsiblePane(main_page, wxID_ANY, "Objects List:"); - collpane_objects->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, main_page, collpane_objects](wxCommandEvent e){ - wxWindowUpdateLocker noUpdates_cp(collpane_objects); - wxWindowUpdateLocker noUpdates(main_page); - parent->Layout(); - main_page->Layout(); - collpane_objects->Refresh(); - })); - + // *** Objects List *** + auto *collpane_objects = new PrusaCollapsiblePane(main_page, wxID_ANY, "Objects List:"); // add the pane with a zero proportion value to the sizer which contains it main_sizer->Add(collpane_objects, 0, wxGROW | wxALL, 0); wxWindow *win_objects = collpane_objects->GetPane(); -#ifdef __WXMSW__ - collpane_objects->GetControlWidget()->SetWindowStyleFlag(wxNO_BORDER); - collpane_objects->GetControlWidget()->SetBackgroundColour(clr); - collpane_objects->SetBackgroundColour(clr); - win_objects->SetBackgroundColour(clr); -#endif //__WXMSW__ - -// auto common_sizer = new wxBoxSizer(wxVERTICAL); -// common_sizer->Add(m_optgroup->sizer); - -// auto listctrl = new wxDataViewListCtrl(win, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); -// listctrl->AppendToggleColumn("Toggle"); -// listctrl->AppendTextColumn("Text"); -// wxVector data; -// data.push_back(wxVariant(true)); -// data.push_back(wxVariant("row 1")); -// listctrl->AppendItem(data); -// data.clear(); -// data.push_back(wxVariant(false)); -// data.push_back(wxVariant("row 3")); -// listctrl->AppendItem(data); -// data.clear(); -// data.push_back(wxVariant(false)); -// data.push_back(wxVariant("row 2")); -// listctrl->AppendItem(data); -// common_sizer->Add(listctrl, 0, wxEXPAND | wxALL, 1); // ********************************************************************************************** auto objects_ctrl = new wxDataViewCtrl(win_objects, wxID_ANY, wxDefaultPosition, wxDefaultSize); wxSizer *objects_sz = new wxBoxSizer(wxVERTICAL); - objects_ctrl->SetBestFittingSize(wxSize(-1, 200)); + objects_ctrl->SetBestFittingSize(wxSize(-1, 200)); + // TODO - Set correct height according to the opened/closed objects // objects_ctrl->SetMinSize(wxSize(-1, 200)); objects_sz->Add(objects_ctrl, 1, wxGROW | wxALL, 5); @@ -1041,6 +995,29 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl win_objects->SetSizer(paneSz_objects); paneSz_objects->SetSizeHints(win_objects); + + +// auto common_sizer = new wxBoxSizer(wxVERTICAL); +// common_sizer->Add(m_optgroup->sizer); + +// auto listctrl = new wxDataViewListCtrl(win, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); +// listctrl->AppendToggleColumn("Toggle"); +// listctrl->AppendTextColumn("Text"); +// wxVector data; +// data.push_back(wxVariant(true)); +// data.push_back(wxVariant("row 1")); +// listctrl->AppendItem(data); +// data.clear(); +// data.push_back(wxVariant(false)); +// data.push_back(wxVariant("row 3")); +// listctrl->AppendItem(data); +// data.clear(); +// data.push_back(wxVariant(false)); +// data.push_back(wxVariant("row 2")); +// listctrl->AppendItem(data); +// common_sizer->Add(listctrl, 0, wxEXPAND | wxALL, 1); + + } ConfigOptionsGroup* get_optgroup() diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 0fb335118..03d6bdaef 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -1,5 +1,11 @@ #include "wxExtensions.hpp" +#include "GUI.hpp" +#include "../../libslic3r/Utils.hpp" + +#include +#include + const unsigned int wxCheckListBoxComboPopup::DefaultWidth = 200; const unsigned int wxCheckListBoxComboPopup::DefaultHeight = 200; const unsigned int wxCheckListBoxComboPopup::DefaultItemHeight = 18; @@ -166,6 +172,119 @@ void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& e cmb->SetText(selected); } +// *** PrusaCollapsiblePane *** +// ---------------------------------------------------------------------------- +bool PrusaCollapsiblePane::Create(wxWindow *parent, wxWindowID id, const wxString& label, + const wxPoint& pos, const wxSize& size, long style, const wxValidator& val, const wxString& name) +{ + if (!wxControl::Create(parent, id, pos, size, style, val, name)) + return false; + m_pStaticLine = NULL; + m_strLabel = label; + + // sizer containing the expand button and possibly a static line + m_sz = new wxBoxSizer(wxHORIZONTAL); + + m_bmp_close.LoadFile(Slic3r::GUI::from_u8(Slic3r::var("disclosure_triangle_close.png")), wxBITMAP_TYPE_PNG); + m_bmp_open.LoadFile(Slic3r::GUI::from_u8(Slic3r::var("disclosure_triangle_open.png")), wxBITMAP_TYPE_PNG); + + m_pDisclosureTriangleButton = new wxButton(this, wxID_ANY, m_strLabel, wxPoint(0, 0), + wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + m_pDisclosureTriangleButton->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) + { + if (event.GetEventObject() != m_pDisclosureTriangleButton) + { + event.Skip(); + return; + } + + Collapse(!IsCollapsed()); + + // this change was generated by the user - send the event + wxCollapsiblePaneEvent ev(this, GetId(), IsCollapsed()); + GetEventHandler()->ProcessEvent(ev); + }); + + UpdateBtnBmp(); + + m_sz->Add(m_pDisclosureTriangleButton, 0, wxLEFT | wxTOP | wxBOTTOM, GetBorder()); + + // do not set sz as our sizers since we handle the pane window without using sizers + m_pPane = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, + wxTAB_TRAVERSAL | wxNO_BORDER, wxT("wxCollapsiblePanePane")); + + wxColour& clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + m_pDisclosureTriangleButton->SetBackgroundColour(clr); + this->SetBackgroundColour(clr); + m_pPane->SetBackgroundColour(clr); + + // start as collapsed: + m_pPane->Hide(); + + return true; +} + +void PrusaCollapsiblePane::UpdateBtnBmp() +{ + IsCollapsed() ? + m_pDisclosureTriangleButton->SetBitmap(m_bmp_close) : + m_pDisclosureTriangleButton->SetBitmap(m_bmp_open); + Layout(); +// m_pDisclosureTriangleButton->Refresh(); +} + +void PrusaCollapsiblePane::Collapse(bool collapse) +{ + // optimization + if (IsCollapsed() == collapse) + return; + + InvalidateBestSize(); + + // update our state + m_pPane->Show(!collapse); + + // update button label +// m_pDisclosureTriangleButton->SetLabel(m_strLabel); + UpdateBtnBmp(); + + OnStateChange(GetBestSize()); +} + +void PrusaCollapsiblePane::SetLabel(const wxString &label) +{ + m_strLabel = label; + + m_pDisclosureTriangleButton->SetLabel(m_strLabel); + + Layout(); +} + +bool PrusaCollapsiblePane::Layout() +{ + if (!m_pDisclosureTriangleButton || !m_pPane || !m_sz) + return false; // we need to complete the creation first! + + wxSize oursz(GetSize()); + + // move & resize the button and the static line + m_sz->SetDimension(0, 0, oursz.GetWidth(), m_sz->GetMinSize().GetHeight()); + m_sz->Layout(); + + if (IsExpanded()) + { + // move & resize the container window + int yoffset = m_sz->GetSize().GetHeight() + GetBorder(); + m_pPane->SetSize(0, yoffset, + oursz.x, oursz.y - yoffset); + + // this is very important to make the pane window layout show correctly + m_pPane->Layout(); + } + + return true; +} + // ***************************************************************************** // ---------------------------------------------------------------------------- // MyObjectTreeModel @@ -178,17 +297,19 @@ MyObjectTreeModel::MyObjectTreeModel() auto root2 = new MyObjectTreeModelNode("Object2"); m_objects.emplace(root2); - root2->Append(new MyObjectTreeModelNode(root2, "SubObject1")); - root2->Append(new MyObjectTreeModelNode(root2, "SubObject2")); - root2->Append(new MyObjectTreeModelNode(root2, "SubObject3")); + root2->Append(new MyObjectTreeModelNode(root2, "SubObject2_1")); + root2->Append(new MyObjectTreeModelNode(root2, "SubObject2_2")); + root2->Append(new MyObjectTreeModelNode(root2, "SubObject2_3")); auto root3 = new MyObjectTreeModelNode("Object3"); m_objects.emplace(root3); auto root4 = new MyObjectTreeModelNode("Object4"); m_objects.emplace(root4); - root4->Append(new MyObjectTreeModelNode(root4, "SubObject1")); - root4->Append(new MyObjectTreeModelNode(root4, "SubObject2")); - root4->Append(new MyObjectTreeModelNode(root4, "SubObject3")); + root4->Append(new MyObjectTreeModelNode(root4, "SubObject4_1")); + root4->Append(new MyObjectTreeModelNode(root4, "SubObject4_2")); + + auto root5 = new MyObjectTreeModelNode("Object5"); + m_objects.emplace(root5); } wxString MyObjectTreeModel::GetName(const wxDataViewItem &item) const diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 6ebdbe8b2..ec3b0d479 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -5,6 +5,10 @@ #include #include #include +#include +#include +#include + #include #include @@ -53,6 +57,63 @@ public: void SetItemsCnt(int cnt) { m_cnt_open_items = cnt; } }; + + +// *** PrusaCollapsiblePane *** +// ---------------------------------------------------------------------------- +class PrusaCollapsiblePane : public wxCollapsiblePane +{ +#ifdef __WXMSW__ + wxButton* m_pDisclosureTriangleButton = nullptr; + wxBitmap m_bmp_close; + wxBitmap m_bmp_open; +#endif //__WXMSW__ +public: + PrusaCollapsiblePane() {} + + + PrusaCollapsiblePane( wxWindow *parent, + wxWindowID winid, + const wxString& label, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxCP_DEFAULT_STYLE, + const wxValidator& val = wxDefaultValidator, + const wxString& name = wxCollapsiblePaneNameStr) + { +#ifdef __WXMSW__ + Create(parent, winid, label, pos, size, style, val, name); +#else + this->Create(parent, winid, label); +#endif //__WXMSW__ + this->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, this](wxCommandEvent e){ + wxWindowUpdateLocker noUpdates_cp(this); + wxWindowUpdateLocker noUpdates(parent); + parent->GetParent()->Layout(); + parent->Layout(); + this->Refresh(); + })); + } + + bool Create(wxWindow *parent, + wxWindowID id, + const wxString& label, + const wxPoint& pos, + const wxSize& size, + long style, + const wxValidator& val, + const wxString& name); + +#ifdef __WXMSW__ + void UpdateBtnBmp(); + void Collapse(bool collapse) override; + void SetLabel(const wxString &label) override; + bool Layout() override; +#endif //__WXMSW__ + +}; + + // ***************************************************************************** // ---------------------------------------------------------------------------- // MyObjectTreeModelNode: a node inside MyObjectTreeModel From 27769edab288a5a99bcd598530a85215e7e43d90 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 11 May 2018 11:25:28 +0200 Subject: [PATCH 006/119] Fixed compilation bag on GTK and OSX --- xs/src/slic3r/GUI/wxExtensions.cpp | 3 +++ xs/src/slic3r/GUI/wxExtensions.hpp | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 03d6bdaef..ace0ad53a 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -172,8 +172,10 @@ void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& e cmb->SetText(selected); } +// ---------------------------------------------------------------------------- // *** PrusaCollapsiblePane *** // ---------------------------------------------------------------------------- +#ifdef __WXMSW__ bool PrusaCollapsiblePane::Create(wxWindow *parent, wxWindowID id, const wxString& label, const wxPoint& pos, const wxSize& size, long style, const wxValidator& val, const wxString& name) { @@ -284,6 +286,7 @@ bool PrusaCollapsiblePane::Layout() return true; } +#endif //__WXMSW__ // ***************************************************************************** // ---------------------------------------------------------------------------- diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index ec3b0d479..cea4ce32b 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -70,8 +70,6 @@ class PrusaCollapsiblePane : public wxCollapsiblePane #endif //__WXMSW__ public: PrusaCollapsiblePane() {} - - PrusaCollapsiblePane( wxWindow *parent, wxWindowID winid, const wxString& label, @@ -84,7 +82,7 @@ public: #ifdef __WXMSW__ Create(parent, winid, label, pos, size, style, val, name); #else - this->Create(parent, winid, label); + Create(parent, winid, label); #endif //__WXMSW__ this->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, this](wxCommandEvent e){ wxWindowUpdateLocker noUpdates_cp(this); @@ -95,6 +93,9 @@ public: })); } + ~PrusaCollapsiblePane() {} + +#ifdef __WXMSW__ bool Create(wxWindow *parent, wxWindowID id, const wxString& label, @@ -104,7 +105,6 @@ public: const wxValidator& val, const wxString& name); -#ifdef __WXMSW__ void UpdateBtnBmp(); void Collapse(bool collapse) override; void SetLabel(const wxString &label) override; From 75a0dea93f0bb1f50b526dd52f2fd1a965609054 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 15 May 2018 12:01:33 +0200 Subject: [PATCH 007/119] PrusaCollapsiblePanel works correct on MSW now --- xs/src/slic3r/GUI/wxExtensions.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index ace0ad53a..2e0f7c90a 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -192,6 +192,7 @@ bool PrusaCollapsiblePane::Create(wxWindow *parent, wxWindowID id, const wxStrin m_pDisclosureTriangleButton = new wxButton(this, wxID_ANY, m_strLabel, wxPoint(0, 0), wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + UpdateBtnBmp(); m_pDisclosureTriangleButton->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) { if (event.GetEventObject() != m_pDisclosureTriangleButton) @@ -207,8 +208,6 @@ bool PrusaCollapsiblePane::Create(wxWindow *parent, wxWindowID id, const wxStrin GetEventHandler()->ProcessEvent(ev); }); - UpdateBtnBmp(); - m_sz->Add(m_pDisclosureTriangleButton, 0, wxLEFT | wxTOP | wxBOTTOM, GetBorder()); // do not set sz as our sizers since we handle the pane window without using sizers @@ -228,11 +227,17 @@ bool PrusaCollapsiblePane::Create(wxWindow *parent, wxWindowID id, const wxStrin void PrusaCollapsiblePane::UpdateBtnBmp() { - IsCollapsed() ? - m_pDisclosureTriangleButton->SetBitmap(m_bmp_close) : + if (IsCollapsed()) + m_pDisclosureTriangleButton->SetBitmap(m_bmp_close); + else{ m_pDisclosureTriangleButton->SetBitmap(m_bmp_open); + // To updating button bitmap it's needed to lost focus on this button, so + // we set focus to mainframe + //GetParent()->GetParent()->GetParent()->SetFocus(); + //or to pane + GetPane()->SetFocus(); + } Layout(); -// m_pDisclosureTriangleButton->Refresh(); } void PrusaCollapsiblePane::Collapse(bool collapse) @@ -246,8 +251,7 @@ void PrusaCollapsiblePane::Collapse(bool collapse) // update our state m_pPane->Show(!collapse); - // update button label -// m_pDisclosureTriangleButton->SetLabel(m_strLabel); + // update button bitmap UpdateBtnBmp(); OnStateChange(GetBestSize()); @@ -256,9 +260,7 @@ void PrusaCollapsiblePane::Collapse(bool collapse) void PrusaCollapsiblePane::SetLabel(const wxString &label) { m_strLabel = label; - m_pDisclosureTriangleButton->SetLabel(m_strLabel); - Layout(); } From 146a02a300f90562e353c294278dbd47879767d7 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 16 May 2018 14:38:37 +0200 Subject: [PATCH 008/119] Added view mode selection to the config_menu --- xs/src/slic3r/GUI/GUI.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 2d487edd5..f97f7e31e 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -378,12 +378,20 @@ void get_installed_languages(wxArrayString & names, } } +std::string get_view_mode() +{ + return g_AppConfig->has("view_mode") ? + g_AppConfig->get("view_mode") : "simple"; +} + enum ConfigMenuIDs { ConfigMenuWizard, ConfigMenuSnapshots, ConfigMenuTakeSnapshot, ConfigMenuUpdate, ConfigMenuPreferences, + ConfigMenuModeSimple, + ConfigMenuModeExpert, ConfigMenuLanguage, ConfigMenuCnt, }; @@ -402,7 +410,14 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l local_menu->AppendSeparator(); local_menu->Append(config_id_base + ConfigMenuPreferences, _(L("Preferences"))+"\u2026\tCtrl+,", _(L("Application preferences"))); local_menu->AppendSeparator(); - local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application Language"))); + auto mode_menu = new wxMenu(); + mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _(L("&Simple")), _(L("Simple View Mode"))); + mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeExpert, _(L("&Expert")), _(L("Expert View Mode"))); + if (get_view_mode() == "expert") + mode_menu->Check(config_id_base + ConfigMenuModeExpert, true); + local_menu->AppendSubMenu(mode_menu, _(L("&Mode")), _(L("Slic3r View Mode"))); + local_menu->AppendSeparator(); + local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application Language"))); local_menu->Bind(wxEVT_MENU, [config_id_base, event_language_change, event_preferences_changed](wxEvent &event){ switch (event.GetId() - config_id_base) { case ConfigMenuWizard: @@ -457,8 +472,21 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l } } break; - } } + } + }); + mode_menu->Bind(wxEVT_MENU, [config_id_base](wxEvent& event) { + std::string mode = ""; + switch (event.GetId() - config_id_base){ + case ConfigMenuModeExpert: + mode = "expert"; + break; + case ConfigMenuModeSimple: + mode = "simple"; + break; + } + g_AppConfig->set("view_mode", mode); + g_AppConfig->save(); }); menu->Append(local_menu, _(L("&Configuration"))); } From d3106684620e8bac7f422daac25e6d959d0ba63b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 17 May 2018 10:46:32 +0200 Subject: [PATCH 009/119] Added Regular view mode to the menu. Right column objects send fron Perl to C++ --- lib/Slic3r/GUI/Plater.pm | 17 ++- xs/src/slic3r/GUI/GUI.cpp | 313 +++++++++++++++++++++----------------- xs/src/slic3r/GUI/GUI.hpp | 11 ++ xs/xsp/GUI.xsp | 23 +++ 4 files changed, 225 insertions(+), 139 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 21cbcca45..93b41af1c 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -409,8 +409,10 @@ sub new { } } - my $frequently_changed_parameters_sizer = Wx::BoxSizer->new(wxVERTICAL);#(wxHORIZONTAL); + my $frequently_changed_parameters_sizer = Wx::BoxSizer->new(wxVERTICAL); Slic3r::GUI::add_frequently_changed_parameters($self, $frequently_changed_parameters_sizer, $presets); + my $expert_mode_part_sizer = Wx::BoxSizer->new(wxVERTICAL); + Slic3r::GUI::add_expert_mode_part($self, $expert_mode_part_sizer); my $object_info_sizer; { @@ -495,9 +497,10 @@ sub new { $scrolled_window_sizer->Add($print_info_sizer, 0, wxEXPAND, 0); my $right_sizer = Wx::BoxSizer->new(wxVERTICAL); - $right_sizer->SetMinSize([-1, 600]); + $right_sizer->SetMinSize([320, 600]); $right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets; $right_sizer->Add($frequently_changed_parameters_sizer, 0, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; + $right_sizer->Add($expert_mode_part_sizer, 0, wxEXPAND | wxTOP, 0) if defined $expert_mode_part_sizer; $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5); $right_sizer->Add($scrolled_window_panel, 1, wxEXPAND | wxALL, 1); # Callback for showing / hiding the print info box. @@ -525,6 +528,16 @@ sub new { $sizer->SetSizeHints($self); $self->SetSizer($sizer); + + # Send sizers/buttons to C++ + Slic3r::GUI::set_objects_from_perl( $frequently_changed_parameters_sizer, + $expert_mode_part_sizer, + $scrolled_window_sizer, + $self->{btn_export_stl}, + $self->{btn_reslice}, + $self->{btn_print}, + $self->{btn_send_gcode}, + $self->{btn_export_gcode}); } # Last correct selected item for each preset diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index f97f7e31e..3cf3c8d0d 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -201,6 +201,16 @@ std::shared_ptr m_optgroup; double m_brim_width = 0.0; wxButton* g_wiping_dialog_button = nullptr; +//showed/hided controls according to the view mode +wxBoxSizer *g_frequently_changed_parameters_sizer = nullptr; +wxBoxSizer *g_expert_mode_part_sizer = nullptr; +wxBoxSizer *g_scrolled_window_sizer = nullptr; +wxButton *g_btn_export_stl = nullptr; +wxButton *g_btn_reslice = nullptr; +wxButton *g_btn_print = nullptr; +wxButton *g_btn_send_gcode = nullptr; +wxButton *g_btn_export_gcode = nullptr; + static void init_label_colours() { auto luma = get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); @@ -260,6 +270,21 @@ void set_preset_updater(PresetUpdater *updater) g_PresetUpdater = updater; } +void set_objects_from_perl( wxBoxSizer *frequently_changed_parameters_sizer, + wxBoxSizer *expert_mode_part_sizer, wxBoxSizer *scrolled_window_sizer, + wxButton *btn_export_stl, wxButton *btn_reslice, wxButton *btn_print, + wxButton *btn_send_gcode, wxButton *btn_export_gcode) +{ + g_frequently_changed_parameters_sizer = frequently_changed_parameters_sizer; + g_expert_mode_part_sizer = expert_mode_part_sizer; + g_scrolled_window_sizer = scrolled_window_sizer; + g_btn_export_stl = btn_export_stl; + g_btn_reslice = btn_reslice; + g_btn_print = btn_print; + g_btn_send_gcode = btn_send_gcode; + g_btn_export_gcode = btn_export_gcode; +} + std::vector& get_tabs_list() { return g_tabs_list; @@ -378,12 +403,6 @@ void get_installed_languages(wxArrayString & names, } } -std::string get_view_mode() -{ - return g_AppConfig->has("view_mode") ? - g_AppConfig->get("view_mode") : "simple"; -} - enum ConfigMenuIDs { ConfigMenuWizard, ConfigMenuSnapshots, @@ -391,10 +410,24 @@ enum ConfigMenuIDs { ConfigMenuUpdate, ConfigMenuPreferences, ConfigMenuModeSimple, + ConfigMenuModeRegular, ConfigMenuModeExpert, ConfigMenuLanguage, ConfigMenuCnt, }; + +ConfigMenuIDs get_view_mode() +{ + if (!g_AppConfig->has("view_mode")) + return ConfigMenuModeSimple; + + const auto mode = g_AppConfig->get("view_mode"); + return mode == "expert" ? + ConfigMenuModeExpert : + mode == "regular" ? + ConfigMenuModeRegular : + ConfigMenuModeSimple; +} void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_language_change) { @@ -412,9 +445,9 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l local_menu->AppendSeparator(); auto mode_menu = new wxMenu(); mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _(L("&Simple")), _(L("Simple View Mode"))); + mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeRegular, _(L("&Regular")), _(L("Regular View Mode"))); mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeExpert, _(L("&Expert")), _(L("Expert View Mode"))); - if (get_view_mode() == "expert") - mode_menu->Check(config_id_base + ConfigMenuModeExpert, true); + mode_menu->Check(config_id_base + get_view_mode(), true); local_menu->AppendSubMenu(mode_menu, _(L("&Mode")), _(L("Slic3r View Mode"))); local_menu->AppendSeparator(); local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application Language"))); @@ -481,12 +514,16 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l case ConfigMenuModeExpert: mode = "expert"; break; + case ConfigMenuModeRegular: + mode = "regular"; + break; case ConfigMenuModeSimple: mode = "simple"; break; } g_AppConfig->set("view_mode", mode); g_AppConfig->save(); + update_mode(); }); menu->Append(local_menu, _(L("&Configuration"))); } @@ -835,9 +872,9 @@ wxString from_u8(const std::string &str) } -void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer) +void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) { - sizer->SetMinSize(-1, 300); + sizer->SetMinSize(-1, 150); auto main_sizer = new wxBoxSizer(wxVERTICAL); auto main_page = new wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); main_page->SetSizer(main_sizer); @@ -845,133 +882,10 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl sizer->Add(main_page, 1, wxEXPAND | wxALL, 1); // Experiments with new UI - - // *** Frequently Changing Parameters *** - auto* collpane = new PrusaCollapsiblePane(main_page, wxID_ANY, "Frequently Changing Parameters:"); - // add the pane with a zero proportion value to the sizer which contains it - main_sizer->Add(collpane, 0, wxGROW | wxALL, 0); - - wxWindow *win = collpane->GetPane(); - - DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config; - m_optgroup = std::make_shared(win, "", config); - m_optgroup->m_on_change = [config](t_config_option_key opt_key, boost::any value){ - TabPrint* tab_print = nullptr; - for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) { - Tab *tab = dynamic_cast(g_wxTabPanel->GetPage(i)); - if (!tab) - continue; - if (tab->name() == "print"){ - tab_print = static_cast(tab); - break; - } - } - if (tab_print == nullptr) - return; - - if (opt_key == "fill_density"){ - value = m_optgroup->get_config_value(*config, opt_key); - tab_print->set_value(opt_key, value); - tab_print->update(); - } - else{ - DynamicPrintConfig new_conf = *config; - if (opt_key == "brim"){ - double new_val; - double brim_width = config->opt_float("brim_width"); - if (boost::any_cast(value) == true) - { - new_val = m_brim_width == 0.0 ? 10 : - m_brim_width < 0.0 ? m_brim_width * (-1) : - m_brim_width; - } - else{ - m_brim_width = brim_width * (-1); - new_val = 0; - } - new_conf.set_key_value("brim_width", new ConfigOptionFloat(new_val)); - } - else{ //(opt_key == "support") - const wxString& selection = boost::any_cast(value); - - auto support_material = selection == _("None") ? false : true; - new_conf.set_key_value("support_material", new ConfigOptionBool(support_material)); - - if (selection == _("Everywhere")) - new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(false)); - else if (selection == _("Support on build plate only")) - new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(true)); - } - tab_print->load_config(new_conf); - } - - tab_print->update_dirty(); - }; - - Option option = m_optgroup->get_option("fill_density"); - option.opt.sidetext = ""; - option.opt.full_width = true; - m_optgroup->append_single_option_line(option); - - ConfigOptionDef def; - - def.label = L("Support"); - def.type = coStrings; - def.gui_type = "select_open"; - def.tooltip = L("Select what kind of support do you need"); - def.enum_labels.push_back(L("None")); - def.enum_labels.push_back(L("Support on build plate only")); - def.enum_labels.push_back(L("Everywhere")); - std::string selection = !config->opt_bool("support_material") ? - "None" : - config->opt_bool("support_material_buildplate_only") ? - "Support on build plate only" : - "Everywhere"; - def.default_value = new ConfigOptionStrings { selection }; - option = Option(def, "support"); - option.opt.full_width = true; - m_optgroup->append_single_option_line(option); - - m_brim_width = config->opt_float("brim_width"); - def.label = L("Brim"); - def.type = coBool; - def.tooltip = L("This flag enables the brim that will be printed around each object on the first layer."); - def.gui_type = ""; - def.default_value = new ConfigOptionBool{ m_brim_width > 0.0 ? true : false }; - option = Option(def, "brim"); - m_optgroup->append_single_option_line(option); - - - Line line = { "", "" }; - line.widget = [config](wxWindow* parent){ - g_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + "\u2026", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); - auto sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(g_wiping_dialog_button); - g_wiping_dialog_button->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent& e) - { - auto &config = g_PresetBundle->project_config; - std::vector init_matrix = (config.option("wiping_volumes_matrix"))->values; - std::vector init_extruders = (config.option("wiping_volumes_extruders"))->values; - - WipingDialog dlg(parent,std::vector(init_matrix.begin(),init_matrix.end()),std::vector(init_extruders.begin(),init_extruders.end())); - - if (dlg.ShowModal() == wxID_OK) { - std::vector matrix = dlg.get_matrix(); - std::vector extruders = dlg.get_extruders(); - (config.option("wiping_volumes_matrix"))->values = std::vector(matrix.begin(),matrix.end()); - (config.option("wiping_volumes_extruders"))->values = std::vector(extruders.begin(),extruders.end()); - } - })); - return sizer; - }; - m_optgroup->append_line(line); - - wxSizer *paneSz = new wxBoxSizer(wxVERTICAL); - paneSz->Add(m_optgroup->sizer, 1, wxGROW | wxEXPAND | wxLEFT | wxRIGHT, 5); - win->SetSizer(paneSz); - paneSz->SetSizeHints(win); - - +// wxSizer *paneSz = new wxBoxSizer(wxVERTICAL); +// paneSz->Add(m_optgroup->sizer, 1, wxGROW | wxEXPAND | wxLEFT | wxRIGHT, 5); +// win->SetSizer(paneSz); +// paneSz->SetSizeHints(win); // *** Objects List *** auto *collpane_objects = new PrusaCollapsiblePane(main_page, wxID_ANY, "Objects List:"); @@ -1046,6 +960,131 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl // common_sizer->Add(listctrl, 0, wxEXPAND | wxALL, 1); +} + +void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer) +{ + DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config; + m_optgroup = std::make_shared(parent, "", config); + // const wxArrayInt& ar = preset_sizer->GetColWidths(); + // m_optgroup->label_width = ar.IsEmpty() ? 100 : ar.front(); // doesn't work + m_optgroup->m_on_change = [config](t_config_option_key opt_key, boost::any value){ + TabPrint* tab_print = nullptr; + for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) { + Tab *tab = dynamic_cast(g_wxTabPanel->GetPage(i)); + if (!tab) + continue; + if (tab->name() == "print"){ + tab_print = static_cast(tab); + break; + } + } + if (tab_print == nullptr) + return; + + if (opt_key == "fill_density"){ + value = m_optgroup->get_config_value(*config, opt_key); + tab_print->set_value(opt_key, value); + tab_print->update(); + } + else{ + DynamicPrintConfig new_conf = *config; + if (opt_key == "brim"){ + double new_val; + double brim_width = config->opt_float("brim_width"); + if (boost::any_cast(value) == true) + { + new_val = m_brim_width == 0.0 ? 10 : + m_brim_width < 0.0 ? m_brim_width * (-1) : + m_brim_width; + } + else{ + m_brim_width = brim_width * (-1); + new_val = 0; + } + new_conf.set_key_value("brim_width", new ConfigOptionFloat(new_val)); + } + else{ //(opt_key == "support") + const wxString& selection = boost::any_cast(value); + + auto support_material = selection == _("None") ? false : true; + new_conf.set_key_value("support_material", new ConfigOptionBool(support_material)); + + if (selection == _("Everywhere")) + new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(false)); + else if (selection == _("Support on build plate only")) + new_conf.set_key_value("support_material_buildplate_only", new ConfigOptionBool(true)); + } + tab_print->load_config(new_conf); + } + + tab_print->update_dirty(); + }; + + Option option = m_optgroup->get_option("fill_density"); + option.opt.sidetext = ""; + option.opt.full_width = true; + m_optgroup->append_single_option_line(option); + + ConfigOptionDef def; + + def.label = L("Support"); + def.type = coStrings; + def.gui_type = "select_open"; + def.tooltip = L("Select what kind of support do you need"); + def.enum_labels.push_back(L("None")); + def.enum_labels.push_back(L("Support on build plate only")); + def.enum_labels.push_back(L("Everywhere")); + std::string selection = !config->opt_bool("support_material") ? + "None" : + config->opt_bool("support_material_buildplate_only") ? + "Support on build plate only" : + "Everywhere"; + def.default_value = new ConfigOptionStrings { selection }; + option = Option(def, "support"); + option.opt.full_width = true; + m_optgroup->append_single_option_line(option); + + m_brim_width = config->opt_float("brim_width"); + def.label = L("Brim"); + def.type = coBool; + def.tooltip = L("This flag enables the brim that will be printed around each object on the first layer."); + def.gui_type = ""; + def.default_value = new ConfigOptionBool{ m_brim_width > 0.0 ? true : false }; + option = Option(def, "brim"); + m_optgroup->append_single_option_line(option); + + + Line line = { "", "" }; + line.widget = [config](wxWindow* parent){ + g_wiping_dialog_button = new wxButton(parent, wxID_ANY, _(L("Purging volumes")) + "\u2026", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); + auto sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(g_wiping_dialog_button); + g_wiping_dialog_button->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent& e) + { + auto &config = g_PresetBundle->project_config; + std::vector init_matrix = (config.option("wiping_volumes_matrix"))->values; + std::vector init_extruders = (config.option("wiping_volumes_extruders"))->values; + + WipingDialog dlg(parent,std::vector(init_matrix.begin(),init_matrix.end()),std::vector(init_extruders.begin(),init_extruders.end())); + + if (dlg.ShowModal() == wxID_OK) { + std::vector matrix = dlg.get_matrix(); + std::vector extruders = dlg.get_extruders(); + (config.option("wiping_volumes_matrix"))->values = std::vector(matrix.begin(),matrix.end()); + (config.option("wiping_volumes_extruders"))->values = std::vector(extruders.begin(),extruders.end()); + } + })); + return sizer; + }; + m_optgroup->append_line(line); + + sizer->Add(m_optgroup->sizer, 1, wxEXPAND | wxBOTTOM, 2); +} + +void update_mode() +{ + } ConfigOptionsGroup* get_optgroup() diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 3752b5a7a..28359decd 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -79,6 +79,14 @@ void set_tab_panel(wxNotebook *tab_panel); void set_app_config(AppConfig *app_config); void set_preset_bundle(PresetBundle *preset_bundle); void set_preset_updater(PresetUpdater *updater); +void set_objects_from_perl( wxBoxSizer *frequently_changed_parameters_sizer, + wxBoxSizer *expert_mode_part_sizer, + wxBoxSizer *scrolled_window_sizer, + wxButton *btn_export_stl, + wxButton *btn_reslice, + wxButton *btn_print, + wxButton *btn_send_gcode, + wxButton *btn_export_gcode); AppConfig* get_app_config(); wxApp* get_app(); @@ -150,7 +158,10 @@ wxString L_str(const std::string &str); wxString from_u8(const std::string &str); +void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); +// Update view mode according to selected menu +void update_mode(); ConfigOptionsGroup* get_optgroup(); wxButton* get_wiping_dialog_button(); diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index aa95bd647..8b173161b 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -86,6 +86,29 @@ void add_frequently_changed_parameters(SV *ui_parent, SV *ui_sizer, SV *ui_p_siz (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), (wxFlexGridSizer*)wxPli_sv_2_object(aTHX_ ui_p_sizer, "Wx::FlexGridSizer")); %}; +void add_expert_mode_part(SV *ui_parent, SV *ui_sizer) + %code%{ Slic3r::GUI::add_expert_mode_part((wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), + (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer")); %}; + +void set_objects_from_perl( SV *frequently_changed_parameters_sizer, + SV *expert_mode_part_sizer, + SV *scrolled_window_sizer, + SV *btn_export_stl, + SV *btn_reslice, + SV *btn_print, + SV *btn_send_gcode, + SV *btn_export_gcode) + %code%{ Slic3r::GUI::set_objects_from_perl( + (wxBoxSizer *)wxPli_sv_2_object(aTHX_ frequently_changed_parameters_sizer, "Wx::BoxSizer"), + (wxBoxSizer *)wxPli_sv_2_object(aTHX_ expert_mode_part_sizer, "Wx::BoxSizer"), + (wxBoxSizer *)wxPli_sv_2_object(aTHX_ scrolled_window_sizer, "Wx::BoxSizer"), + (wxButton *)wxPli_sv_2_object(aTHX_ btn_export_stl, "Wx::Button"), + (wxButton *)wxPli_sv_2_object(aTHX_ btn_reslice, "Wx::Button"), + (wxButton *)wxPli_sv_2_object(aTHX_ btn_print, "Wx::Button"), + (wxButton *)wxPli_sv_2_object(aTHX_ btn_send_gcode, "Wx::Button"), + (wxButton *)wxPli_sv_2_object(aTHX_ btn_export_gcode, "Wx::Button")); %}; + + std::string fold_utf8_to_ascii(const char *src) %code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %}; From 4e47f4973cc7ac151ce6bc16f9a12ae2af48888d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 17 May 2018 14:07:50 +0200 Subject: [PATCH 010/119] Updating of the right column according selected view mode --- lib/Slic3r/GUI/Plater.pm | 13 +++++-- xs/src/slic3r/GUI/GUI.cpp | 59 +++++++++++++++++++++++++++--- xs/src/slic3r/GUI/GUI.hpp | 7 ++-- xs/src/slic3r/GUI/OptionsGroup.cpp | 27 ++++++++------ xs/src/slic3r/GUI/OptionsGroup.hpp | 1 + xs/src/slic3r/GUI/Tab.hpp | 2 +- xs/xsp/GUI.xsp | 14 ++++--- 7 files changed, 92 insertions(+), 31 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 93b41af1c..ebb561a9e 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -509,7 +509,12 @@ sub new { # $right_sizer->Show(5, $_[0]); # $self->Layout # } - if ($scrolled_window_sizer->IsShown(2) != $_[0]) { + if ($scrolled_window_sizer->IsShown(2) != $_[0]) { + Slic3r::GUI::set_show_print_info($_[0]); + my $mode = wxTheApp->{app_config}->get("view_mode"); + printf $mode."\n"; + return if ($mode eq "simple"); + print "non-simple\n"; $scrolled_window_sizer->Show(2, $_[0]); $scrolled_window_panel->Layout } @@ -530,14 +535,14 @@ sub new { $self->SetSizer($sizer); # Send sizers/buttons to C++ - Slic3r::GUI::set_objects_from_perl( $frequently_changed_parameters_sizer, + Slic3r::GUI::set_objects_from_perl( $self, + $frequently_changed_parameters_sizer, $expert_mode_part_sizer, $scrolled_window_sizer, $self->{btn_export_stl}, $self->{btn_reslice}, $self->{btn_print}, - $self->{btn_send_gcode}, - $self->{btn_export_gcode}); + $self->{btn_send_gcode} ); } # Last correct selected item for each preset diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 3cf3c8d0d..09ede75be 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -202,6 +202,7 @@ double m_brim_width = 0.0; wxButton* g_wiping_dialog_button = nullptr; //showed/hided controls according to the view mode +wxWindow *g_plater = nullptr; wxBoxSizer *g_frequently_changed_parameters_sizer = nullptr; wxBoxSizer *g_expert_mode_part_sizer = nullptr; wxBoxSizer *g_scrolled_window_sizer = nullptr; @@ -209,7 +210,7 @@ wxButton *g_btn_export_stl = nullptr; wxButton *g_btn_reslice = nullptr; wxButton *g_btn_print = nullptr; wxButton *g_btn_send_gcode = nullptr; -wxButton *g_btn_export_gcode = nullptr; +bool g_show_print_info = false; static void init_label_colours() { @@ -270,11 +271,12 @@ void set_preset_updater(PresetUpdater *updater) g_PresetUpdater = updater; } -void set_objects_from_perl( wxBoxSizer *frequently_changed_parameters_sizer, +void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_parameters_sizer, wxBoxSizer *expert_mode_part_sizer, wxBoxSizer *scrolled_window_sizer, - wxButton *btn_export_stl, wxButton *btn_reslice, wxButton *btn_print, - wxButton *btn_send_gcode, wxButton *btn_export_gcode) + wxButton *btn_export_stl, wxButton *btn_reslice, + wxButton *btn_print, wxButton *btn_send_gcode) { + g_plater = parent; g_frequently_changed_parameters_sizer = frequently_changed_parameters_sizer; g_expert_mode_part_sizer = expert_mode_part_sizer; g_scrolled_window_sizer = scrolled_window_sizer; @@ -282,7 +284,11 @@ void set_objects_from_perl( wxBoxSizer *frequently_changed_parameters_sizer, g_btn_reslice = btn_reslice; g_btn_print = btn_print; g_btn_send_gcode = btn_send_gcode; - g_btn_export_gcode = btn_export_gcode; +} + +void set_show_print_info(bool show) +{ + g_show_print_info = show; } std::vector& get_tabs_list() @@ -601,6 +607,7 @@ void create_preset_tabs(bool no_controller, int event_value_change, int event_pr tab->set_event_value_change(wxEventType(event_value_change)); tab->set_event_presets_changed(wxEventType(event_presets_changed)); } + update_mode();// TODO change place of call this function } TabIface* get_preset_tab_iface(char *name) @@ -1082,9 +1089,51 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl sizer->Add(m_optgroup->sizer, 1, wxEXPAND | wxBOTTOM, 2); } +void show_frequently_changed_parameters(bool show) +{ + g_frequently_changed_parameters_sizer->Show(show); + if (!show) return; + + for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) { + Tab *tab = dynamic_cast(g_wxTabPanel->GetPage(i)); + if (!tab) + continue; + tab->update_wiping_button_visibility(); + break; + } +} + +void show_buttons(bool show) +{ + g_btn_export_stl->Show(show); + g_btn_reslice->Show(show); + for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) { + TabPrinter *tab = dynamic_cast(g_wxTabPanel->GetPage(i)); + if (!tab) + continue; + g_btn_print->Show(show && !tab->m_config->opt_string("serial_port").empty()); + g_btn_send_gcode->Show(show && !tab->m_config->opt_string("octoprint_host").empty()); + break; + } +} + +void show_scrolled_window_sizer(bool show) +{ + g_scrolled_window_sizer->Show(static_cast(0), show); + g_scrolled_window_sizer->Show(1, show); + g_scrolled_window_sizer->Show(2, show && g_show_print_info); +} + void update_mode() { + wxWindowUpdateLocker noUpdates(g_plater); + ConfigMenuIDs mode = get_view_mode(); + show_frequently_changed_parameters(mode >= ConfigMenuModeRegular); + g_expert_mode_part_sizer->Show(mode == ConfigMenuModeExpert); + show_scrolled_window_sizer(mode >= ConfigMenuModeRegular); + show_buttons(mode >= ConfigMenuModeRegular); + g_plater->Layout(); } ConfigOptionsGroup* get_optgroup() diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 28359decd..1cca99319 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -79,14 +79,15 @@ void set_tab_panel(wxNotebook *tab_panel); void set_app_config(AppConfig *app_config); void set_preset_bundle(PresetBundle *preset_bundle); void set_preset_updater(PresetUpdater *updater); -void set_objects_from_perl( wxBoxSizer *frequently_changed_parameters_sizer, +void set_objects_from_perl( wxWindow* parent, + wxBoxSizer *frequently_changed_parameters_sizer, wxBoxSizer *expert_mode_part_sizer, wxBoxSizer *scrolled_window_sizer, wxButton *btn_export_stl, wxButton *btn_reslice, wxButton *btn_print, - wxButton *btn_send_gcode, - wxButton *btn_export_gcode); + wxButton *btn_send_gcode); +void set_show_print_info(bool show); AppConfig* get_app_config(); wxApp* get_app(); diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index 657ad03c0..40176a000 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -86,17 +86,23 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co if (!this->m_disabled) this->back_to_sys_value(opt_id); }; - if (!m_is_tab_opt) { - field->m_Undo_btn->Hide(); - field->m_Undo_to_sys_btn->Hide(); - } -// if (nonsys_btn_icon != nullptr) -// field->set_nonsys_btn_icon(*nonsys_btn_icon); // assign function objects for callbacks, etc. return field; } +void OptionsGroup::add_undo_buttuns_to_sizer(wxBoxSizer* sizer, const t_field& field) +{ + if (!m_is_tab_opt) { + field->m_Undo_btn->Hide(); + field->m_Undo_to_sys_btn->Hide(); + return; + } + + sizer->Add(field->m_Undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL); + sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL); +} + void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* = nullptr*/) { //! if (line.sizer != nullptr || (line.widget != nullptr && line.full_width > 0)){ if ( (line.sizer != nullptr || line.widget != nullptr) && line.full_width){ @@ -131,8 +137,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* const auto& field = build_field(option); auto btn_sizer = new wxBoxSizer(wxHORIZONTAL); - btn_sizer->Add(field->m_Undo_to_sys_btn); - btn_sizer->Add(field->m_Undo_btn); + add_undo_buttuns_to_sizer(btn_sizer, field); tmp_sizer->Add(btn_sizer, 0, wxEXPAND | wxALL, 0); if (is_window_field(field)) tmp_sizer->Add(field->getWindow(), 0, wxEXPAND | wxALL, wxOSX ? 0 : 5); @@ -176,8 +181,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* const auto& option = option_set.front(); const auto& field = build_field(option, label); - sizer->Add(field->m_Undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL); - sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL); + add_undo_buttuns_to_sizer(sizer, field); if (is_window_field(field)) sizer->Add(field->getWindow(), option.opt.full_width ? 1 : 0, (option.opt.full_width ? wxEXPAND : 0) | wxBOTTOM | wxTOP | wxALIGN_CENTER_VERTICAL, wxOSX ? 0 : 2); @@ -205,8 +209,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* // add field const Option& opt_ref = opt; auto& field = build_field(opt_ref, label); - sizer->Add(field->m_Undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL); - sizer->Add(field->m_Undo_btn, 0, wxALIGN_CENTER_VERTICAL, 0); + add_undo_buttuns_to_sizer(sizer, field); is_sizer_field(field) ? sizer->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) : sizer->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0); diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index 83b5b1233..55a8dc70b 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -171,6 +171,7 @@ protected: const t_field& build_field(const t_config_option_key& id, const ConfigOptionDef& opt, wxStaticText* label = nullptr); const t_field& build_field(const t_config_option_key& id, wxStaticText* label = nullptr); const t_field& build_field(const Option& opt, wxStaticText* label = nullptr); + void add_undo_buttuns_to_sizer(wxBoxSizer* sizer, const t_field& field); virtual void on_kill_focus (){}; virtual void on_change_OG(const t_config_option_key& opt_id, const boost::any& value); diff --git a/xs/src/slic3r/GUI/Tab.hpp b/xs/src/slic3r/GUI/Tab.hpp index 62030bce3..8f540b197 100644 --- a/xs/src/slic3r/GUI/Tab.hpp +++ b/xs/src/slic3r/GUI/Tab.hpp @@ -264,11 +264,11 @@ public: void on_value_change(const std::string& opt_key, const boost::any& value); + void update_wiping_button_visibility(); protected: void on_presets_changed(); void update_preset_description_line(); void update_frequently_changed_parameters(); - void update_wiping_button_visibility(); void update_tab_presets(wxComboCtrl* ui, bool show_incompatible); void fill_icon_descriptions(); void set_tooltips_text(); diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 8b173161b..b402ab656 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -90,24 +90,26 @@ void add_expert_mode_part(SV *ui_parent, SV *ui_sizer) %code%{ Slic3r::GUI::add_expert_mode_part((wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer")); %}; -void set_objects_from_perl( SV *frequently_changed_parameters_sizer, +void set_objects_from_perl( SV *ui_parent, + SV *frequently_changed_parameters_sizer, SV *expert_mode_part_sizer, SV *scrolled_window_sizer, SV *btn_export_stl, SV *btn_reslice, SV *btn_print, - SV *btn_send_gcode, - SV *btn_export_gcode) - %code%{ Slic3r::GUI::set_objects_from_perl( + SV *btn_send_gcode) + %code%{ Slic3r::GUI::set_objects_from_perl( + (wxWindow *)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), (wxBoxSizer *)wxPli_sv_2_object(aTHX_ frequently_changed_parameters_sizer, "Wx::BoxSizer"), (wxBoxSizer *)wxPli_sv_2_object(aTHX_ expert_mode_part_sizer, "Wx::BoxSizer"), (wxBoxSizer *)wxPli_sv_2_object(aTHX_ scrolled_window_sizer, "Wx::BoxSizer"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_export_stl, "Wx::Button"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_reslice, "Wx::Button"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_print, "Wx::Button"), - (wxButton *)wxPli_sv_2_object(aTHX_ btn_send_gcode, "Wx::Button"), - (wxButton *)wxPli_sv_2_object(aTHX_ btn_export_gcode, "Wx::Button")); %}; + (wxButton *)wxPli_sv_2_object(aTHX_ btn_send_gcode, "Wx::Button")); %}; +void set_show_print_info(bool show) + %code%{ Slic3r::GUI::set_show_print_info(show); %}; std::string fold_utf8_to_ascii(const char *src) %code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %}; From 876cf9aa8bb89ce977d6d4a6463a783fcb79d079 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 18 May 2018 11:39:49 +0200 Subject: [PATCH 011/119] Show/hide warning icon according to the view mode --- lib/Slic3r/GUI/Plater.pm | 34 +++++++++++++++++++++++++--------- xs/src/slic3r/GUI/GUI.cpp | 12 +++++++++++- xs/src/slic3r/GUI/GUI.hpp | 5 ++++- xs/xsp/GUI.xsp | 9 +++++++-- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index ebb561a9e..5a3c1bb9f 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -442,7 +442,16 @@ sub new { $self->{"object_info_$field"}->SetFont($Slic3r::GUI::small_font); if ($field eq 'manifold') { $self->{object_info_manifold_warning_icon} = Wx::StaticBitmap->new($scrolled_window_panel, -1, Wx::Bitmap->new(Slic3r::var("error.png"), wxBITMAP_TYPE_PNG)); - $self->{object_info_manifold_warning_icon}->Hide; + #$self->{object_info_manifold_warning_icon}->Hide; + $self->{"object_info_manifold_warning_icon_show"} = sub { + if ($self->{object_info_manifold_warning_icon}->IsShown() != $_[0]) { + Slic3r::GUI::set_show_manifold_warning_icon($_[0]); + return if (wxTheApp->{app_config}->get("view_mode") eq "simple"); + $self->{object_info_manifold_warning_icon}->Show($_[0]); + $self->Layout + } + }; + $self->{"object_info_manifold_warning_icon_show"}->(0); my $h_sizer = Wx::BoxSizer->new(wxHORIZONTAL); $h_sizer->Add($self->{object_info_manifold_warning_icon}, 0); @@ -511,10 +520,7 @@ sub new { # } if ($scrolled_window_sizer->IsShown(2) != $_[0]) { Slic3r::GUI::set_show_print_info($_[0]); - my $mode = wxTheApp->{app_config}->get("view_mode"); - printf $mode."\n"; - return if ($mode eq "simple"); - print "non-simple\n"; + return if (wxTheApp->{app_config}->get("view_mode") eq "simple"); $scrolled_window_sizer->Show(2, $_[0]); $scrolled_window_panel->Layout } @@ -542,7 +548,8 @@ sub new { $self->{btn_export_stl}, $self->{btn_reslice}, $self->{btn_print}, - $self->{btn_send_gcode} ); + $self->{btn_send_gcode}, + $self->{object_info_manifold_warning_icon} ); } # Last correct selected item for each preset @@ -881,6 +888,9 @@ sub remove { $self->select_object(undef); $self->update; $self->schedule_background_process; + + # Hide the slicing results if the current slicing status is no more valid. + $self->{"print_info_box_show"}->(0); } sub reset { @@ -900,6 +910,9 @@ sub reset { $self->select_object(undef); $self->update; + + # Hide the slicing results if the current slicing status is no more valid. + $self->{"print_info_box_show"}->(0); } sub increase { @@ -2017,7 +2030,8 @@ sub selection_changed { $self->{object_info_facets}->SetLabel(sprintf(L('%d (%d shells)'), $model_object->facets_count, $stats->{number_of_parts})); if (my $errors = sum(@$stats{qw(degenerate_facets edges_fixed facets_removed facets_added facets_reversed backwards_edges)})) { $self->{object_info_manifold}->SetLabel(sprintf(L("Auto-repaired (%d errors)"), $errors)); - $self->{object_info_manifold_warning_icon}->Show; + #$self->{object_info_manifold_warning_icon}->Show; + $self->{"object_info_manifold_warning_icon_show"}->(1); # we don't show normals_fixed because we never provide normals # to admesh, so it generates normals for all facets @@ -2027,14 +2041,16 @@ sub selection_changed { $self->{object_info_manifold_warning_icon}->SetToolTipString($message); } else { $self->{object_info_manifold}->SetLabel(L("Yes")); - $self->{object_info_manifold_warning_icon}->Hide; + #$self->{object_info_manifold_warning_icon}->Hide; + $self->{"object_info_manifold_warning_icon_show"}->(0); } } else { $self->{object_info_facets}->SetLabel($object->facets); } } else { $self->{"object_info_$_"}->SetLabel("") for qw(size volume facets materials manifold); - $self->{object_info_manifold_warning_icon}->Hide; + #$self->{object_info_manifold_warning_icon}->Hide; + $self->{"object_info_manifold_warning_icon_show"}->(0); $self->{object_info_manifold}->SetToolTipString(""); } $self->Layout; diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 09ede75be..abdeb6c72 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -210,7 +210,9 @@ wxButton *g_btn_export_stl = nullptr; wxButton *g_btn_reslice = nullptr; wxButton *g_btn_print = nullptr; wxButton *g_btn_send_gcode = nullptr; +wxStaticBitmap *g_manifold_warning_icon = nullptr; bool g_show_print_info = false; +bool g_show_manifold_warning_icon = false; static void init_label_colours() { @@ -274,7 +276,8 @@ void set_preset_updater(PresetUpdater *updater) void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_parameters_sizer, wxBoxSizer *expert_mode_part_sizer, wxBoxSizer *scrolled_window_sizer, wxButton *btn_export_stl, wxButton *btn_reslice, - wxButton *btn_print, wxButton *btn_send_gcode) + wxButton *btn_print, wxButton *btn_send_gcode, + wxStaticBitmap *manifold_warning_icon) { g_plater = parent; g_frequently_changed_parameters_sizer = frequently_changed_parameters_sizer; @@ -284,6 +287,7 @@ void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_par g_btn_reslice = btn_reslice; g_btn_print = btn_print; g_btn_send_gcode = btn_send_gcode; + g_manifold_warning_icon = manifold_warning_icon; } void set_show_print_info(bool show) @@ -291,6 +295,11 @@ void set_show_print_info(bool show) g_show_print_info = show; } +void set_show_manifold_warning_icon(bool show) +{ + g_show_manifold_warning_icon = show; +} + std::vector& get_tabs_list() { return g_tabs_list; @@ -1122,6 +1131,7 @@ void show_scrolled_window_sizer(bool show) g_scrolled_window_sizer->Show(static_cast(0), show); g_scrolled_window_sizer->Show(1, show); g_scrolled_window_sizer->Show(2, show && g_show_print_info); + g_manifold_warning_icon->Show(show && g_show_manifold_warning_icon); } void update_mode() diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 1cca99319..4fd8b800a 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -20,6 +20,7 @@ class wxBoxSizer; class wxFlexGridSizer; class wxButton; class wxFileDialog; +class wxStaticBitmap; namespace Slic3r { @@ -86,8 +87,10 @@ void set_objects_from_perl( wxWindow* parent, wxButton *btn_export_stl, wxButton *btn_reslice, wxButton *btn_print, - wxButton *btn_send_gcode); + wxButton *btn_send_gcode, + wxStaticBitmap *manifold_warning_icon); void set_show_print_info(bool show); +void set_show_manifold_warning_icon(bool show); AppConfig* get_app_config(); wxApp* get_app(); diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index b402ab656..6dcb4a6ab 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -97,7 +97,8 @@ void set_objects_from_perl( SV *ui_parent, SV *btn_export_stl, SV *btn_reslice, SV *btn_print, - SV *btn_send_gcode) + SV *btn_send_gcode, + SV *manifold_warning_icon) %code%{ Slic3r::GUI::set_objects_from_perl( (wxWindow *)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), (wxBoxSizer *)wxPli_sv_2_object(aTHX_ frequently_changed_parameters_sizer, "Wx::BoxSizer"), @@ -106,11 +107,15 @@ void set_objects_from_perl( SV *ui_parent, (wxButton *)wxPli_sv_2_object(aTHX_ btn_export_stl, "Wx::Button"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_reslice, "Wx::Button"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_print, "Wx::Button"), - (wxButton *)wxPli_sv_2_object(aTHX_ btn_send_gcode, "Wx::Button")); %}; + (wxButton *)wxPli_sv_2_object(aTHX_ btn_send_gcode, "Wx::Button"), + (wxStaticBitmap *)wxPli_sv_2_object(aTHX_ manifold_warning_icon, "Wx::StaticBitmap")); %}; void set_show_print_info(bool show) %code%{ Slic3r::GUI::set_show_print_info(show); %}; +void set_show_manifold_warning_icon(bool show) + %code%{ Slic3r::GUI::set_show_manifold_warning_icon(show); %}; + std::string fold_utf8_to_ascii(const char *src) %code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %}; From bd2371cb03ff69a0d2fc87e9c9653d91c07caf5f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 18 May 2018 12:16:15 +0200 Subject: [PATCH 012/119] Right column of the Plater is passed to own panel to be able be updated separately from whole Plater panel --- lib/Slic3r/GUI/Plater.pm | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 5a3c1bb9f..e57c2267a 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -225,9 +225,12 @@ sub new { $self->{btoolbar}->Add($self->{"btn_layer_editing"}); } + ### Panel for right column + $self->{right_panel} = Wx::Panel->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + ### Scrolled Window for info boxes my $scrolled_window_sizer = Wx::BoxSizer->new(wxVERTICAL); - my $scrolled_window_panel = Wx::ScrolledWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + my $scrolled_window_panel = Wx::ScrolledWindow->new($self->{right_panel}, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); $scrolled_window_panel->SetSizer($scrolled_window_sizer); $scrolled_window_panel->SetScrollbars(1, 1, 1, 1); @@ -249,11 +252,11 @@ sub new { }); # right pane buttons - $self->{btn_export_gcode} = Wx::Button->new($self, -1, L("Export G-code…"), wxDefaultPosition, [-1, 30], wxBU_LEFT); - $self->{btn_reslice} = Wx::Button->new($self, -1, L("Slice now"), wxDefaultPosition, [-1, 30], wxBU_LEFT); - $self->{btn_print} = Wx::Button->new($self, -1, L("Print…"), wxDefaultPosition, [-1, 30], wxBU_LEFT); - $self->{btn_send_gcode} = Wx::Button->new($self, -1, L("Send to printer"), wxDefaultPosition, [-1, 30], wxBU_LEFT); - $self->{btn_export_stl} = Wx::Button->new($self, -1, L("Export STL…"), wxDefaultPosition, [-1, 30], wxBU_LEFT); + $self->{btn_export_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Export G-code…"), wxDefaultPosition, [-1, 30], wxBU_LEFT); + $self->{btn_reslice} = Wx::Button->new($self->{right_panel}, -1, L("Slice now"), wxDefaultPosition, [-1, 30], wxBU_LEFT); + $self->{btn_print} = Wx::Button->new($self->{right_panel}, -1, L("Print…"), wxDefaultPosition, [-1, 30], wxBU_LEFT); + $self->{btn_send_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Send to printer"), wxDefaultPosition, [-1, 30], wxBU_LEFT); + $self->{btn_export_stl} = Wx::Button->new($self->{right_panel}, -1, L("Export STL…"), wxDefaultPosition, [-1, 30], wxBU_LEFT); #$self->{btn_export_gcode}->SetFont($Slic3r::GUI::small_font); #$self->{btn_export_stl}->SetFont($Slic3r::GUI::small_font); $self->{btn_print}->Hide; @@ -390,9 +393,9 @@ sub new { # $self->{preset_choosers}{$group}[$idx] $self->{preset_choosers} = {}; for my $group (qw(print filament printer)) { - my $text = Wx::StaticText->new($self, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + my $text = Wx::StaticText->new($self->{right_panel}, -1, "$group_labels{$group}:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); $text->SetFont($Slic3r::GUI::small_font); - my $choice = Wx::BitmapComboBox->new($self, -1, "", wxDefaultPosition, wxDefaultSize, [], wxCB_READONLY); + my $choice = Wx::BitmapComboBox->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [], wxCB_READONLY); if ($group eq 'filament') { EVT_LEFT_DOWN($choice, sub { $self->filament_color_box_lmouse_down(0, @_); } ); } @@ -410,9 +413,9 @@ sub new { } my $frequently_changed_parameters_sizer = Wx::BoxSizer->new(wxVERTICAL); - Slic3r::GUI::add_frequently_changed_parameters($self, $frequently_changed_parameters_sizer, $presets); + Slic3r::GUI::add_frequently_changed_parameters($self->{right_panel}, $frequently_changed_parameters_sizer, $presets); my $expert_mode_part_sizer = Wx::BoxSizer->new(wxVERTICAL); - Slic3r::GUI::add_expert_mode_part($self, $expert_mode_part_sizer); + Slic3r::GUI::add_expert_mode_part($self->{right_panel}, $expert_mode_part_sizer); my $object_info_sizer; { @@ -528,9 +531,13 @@ sub new { # Show the box initially, let it be shown after the slicing is finished. $self->{"print_info_box_show"}->(0); + $right_sizer->SetSizeHints($self->{right_panel}); + $self->{right_panel}->SetSizer($right_sizer); + my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL); $hsizer->Add($self->{preview_notebook}, 1, wxEXPAND | wxTOP, 1); - $hsizer->Add($right_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, 3); + $hsizer->Add($self->{right_panel}, 0, wxEXPAND | wxLEFT | wxRIGHT, 3); + #$hsizer->Add($right_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT, 3); my $sizer = Wx::BoxSizer->new(wxVERTICAL); $sizer->Add($self->{htoolbar}, 0, wxEXPAND, 0) if $self->{htoolbar}; @@ -2004,7 +2011,7 @@ sub selection_changed { my ($obj_idx, $object) = $self->selected_object; my $have_sel = defined $obj_idx; - $self->Freeze; + $self->{right_panel}->Freeze; if ($self->{htoolbar}) { # On OSX or Linux $self->{htoolbar}->EnableTool($_, $have_sel) @@ -2058,7 +2065,7 @@ sub selection_changed { # prepagate the event to the frame (a custom Wx event would be cleaner) $self->GetFrame->on_plater_selection_changed($have_sel); - $self->Thaw; + $self->{right_panel}->Thaw; } sub select_object { From 622c613b410fd0f8ac82b78ae577194f9e1c3607 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 21 May 2018 14:49:31 +0200 Subject: [PATCH 013/119] Update of the view mode works correctly --- lib/Slic3r/GUI/MainFrame.pm | 2 ++ lib/Slic3r/GUI/Plater.pm | 7 ++++--- lib/Slic3r/GUI/Plater/3D.pm | 2 +- xs/src/slic3r/GUI/GUI.cpp | 9 ++++----- xs/src/slic3r/GUI/GUI.hpp | 2 ++ xs/src/slic3r/GUI/Tab.cpp | 16 ++++++++++------ xs/xsp/GUI.xsp | 3 +++ 7 files changed, 26 insertions(+), 15 deletions(-) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index fbcd34a3f..51f5911f0 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -96,6 +96,8 @@ sub new { $self->update_ui_from_settings; + Slic3r::GUI::update_mode(); + return $self; } diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index e57c2267a..5bd4587bb 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -449,7 +449,8 @@ sub new { $self->{"object_info_manifold_warning_icon_show"} = sub { if ($self->{object_info_manifold_warning_icon}->IsShown() != $_[0]) { Slic3r::GUI::set_show_manifold_warning_icon($_[0]); - return if (wxTheApp->{app_config}->get("view_mode") eq "simple"); + my $mode = wxTheApp->{app_config}->get("view_mode"); + return if ($mode eq "" || $mode eq "simple"); $self->{object_info_manifold_warning_icon}->Show($_[0]); $self->Layout } @@ -548,7 +549,7 @@ sub new { $self->SetSizer($sizer); # Send sizers/buttons to C++ - Slic3r::GUI::set_objects_from_perl( $self, + Slic3r::GUI::set_objects_from_perl( $self->{right_panel}, $frequently_changed_parameters_sizer, $expert_mode_part_sizer, $scrolled_window_sizer, @@ -1767,7 +1768,7 @@ sub on_extruders_change { my @presets = $choices->[0]->GetStrings; # initialize new choice - my $choice = Wx::BitmapComboBox->new($self, -1, "", wxDefaultPosition, wxDefaultSize, [@presets], wxCB_READONLY); + my $choice = Wx::BitmapComboBox->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, [@presets], wxCB_READONLY); my $extruder_idx = scalar @$choices; EVT_LEFT_DOWN($choice, sub { $self->filament_color_box_lmouse_down($extruder_idx, @_); } ); push @$choices, $choice; diff --git a/lib/Slic3r/GUI/Plater/3D.pm b/lib/Slic3r/GUI/Plater/3D.pm index c9c954276..c3521a4da 100644 --- a/lib/Slic3r/GUI/Plater/3D.pm +++ b/lib/Slic3r/GUI/Plater/3D.pm @@ -245,7 +245,7 @@ sub reload_scene { $self->set_warning_enabled(0); $self->volumes->update_outside_state($self->{config}, 1); Slic3r::GUI::_3DScene::reset_warning_texture(); - $self->on_enable_action_buttons->(1) if ($self->on_enable_action_buttons); + $self->on_enable_action_buttons->(scalar @{$self->{model}->objects} > 0) if ($self->on_enable_action_buttons); } } else { $self->set_warning_enabled(0); diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index abdeb6c72..1fc02ed1f 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -202,7 +202,7 @@ double m_brim_width = 0.0; wxButton* g_wiping_dialog_button = nullptr; //showed/hided controls according to the view mode -wxWindow *g_plater = nullptr; +wxWindow *g_right_panel = nullptr; wxBoxSizer *g_frequently_changed_parameters_sizer = nullptr; wxBoxSizer *g_expert_mode_part_sizer = nullptr; wxBoxSizer *g_scrolled_window_sizer = nullptr; @@ -279,7 +279,7 @@ void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_par wxButton *btn_print, wxButton *btn_send_gcode, wxStaticBitmap *manifold_warning_icon) { - g_plater = parent; + g_right_panel = parent; g_frequently_changed_parameters_sizer = frequently_changed_parameters_sizer; g_expert_mode_part_sizer = expert_mode_part_sizer; g_scrolled_window_sizer = scrolled_window_sizer; @@ -616,7 +616,6 @@ void create_preset_tabs(bool no_controller, int event_value_change, int event_pr tab->set_event_value_change(wxEventType(event_value_change)); tab->set_event_presets_changed(wxEventType(event_presets_changed)); } - update_mode();// TODO change place of call this function } TabIface* get_preset_tab_iface(char *name) @@ -1136,14 +1135,14 @@ void show_scrolled_window_sizer(bool show) void update_mode() { - wxWindowUpdateLocker noUpdates(g_plater); + wxWindowUpdateLocker noUpdates(g_right_panel); ConfigMenuIDs mode = get_view_mode(); show_frequently_changed_parameters(mode >= ConfigMenuModeRegular); g_expert_mode_part_sizer->Show(mode == ConfigMenuModeExpert); show_scrolled_window_sizer(mode >= ConfigMenuModeRegular); show_buttons(mode >= ConfigMenuModeRegular); - g_plater->Layout(); + g_right_panel->Layout(); } ConfigOptionsGroup* get_optgroup() diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 4fd8b800a..5f89d8b66 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -142,6 +142,8 @@ void save_language(); void get_installed_languages(wxArrayString & names, wxArrayLong & identifiers); // select language from the list of installed languages bool select_language(wxArrayString & names, wxArrayLong & identifiers); +// update right panel of the Plater according to view mode +void update_mode(); std::vector& get_tabs_list(); bool checked_tab(Tab* tab); diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 5a47dd1e7..21c85925d 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -705,13 +705,17 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) // Show/hide the 'purging volumes' button void Tab::update_wiping_button_visibility() { - bool wipe_tower_enabled = dynamic_cast( (m_preset_bundle->prints.get_edited_preset().config ).option("wipe_tower"))->value; - bool multiple_extruders = dynamic_cast((m_preset_bundle->printers.get_edited_preset().config).option("nozzle_diameter"))->values.size() > 1; - bool single_extruder_mm = dynamic_cast( (m_preset_bundle->printers.get_edited_preset().config).option("single_extruder_multi_material"))->value; + if (!get_app_config()->has("view_mode") || get_app_config()->get("view_mode") == "simple") + get_wiping_dialog_button()->Hide(); + else { + bool wipe_tower_enabled = dynamic_cast((m_preset_bundle->prints.get_edited_preset().config).option("wipe_tower"))->value; + bool multiple_extruders = dynamic_cast((m_preset_bundle->printers.get_edited_preset().config).option("nozzle_diameter"))->values.size() > 1; + bool single_extruder_mm = dynamic_cast((m_preset_bundle->printers.get_edited_preset().config).option("single_extruder_multi_material"))->value; - if (wipe_tower_enabled && multiple_extruders && single_extruder_mm) - get_wiping_dialog_button()->Show(); - else get_wiping_dialog_button()->Hide(); + if (wipe_tower_enabled && multiple_extruders && single_extruder_mm) + get_wiping_dialog_button()->Show(); + else get_wiping_dialog_button()->Hide(); + } (get_wiping_dialog_button()->GetParent())->Layout(); } diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 6dcb4a6ab..aca60d0f8 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -116,6 +116,9 @@ void set_show_print_info(bool show) void set_show_manifold_warning_icon(bool show) %code%{ Slic3r::GUI::set_show_manifold_warning_icon(show); %}; +void update_mode() + %code%{ Slic3r::GUI::update_mode(); %}; + std::string fold_utf8_to_ascii(const char *src) %code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %}; From 6e2d72f35cb10a8af3532d3af43af4d9b96d2b48 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 22 May 2018 08:41:33 +0200 Subject: [PATCH 014/119] Billet for the part of the expert view mode --- xs/src/slic3r/GUI/GUI.cpp | 92 ++++++++++++++++++------------ xs/src/slic3r/GUI/GUI.hpp | 5 ++ xs/src/slic3r/GUI/OptionsGroup.cpp | 8 +-- xs/src/slic3r/GUI/OptionsGroup.hpp | 6 +- 4 files changed, 67 insertions(+), 44 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 1fc02ed1f..c49cccc3d 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -886,35 +886,28 @@ wxString from_u8(const std::string &str) return wxString::FromUTF8(str.c_str()); } - -void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) +// add PrusaCollapsiblePane to sizer +void add_prusa_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, const wxString& name, std::function content_function) { - sizer->SetMinSize(-1, 150); - auto main_sizer = new wxBoxSizer(wxVERTICAL); - auto main_page = new wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - main_page->SetSizer(main_sizer); - main_page->SetScrollbars(1, 1, 1, 1); - sizer->Add(main_page, 1, wxEXPAND | wxALL, 1); - - // Experiments with new UI -// wxSizer *paneSz = new wxBoxSizer(wxVERTICAL); -// paneSz->Add(m_optgroup->sizer, 1, wxGROW | wxEXPAND | wxLEFT | wxRIGHT, 5); -// win->SetSizer(paneSz); -// paneSz->SetSizeHints(win); - - // *** Objects List *** - auto *collpane_objects = new PrusaCollapsiblePane(main_page, wxID_ANY, "Objects List:"); + auto *collpane = new PrusaCollapsiblePane(parent, wxID_ANY, name); // add the pane with a zero proportion value to the sizer which contains it - main_sizer->Add(collpane_objects, 0, wxGROW | wxALL, 0); + sizer_parent->Add(collpane, 0, wxGROW | wxALL, 0); - wxWindow *win_objects = collpane_objects->GetPane(); + wxWindow *win = collpane->GetPane(); - // ********************************************************************************************** - auto objects_ctrl = new wxDataViewCtrl(win_objects, wxID_ANY, wxDefaultPosition, wxDefaultSize); - wxSizer *objects_sz = new wxBoxSizer(wxVERTICAL); - objects_ctrl->SetBestFittingSize(wxSize(-1, 200)); - // TODO - Set correct height according to the opened/closed objects -// objects_ctrl->SetMinSize(wxSize(-1, 200)); + wxSizer *sizer = content_function(win); + + wxSizer *sizer_pane = new wxBoxSizer(wxVERTICAL); + sizer_pane->Add(sizer, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); + win->SetSizer(sizer_pane); + sizer_pane->SetSizeHints(win); +} + +wxBoxSizer* content_objects_list(wxWindow *win) +{ + auto objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); + objects_ctrl->SetBestFittingSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects + auto objects_sz = new wxBoxSizer(wxVERTICAL); objects_sz->Add(objects_ctrl, 1, wxGROW | wxALL, 5); auto objects_model = new MyObjectTreeModel; @@ -945,19 +938,44 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); objects_ctrl->AppendColumn(column02); -// common_sizer->Add(objects_sz, 0, wxEXPAND | wxALL, 1); + return objects_sz; +} - wxSizer *paneSz_objects = new wxBoxSizer(wxVERTICAL); - paneSz_objects->Add(objects_sz, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); - win_objects->SetSizer(paneSz_objects); - paneSz_objects->SetSizeHints(win_objects); +wxBoxSizer* content_object_settings(wxWindow *win) +{ + auto sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(new wxStaticText(win, wxID_ANY, "Some object text")); + return sizer; +} + +wxBoxSizer* content_part_settings(wxWindow *win) +{ + auto sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(new wxStaticText(win, wxID_ANY, "Some part text")); + return sizer; +} + +void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) +{ + sizer->SetMinSize(-1, 150); + auto main_sizer = new wxBoxSizer(wxVERTICAL); + auto main_page = new wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + main_page->SetSizer(main_sizer); + main_page->SetScrollbars(1, 1, 1, 1); + sizer->Add(main_page, 1, wxEXPAND | wxALL, 1); + + // Experiments with new UI + + // *** Objects List *** + add_prusa_collapsible_pane(main_page, main_sizer, "Objects List:", content_objects_list); + // *** Object Settings *** + add_prusa_collapsible_pane(main_page, main_sizer, "Object Settings:", content_object_settings); + // *** Part Settings *** + add_prusa_collapsible_pane(main_page, main_sizer, "Part Settings:", content_part_settings); - -// auto common_sizer = new wxBoxSizer(wxVERTICAL); -// common_sizer->Add(m_optgroup->sizer); - -// auto listctrl = new wxDataViewListCtrl(win, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); + // More experiments with UI +// auto listctrl = new wxDataViewListCtrl(main_page, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); // listctrl->AppendToggleColumn("Toggle"); // listctrl->AppendTextColumn("Text"); // wxVector data; @@ -972,9 +990,7 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) // data.push_back(wxVariant(false)); // data.push_back(wxVariant("row 2")); // listctrl->AppendItem(data); -// common_sizer->Add(listctrl, 0, wxEXPAND | wxALL, 1); - - +// main_sizer->Add(listctrl, 0, wxEXPAND | wxALL, 1); } void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer) diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 5f89d8b66..2b3c96821 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -47,6 +47,11 @@ class TabIface; namespace GUI { +enum ogDrawFlag{ + ogDEFAULT, + ogSIDE_OPTIONS_TO_GRID +}; + class Tab; class ConfigOptionsGroup; // Map from an file_type name to full file wildcard name. diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index 40176a000..dcb73f5cf 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -173,7 +173,9 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* return; } - // if we have a single option with no sidetext just add it directly to the grid sizer + // If we're here, we have more than one option or a single option with sidetext + // so we need a horizontal sizer to arrange these things + // If we have a single option with no sidetext just add it directly to the grid sizer auto sizer = new wxBoxSizer(wxHORIZONTAL); grid_sizer->Add(sizer, 0, wxEXPAND | wxALL, 0); if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 && @@ -190,9 +192,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* return; } - // if we're here, we have more than one option or a single option with sidetext - // so we need a horizontal sizer to arrange these things - for (auto opt : option_set) { + for (auto opt : option_set) { ConfigOptionDef option = opt.opt; // add label if any if (option.label != "") { diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index 55a8dc70b..7da39dbf9 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -127,8 +127,8 @@ public: inline void enable() { for (auto& field : m_fields) field.second->enable(); } inline void disable() { for (auto& field : m_fields) field.second->disable(); } - OptionsGroup(wxWindow* _parent, const wxString& title, bool is_tab_opt=false) : - m_parent(_parent), title(title), m_is_tab_opt(is_tab_opt), staticbox(title!="") { + OptionsGroup(wxWindow* _parent, const wxString& title, bool is_tab_opt=false, ogDrawFlag flag = ogDEFAULT) : + m_parent(_parent), title(title), m_is_tab_opt(is_tab_opt), staticbox(title!=""), m_flag(flag) { sizer = (staticbox ? new wxStaticBoxSizer(new wxStaticBox(_parent, wxID_ANY, title), wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); auto num_columns = 1U; if (label_width != 0) num_columns++; @@ -158,6 +158,8 @@ protected: // "true" if option is created in preset tabs bool m_is_tab_opt{ false }; + ogDrawFlag m_flag{ ogDEFAULT }; + // This panel is needed for correct showing of the ToolTips for Button, StaticText and CheckBox // Tooltips on GTK doesn't work inside wxStaticBoxSizer unless you insert a panel // inside it before you insert the other controls. From ec5b98477d2773a24d237491c9bec63befe9f005 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 22 May 2018 16:14:41 +0200 Subject: [PATCH 015/119] Filled content_object_settings --- xs/src/slic3r/GUI/GUI.cpp | 68 ++++++++++++++++++++++-------- xs/src/slic3r/GUI/GUI.hpp | 9 ++-- xs/src/slic3r/GUI/OptionsGroup.cpp | 4 +- xs/src/slic3r/GUI/OptionsGroup.hpp | 9 +++- xs/src/slic3r/GUI/Tab.cpp | 16 +++---- 5 files changed, 73 insertions(+), 33 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 1af1ce541..511e7edd1 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -118,8 +118,8 @@ std::vector g_tabs_list; wxLocale* g_wxLocale; -std::shared_ptr m_optgroup; -double m_brim_width = 0.0; +std::vector > m_optgroups; +double m_brim_width = 0.0; wxButton* g_wiping_dialog_button = nullptr; //showed/hided controls according to the view mode @@ -379,8 +379,7 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l // local_menu->Append(config_id_base + ConfigMenuUpdate, _(L("Check for updates")), _(L("Check for configuration updates"))); local_menu->AppendSeparator(); local_menu->Append(config_id_base + ConfigMenuPreferences, _(L("Preferences"))+"\u2026\tCtrl+,", _(L("Application preferences"))); - local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application Language"))); - local_menu->AppendSeparator(); + local_menu->AppendSeparator(); auto mode_menu = new wxMenu(); mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _(L("&Simple")), _(L("Simple View Mode"))); mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeRegular, _(L("&Regular")), _(L("Regular View Mode"))); @@ -389,6 +388,11 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l local_menu->AppendSubMenu(mode_menu, _(L("&Mode")), _(L("Slic3r View Mode"))); local_menu->AppendSeparator(); local_menu->Append(config_id_base + ConfigMenuLanguage, _(L("Change Application Language"))); + local_menu->AppendSeparator(); + local_menu->Append(config_id_base + ConfigMenuFlashFirmware, _(L("Flash printer firmware")), _(L("Upload a firmware image into an Arduino based printer"))); + // TODO: for when we're able to flash dictionaries + // local_menu->Append(config_id_base + FirmwareMenuDict, _(L("Flash language file")), _(L("Upload a language dictionary file into a Prusa printer"))); + local_menu->Bind(wxEVT_MENU, [config_id_base, event_language_change, event_preferences_changed](wxEvent &event){ switch (event.GetId() - config_id_base) { case ConfigMenuWizard: @@ -876,8 +880,36 @@ wxBoxSizer* content_objects_list(wxWindow *win) wxBoxSizer* content_object_settings(wxWindow *win) { + DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config; + std::shared_ptr optgroup = std::make_shared(win, "", config, false, ogSIDE_OPTIONS_VERTICAL); + optgroup->label_width = 100; + + Line line = { _(L("Position")), "" }; + ConfigOptionDef def; + + def.label = L("X"); + def.type = coInt; + def.default_value = new ConfigOptionInt(1); + def.sidetext = L("mm"); + + Option option = Option(def, "position_X"); + option.opt.full_width = true; + line.append_option(option); + + def.label = L("Y"); + option = Option(def, "position_Y"); + line.append_option(option); + + def.label = L("Z"); + option = Option(def, "position_Z"); + line.append_option(option); + + optgroup->append_line(line); + + m_optgroups.push_back(optgroup); // ogObjectSettings + auto sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(new wxStaticText(win, wxID_ANY, "Some object text")); + sizer->Add(optgroup->sizer, 1, wxEXPAND | wxBOTTOM, 2); return sizer; } @@ -929,10 +961,10 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer) { DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config; - m_optgroup = std::make_shared(parent, "", config); + std::shared_ptr optgroup = std::make_shared(parent, "", config); const wxArrayInt& ar = preset_sizer->GetColWidths(); - m_optgroup->label_width = ar.IsEmpty() ? 100 : ar.front()-4; // doesn't work - m_optgroup->m_on_change = [config](t_config_option_key opt_key, boost::any value){ + optgroup->label_width = ar.IsEmpty() ? 100 : ar.front()-4; // doesn't work + optgroup->m_on_change = [config](t_config_option_key opt_key, boost::any value){ TabPrint* tab_print = nullptr; for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) { Tab *tab = dynamic_cast(g_wxTabPanel->GetPage(i)); @@ -947,7 +979,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl return; if (opt_key == "fill_density"){ - value = m_optgroup->get_config_value(*config, opt_key); + value = m_optgroups[ogFrequentlyChangingParameters]->get_config_value(*config, opt_key); tab_print->set_value(opt_key, value); tab_print->update(); } @@ -985,10 +1017,10 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl tab_print->update_dirty(); }; - Option option = m_optgroup->get_option("fill_density"); + Option option = optgroup->get_option("fill_density"); option.opt.sidetext = ""; option.opt.full_width = true; - m_optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); ConfigOptionDef def; @@ -1007,7 +1039,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl def.default_value = new ConfigOptionStrings { selection }; option = Option(def, "support"); option.opt.full_width = true; - m_optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); m_brim_width = config->opt_float("brim_width"); def.label = L("Brim"); @@ -1016,7 +1048,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl def.gui_type = ""; def.default_value = new ConfigOptionBool{ m_brim_width > 0.0 ? true : false }; option = Option(def, "brim"); - m_optgroup->append_single_option_line(option); + optgroup->append_single_option_line(option); Line line = { "", "" }; @@ -1041,9 +1073,11 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl })); return sizer; }; - m_optgroup->append_line(line); + optgroup->append_line(line); - sizer->Add(m_optgroup->sizer, 1, wxEXPAND | wxBOTTOM, 2); + sizer->Add(optgroup->sizer, 1, wxEXPAND | wxBOTTOM, 2); + + m_optgroups.push_back(optgroup);// ogFrequentlyChangingParameters } void show_frequently_changed_parameters(bool show) @@ -1094,9 +1128,9 @@ void update_mode() g_right_panel->Layout(); } -ConfigOptionsGroup* get_optgroup() +ConfigOptionsGroup* get_optgroup(size_t i) { - return m_optgroup.get(); + return m_optgroups[i].get(); } diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 3681827b6..243c63cc3 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -47,9 +47,10 @@ class TabIface; namespace GUI { -enum ogDrawFlag{ - ogDEFAULT, - ogSIDE_OPTIONS_TO_GRID +enum ogGroup{ + ogFrequentlyChangingParameters, + ogObjectSettings, + ogPartSettings }; class Tab; @@ -173,7 +174,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl // Update view mode according to selected menu void update_mode(); -ConfigOptionsGroup* get_optgroup(); +ConfigOptionsGroup* get_optgroup(size_t i); wxButton* get_wiping_dialog_button(); void add_export_option(wxFileDialog* dlg, const std::string& format); diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index e17315802..052bf6e6c 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -175,9 +175,9 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* // If we're here, we have more than one option or a single option with sidetext // so we need a horizontal sizer to arrange these things - // If we have a single option with no sidetext just add it directly to the grid sizer - auto sizer = new wxBoxSizer(wxHORIZONTAL); + auto sizer = new wxBoxSizer((m_flag & ogSIDE_OPTIONS_VERTICAL) != 0 ? wxVERTICAL :wxHORIZONTAL); grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM|wxTOP|wxLEFT), staticbox ? 0 : 1); + // If we have a single option with no sidetext just add it directly to the grid sizer if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr && line.get_extra_widgets().size() == 0) { const auto& option = option_set.front(); diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index 7da39dbf9..d302fa1ec 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -26,6 +26,11 @@ namespace Slic3r { namespace GUI { +enum ogDrawFlag{ + ogDEFAULT, + ogSIDE_OPTIONS_VERTICAL +}; + /// Widget type describes a function object that returns a wxWindow (our widget) and accepts a wxWidget (parent window). using widget_t = std::function;//!std::function; using column_t = std::function; @@ -183,8 +188,8 @@ protected: class ConfigOptionsGroup: public OptionsGroup { public: - ConfigOptionsGroup(wxWindow* parent, const wxString& title, DynamicPrintConfig* _config = nullptr, bool is_tab_opt = false) : - OptionsGroup(parent, title, is_tab_opt), m_config(_config) {} + ConfigOptionsGroup(wxWindow* parent, const wxString& title, DynamicPrintConfig* _config = nullptr, bool is_tab_opt = false, ogDrawFlag flag = ogDEFAULT) : + OptionsGroup(parent, title, is_tab_opt, flag), m_config(_config) {} /// reference to libslic3r config, non-owning pointer (?). DynamicPrintConfig* m_config {nullptr}; diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 52fc499d5..88a97c5c8 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -679,8 +679,8 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) } if (opt_key == "fill_density") { - boost::any val = get_optgroup()->get_config_value(*m_config, opt_key); - get_optgroup()->set_value(opt_key, val); + boost::any val = get_optgroup(ogFrequentlyChangingParameters)->get_config_value(*m_config, opt_key); + get_optgroup(ogFrequentlyChangingParameters)->set_value(opt_key, val); } if (opt_key == "support_material" || opt_key == "support_material_buildplate_only") { @@ -689,12 +689,12 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) m_config->opt_bool("support_material_buildplate_only") ? _("Support on build plate only") : _("Everywhere"); - get_optgroup()->set_value("support", new_selection); + get_optgroup(ogFrequentlyChangingParameters)->set_value("support", new_selection); } if (opt_key == "brim_width") { bool val = m_config->opt_float("brim_width") > 0.0 ? true : false; - get_optgroup()->set_value("brim", val); + get_optgroup(ogFrequentlyChangingParameters)->set_value("brim", val); } if (opt_key == "wipe_tower" || opt_key == "single_extruder_multi_material" || opt_key == "extruders_count" ) @@ -784,18 +784,18 @@ void Tab::update_preset_description_line() void Tab::update_frequently_changed_parameters() { - boost::any value = get_optgroup()->get_config_value(*m_config, "fill_density"); - get_optgroup()->set_value("fill_density", value); + boost::any value = get_optgroup(ogFrequentlyChangingParameters)->get_config_value(*m_config, "fill_density"); + get_optgroup(ogFrequentlyChangingParameters)->set_value("fill_density", value); wxString new_selection = !m_config->opt_bool("support_material") ? _("None") : m_config->opt_bool("support_material_buildplate_only") ? _("Support on build plate only") : _("Everywhere"); - get_optgroup()->set_value("support", new_selection); + get_optgroup(ogFrequentlyChangingParameters)->set_value("support", new_selection); bool val = m_config->opt_float("brim_width") > 0.0 ? true : false; - get_optgroup()->set_value("brim", val); + get_optgroup(ogFrequentlyChangingParameters)->set_value("brim", val); update_wiping_button_visibility(); } From a877846699efa4b4b25144d3c53cb49935580022 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 23 May 2018 16:21:42 +0200 Subject: [PATCH 016/119] Filling object settings (continue) --- lib/Slic3r/GUI/Plater.pm | 4 +- xs/src/slic3r/GUI/GUI.cpp | 62 +++++++++++++++++++++++------- xs/src/slic3r/GUI/OptionsGroup.cpp | 24 +++++++----- xs/src/slic3r/GUI/OptionsGroup.hpp | 3 +- xs/src/slic3r/GUI/wxExtensions.hpp | 6 +-- 5 files changed, 69 insertions(+), 30 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 619af0510..eec9b304a 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -512,10 +512,10 @@ sub new { $scrolled_window_sizer->Add($print_info_sizer, 0, wxEXPAND, 0); my $right_sizer = Wx::BoxSizer->new(wxVERTICAL); - $right_sizer->SetMinSize([320, 600]); + $right_sizer->SetMinSize([320, -1]); $right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets; $right_sizer->Add($frequently_changed_parameters_sizer, 0, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; - $right_sizer->Add($expert_mode_part_sizer, 0, wxEXPAND | wxTOP, 0) if defined $expert_mode_part_sizer; + $right_sizer->Add($expert_mode_part_sizer, 1, wxEXPAND | wxTOP, 0) if defined $expert_mode_part_sizer; $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5); $right_sizer->Add($scrolled_window_panel, 1, wxEXPAND | wxALL, 1); # Callback for showing / hiding the print info box. diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index adb5eaf18..22554bba5 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -120,6 +120,7 @@ wxLocale* g_wxLocale; std::vector > m_optgroups; double m_brim_width = 0.0; +size_t m_label_width = 100; wxButton* g_wiping_dialog_button = nullptr; //showed/hided controls according to the view mode @@ -878,33 +879,66 @@ wxBoxSizer* content_objects_list(wxWindow *win) return objects_sz; } -wxBoxSizer* content_object_settings(wxWindow *win) +Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value=0) { - DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config; - std::shared_ptr optgroup = std::make_shared(win, "", config, false, ogSIDE_OPTIONS_VERTICAL); - optgroup->label_width = 100; - - Line line = { _(L("Position")), "" }; + Line line = { _(option_name), "" }; ConfigOptionDef def; def.label = L("X"); def.type = coInt; - def.default_value = new ConfigOptionInt(1); - def.sidetext = L("mm"); + def.default_value = new ConfigOptionInt(def_value); + def.sidetext = sidetext; + def.width = 50; - Option option = Option(def, "position_X"); + const std::string lower_name = boost::algorithm::to_lower_copy(option_name); + + Option option = Option(def, lower_name + "_X"); option.opt.full_width = true; line.append_option(option); def.label = L("Y"); - option = Option(def, "position_Y"); + option = Option(def, lower_name + "_Y"); line.append_option(option); def.label = L("Z"); - option = Option(def, "position_Z"); + option = Option(def, lower_name + "_Z"); line.append_option(option); + return line; +} - optgroup->append_line(line); +wxBoxSizer* content_object_settings(wxWindow *win) +{ + DynamicPrintConfig* config = /*&g_PresetBundle->full_config();*/&g_PresetBundle->prints.get_edited_preset().config; + std::shared_ptr optgroup = std::make_shared(win, "", config); + optgroup->label_width = m_label_width; + + ConfigOptionDef def; + def.label = L("Name"); + def.type = coString; + def.tooltip = L("Object name"); + def.full_width = true; + def.default_value = new ConfigOptionString{ "BlaBla_object.stl" }; + optgroup->append_single_option_line(Option(def, "object_name")); + + optgroup->set_flag(ogSIDE_OPTIONS_VERTICAL); + + optgroup->append_line(add_og_to_object_settings(L("Position"), L("mm"))); + optgroup->append_line(add_og_to_object_settings(L("Rotation"), "°"/*"\u00b0"*/, 1)); + optgroup->append_line(add_og_to_object_settings(L("Scale"), "%", 2)); + + optgroup->set_flag(ogDEFAULT); + + def.label = L("Place on bed"); + def.type = coBool; + def.tooltip = L("Automatic placing of models on printing bed in Y axis"); + def.gui_type = ""; + def.sidetext = ""; + def.default_value = new ConfigOptionBool{ false }; + optgroup->append_single_option_line(Option(def, "place_on_bed")); + + Option option = optgroup->get_option("extruder"); + option.opt.default_value = new ConfigOptionInt(1); + optgroup->append_single_option_line(option); m_optgroups.push_back(optgroup); // ogObjectSettings @@ -922,7 +956,6 @@ wxBoxSizer* content_part_settings(wxWindow *win) void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) { - sizer->SetMinSize(-1, 150); auto main_sizer = new wxBoxSizer(wxVERTICAL); auto main_page = new wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); main_page->SetSizer(main_sizer); @@ -963,7 +996,8 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config; std::shared_ptr optgroup = std::make_shared(parent, "", config); const wxArrayInt& ar = preset_sizer->GetColWidths(); - optgroup->label_width = ar.IsEmpty() ? 100 : ar.front()-4; // doesn't work + m_label_width = ar.IsEmpty() ? 100 : ar.front()-4; + optgroup->label_width = m_label_width; optgroup->m_on_change = [config](t_config_option_key opt_key, boost::any value){ TabPrint* tab_print = nullptr; for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) { diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index 052bf6e6c..55887da91 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -159,7 +159,8 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* wxDefaultPosition, wxSize(label_width, -1), staticbox ? 0 : wxALIGN_RIGHT); label->SetFont(label_font); label->Wrap(label_width); // avoid a Linux/GTK bug - grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5); + grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | + (m_flag == ogSIDE_OPTIONS_VERTICAL ? wxTOP : wxALIGN_CENTER_VERTICAL), 5); if (line.label_tooltip.compare("") != 0) label->SetToolTip(line.label_tooltip); } @@ -175,7 +176,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* // If we're here, we have more than one option or a single option with sidetext // so we need a horizontal sizer to arrange these things - auto sizer = new wxBoxSizer((m_flag & ogSIDE_OPTIONS_VERTICAL) != 0 ? wxVERTICAL :wxHORIZONTAL); + auto sizer = new wxBoxSizer(m_flag == ogSIDE_OPTIONS_VERTICAL ? wxVERTICAL : wxHORIZONTAL); grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM|wxTOP|wxLEFT), staticbox ? 0 : 1); // If we have a single option with no sidetext just add it directly to the grid sizer if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 && @@ -194,6 +195,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* for (auto opt : option_set) { ConfigOptionDef option = opt.opt; + wxBoxSizer* sizer_tmp = m_flag == ogSIDE_OPTIONS_VERTICAL ? new wxBoxSizer(wxHORIZONTAL) : sizer; // add label if any if (option.label != "") { wxString str_label = L_str(option.label); @@ -203,33 +205,35 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* // L_str(option.label); label = new wxStaticText(parent(), wxID_ANY, str_label + ":", wxDefaultPosition, wxDefaultSize); label->SetFont(label_font); - sizer->Add(label, 0, wxALIGN_CENTER_VERTICAL, 0); + sizer_tmp->Add(label, 0, wxALIGN_CENTER_VERTICAL, 0); } // add field const Option& opt_ref = opt; auto& field = build_field(opt_ref, label); - add_undo_buttuns_to_sizer(sizer, field); + add_undo_buttuns_to_sizer(sizer_tmp, field); is_sizer_field(field) ? - sizer->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) : - sizer->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0); + sizer_tmp->Add(field->getSizer(), 0, wxALIGN_CENTER_VERTICAL, 0) : + sizer_tmp->Add(field->getWindow(), 0, wxALIGN_CENTER_VERTICAL, 0); // add sidetext if any if (option.sidetext != "") { auto sidetext = new wxStaticText(parent(), wxID_ANY, L_str(option.sidetext), wxDefaultPosition, wxDefaultSize); sidetext->SetFont(sidetext_font); - sizer->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); + sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); } // add side widget if any if (opt.side_widget != nullptr) { - sizer->Add(opt.side_widget(parent())/*!.target()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification + sizer_tmp->Add(opt.side_widget(parent())/*!.target()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification } - if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back()) + if (opt.opt_id != option_set.back().opt_id && m_flag != ogSIDE_OPTIONS_VERTICAL) //! istead of (opt != option_set.back()) { - sizer->AddSpacer(6); + sizer_tmp->AddSpacer(6); } + if (m_flag == ogSIDE_OPTIONS_VERTICAL) + sizer->Add(sizer_tmp, 1, wxEXPAND|wxALIGN_RIGHT|wxALL, 0); } // add extra sizers if any for (auto extra_widget : line.get_extra_widgets()) { diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index d302fa1ec..8285dade6 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -131,6 +131,7 @@ public: inline void enable() { for (auto& field : m_fields) field.second->enable(); } inline void disable() { for (auto& field : m_fields) field.second->disable(); } + void set_flag(ogDrawFlag flag) { m_flag = flag; } OptionsGroup(wxWindow* _parent, const wxString& title, bool is_tab_opt=false, ogDrawFlag flag = ogDEFAULT) : m_parent(_parent), title(title), m_is_tab_opt(is_tab_opt), staticbox(title!=""), m_flag(flag) { @@ -139,7 +140,7 @@ public: if (label_width != 0) num_columns++; if (extra_column != nullptr) num_columns++; m_grid_sizer = new wxFlexGridSizer(0, num_columns, 0,0); - static_cast(m_grid_sizer)->SetFlexibleDirection(wxHORIZONTAL); + static_cast(m_grid_sizer)->SetFlexibleDirection(wxBOTH/*wxHORIZONTAL*/); static_cast(m_grid_sizer)->AddGrowableCol(label_width != 0); #ifdef __WXGTK__ m_panel = new wxPanel( _parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index d4fdcb752..1a34282c1 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -102,9 +102,9 @@ public: this->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, this](wxCommandEvent e){ wxWindowUpdateLocker noUpdates_cp(this); wxWindowUpdateLocker noUpdates(parent); - parent->GetParent()->Layout(); - parent->Layout(); - this->Refresh(); + parent->GetParent() ? parent->GetParent()->Layout() : //; + parent->Layout(); +// this->Refresh(); })); } From 46f71661b2d68f5805a3e9dc19dcc79efa78dd49 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 24 May 2018 16:57:35 +0200 Subject: [PATCH 017/119] Some changes in the concept of the new right column --- lib/Slic3r/GUI/Plater.pm | 11 ++- xs/src/slic3r/GUI/GUI.cpp | 151 +++++++++++++++++++++++------ xs/src/slic3r/GUI/GUI.hpp | 5 + xs/src/slic3r/GUI/OptionsGroup.cpp | 23 +++-- xs/src/slic3r/GUI/OptionsGroup.hpp | 12 ++- xs/src/slic3r/GUI/Tab.cpp | 4 +- 6 files changed, 158 insertions(+), 48 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 5e568d279..b446bf124 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -226,14 +226,17 @@ sub new { } ### Panel for right column - $self->{right_panel} = Wx::Panel->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); +# $self->{right_panel} = Wx::Panel->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + $self->{right_panel} = Wx::ScrolledWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + $self->{right_panel}->SetScrollbars(0, 1, 1, 1); ### Scrolled Window for info boxes my $scrolled_window_sizer = Wx::BoxSizer->new(wxVERTICAL); $scrolled_window_sizer->SetMinSize([310, -1]); - my $scrolled_window_panel = Wx::ScrolledWindow->new($self->{right_panel}, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); +# my $scrolled_window_panel = Wx::ScrolledWindow->new($self->{right_panel}, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + my $scrolled_window_panel = Wx::Panel->new($self->{right_panel}, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); $scrolled_window_panel->SetSizer($scrolled_window_sizer); - $scrolled_window_panel->SetScrollbars(1, 1, 1, 1); +# $scrolled_window_panel->SetScrollbars(1, 1, 1, 1); $self->{list} = Wx::ListView->new($scrolled_window_panel, -1, wxDefaultPosition, wxDefaultSize, wxLC_SINGLE_SEL | wxLC_REPORT | wxBORDER_SUNKEN | wxTAB_TRAVERSAL | wxWANTS_CHARS ); @@ -517,7 +520,7 @@ sub new { $right_sizer->Add($frequently_changed_parameters_sizer, 0, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; $right_sizer->Add($expert_mode_part_sizer, 1, wxEXPAND | wxTOP, 0) if defined $expert_mode_part_sizer; $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5); - $right_sizer->Add($scrolled_window_panel, 1, wxEXPAND | wxALL, 1); + $right_sizer->Add($scrolled_window_panel, 0, wxEXPAND | wxALL, 1); # Callback for showing / hiding the print info box. $self->{"print_info_box_show"} = sub { # if ($right_sizer->IsShown(5) != $_[0]) { diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 22554bba5..33572bd04 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -136,6 +136,12 @@ wxStaticBitmap *g_manifold_warning_icon = nullptr; bool g_show_print_info = false; bool g_show_manifold_warning_icon = false; +wxFont g_small_font{ wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; +#ifdef __WXMAC__ +g_small_font->SetPointSize(11); +#endif /*__WXMAC__*/ +wxFont g_bold_font{ wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold() }; + static void init_label_colours() { auto luma = get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); @@ -739,6 +745,14 @@ void set_label_clr_sys(const wxColour& clr) { g_AppConfig->save(); } +const wxFont& small_font(){ + return g_small_font; +} + +const wxFont& bold_font(){ + return g_bold_font; +} + const wxColour& get_label_clr_default() { return g_color_label_default; } @@ -879,6 +893,58 @@ wxBoxSizer* content_objects_list(wxWindow *win) return objects_sz; } +wxBoxSizer* content_edit_object_buttons(wxWindow* win) +{ + auto sizer = new wxBoxSizer(wxVERTICAL); + + auto btn_load_part = new wxButton(win, wxID_ANY, "Load part…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); + auto btn_load_modifier = new wxButton(win, wxID_ANY, "Load modifier…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); + auto btn_load_lambda_modifier = new wxButton(win, wxID_ANY, "Load generic…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); + auto btn_delete = new wxButton(win, wxID_ANY, "Delete part", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); + auto btn_split = new wxButton(win, wxID_ANY, "Split part", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); + auto btn_move_up = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); + auto btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); + btn_move_up->SetMinSize(wxSize(20, -1)); + btn_move_down->SetMinSize(wxSize(20, -1)); + btn_load_part->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); + btn_load_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); + btn_load_lambda_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); + btn_delete->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_delete.png")), wxBITMAP_TYPE_PNG)); + btn_split->SetBitmap(wxBitmap(from_u8(Slic3r::var("shape_ungroup.png")), wxBITMAP_TYPE_PNG)); + btn_move_up->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_up.png")), wxBITMAP_TYPE_PNG)); + btn_move_down->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_down.png")), wxBITMAP_TYPE_PNG)); + + auto buttons_object_sizer = new wxFlexGridSizer(1, 3, 0, 1); + buttons_object_sizer->SetFlexibleDirection(wxBOTH); + buttons_object_sizer->Add(btn_load_part, 0, wxEXPAND); + buttons_object_sizer->Add(btn_load_modifier, 0, wxEXPAND); + buttons_object_sizer->Add(btn_load_lambda_modifier, 0, wxEXPAND); + + auto buttons_part_sizer = new wxFlexGridSizer(1, 3, 0, 1); + buttons_part_sizer->SetFlexibleDirection(wxBOTH); + buttons_part_sizer->Add(btn_delete, 0, wxEXPAND); + buttons_part_sizer->Add(btn_split, 0, wxEXPAND); + { + auto up_down_sizer = new wxGridSizer(1, 2, 0, 1); + up_down_sizer->Add(btn_move_up, 1, wxEXPAND); + up_down_sizer->Add(btn_move_down, 1, wxEXPAND); + buttons_part_sizer->Add(up_down_sizer, 0, wxEXPAND); + } + buttons_part_sizer->Show(false); + + btn_load_part->SetFont(Slic3r::GUI::small_font()); + btn_load_modifier->SetFont(Slic3r::GUI::small_font()); + btn_load_lambda_modifier->SetFont(Slic3r::GUI::small_font()); + btn_delete->SetFont(Slic3r::GUI::small_font()); + btn_split->SetFont(Slic3r::GUI::small_font()); + btn_move_up->SetFont(Slic3r::GUI::small_font()); + btn_move_down->SetFont(Slic3r::GUI::small_font()); + + sizer->Add(buttons_object_sizer, 0, wxALIGN_CENTER_HORIZONTAL); + sizer->Add(buttons_part_sizer, 0, wxALIGN_CENTER_HORIZONTAL); + return sizer; +} + Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value=0) { Line line = { _(option_name), "" }; @@ -888,7 +954,7 @@ Line add_og_to_object_settings(const std::string& option_name, const std::string def.type = coInt; def.default_value = new ConfigOptionInt(def_value); def.sidetext = sidetext; - def.width = 50; + def.width = 70; const std::string lower_name = boost::algorithm::to_lower_copy(option_name); @@ -903,39 +969,29 @@ Line add_og_to_object_settings(const std::string& option_name, const std::string def.label = L("Z"); option = Option(def, lower_name + "_Z"); line.append_option(option); + + if (option_name == "Scale") + { + def.label = L("Units"); + def.type = coStrings; + def.gui_type = "select_open"; + def.enum_labels.push_back(L("%")); + def.enum_labels.push_back(L("mm")); + def.default_value = new ConfigOptionStrings{ "%" }; + def.sidetext = " "; + + option = Option(def, lower_name + "_unit"); + line.append_option(option); + } return line; } wxBoxSizer* content_object_settings(wxWindow *win) { - DynamicPrintConfig* config = /*&g_PresetBundle->full_config();*/&g_PresetBundle->prints.get_edited_preset().config; - std::shared_ptr optgroup = std::make_shared(win, "", config); + DynamicPrintConfig* config = &g_PresetBundle->printers.get_edited_preset().config; // TODO get config from Model_volume + std::shared_ptr optgroup = std::make_shared(win, "Extruders", config); optgroup->label_width = m_label_width; - ConfigOptionDef def; - def.label = L("Name"); - def.type = coString; - def.tooltip = L("Object name"); - def.full_width = true; - def.default_value = new ConfigOptionString{ "BlaBla_object.stl" }; - optgroup->append_single_option_line(Option(def, "object_name")); - - optgroup->set_flag(ogSIDE_OPTIONS_VERTICAL); - - optgroup->append_line(add_og_to_object_settings(L("Position"), L("mm"))); - optgroup->append_line(add_og_to_object_settings(L("Rotation"), "°"/*"\u00b0"*/, 1)); - optgroup->append_line(add_og_to_object_settings(L("Scale"), "%", 2)); - - optgroup->set_flag(ogDEFAULT); - - def.label = L("Place on bed"); - def.type = coBool; - def.tooltip = L("Automatic placing of models on printing bed in Y axis"); - def.gui_type = ""; - def.sidetext = ""; - def.default_value = new ConfigOptionBool{ false }; - optgroup->append_single_option_line(Option(def, "place_on_bed")); - Option option = optgroup->get_option("extruder"); option.opt.default_value = new ConfigOptionInt(1); optgroup->append_single_option_line(option); @@ -957,15 +1013,17 @@ wxBoxSizer* content_part_settings(wxWindow *win) void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) { auto main_sizer = new wxBoxSizer(wxVERTICAL); - auto main_page = new wxScrolledWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + auto main_page = new wxPanel/*ScrolledWindow*/(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); main_page->SetSizer(main_sizer); - main_page->SetScrollbars(1, 1, 1, 1); +// main_page->SetScrollbars(0, 1, 1, 1); sizer->Add(main_page, 1, wxEXPAND | wxALL, 1); // Experiments with new UI // *** Objects List *** add_prusa_collapsible_pane(main_page, main_sizer, "Objects List:", content_objects_list); + // *** Edit Object Buttons*** + main_sizer->Add(content_edit_object_buttons(main_page), 0, wxEXPAND, 0); // *** Object Settings *** add_prusa_collapsible_pane(main_page, main_sizer, "Object Settings:", content_object_settings); // *** Part Settings *** @@ -1109,9 +1167,42 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl }; optgroup->append_line(line); - sizer->Add(optgroup->sizer, 1, wxEXPAND | wxBOTTOM, 2); + sizer->Add(optgroup->sizer, 0, wxEXPAND | wxBOTTOM, 2); m_optgroups.push_back(optgroup);// ogFrequentlyChangingParameters + + // Frequently Object Settings + optgroup = std::make_shared(parent, _(L("Object Settings")), config); + optgroup->label_width = 100; + optgroup->set_grid_vgap(5); + + def.label = L("Name"); + def.type = coString; + def.tooltip = L("Object name"); + def.full_width = true; + def.default_value = new ConfigOptionString{ "BlaBla_object.stl" }; + optgroup->append_single_option_line(Option(def, "object_name")); + + optgroup->set_flag(ogSIDE_OPTIONS_VERTICAL); + optgroup->sidetext_width = 25; + + optgroup->append_line(add_og_to_object_settings(L("Position"), L("mm"))); + optgroup->append_line(add_og_to_object_settings(L("Rotation"), "°", 1)); + optgroup->append_line(add_og_to_object_settings(L("Scale"), "%", 2)); + + optgroup->set_flag(ogDEFAULT); + + def.label = L("Place on bed"); + def.type = coBool; + def.tooltip = L("Automatic placing of models on printing bed in Y axis"); + def.gui_type = ""; + def.sidetext = ""; + def.default_value = new ConfigOptionBool{ false }; + optgroup->append_single_option_line(Option(def, "place_on_bed")); + + sizer->Add(optgroup->sizer, 0, wxEXPAND | wxLEFT, 20); + + m_optgroups.push_back(optgroup); // ogFrequentlyObjectSettings } void show_frequently_changed_parameters(bool show) diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 243c63cc3..a7314541e 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -21,6 +21,7 @@ class wxFlexGridSizer; class wxButton; class wxFileDialog; class wxStaticBitmap; +class wxFont; namespace Slic3r { @@ -49,6 +50,7 @@ namespace GUI { enum ogGroup{ ogFrequentlyChangingParameters, + ogFrequentlyObjectSettings, ogObjectSettings, ogPartSettings }; @@ -108,6 +110,9 @@ unsigned get_colour_approx_luma(const wxColour &colour); void set_label_clr_modified(const wxColour& clr); void set_label_clr_sys(const wxColour& clr); +const wxFont& small_font(); +const wxFont& bold_font(); + extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change); // This is called when closing the application, when loading a config file or when starting the config wizard diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index 55887da91..f59fffd7f 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -91,7 +91,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co return field; } -void OptionsGroup::add_undo_buttuns_to_sizer(wxBoxSizer* sizer, const t_field& field) +void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field) { if (!m_is_tab_opt) { field->m_Undo_btn->Hide(); @@ -177,7 +177,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* // If we're here, we have more than one option or a single option with sidetext // so we need a horizontal sizer to arrange these things auto sizer = new wxBoxSizer(m_flag == ogSIDE_OPTIONS_VERTICAL ? wxVERTICAL : wxHORIZONTAL); - grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM|wxTOP|wxLEFT), staticbox ? 0 : 1); + grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1); // If we have a single option with no sidetext just add it directly to the grid sizer if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr && line.get_extra_widgets().size() == 0) { @@ -195,7 +195,14 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* for (auto opt : option_set) { ConfigOptionDef option = opt.opt; - wxBoxSizer* sizer_tmp = m_flag == ogSIDE_OPTIONS_VERTICAL ? new wxBoxSizer(wxHORIZONTAL) : sizer; + wxSizer* sizer_tmp; + if (m_flag == ogSIDE_OPTIONS_VERTICAL){ + auto sz = new wxFlexGridSizer(1, 3, 2, 2); + sz->RemoveGrowableCol(2); + sizer_tmp = sz; + } + else + sizer_tmp = sizer; // add label if any if (option.label != "") { wxString str_label = L_str(option.label); @@ -205,7 +212,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* // L_str(option.label); label = new wxStaticText(parent(), wxID_ANY, str_label + ":", wxDefaultPosition, wxDefaultSize); label->SetFont(label_font); - sizer_tmp->Add(label, 0, wxALIGN_CENTER_VERTICAL, 0); + sizer_tmp->Add(label, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 0); } // add field @@ -218,9 +225,10 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* // add sidetext if any if (option.sidetext != "") { - auto sidetext = new wxStaticText(parent(), wxID_ANY, L_str(option.sidetext), wxDefaultPosition, wxDefaultSize); + auto sidetext = new wxStaticText( parent(), wxID_ANY, L_str(option.sidetext), wxDefaultPosition, + wxSize(sidetext_width, -1)/*wxDefaultSize*/, wxALIGN_LEFT); sidetext->SetFont(sidetext_font); - sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); + sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, m_flag == ogSIDE_OPTIONS_VERTICAL ? 0 : 4); } // add side widget if any @@ -232,8 +240,9 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* { sizer_tmp->AddSpacer(6); } + if (m_flag == ogSIDE_OPTIONS_VERTICAL) - sizer->Add(sizer_tmp, 1, wxEXPAND|wxALIGN_RIGHT|wxALL, 0); + sizer->Add(sizer_tmp, 0, wxALIGN_RIGHT|wxALL, 0); } // add extra sizers if any for (auto extra_widget : line.get_extra_widgets()) { diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index 8285dade6..cd604fc8e 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -93,8 +93,7 @@ public: wxFont sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; wxFont label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; - -// std::function nonsys_btn_icon{ nullptr }; + int sidetext_width{ -1 }; /// Returns a copy of the pointer of the parent wxWindow. /// Accessor function is because users are not allowed to change the parent @@ -132,14 +131,17 @@ public: inline void enable() { for (auto& field : m_fields) field.second->enable(); } inline void disable() { for (auto& field : m_fields) field.second->disable(); } void set_flag(ogDrawFlag flag) { m_flag = flag; } + void set_grid_vgap(int gap) { m_grid_sizer->SetVGap(gap); } OptionsGroup(wxWindow* _parent, const wxString& title, bool is_tab_opt=false, ogDrawFlag flag = ogDEFAULT) : m_parent(_parent), title(title), m_is_tab_opt(is_tab_opt), staticbox(title!=""), m_flag(flag) { - sizer = (staticbox ? new wxStaticBoxSizer(new wxStaticBox(_parent, wxID_ANY, title), wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); + auto stb = new wxStaticBox(_parent, wxID_ANY, title); + stb->SetFont(bold_font()); + sizer = (staticbox ? new wxStaticBoxSizer(stb/*new wxStaticBox(_parent, wxID_ANY, title)*/, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); auto num_columns = 1U; if (label_width != 0) num_columns++; if (extra_column != nullptr) num_columns++; - m_grid_sizer = new wxFlexGridSizer(0, num_columns, 0,0); + m_grid_sizer = new wxFlexGridSizer(0, num_columns, 1,0); static_cast(m_grid_sizer)->SetFlexibleDirection(wxBOTH/*wxHORIZONTAL*/); static_cast(m_grid_sizer)->AddGrowableCol(label_width != 0); #ifdef __WXGTK__ @@ -179,7 +181,7 @@ protected: const t_field& build_field(const t_config_option_key& id, const ConfigOptionDef& opt, wxStaticText* label = nullptr); const t_field& build_field(const t_config_option_key& id, wxStaticText* label = nullptr); const t_field& build_field(const Option& opt, wxStaticText* label = nullptr); - void add_undo_buttuns_to_sizer(wxBoxSizer* sizer, const t_field& field); + void add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field); virtual void on_kill_focus (){}; virtual void on_change_OG(const t_config_option_key& opt_id, const boost::any& value); diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 88a97c5c8..6b45abc92 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1446,7 +1446,7 @@ void TabPrinter::build() Line line{ _(L("Bed shape")), "" }; line.widget = [this](wxWindow* parent){ auto btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+"\u2026", wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); - // btn->SetFont(Slic3r::GUI::small_font); + btn->SetFont(Slic3r::GUI::small_font()); btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG)); auto sizer = new wxBoxSizer(wxHORIZONTAL); @@ -1514,7 +1514,7 @@ void TabPrinter::build() auto serial_test = [this](wxWindow* parent){ auto btn = m_serial_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")), wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); -// btn->SetFont($Slic3r::GUI::small_font); + btn->SetFont(Slic3r::GUI::small_font()); btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("wrench.png")), wxBITMAP_TYPE_PNG)); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); From d93a8aec3df2ed60c4c6644e37a0423f09e248d5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Sun, 27 May 2018 22:12:01 +0200 Subject: [PATCH 018/119] New concept of the main IU. * only 2 mode - Regular & Expert * "Export Gcode" moved to bottom of the window (analogue to the PrusaControll) * Experiments with layout of collapsible_pane [! not successful] --- lib/Slic3r/GUI/Plater.pm | 12 ++- xs/src/slic3r/GUI/GUI.cpp | 148 ++++++++++++++++++----------- xs/src/slic3r/GUI/GUI.hpp | 1 + xs/src/slic3r/GUI/OptionsGroup.cpp | 2 +- xs/src/slic3r/GUI/Tab.cpp | 16 +--- xs/src/slic3r/GUI/wxExtensions.hpp | 26 ++++- xs/xsp/GUI.xsp | 2 + 7 files changed, 131 insertions(+), 76 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index b446bf124..64dab1d81 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -256,7 +256,7 @@ sub new { }); # right pane buttons - $self->{btn_export_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Export G-code…"), wxDefaultPosition, [-1, 30], wxBU_LEFT); + $self->{btn_export_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Export G-code…"), wxDefaultPosition, [-1, 30], wxNO_BORDER);#, wxBU_LEFT); $self->{btn_reslice} = Wx::Button->new($self->{right_panel}, -1, L("Slice now"), wxDefaultPosition, [-1, 30], wxBU_LEFT); $self->{btn_print} = Wx::Button->new($self->{right_panel}, -1, L("Print…"), wxDefaultPosition, [-1, 30], wxBU_LEFT); $self->{btn_send_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Send to printer"), wxDefaultPosition, [-1, 30], wxBU_LEFT); @@ -266,12 +266,12 @@ sub new { $self->{btn_print}->Hide; $self->{btn_send_gcode}->Hide; + # export_gcode cog_go.png my %icons = qw( add brick_add.png remove brick_delete.png reset cross.png arrange bricks.png - export_gcode cog_go.png print arrow_up.png send_gcode arrow_up.png reslice reslice.png @@ -508,7 +508,7 @@ sub new { $buttons_sizer->Add($self->{btn_reslice}, 0, wxALIGN_RIGHT, 0); $buttons_sizer->Add($self->{btn_print}, 0, wxALIGN_RIGHT, 0); $buttons_sizer->Add($self->{btn_send_gcode}, 0, wxALIGN_RIGHT, 0); - $buttons_sizer->Add($self->{btn_export_gcode}, 0, wxALIGN_RIGHT, 0); + #$buttons_sizer->Add($self->{btn_export_gcode}, 0, wxALIGN_RIGHT, 0); $scrolled_window_sizer->Add($self->{list}, 1, wxEXPAND, 5); $scrolled_window_sizer->Add($object_info_sizer, 0, wxEXPAND, 0); @@ -517,10 +517,11 @@ sub new { my $right_sizer = Wx::BoxSizer->new(wxVERTICAL); $right_sizer->SetMinSize([320, -1]); $right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets; - $right_sizer->Add($frequently_changed_parameters_sizer, 0, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; - $right_sizer->Add($expert_mode_part_sizer, 1, wxEXPAND | wxTOP, 0) if defined $expert_mode_part_sizer; + $right_sizer->Add($frequently_changed_parameters_sizer, 1, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; + $right_sizer->Add($expert_mode_part_sizer, 0, wxEXPAND | wxTOP, 0) if defined $expert_mode_part_sizer; $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5); $right_sizer->Add($scrolled_window_panel, 0, wxEXPAND | wxALL, 1); + $right_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 20); # Callback for showing / hiding the print info box. $self->{"print_info_box_show"} = sub { # if ($right_sizer->IsShown(5) != $_[0]) { @@ -556,6 +557,7 @@ sub new { $frequently_changed_parameters_sizer, $expert_mode_part_sizer, $scrolled_window_sizer, + $self->{btn_export_gcode}, $self->{btn_export_stl}, $self->{btn_reslice}, $self->{btn_print}, diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 33572bd04..ccdfcb6d5 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -128,6 +128,7 @@ wxWindow *g_right_panel = nullptr; wxBoxSizer *g_frequently_changed_parameters_sizer = nullptr; wxBoxSizer *g_expert_mode_part_sizer = nullptr; wxBoxSizer *g_scrolled_window_sizer = nullptr; +wxButton *g_btn_export_gcode = nullptr; wxButton *g_btn_export_stl = nullptr; wxButton *g_btn_reslice = nullptr; wxButton *g_btn_print = nullptr; @@ -135,6 +136,9 @@ wxButton *g_btn_send_gcode = nullptr; wxStaticBitmap *g_manifold_warning_icon = nullptr; bool g_show_print_info = false; bool g_show_manifold_warning_icon = false; +wxSizer *m_sizer_object_buttons = nullptr; +wxSizer *m_sizer_part_buttons = nullptr; +wxDataViewCtrl *m_objects_ctrl = nullptr; wxFont g_small_font{ wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; #ifdef __WXMAC__ @@ -203,6 +207,7 @@ void set_preset_updater(PresetUpdater *updater) void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_parameters_sizer, wxBoxSizer *expert_mode_part_sizer, wxBoxSizer *scrolled_window_sizer, + wxButton *btn_export_gcode, wxButton *btn_export_stl, wxButton *btn_reslice, wxButton *btn_print, wxButton *btn_send_gcode, wxStaticBitmap *manifold_warning_icon) @@ -211,6 +216,7 @@ void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_par g_frequently_changed_parameters_sizer = frequently_changed_parameters_sizer; g_expert_mode_part_sizer = expert_mode_part_sizer; g_scrolled_window_sizer = scrolled_window_sizer; + g_btn_export_gcode = btn_export_gcode; g_btn_export_stl = btn_export_stl; g_btn_reslice = btn_reslice; g_btn_print = btn_print; @@ -353,7 +359,6 @@ enum ConfigMenuIDs { ConfigMenuUpdate, ConfigMenuPreferences, ConfigMenuModeSimple, - ConfigMenuModeRegular, ConfigMenuModeExpert, ConfigMenuLanguage, ConfigMenuFlashFirmware, @@ -366,11 +371,7 @@ ConfigMenuIDs get_view_mode() return ConfigMenuModeSimple; const auto mode = g_AppConfig->get("view_mode"); - return mode == "expert" ? - ConfigMenuModeExpert : - mode == "regular" ? - ConfigMenuModeRegular : - ConfigMenuModeSimple; + return mode == "expert" ? ConfigMenuModeExpert : ConfigMenuModeSimple; } void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_language_change) @@ -389,7 +390,6 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l local_menu->AppendSeparator(); auto mode_menu = new wxMenu(); mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeSimple, _(L("&Simple")), _(L("Simple View Mode"))); - mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeRegular, _(L("&Regular")), _(L("Regular View Mode"))); mode_menu->AppendRadioItem(config_id_base + ConfigMenuModeExpert, _(L("&Expert")), _(L("Expert View Mode"))); mode_menu->Check(config_id_base + get_view_mode(), true); local_menu->AppendSubMenu(mode_menu, _(L("&Mode")), _(L("Slic3r View Mode"))); @@ -463,18 +463,8 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l } }); mode_menu->Bind(wxEVT_MENU, [config_id_base](wxEvent& event) { - std::string mode = ""; - switch (event.GetId() - config_id_base){ - case ConfigMenuModeExpert: - mode = "expert"; - break; - case ConfigMenuModeRegular: - mode = "regular"; - break; - case ConfigMenuModeSimple: - mode = "simple"; - break; - } + std::string mode = event.GetId() - config_id_base == ConfigMenuModeExpert ? + "expert" : "simple"; g_AppConfig->set("view_mode", mode); g_AppConfig->save(); update_mode(); @@ -839,9 +829,10 @@ wxString from_u8(const std::string &str) } // add PrusaCollapsiblePane to sizer -void add_prusa_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, const wxString& name, std::function content_function) +PrusaCollapsiblePane* add_prusa_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, const wxString& name, std::function content_function) { auto *collpane = new PrusaCollapsiblePane(parent, wxID_ANY, name); + collpane->SetTopParent(g_right_panel); // add the pane with a zero proportion value to the sizer which contains it sizer_parent->Add(collpane, 0, wxGROW | wxALL, 0); @@ -853,42 +844,54 @@ void add_prusa_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, cons sizer_pane->Add(sizer, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); win->SetSizer(sizer_pane); sizer_pane->SetSizeHints(win); + return collpane; } wxBoxSizer* content_objects_list(wxWindow *win) { - auto objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); - objects_ctrl->SetBestFittingSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects + m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); + m_objects_ctrl->SetBestFittingSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects auto objects_sz = new wxBoxSizer(wxVERTICAL); - objects_sz->Add(objects_ctrl, 1, wxGROW | wxALL, 5); + objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT/*ALL*/, 20/*5*/); auto objects_model = new MyObjectTreeModel; - objects_ctrl->AssociateModel(objects_model); + m_objects_ctrl->AssociateModel(objects_model); #if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE - objects_ctrl->EnableDragSource(wxDF_UNICODETEXT); - objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT); + m_objects_ctrl->EnableDragSource(wxDF_UNICODETEXT); + m_objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT); #endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE // column 0 of the view control: wxDataViewTextRenderer *tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); - wxDataViewColumn *column00 = new wxDataViewColumn("Name", tr, 0, 140, wxALIGN_LEFT, + wxDataViewColumn *column00 = new wxDataViewColumn("Name", tr, 0, 110, wxALIGN_LEFT, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); - objects_ctrl->AppendColumn(column00); + m_objects_ctrl->AppendColumn(column00); // column 1 of the view control: tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); wxDataViewColumn *column01 = new wxDataViewColumn("Copy", tr, 1, 75, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); - objects_ctrl->AppendColumn(column01); + m_objects_ctrl->AppendColumn(column01); // column 2 of the view control: tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); wxDataViewColumn *column02 = new wxDataViewColumn("Scale", tr, 2, 80, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); - objects_ctrl->AppendColumn(column02); + m_objects_ctrl->AppendColumn(column02); + + m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [objects_model](wxCommandEvent& evt) + { + wxWindowUpdateLocker noUpdates(g_right_panel); + auto item = m_objects_ctrl->GetSelection(); + auto show_obj_sizer = objects_model->GetParent(item) == wxDataViewItem(0); + m_sizer_object_buttons->Show(show_obj_sizer); + m_sizer_part_buttons->Show(!show_obj_sizer); + + g_right_panel->Layout(); + }); return objects_sz; } @@ -897,11 +900,11 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) { auto sizer = new wxBoxSizer(wxVERTICAL); - auto btn_load_part = new wxButton(win, wxID_ANY, "Load part…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); - auto btn_load_modifier = new wxButton(win, wxID_ANY, "Load modifier…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); - auto btn_load_lambda_modifier = new wxButton(win, wxID_ANY, "Load generic…", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); - auto btn_delete = new wxButton(win, wxID_ANY, "Delete part", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); - auto btn_split = new wxButton(win, wxID_ANY, "Split part", wxDefaultPosition, wxDefaultSize, wxBU_LEFT); + auto btn_load_part = new wxButton(win, wxID_ANY, /*Load */"part…", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_load_modifier = new wxButton(win, wxID_ANY, /*Load */"modifier…", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_load_lambda_modifier = new wxButton(win, wxID_ANY, /*Load */"generic…", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_delete = new wxButton(win, wxID_ANY, "Delete"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_split = new wxButton(win, wxID_ANY, "Split"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); auto btn_move_up = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); auto btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); btn_move_up->SetMinSize(wxSize(20, -1)); @@ -914,23 +917,24 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) btn_move_up->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_up.png")), wxBITMAP_TYPE_PNG)); btn_move_down->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_down.png")), wxBITMAP_TYPE_PNG)); - auto buttons_object_sizer = new wxFlexGridSizer(1, 3, 0, 1); - buttons_object_sizer->SetFlexibleDirection(wxBOTH); - buttons_object_sizer->Add(btn_load_part, 0, wxEXPAND); - buttons_object_sizer->Add(btn_load_modifier, 0, wxEXPAND); - buttons_object_sizer->Add(btn_load_lambda_modifier, 0, wxEXPAND); + m_sizer_object_buttons = new /*wxFlex*/wxGridSizer(1, 3, 0, 0); +// static_cast(m_sizer_object_buttons)->SetFlexibleDirection(wxBOTH); + m_sizer_object_buttons->Add(btn_load_part, 0, wxEXPAND); + m_sizer_object_buttons->Add(btn_load_modifier, 0, wxEXPAND); + m_sizer_object_buttons->Add(btn_load_lambda_modifier, 0, wxEXPAND); + m_sizer_object_buttons->Show(false); - auto buttons_part_sizer = new wxFlexGridSizer(1, 3, 0, 1); - buttons_part_sizer->SetFlexibleDirection(wxBOTH); - buttons_part_sizer->Add(btn_delete, 0, wxEXPAND); - buttons_part_sizer->Add(btn_split, 0, wxEXPAND); + m_sizer_part_buttons = new /*wxFlex*/wxGridSizer(1, 3, 0, 0); +// m_sizer_part_buttons->SetFlexibleDirection(wxBOTH); + m_sizer_part_buttons->Add(btn_delete, 0, wxEXPAND); + m_sizer_part_buttons->Add(btn_split, 0, wxEXPAND); { - auto up_down_sizer = new wxGridSizer(1, 2, 0, 1); + auto up_down_sizer = new wxGridSizer(1, 2, 0, 0); up_down_sizer->Add(btn_move_up, 1, wxEXPAND); up_down_sizer->Add(btn_move_down, 1, wxEXPAND); - buttons_part_sizer->Add(up_down_sizer, 0, wxEXPAND); + m_sizer_part_buttons->Add(up_down_sizer, 0, wxEXPAND); } - buttons_part_sizer->Show(false); + m_sizer_part_buttons->Show(false); btn_load_part->SetFont(Slic3r::GUI::small_font()); btn_load_modifier->SetFont(Slic3r::GUI::small_font()); @@ -940,8 +944,8 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) btn_move_up->SetFont(Slic3r::GUI::small_font()); btn_move_down->SetFont(Slic3r::GUI::small_font()); - sizer->Add(buttons_object_sizer, 0, wxALIGN_CENTER_HORIZONTAL); - sizer->Add(buttons_part_sizer, 0, wxALIGN_CENTER_HORIZONTAL); + sizer->Add(m_sizer_object_buttons, 0, wxEXPAND|wxLEFT, 20/*wxALIGN_CENTER_HORIZONTAL*/); + sizer->Add(m_sizer_part_buttons, 0, wxEXPAND|wxLEFT, 20/*wxALIGN_CENTER_HORIZONTAL*/); return sizer; } @@ -999,14 +1003,27 @@ wxBoxSizer* content_object_settings(wxWindow *win) m_optgroups.push_back(optgroup); // ogObjectSettings auto sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(optgroup->sizer, 1, wxEXPAND | wxBOTTOM, 2); + sizer->Add(optgroup->sizer, 1, wxEXPAND | wxLEFT, 20); + + return sizer; } wxBoxSizer* content_part_settings(wxWindow *win) { + DynamicPrintConfig* config = &g_PresetBundle->printers.get_edited_preset().config; // TODO get config from Model_volume + std::shared_ptr optgroup = std::make_shared(win, "Extruders", config); + optgroup->label_width = m_label_width; + + Option option = optgroup->get_option("extruder"); + option.opt.default_value = new ConfigOptionInt(1); + optgroup->append_single_option_line(option); + + m_optgroups.push_back(optgroup); // ogPartSettings + auto sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(new wxStaticText(win, wxID_ANY, "Some part text")); + sizer->Add(optgroup->sizer, 1, wxEXPAND | wxLEFT, 20); + return sizer; } @@ -1021,7 +1038,17 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) // Experiments with new UI // *** Objects List *** - add_prusa_collapsible_pane(main_page, main_sizer, "Objects List:", content_objects_list); + auto collpane = add_prusa_collapsible_pane(main_page, main_sizer, "Objects List:", content_objects_list); + collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([collpane](wxCommandEvent e){ + wxWindowUpdateLocker noUpdates(g_right_panel); + if (collpane->IsCollapsed()) { + m_sizer_object_buttons->Show(false); + m_sizer_part_buttons->Show(false); + } + else + m_objects_ctrl->UnselectAll(); + g_right_panel->Layout(); + })); // *** Edit Object Buttons*** main_sizer->Add(content_edit_object_buttons(main_page), 0, wxEXPAND, 0); // *** Object Settings *** @@ -1235,7 +1262,7 @@ void show_buttons(bool show) void show_scrolled_window_sizer(bool show) { - g_scrolled_window_sizer->Show(static_cast(0), show); + g_scrolled_window_sizer->Show(static_cast(0), false/*show*/); //don't used now g_scrolled_window_sizer->Show(1, show); g_scrolled_window_sizer->Show(2, show && g_show_print_info); g_manifold_warning_icon->Show(show && g_show_manifold_warning_icon); @@ -1243,13 +1270,22 @@ void show_scrolled_window_sizer(bool show) void update_mode() { + //TODO There is a not the best place of it! + //*** Update style of the "Export G-code" button**** + if (g_btn_export_gcode->GetFont() != bold_font()){ + g_btn_export_gcode->SetBackgroundColour(wxColour(252, 77, 1)); + g_btn_export_gcode->SetFont(bold_font()); + } + //************************************ + wxWindowUpdateLocker noUpdates(g_right_panel); ConfigMenuIDs mode = get_view_mode(); - show_frequently_changed_parameters(mode >= ConfigMenuModeRegular); +// show_frequently_changed_parameters(mode >= ConfigMenuModeRegular); g_expert_mode_part_sizer->Show(mode == ConfigMenuModeExpert); - show_scrolled_window_sizer(mode >= ConfigMenuModeRegular); - show_buttons(mode >= ConfigMenuModeRegular); + show_scrolled_window_sizer(mode == ConfigMenuModeExpert); + show_buttons(mode == ConfigMenuModeExpert); + g_right_panel->GetParent()->Layout(); g_right_panel->Layout(); } diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index a7314541e..19ee54533 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -91,6 +91,7 @@ void set_objects_from_perl( wxWindow* parent, wxBoxSizer *frequently_changed_parameters_sizer, wxBoxSizer *expert_mode_part_sizer, wxBoxSizer *scrolled_window_sizer, + wxButton *btn_export_gcode, wxButton *btn_export_stl, wxButton *btn_reslice, wxButton *btn_print, diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index f59fffd7f..52882afda 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -266,7 +266,7 @@ void OptionsGroup::on_change_OG(const t_config_option_key& opt_id, const boost:: Option ConfigOptionsGroup::get_option(const std::string& opt_key, int opt_index /*= -1*/) { if (!m_config->has(opt_key)) { - std::cerr << "No " << opt_key << " in ConfigOptionsGroup config."; + std::cerr << "No " << opt_key << " in ConfigOptionsGroup config.\n"; } std::string opt_id = opt_index == -1 ? opt_key : opt_key + "#" + std::to_string(opt_index); diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 6b45abc92..cecbb9daf 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -706,18 +706,12 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) // Show/hide the 'purging volumes' button void Tab::update_wiping_button_visibility() { - if (!get_app_config()->has("view_mode") || get_app_config()->get("view_mode") == "simple") - get_wiping_dialog_button()->Hide(); - else { - bool wipe_tower_enabled = dynamic_cast((m_preset_bundle->prints.get_edited_preset().config).option("wipe_tower"))->value; - bool multiple_extruders = dynamic_cast((m_preset_bundle->printers.get_edited_preset().config).option("nozzle_diameter"))->values.size() > 1; - bool single_extruder_mm = dynamic_cast((m_preset_bundle->printers.get_edited_preset().config).option("single_extruder_multi_material"))->value; - - if (wipe_tower_enabled && multiple_extruders && single_extruder_mm) - get_wiping_dialog_button()->Show(); - else get_wiping_dialog_button()->Hide(); - } + bool wipe_tower_enabled = dynamic_cast((m_preset_bundle->prints.get_edited_preset().config).option("wipe_tower"))->value; + bool multiple_extruders = dynamic_cast((m_preset_bundle->printers.get_edited_preset().config).option("nozzle_diameter"))->values.size() > 1; + bool single_extruder_mm = dynamic_cast((m_preset_bundle->printers.get_edited_preset().config).option("single_extruder_multi_material"))->value; + get_wiping_dialog_button()->Show(wipe_tower_enabled && multiple_extruders && single_extruder_mm); + (get_wiping_dialog_button()->GetParent())->Layout(); } diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 1a34282c1..b256ac8bb 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -83,6 +84,7 @@ class PrusaCollapsiblePane : public wxCollapsiblePane wxBitmap m_bmp_close; wxBitmap m_bmp_open; #endif //__WXMSW__ + wxWindow* m_top_parent = nullptr; public: PrusaCollapsiblePane() {} PrusaCollapsiblePane( wxWindow *parent, @@ -102,14 +104,32 @@ public: this->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, this](wxCommandEvent e){ wxWindowUpdateLocker noUpdates_cp(this); wxWindowUpdateLocker noUpdates(parent); - parent->GetParent() ? parent->GetParent()->Layout() : //; - parent->Layout(); -// this->Refresh(); + + parent->Layout(); + this->Refresh(); + + if (m_top_parent) + { + m_top_parent->GetSizer()->Layout(); + } + else{ + wxGetTopLevelParent(this)->Layout(); + } + +// if (parent->GetParent()){ +// parent->GetParent()->Layout(); +// parent->Refresh(); +// } +// else{ +// parent->Layout(); +// this->Refresh();} })); } ~PrusaCollapsiblePane() {} + void SetTopParent(wxWindow *parent) { m_top_parent = parent; } + #ifdef __WXMSW__ bool Create(wxWindow *parent, wxWindowID id, diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 64ca4f28a..f7d84d87c 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -95,6 +95,7 @@ void set_objects_from_perl( SV *ui_parent, SV *frequently_changed_parameters_sizer, SV *expert_mode_part_sizer, SV *scrolled_window_sizer, + SV *btn_export_gcode, SV *btn_export_stl, SV *btn_reslice, SV *btn_print, @@ -105,6 +106,7 @@ void set_objects_from_perl( SV *ui_parent, (wxBoxSizer *)wxPli_sv_2_object(aTHX_ frequently_changed_parameters_sizer, "Wx::BoxSizer"), (wxBoxSizer *)wxPli_sv_2_object(aTHX_ expert_mode_part_sizer, "Wx::BoxSizer"), (wxBoxSizer *)wxPli_sv_2_object(aTHX_ scrolled_window_sizer, "Wx::BoxSizer"), + (wxButton *)wxPli_sv_2_object(aTHX_ btn_export_gcode, "Wx::Button"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_export_stl, "Wx::Button"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_reslice, "Wx::Button"), (wxButton *)wxPli_sv_2_object(aTHX_ btn_print, "Wx::Button"), From 3fb567d2860495ba99213b379b174fdeaa605b40 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 28 May 2018 11:10:09 +0200 Subject: [PATCH 019/119] Final prototype --- lib/Slic3r/GUI/Plater.pm | 6 ++++-- xs/src/slic3r/GUI/GUI.cpp | 41 +++++++++++++++------------------------ 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 64dab1d81..68a06b01d 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -425,6 +425,7 @@ sub new { my $object_info_sizer; { my $box = Wx::StaticBox->new($scrolled_window_panel, -1, L("Info")); + $box->SetFont($Slic3r::GUI::small_bold_font); $object_info_sizer = Wx::StaticBoxSizer->new($box, wxVERTICAL); $object_info_sizer->SetMinSize([300,-1]); my $grid_sizer = Wx::FlexGridSizer->new(3, 4, 5, 5); @@ -475,6 +476,7 @@ sub new { my $print_info_sizer; { my $box = Wx::StaticBox->new($scrolled_window_panel, -1, L("Sliced Info")); + $box->SetFont($Slic3r::GUI::small_bold_font); $print_info_sizer = Wx::StaticBoxSizer->new($box, wxVERTICAL); $print_info_sizer->SetMinSize([300,-1]); my $grid_sizer = Wx::FlexGridSizer->new(2, 2, 5, 5); @@ -511,8 +513,8 @@ sub new { #$buttons_sizer->Add($self->{btn_export_gcode}, 0, wxALIGN_RIGHT, 0); $scrolled_window_sizer->Add($self->{list}, 1, wxEXPAND, 5); - $scrolled_window_sizer->Add($object_info_sizer, 0, wxEXPAND, 0); - $scrolled_window_sizer->Add($print_info_sizer, 0, wxEXPAND, 0); + $scrolled_window_sizer->Add($object_info_sizer, 0, wxEXPAND | wxLEFT, 20); + $scrolled_window_sizer->Add($print_info_sizer, 0, wxEXPAND | wxLEFT, 20); my $right_sizer = Wx::BoxSizer->new(wxVERTICAL); $right_sizer->SetMinSize([320, -1]); diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index ccdfcb6d5..166fc9c26 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -139,6 +139,7 @@ bool g_show_manifold_warning_icon = false; wxSizer *m_sizer_object_buttons = nullptr; wxSizer *m_sizer_part_buttons = nullptr; wxDataViewCtrl *m_objects_ctrl = nullptr; +PrusaCollapsiblePane *m_collpane_settings = nullptr; wxFont g_small_font{ wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; #ifdef __WXMAC__ @@ -886,9 +887,12 @@ wxBoxSizer* content_objects_list(wxWindow *win) { wxWindowUpdateLocker noUpdates(g_right_panel); auto item = m_objects_ctrl->GetSelection(); + if (!item) return; auto show_obj_sizer = objects_model->GetParent(item) == wxDataViewItem(0); m_sizer_object_buttons->Show(show_obj_sizer); m_sizer_part_buttons->Show(!show_obj_sizer); + m_collpane_settings->SetLabelText((show_obj_sizer ? _(L("Object Settings")) : _(L("Part Settings"))) + ":"); + m_collpane_settings->Show(true); g_right_panel->Layout(); }); @@ -990,7 +994,7 @@ Line add_og_to_object_settings(const std::string& option_name, const std::string return line; } -wxBoxSizer* content_object_settings(wxWindow *win) +wxBoxSizer* content_settings(wxWindow *win) { DynamicPrintConfig* config = &g_PresetBundle->printers.get_edited_preset().config; // TODO get config from Model_volume std::shared_ptr optgroup = std::make_shared(win, "Extruders", config); @@ -1005,24 +1009,10 @@ wxBoxSizer* content_object_settings(wxWindow *win) auto sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(optgroup->sizer, 1, wxEXPAND | wxLEFT, 20); - - return sizer; -} - -wxBoxSizer* content_part_settings(wxWindow *win) -{ - DynamicPrintConfig* config = &g_PresetBundle->printers.get_edited_preset().config; // TODO get config from Model_volume - std::shared_ptr optgroup = std::make_shared(win, "Extruders", config); - optgroup->label_width = m_label_width; - - Option option = optgroup->get_option("extruder"); - option.opt.default_value = new ConfigOptionInt(1); - optgroup->append_single_option_line(option); - - m_optgroups.push_back(optgroup); // ogPartSettings - - auto sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(optgroup->sizer, 1, wxEXPAND | wxLEFT, 20); + auto add_btn = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + if (wxMSW) add_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + add_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG)); + sizer->Add(add_btn, 0, wxALIGN_LEFT | wxLEFT, 20); return sizer; } @@ -1030,9 +1020,8 @@ wxBoxSizer* content_part_settings(wxWindow *win) void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) { auto main_sizer = new wxBoxSizer(wxVERTICAL); - auto main_page = new wxPanel/*ScrolledWindow*/(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + auto main_page = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); main_page->SetSizer(main_sizer); -// main_page->SetScrollbars(0, 1, 1, 1); sizer->Add(main_page, 1, wxEXPAND | wxALL, 1); // Experiments with new UI @@ -1044,17 +1033,19 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) if (collpane->IsCollapsed()) { m_sizer_object_buttons->Show(false); m_sizer_part_buttons->Show(false); + m_collpane_settings->Show(false); } else m_objects_ctrl->UnselectAll(); g_right_panel->Layout(); })); + // *** Edit Object Buttons*** main_sizer->Add(content_edit_object_buttons(main_page), 0, wxEXPAND, 0); - // *** Object Settings *** - add_prusa_collapsible_pane(main_page, main_sizer, "Object Settings:", content_object_settings); - // *** Part Settings *** - add_prusa_collapsible_pane(main_page, main_sizer, "Part Settings:", content_part_settings); + + // *** Object/Part Settings *** + m_collpane_settings = add_prusa_collapsible_pane(main_page, main_sizer, "Settings:", content_settings); + m_collpane_settings->Show(false); // More experiments with UI From d7d0edf4dc35a2c2909a2ade506e75f628d4ab9a Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 28 May 2018 12:04:39 +0200 Subject: [PATCH 020/119] edit_object_buttons moved to Object/Part Settings --- xs/src/slic3r/GUI/GUI.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 166fc9c26..bbb113105 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1007,6 +1007,8 @@ wxBoxSizer* content_settings(wxWindow *win) m_optgroups.push_back(optgroup); // ogObjectSettings auto sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(content_edit_object_buttons(win), 0, wxEXPAND, 0); // *** Edit Object Buttons*** + sizer->Add(optgroup->sizer, 1, wxEXPAND | wxLEFT, 20); auto add_btn = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); @@ -1040,9 +1042,6 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) g_right_panel->Layout(); })); - // *** Edit Object Buttons*** - main_sizer->Add(content_edit_object_buttons(main_page), 0, wxEXPAND, 0); - // *** Object/Part Settings *** m_collpane_settings = add_prusa_collapsible_pane(main_page, main_sizer, "Settings:", content_settings); m_collpane_settings->Show(false); From c7d7da452e28eac4c3b62ecfd670793dc7dce296 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 28 May 2018 17:08:48 +0200 Subject: [PATCH 021/119] Updated Collapsed/Layout for PrusaCollapsiblePane. Cleaned right_panel --- lib/Slic3r/GUI/Plater.pm | 48 +++++++++++++----------------- xs/src/slic3r/GUI/GUI.cpp | 47 +++++++++++++---------------- xs/src/slic3r/GUI/wxExtensions.cpp | 42 +++++++++++++++++++++++++- xs/src/slic3r/GUI/wxExtensions.hpp | 31 ++----------------- 4 files changed, 86 insertions(+), 82 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 68a06b01d..6649e491a 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -230,15 +230,7 @@ sub new { $self->{right_panel} = Wx::ScrolledWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); $self->{right_panel}->SetScrollbars(0, 1, 1, 1); - ### Scrolled Window for info boxes - my $scrolled_window_sizer = Wx::BoxSizer->new(wxVERTICAL); - $scrolled_window_sizer->SetMinSize([310, -1]); -# my $scrolled_window_panel = Wx::ScrolledWindow->new($self->{right_panel}, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - my $scrolled_window_panel = Wx::Panel->new($self->{right_panel}, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - $scrolled_window_panel->SetSizer($scrolled_window_sizer); -# $scrolled_window_panel->SetScrollbars(1, 1, 1, 1); - - $self->{list} = Wx::ListView->new($scrolled_window_panel, -1, wxDefaultPosition, wxDefaultSize, + $self->{list} = Wx::ListView->new($self->{right_panel}, -1, wxDefaultPosition, wxDefaultSize, wxLC_SINGLE_SEL | wxLC_REPORT | wxBORDER_SUNKEN | wxTAB_TRAVERSAL | wxWANTS_CHARS ); $self->{list}->InsertColumn(0, L("Name"), wxLIST_FORMAT_LEFT, 145); $self->{list}->InsertColumn(1, L("Copies"), wxLIST_FORMAT_CENTER, 45); @@ -424,7 +416,7 @@ sub new { my $object_info_sizer; { - my $box = Wx::StaticBox->new($scrolled_window_panel, -1, L("Info")); + my $box = Wx::StaticBox->new($self->{right_panel}, -1, L("Info")); $box->SetFont($Slic3r::GUI::small_bold_font); $object_info_sizer = Wx::StaticBoxSizer->new($box, wxVERTICAL); $object_info_sizer->SetMinSize([300,-1]); @@ -443,14 +435,14 @@ sub new { ); while (my $field = shift @info) { my $label = shift @info; - my $text = Wx::StaticText->new($scrolled_window_panel, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + my $text = Wx::StaticText->new($self->{right_panel}, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); $text->SetFont($Slic3r::GUI::small_font); $grid_sizer->Add($text, 0); - $self->{"object_info_$field"} = Wx::StaticText->new($scrolled_window_panel, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + $self->{"object_info_$field"} = Wx::StaticText->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); $self->{"object_info_$field"}->SetFont($Slic3r::GUI::small_font); if ($field eq 'manifold') { - $self->{object_info_manifold_warning_icon} = Wx::StaticBitmap->new($scrolled_window_panel, -1, Wx::Bitmap->new(Slic3r::var("error.png"), wxBITMAP_TYPE_PNG)); + $self->{object_info_manifold_warning_icon} = Wx::StaticBitmap->new($self->{right_panel}, -1, Wx::Bitmap->new(Slic3r::var("error.png"), wxBITMAP_TYPE_PNG)); #$self->{object_info_manifold_warning_icon}->Hide; $self->{"object_info_manifold_warning_icon_show"} = sub { if ($self->{object_info_manifold_warning_icon}->IsShown() != $_[0]) { @@ -475,7 +467,7 @@ sub new { my $print_info_sizer; { - my $box = Wx::StaticBox->new($scrolled_window_panel, -1, L("Sliced Info")); + my $box = Wx::StaticBox->new($self->{right_panel}, -1, L("Sliced Info")); $box->SetFont($Slic3r::GUI::small_bold_font); $print_info_sizer = Wx::StaticBoxSizer->new($box, wxVERTICAL); $print_info_sizer->SetMinSize([300,-1]); @@ -493,11 +485,11 @@ sub new { ); while (my $field = shift @info) { my $label = shift @info; - my $text = Wx::StaticText->new($scrolled_window_panel, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + my $text = Wx::StaticText->new($self->{right_panel}, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); $text->SetFont($Slic3r::GUI::small_font); $grid_sizer->Add($text, 0); - $self->{"print_info_$field"} = Wx::StaticText->new($scrolled_window_panel, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + $self->{"print_info_$field"} = Wx::StaticText->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); $self->{"print_info_$field"}->SetFont($Slic3r::GUI::small_font); $grid_sizer->Add($self->{"print_info_$field"}, 0); } @@ -511,18 +503,22 @@ sub new { $buttons_sizer->Add($self->{btn_print}, 0, wxALIGN_RIGHT, 0); $buttons_sizer->Add($self->{btn_send_gcode}, 0, wxALIGN_RIGHT, 0); #$buttons_sizer->Add($self->{btn_export_gcode}, 0, wxALIGN_RIGHT, 0); - - $scrolled_window_sizer->Add($self->{list}, 1, wxEXPAND, 5); - $scrolled_window_sizer->Add($object_info_sizer, 0, wxEXPAND | wxLEFT, 20); - $scrolled_window_sizer->Add($print_info_sizer, 0, wxEXPAND | wxLEFT, 20); + + ### Sizer for info boxes + my $info_sizer = Wx::BoxSizer->new(wxVERTICAL); + $info_sizer->SetMinSize([310, -1]); + $info_sizer->Add($self->{list}, 1, wxEXPAND, 5); + $info_sizer->Add($object_info_sizer, 0, wxEXPAND | wxBOTTOM, 5); + $info_sizer->Add($print_info_sizer, 0, wxEXPAND | wxBOTTOM, 5); my $right_sizer = Wx::BoxSizer->new(wxVERTICAL); + $self->{right_panel}->SetSizer($right_sizer); $right_sizer->SetMinSize([320, -1]); $right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets; $right_sizer->Add($frequently_changed_parameters_sizer, 1, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; $right_sizer->Add($expert_mode_part_sizer, 0, wxEXPAND | wxTOP, 0) if defined $expert_mode_part_sizer; $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5); - $right_sizer->Add($scrolled_window_panel, 0, wxEXPAND | wxALL, 1); + $right_sizer->Add($info_sizer, 0, wxEXPAND | wxLEFT, 20); $right_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 20); # Callback for showing / hiding the print info box. $self->{"print_info_box_show"} = sub { @@ -530,18 +526,16 @@ sub new { # $right_sizer->Show(5, $_[0]); # $self->Layout # } - if ($scrolled_window_sizer->IsShown(2) != $_[0]) { + if ($info_sizer->IsShown(2) != $_[0]) { Slic3r::GUI::set_show_print_info($_[0]); return if (wxTheApp->{app_config}->get("view_mode") eq "simple"); - $scrolled_window_sizer->Show(2, $_[0]); - $scrolled_window_panel->Layout + $info_sizer->Show(2, $_[0]); + $self->{right_panel}->Layout } }; # Show the box initially, let it be shown after the slicing is finished. $self->{"print_info_box_show"}->(0); - $self->{right_panel}->SetSizer($right_sizer); - my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL); $hsizer->Add($self->{preview_notebook}, 1, wxEXPAND | wxTOP, 1); $hsizer->Add($self->{right_panel}, 0, wxEXPAND | wxLEFT | wxRIGHT, 3); @@ -558,7 +552,7 @@ sub new { Slic3r::GUI::set_objects_from_perl( $self->{right_panel}, $frequently_changed_parameters_sizer, $expert_mode_part_sizer, - $scrolled_window_sizer, + $info_sizer, $self->{btn_export_gcode}, $self->{btn_export_stl}, $self->{btn_reslice}, diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index bbb113105..170051207 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -142,10 +142,11 @@ wxDataViewCtrl *m_objects_ctrl = nullptr; PrusaCollapsiblePane *m_collpane_settings = nullptr; wxFont g_small_font{ wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; -#ifdef __WXMAC__ -g_small_font->SetPointSize(11); -#endif /*__WXMAC__*/ wxFont g_bold_font{ wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold() }; +#ifdef __WXMAC__ +g_small_font.SetPointSize(11); +g_bold_font.SetPointSize(11); +#endif /*__WXMAC__*/ static void init_label_colours() { @@ -833,7 +834,6 @@ wxString from_u8(const std::string &str) PrusaCollapsiblePane* add_prusa_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, const wxString& name, std::function content_function) { auto *collpane = new PrusaCollapsiblePane(parent, wxID_ANY, name); - collpane->SetTopParent(g_right_panel); // add the pane with a zero proportion value to the sizer which contains it sizer_parent->Add(collpane, 0, wxGROW | wxALL, 0); @@ -844,14 +844,14 @@ PrusaCollapsiblePane* add_prusa_collapsible_pane(wxWindow* parent, wxBoxSizer* s wxSizer *sizer_pane = new wxBoxSizer(wxVERTICAL); sizer_pane->Add(sizer, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); win->SetSizer(sizer_pane); - sizer_pane->SetSizeHints(win); +// sizer_pane->SetSizeHints(win); return collpane; } wxBoxSizer* content_objects_list(wxWindow *win) { m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); - m_objects_ctrl->SetBestFittingSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects + m_objects_ctrl->SetInitialSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects auto objects_sz = new wxBoxSizer(wxVERTICAL); objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT/*ALL*/, 20/*5*/); @@ -883,18 +883,17 @@ wxBoxSizer* content_objects_list(wxWindow *win) wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); m_objects_ctrl->AppendColumn(column02); - m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [objects_model](wxCommandEvent& evt) + m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [objects_model](wxEvent& evt) { wxWindowUpdateLocker noUpdates(g_right_panel); auto item = m_objects_ctrl->GetSelection(); if (!item) return; +// m_objects_ctrl->SetSize(m_objects_ctrl->GetBestSize()); // TODO override GetBestSize(), than use it auto show_obj_sizer = objects_model->GetParent(item) == wxDataViewItem(0); m_sizer_object_buttons->Show(show_obj_sizer); m_sizer_part_buttons->Show(!show_obj_sizer); m_collpane_settings->SetLabelText((show_obj_sizer ? _(L("Object Settings")) : _(L("Part Settings"))) + ":"); - m_collpane_settings->Show(true); - - g_right_panel->Layout(); + m_collpane_settings->show_it(true); }); return objects_sz; @@ -921,15 +920,13 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) btn_move_up->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_up.png")), wxBITMAP_TYPE_PNG)); btn_move_down->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_down.png")), wxBITMAP_TYPE_PNG)); - m_sizer_object_buttons = new /*wxFlex*/wxGridSizer(1, 3, 0, 0); -// static_cast(m_sizer_object_buttons)->SetFlexibleDirection(wxBOTH); + m_sizer_object_buttons = new wxGridSizer(1, 3, 0, 0); m_sizer_object_buttons->Add(btn_load_part, 0, wxEXPAND); m_sizer_object_buttons->Add(btn_load_modifier, 0, wxEXPAND); m_sizer_object_buttons->Add(btn_load_lambda_modifier, 0, wxEXPAND); m_sizer_object_buttons->Show(false); - m_sizer_part_buttons = new /*wxFlex*/wxGridSizer(1, 3, 0, 0); -// m_sizer_part_buttons->SetFlexibleDirection(wxBOTH); + m_sizer_part_buttons = new wxGridSizer(1, 3, 0, 0); m_sizer_part_buttons->Add(btn_delete, 0, wxEXPAND); m_sizer_part_buttons->Add(btn_split, 0, wxEXPAND); { @@ -948,8 +945,8 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) btn_move_up->SetFont(Slic3r::GUI::small_font()); btn_move_down->SetFont(Slic3r::GUI::small_font()); - sizer->Add(m_sizer_object_buttons, 0, wxEXPAND|wxLEFT, 20/*wxALIGN_CENTER_HORIZONTAL*/); - sizer->Add(m_sizer_part_buttons, 0, wxEXPAND|wxLEFT, 20/*wxALIGN_CENTER_HORIZONTAL*/); + sizer->Add(m_sizer_object_buttons, 0, wxEXPAND|wxLEFT, 20); + sizer->Add(m_sizer_part_buttons, 0, wxEXPAND|wxLEFT, 20); return sizer; } @@ -1021,31 +1018,29 @@ wxBoxSizer* content_settings(wxWindow *win) void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) { - auto main_sizer = new wxBoxSizer(wxVERTICAL); - auto main_page = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); - main_page->SetSizer(main_sizer); - sizer->Add(main_page, 1, wxEXPAND | wxALL, 1); + wxWindowUpdateLocker noUpdates(parent); // Experiments with new UI // *** Objects List *** - auto collpane = add_prusa_collapsible_pane(main_page, main_sizer, "Objects List:", content_objects_list); - collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([collpane](wxCommandEvent e){ + auto collpane = add_prusa_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); + collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([collpane](wxCommandEvent& e){ + e.Skip(); wxWindowUpdateLocker noUpdates(g_right_panel); if (collpane->IsCollapsed()) { m_sizer_object_buttons->Show(false); m_sizer_part_buttons->Show(false); - m_collpane_settings->Show(false); + m_collpane_settings->show_it(false); } else m_objects_ctrl->UnselectAll(); + g_right_panel->Layout(); })); // *** Object/Part Settings *** - m_collpane_settings = add_prusa_collapsible_pane(main_page, main_sizer, "Settings:", content_settings); - m_collpane_settings->Show(false); - + m_collpane_settings = add_prusa_collapsible_pane(parent, sizer, "Settings:", content_settings); + m_collpane_settings->Hide(); // ? TODO why doesn't work? // More experiments with UI // auto listctrl = new wxDataViewListCtrl(main_page, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index d993b2240..eb851ffd4 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -257,6 +257,36 @@ void PrusaCollapsiblePane::UpdateBtnBmp() Layout(); } +void PrusaCollapsiblePane::OnStateChange_(const wxSize& sz) +{ + SetSize(sz); + + if (this->HasFlag(wxCP_NO_TLW_RESIZE)) + { + // the user asked to explicitly handle the resizing itself... + return; + } + + auto top = GetParent(); //right_panel + if (!top) + return; + + wxSizer *sizer = top->GetSizer(); + if (!sizer) + return; + + const wxSize newBestSize = sizer->ComputeFittingClientSize(top); + top->SetMinClientSize(newBestSize); + + wxWindowUpdateLocker noUpdates_p(top->GetParent()); + // we shouldn't attempt to resize a maximized window, whatever happens +// if (!top->IsMaximized()) +// top->SetClientSize(newBestSize); + top->GetParent()->Layout(); + top->Refresh(); +} + + void PrusaCollapsiblePane::Collapse(bool collapse) { // optimization @@ -268,10 +298,20 @@ void PrusaCollapsiblePane::Collapse(bool collapse) // update our state m_pPane->Show(!collapse); + // update button label +#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__) + m_pButton->SetOpen(!collapse); +#else +#ifdef __WXMSW__ // update button bitmap UpdateBtnBmp(); +#else + // NB: this must be done after updating our "state" + m_pButton->SetLabel(GetBtnLabel()); +#endif //__WXMSW__ +#endif - OnStateChange(GetBestSize()); + OnStateChange_(GetBestSize()); } void PrusaCollapsiblePane::SetLabel(const wxString &label) diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index b256ac8bb..51c77210e 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -84,7 +84,6 @@ class PrusaCollapsiblePane : public wxCollapsiblePane wxBitmap m_bmp_close; wxBitmap m_bmp_open; #endif //__WXMSW__ - wxWindow* m_top_parent = nullptr; public: PrusaCollapsiblePane() {} PrusaCollapsiblePane( wxWindow *parent, @@ -101,35 +100,10 @@ public: #else Create(parent, winid, label); #endif //__WXMSW__ - this->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([parent, this](wxCommandEvent e){ - wxWindowUpdateLocker noUpdates_cp(this); - wxWindowUpdateLocker noUpdates(parent); - - parent->Layout(); - this->Refresh(); - - if (m_top_parent) - { - m_top_parent->GetSizer()->Layout(); - } - else{ - wxGetTopLevelParent(this)->Layout(); - } - -// if (parent->GetParent()){ -// parent->GetParent()->Layout(); -// parent->Refresh(); -// } -// else{ -// parent->Layout(); -// this->Refresh();} - })); } ~PrusaCollapsiblePane() {} - void SetTopParent(wxWindow *parent) { m_top_parent = parent; } - #ifdef __WXMSW__ bool Create(wxWindow *parent, wxWindowID id, @@ -141,11 +115,12 @@ public: const wxString& name); void UpdateBtnBmp(); - void Collapse(bool collapse) override; void SetLabel(const wxString &label) override; bool Layout() override; #endif //__WXMSW__ - + void Collapse(bool collapse) override; + void OnStateChange_(const wxSize& sz); //override of OnStateChange + void show_it(bool show) { Show(show); OnStateChange_(GetBestSize()); } }; From 45b6c99353c062558d04a3d453008cd0501dfd8d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 29 May 2018 20:55:43 +0200 Subject: [PATCH 022/119] print_info_box is correct placed on right_panel --- lib/Slic3r/GUI/Plater.pm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 6649e491a..98c9a9466 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -529,8 +529,9 @@ sub new { if ($info_sizer->IsShown(2) != $_[0]) { Slic3r::GUI::set_show_print_info($_[0]); return if (wxTheApp->{app_config}->get("view_mode") eq "simple"); - $info_sizer->Show(2, $_[0]); - $self->{right_panel}->Layout + $info_sizer->Show(2, $_[0]); + $self->Layout; + $self->{right_panel}->Refresh; } }; # Show the box initially, let it be shown after the slicing is finished. From db7c58009c1ea375f72c7feac9cbb5305b2ec55b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 29 May 2018 22:45:35 +0200 Subject: [PATCH 023/119] Added "Add/Delete" functions to the MyObjectTreeModel --- xs/src/slic3r/GUI/GUI.cpp | 34 ++++++++++++++--- xs/src/slic3r/GUI/wxExtensions.cpp | 60 +++++++++++++++++++++--------- xs/src/slic3r/GUI/wxExtensions.hpp | 10 ++--- 3 files changed, 76 insertions(+), 28 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 170051207..991402a51 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -138,7 +138,8 @@ bool g_show_print_info = false; bool g_show_manifold_warning_icon = false; wxSizer *m_sizer_object_buttons = nullptr; wxSizer *m_sizer_part_buttons = nullptr; -wxDataViewCtrl *m_objects_ctrl = nullptr; +wxDataViewCtrl *m_objects_ctrl = nullptr; +MyObjectTreeModel *m_objects_model = nullptr; PrusaCollapsiblePane *m_collpane_settings = nullptr; wxFont g_small_font{ wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; @@ -853,10 +854,10 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); m_objects_ctrl->SetInitialSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects auto objects_sz = new wxBoxSizer(wxVERTICAL); - objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT/*ALL*/, 20/*5*/); + objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT, 20); - auto objects_model = new MyObjectTreeModel; - m_objects_ctrl->AssociateModel(objects_model); + m_objects_model = new MyObjectTreeModel; + m_objects_ctrl->AssociateModel(m_objects_model); #if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE m_objects_ctrl->EnableDragSource(wxDF_UNICODETEXT); m_objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT); @@ -883,13 +884,13 @@ wxBoxSizer* content_objects_list(wxWindow *win) wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); m_objects_ctrl->AppendColumn(column02); - m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [objects_model](wxEvent& evt) + m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& evt) { wxWindowUpdateLocker noUpdates(g_right_panel); auto item = m_objects_ctrl->GetSelection(); if (!item) return; // m_objects_ctrl->SetSize(m_objects_ctrl->GetBestSize()); // TODO override GetBestSize(), than use it - auto show_obj_sizer = objects_model->GetParent(item) == wxDataViewItem(0); + auto show_obj_sizer = m_objects_model->GetParent(item) == wxDataViewItem(0); m_sizer_object_buttons->Show(show_obj_sizer); m_sizer_part_buttons->Show(!show_obj_sizer); m_collpane_settings->SetLabelText((show_obj_sizer ? _(L("Object Settings")) : _(L("Part Settings"))) + ":"); @@ -910,6 +911,17 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) auto btn_split = new wxButton(win, wxID_ANY, "Split"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); auto btn_move_up = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); auto btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); + + //*** button's functions + btn_load_part->Bind(wxEVT_BUTTON, [](wxEvent&) + { + auto item = m_objects_ctrl->GetSelection(); + if (!item) return; + wxString name = "Part"; + m_objects_model->AddChild(item, name); + }); + //*** + btn_move_up->SetMinSize(wxSize(20, -1)); btn_move_down->SetMinSize(wxSize(20, -1)); btn_load_part->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); @@ -1021,6 +1033,10 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) wxWindowUpdateLocker noUpdates(parent); // Experiments with new UI + auto add_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + if (wxMSW) add_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + add_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG)); + sizer->Add(add_btn, 0, wxALIGN_LEFT | wxLEFT, 20); // *** Objects List *** auto collpane = add_prusa_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); @@ -1042,6 +1058,12 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) m_collpane_settings = add_prusa_collapsible_pane(parent, sizer, "Settings:", content_settings); m_collpane_settings->Hide(); // ? TODO why doesn't work? + add_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) + { + wxString name = "Object"; + m_objects_model->Add(name); + }); + // More experiments with UI // auto listctrl = new wxDataViewListCtrl(main_page, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); // listctrl->AppendToggleColumn("Toggle"); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index eb851ffd4..7e7792ee4 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -352,26 +352,52 @@ bool PrusaCollapsiblePane::Layout() // MyObjectTreeModel // ---------------------------------------------------------------------------- -MyObjectTreeModel::MyObjectTreeModel() +void MyObjectTreeModel::Add(wxString &name) { - auto root1 = new MyObjectTreeModelNode("Object1"); - m_objects.emplace(root1); + auto root = new MyObjectTreeModelNode(name); + m_objects.emplace(root); + // notify control + wxDataViewItem child((void*)root); + wxDataViewItem parent((void*)NULL); + ItemAdded(parent, child); +} - auto root2 = new MyObjectTreeModelNode("Object2"); - m_objects.emplace(root2); - root2->Append(new MyObjectTreeModelNode(root2, "SubObject2_1")); - root2->Append(new MyObjectTreeModelNode(root2, "SubObject2_2")); - root2->Append(new MyObjectTreeModelNode(root2, "SubObject2_3")); +void MyObjectTreeModel::AddChild(const wxDataViewItem &parent_item, wxString &name) +{ + MyObjectTreeModelNode *root = (MyObjectTreeModelNode*)parent_item.GetID(); + if (!root) return; - auto root3 = new MyObjectTreeModelNode("Object3"); - m_objects.emplace(root3); - auto root4 = new MyObjectTreeModelNode("Object4"); - m_objects.emplace(root4); - root4->Append(new MyObjectTreeModelNode(root4, "SubObject4_1")); - root4->Append(new MyObjectTreeModelNode(root4, "SubObject4_2")); + auto node = new MyObjectTreeModelNode(root, name); + root->Append(node); + // notify control + wxDataViewItem child((void*)node); + ItemAdded(parent_item, child); +} - auto root5 = new MyObjectTreeModelNode("Object5"); - m_objects.emplace(root5); +void MyObjectTreeModel::Delete(const wxDataViewItem &item) +{ + MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return; + + wxDataViewItem parent(node->GetParent()); + if (!parent.IsOk()) + { +// wxASSERT(node == m_root); + // don't make the control completely empty: + //wxLogError("Cannot remove the root item!"); + return; + } + + // first remove the node from the parent's array of children; + // NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_ + // thus removing the node from it doesn't result in freeing it + node->GetParent()->GetChildren().Remove(node); + // free the node + delete node; + + // notify control + ItemDeleted(parent, item); } wxString MyObjectTreeModel::GetName(const wxDataViewItem &item) const @@ -463,7 +489,7 @@ wxDataViewItem MyObjectTreeModel::GetParent(const wxDataViewItem &item) const MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); - // objects nodes also has no parent + // objects nodes has no parent too if (m_objects.find(node) != m_objects.end()) return wxDataViewItem(0); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 51c77210e..02bcfe148 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -209,13 +209,17 @@ class MyObjectTreeModel :public wxDataViewModel { std::set m_objects; public: - MyObjectTreeModel(); + MyObjectTreeModel(){} ~MyObjectTreeModel() { for (auto object : m_objects) delete object; } + void Add(wxString &name); + void AddChild(const wxDataViewItem &parent_item, wxString &name); + void Delete(const wxDataViewItem &item); + // helper method for wxLog wxString GetName(const wxDataViewItem &item) const; @@ -224,10 +228,6 @@ public: // helper methods to change the model -// void AddToClassical(const wxString &title, const wxString &artist, -// unsigned int year); -// void Delete(const wxDataViewItem &item); - virtual unsigned int GetColumnCount() const override { return 3;} virtual wxString GetColumnType(unsigned int col) const override{ return wxT("string"); } From 5c4c9121323b5f5d04db737fc046c7f1ada861b2 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 30 May 2018 00:36:44 +0200 Subject: [PATCH 024/119] Extended "Delete" functions --- xs/src/slic3r/GUI/GUI.cpp | 23 +++++++++++++++++++- xs/src/slic3r/GUI/wxExtensions.cpp | 34 +++++++++++++++++++++--------- xs/src/slic3r/GUI/wxExtensions.hpp | 3 ++- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 991402a51..296dd7691 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -920,6 +920,13 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) wxString name = "Part"; m_objects_model->AddChild(item, name); }); + + btn_delete->Bind(wxEVT_BUTTON, [](wxEvent&) + { + auto item = m_objects_ctrl->GetSelection(); + if (!item) return; + m_objects_model->Delete(item); + }); //*** btn_move_up->SetMinSize(wxSize(20, -1)); @@ -1036,7 +1043,12 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) auto add_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); if (wxMSW) add_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); add_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG)); - sizer->Add(add_btn, 0, wxALIGN_LEFT | wxLEFT, 20); + sizer->Add(add_btn, 0, wxALIGN_LEFT | wxLEFT | wxTOP, 20); + + auto del_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + if (wxMSW) del_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + del_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_delete.png")), wxBITMAP_TYPE_PNG)); + sizer->Add(del_btn, 0, wxALIGN_LEFT | wxLEFT, 20); // *** Objects List *** auto collpane = add_prusa_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); @@ -1064,6 +1076,15 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) m_objects_model->Add(name); }); + del_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) + { + auto item = m_objects_ctrl->GetSelection(); + if (!item) return; + m_objects_model->Delete(item); + if (m_objects_model->IsEmpty()) + m_collpane_settings->show_it(false); + }); + // More experiments with UI // auto listctrl = new wxDataViewListCtrl(main_page, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); // listctrl->AppendToggleColumn("Toggle"); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 7e7792ee4..84953ebaa 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -367,6 +367,15 @@ void MyObjectTreeModel::AddChild(const wxDataViewItem &parent_item, wxString &na MyObjectTreeModelNode *root = (MyObjectTreeModelNode*)parent_item.GetID(); if (!root) return; + if (root->GetChildren().Count() == 0) + { + auto node = new MyObjectTreeModelNode(root, root->m_name); + root->Append(node); + // notify control + wxDataViewItem child((void*)node); + ItemAdded(parent_item, child); + } + auto node = new MyObjectTreeModelNode(root, name); root->Append(node); // notify control @@ -380,22 +389,27 @@ void MyObjectTreeModel::Delete(const wxDataViewItem &item) if (!node) // happens if item.IsOk()==false return; - wxDataViewItem parent(node->GetParent()); - if (!parent.IsOk()) - { -// wxASSERT(node == m_root); - // don't make the control completely empty: - //wxLogError("Cannot remove the root item!"); - return; - } + auto node_parent = node->GetParent(); + wxDataViewItem parent(node_parent); // first remove the node from the parent's array of children; // NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_ // thus removing the node from it doesn't result in freeing it - node->GetParent()->GetChildren().Remove(node); + if (node_parent) + node_parent->GetChildren().Remove(node); + else + { + auto it = m_objects.find(node); + if (it != m_objects.end()) + m_objects.erase(it); + } // free the node delete node; + // set m_containet to FALSE if parent has no child + if (node_parent && node_parent->GetChildCount() == 0) + node_parent->m_container = false; + // notify control ItemDeleted(parent, item); } @@ -498,7 +512,7 @@ wxDataViewItem MyObjectTreeModel::GetParent(const wxDataViewItem &item) const bool MyObjectTreeModel::IsContainer(const wxDataViewItem &item) const { - // the invisble root node can have children + // the invisible root node can have children if (!item.IsOk()) return true; diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 02bcfe148..cabd1e7ca 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -195,7 +195,7 @@ public: m_container = true; m_children.Add(child); } - unsigned int GetChildCount() const + size_t GetChildCount() const { return m_children.GetCount(); } @@ -219,6 +219,7 @@ public: void Add(wxString &name); void AddChild(const wxDataViewItem &parent_item, wxString &name); void Delete(const wxDataViewItem &item); + bool IsEmpty() { return m_objects.empty(); } // helper method for wxLog From c857b68fbebec2745ea7f10654585c16eba14e54 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 30 May 2018 17:52:28 +0200 Subject: [PATCH 025/119] Functions "Add/Delete" objects to/from list works correct now --- xs/src/slic3r/GUI/GUI.cpp | 34 ++++++++++++++++-------- xs/src/slic3r/GUI/GUI.hpp | 4 +++ xs/src/slic3r/GUI/wxExtensions.cpp | 42 +++++++++++++++++++----------- xs/src/slic3r/GUI/wxExtensions.hpp | 8 +++--- xs/xsp/GUI.xsp | 6 +++++ 5 files changed, 64 insertions(+), 30 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 296dd7691..77a1a54b8 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -917,15 +917,18 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) { auto item = m_objects_ctrl->GetSelection(); if (!item) return; + if (m_objects_model->GetParent(item) != wxDataViewItem(0)) + item = m_objects_model->GetParent(item); + if (!item) return; wxString name = "Part"; - m_objects_model->AddChild(item, name); + m_objects_ctrl->Select(m_objects_model->AddChild(item, name)); }); btn_delete->Bind(wxEVT_BUTTON, [](wxEvent&) { auto item = m_objects_ctrl->GetSelection(); if (!item) return; - m_objects_model->Delete(item); + m_objects_ctrl->Select(m_objects_model->Delete(item)); }); //*** @@ -1035,6 +1038,22 @@ wxBoxSizer* content_settings(wxWindow *win) return sizer; } +void add_object(const std::string &name) +{ + wxString item = name; + m_objects_ctrl->Select(m_objects_model->Add(item)); +} + +void del_object() +{ + auto item = m_objects_ctrl->GetSelection(); + if (!item) return; + m_objects_ctrl->Select(m_objects_model->Delete(item)); + + if (m_objects_model->IsEmpty()) + m_collpane_settings->show_it(false); +} + void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) { wxWindowUpdateLocker noUpdates(parent); @@ -1073,17 +1092,10 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) add_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) { wxString name = "Object"; - m_objects_model->Add(name); + m_objects_ctrl->Select(m_objects_model->Add(name)); }); - del_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) - { - auto item = m_objects_ctrl->GetSelection(); - if (!item) return; - m_objects_model->Delete(item); - if (m_objects_model->IsEmpty()) - m_collpane_settings->show_it(false); - }); + del_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) { del_object(); }); // More experiments with UI // auto listctrl = new wxDataViewListCtrl(main_page, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 19ee54533..79dc2c595 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -174,6 +174,10 @@ wxString L_str(const std::string &str); // Return wxString from std::string in UTF8 wxString from_u8(const std::string &str); +// Add object to the list +void add_object(const std::string &name); +// Delete object from the list +void del_object(); void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 84953ebaa..ecb79caaf 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -352,20 +352,21 @@ bool PrusaCollapsiblePane::Layout() // MyObjectTreeModel // ---------------------------------------------------------------------------- -void MyObjectTreeModel::Add(wxString &name) +wxDataViewItem MyObjectTreeModel::Add(wxString &name) { auto root = new MyObjectTreeModelNode(name); - m_objects.emplace(root); + m_objects.push_back(root); // notify control wxDataViewItem child((void*)root); wxDataViewItem parent((void*)NULL); ItemAdded(parent, child); + return child; } -void MyObjectTreeModel::AddChild(const wxDataViewItem &parent_item, wxString &name) +wxDataViewItem MyObjectTreeModel::AddChild(const wxDataViewItem &parent_item, wxString &name) { MyObjectTreeModelNode *root = (MyObjectTreeModelNode*)parent_item.GetID(); - if (!root) return; + if (!root) return wxDataViewItem(0); if (root->GetChildren().Count() == 0) { @@ -381,13 +382,15 @@ void MyObjectTreeModel::AddChild(const wxDataViewItem &parent_item, wxString &na // notify control wxDataViewItem child((void*)node); ItemAdded(parent_item, child); + return child; } -void MyObjectTreeModel::Delete(const wxDataViewItem &item) +wxDataViewItem MyObjectTreeModel::Delete(const wxDataViewItem &item) { + auto ret_item = wxDataViewItem(0); MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); if (!node) // happens if item.IsOk()==false - return; + return ret_item; auto node_parent = node->GetParent(); wxDataViewItem parent(node_parent); @@ -395,23 +398,37 @@ void MyObjectTreeModel::Delete(const wxDataViewItem &item) // first remove the node from the parent's array of children; // NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_ // thus removing the node from it doesn't result in freeing it - if (node_parent) + if (node_parent){ + auto id = node_parent->GetChildren().Index(node); node_parent->GetChildren().Remove(node); + if (id > 0){ + if(id == node_parent->GetChildCount()) id--; + ret_item = wxDataViewItem(node_parent->GetChildren().Item(id)); + } + } else { - auto it = m_objects.find(node); + auto it = find(m_objects.begin(), m_objects.end(), node); + auto id = it - m_objects.begin(); if (it != m_objects.end()) m_objects.erase(it); + if (id > 0){ + if(id == m_objects.size()) id--; + ret_item = wxDataViewItem(m_objects[id]); + } } // free the node delete node; // set m_containet to FALSE if parent has no child - if (node_parent && node_parent->GetChildCount() == 0) + if (node_parent && node_parent->GetChildCount() == 0){ node_parent->m_container = false; + ret_item = parent; + } // notify control ItemDeleted(parent, item); + return ret_item; } wxString MyObjectTreeModel::GetName(const wxDataViewItem &item) const @@ -441,11 +458,6 @@ wxString MyObjectTreeModel::GetScale(const wxDataViewItem &item) const return node->m_scale; } -// void MyObjectTreeModel::Delete(const wxDataViewItem &item) -// { -// -// } - void MyObjectTreeModel::GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned int col) const { wxASSERT(item.IsOk()); @@ -504,7 +516,7 @@ wxDataViewItem MyObjectTreeModel::GetParent(const wxDataViewItem &item) const MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); // objects nodes has no parent too - if (m_objects.find(node) != m_objects.end()) + if (find(m_objects.begin(), m_objects.end(),node) != m_objects.end()) return wxDataViewItem(0); return wxDataViewItem((void*)node->GetParent()); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index cabd1e7ca..329eecd59 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -207,7 +207,7 @@ public: class MyObjectTreeModel :public wxDataViewModel { - std::set m_objects; + std::vector m_objects; public: MyObjectTreeModel(){} ~MyObjectTreeModel() @@ -216,9 +216,9 @@ public: delete object; } - void Add(wxString &name); - void AddChild(const wxDataViewItem &parent_item, wxString &name); - void Delete(const wxDataViewItem &item); + wxDataViewItem Add(wxString &name); + wxDataViewItem AddChild(const wxDataViewItem &parent_item, wxString &name); + wxDataViewItem Delete(const wxDataViewItem &item); bool IsEmpty() { return m_objects.empty(); } // helper method for wxLog diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index f7d84d87c..905954172 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -122,6 +122,12 @@ void set_show_manifold_warning_icon(bool show) void update_mode() %code%{ Slic3r::GUI::update_mode(); %}; +void add_object(const char *name) + %code%{ Slic3r::GUI::add_object(name); %}; + +void del_object() + %code%{ Slic3r::GUI::del_object(); %}; + std::string fold_utf8_to_ascii(const char *src) %code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %}; From 04dc50cec4d20079319f98588e86303ef2484645 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 4 Jun 2018 15:59:55 +0200 Subject: [PATCH 026/119] Add, Delete and DeleteAll are working for new list now --- lib/Slic3r/GUI/Plater.pm | 11 +++++++-- xs/src/slic3r/GUI/GUI.cpp | 38 ++++++++++++++++++++++-------- xs/src/slic3r/GUI/GUI.hpp | 7 ++++-- xs/src/slic3r/GUI/wxExtensions.cpp | 34 +++++++++++++++++++++++++- xs/src/slic3r/GUI/wxExtensions.hpp | 23 +++++++++++++++--- xs/xsp/GUI.xsp | 11 +++++---- 6 files changed, 102 insertions(+), 22 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 98c9a9466..a3f381e5c 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -515,10 +515,10 @@ sub new { $self->{right_panel}->SetSizer($right_sizer); $right_sizer->SetMinSize([320, -1]); $right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets; - $right_sizer->Add($frequently_changed_parameters_sizer, 1, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; + $right_sizer->Add($frequently_changed_parameters_sizer, 2, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; $right_sizer->Add($expert_mode_part_sizer, 0, wxEXPAND | wxTOP, 0) if defined $expert_mode_part_sizer; $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5); - $right_sizer->Add($info_sizer, 0, wxEXPAND | wxLEFT, 20); + $right_sizer->Add($info_sizer, 1, wxEXPAND | wxLEFT, 20); $right_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 20); # Callback for showing / hiding the print info box. $self->{"print_info_box_show"} = sub { @@ -847,6 +847,9 @@ sub load_model_objects { $self->{list}->SetItem($obj_idx, 1, $model_object->instances_count); $self->{list}->SetItem($obj_idx, 2, ($model_object->instances->[0]->scaling_factor * 100) . "%"); + + # Add object to list on c++ side + Slic3r::GUI::add_object_to_list($object->name, $model_object->instances_count, ($model_object->instances->[0]->scaling_factor * 100)); $self->reset_thumbnail($obj_idx); } @@ -894,6 +897,8 @@ sub remove { $self->{model}->delete_object($obj_idx); $self->{print}->delete_object($obj_idx); $self->{list}->DeleteItem($obj_idx); + # Delete object from list on c++ side + Slic3r::GUI::delete_object_from_list(); $self->object_list_changed; $self->select_object(undef); @@ -917,6 +922,8 @@ sub reset { $self->{model}->clear_objects; $self->{print}->clear_objects; $self->{list}->DeleteAllItems; + # Delete all objects from list on c++ side + Slic3r::GUI::delete_all_objects_from_list(); $self->object_list_changed; $self->select_object(undef); diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 77a1a54b8..7f26816f0 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -477,7 +477,7 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change) { - add_config_menu(menu, event_language_change, event_language_change); + add_config_menu(menu, event_preferences_changed, event_language_change); } // This is called when closing the application, when loading a config file or when starting the config wizard @@ -1038,36 +1038,52 @@ wxBoxSizer* content_settings(wxWindow *win) return sizer; } -void add_object(const std::string &name) +void add_object_to_list(const std::string &name, int instances_count, int scale) { wxString item = name; - m_objects_ctrl->Select(m_objects_model->Add(item)); + m_objects_ctrl->Select(m_objects_model->Add(item, instances_count, scale)); } -void del_object() +void delete_object_from_list() { auto item = m_objects_ctrl->GetSelection(); - if (!item) return; - m_objects_ctrl->Select(m_objects_model->Delete(item)); + if (!item || m_objects_model->GetParent(item) != wxDataViewItem(0)) + return; +// m_objects_ctrl->Select(m_objects_model->Delete(item)); + m_objects_model->Delete(item); if (m_objects_model->IsEmpty()) m_collpane_settings->show_it(false); } +void delete_all_objects_from_list() +{ + m_objects_model->DeleteAll(); + m_collpane_settings->show_it(false); +} + void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) { wxWindowUpdateLocker noUpdates(parent); + auto btn_grid_sizer = new wxGridSizer(1, 3, 2, 2); + sizer->Add(btn_grid_sizer, 0, wxALIGN_LEFT | wxLEFT, 20); + // Experiments with new UI auto add_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); if (wxMSW) add_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); add_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG)); - sizer->Add(add_btn, 0, wxALIGN_LEFT | wxLEFT | wxTOP, 20); + btn_grid_sizer->Add(add_btn, 0, wxEXPAND, 0); auto del_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); if (wxMSW) del_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); del_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_delete.png")), wxBITMAP_TYPE_PNG)); - sizer->Add(del_btn, 0, wxALIGN_LEFT | wxLEFT, 20); + btn_grid_sizer->Add(del_btn, 0, wxEXPAND, 0); + + auto del_all_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + if (wxMSW) del_all_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + del_all_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("delete.png")), wxBITMAP_TYPE_PNG)); + btn_grid_sizer->Add(del_all_btn, 0, wxEXPAND, 0); // *** Objects List *** auto collpane = add_prusa_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); @@ -1095,7 +1111,9 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) m_objects_ctrl->Select(m_objects_model->Add(name)); }); - del_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) { del_object(); }); + del_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) { delete_object_from_list(); }); + + del_all_btn->Bind(wxEVT_BUTTON, [](wxEvent&) { delete_all_objects_from_list(); }); // More experiments with UI // auto listctrl = new wxDataViewListCtrl(main_page, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); @@ -1302,7 +1320,7 @@ void show_buttons(bool show) void show_scrolled_window_sizer(bool show) { - g_scrolled_window_sizer->Show(static_cast(0), false/*show*/); //don't used now + g_scrolled_window_sizer->Show(static_cast(0), /*false*/show); //don't used now g_scrolled_window_sizer->Show(1, show); g_scrolled_window_sizer->Show(2, show && g_show_print_info); g_manifold_warning_icon->Show(show && g_show_manifold_warning_icon); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 79dc2c595..293183e7d 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -175,9 +175,12 @@ wxString L_str(const std::string &str); wxString from_u8(const std::string &str); // Add object to the list -void add_object(const std::string &name); +//void add_object(const std::string &name); +void add_object_to_list(const std::string &name, int instances_count=1, int scale=100); // Delete object from the list -void del_object(); +void delete_object_from_list(); +// Delete all objects from the list +void delete_all_objects_from_list(); void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index ecb79caaf..268267cd2 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -363,6 +363,17 @@ wxDataViewItem MyObjectTreeModel::Add(wxString &name) return child; } +wxDataViewItem MyObjectTreeModel::Add(wxString &name, int instances_count, int scale) +{ + auto root = new MyObjectTreeModelNode(name, instances_count, scale); + m_objects.push_back(root); + // notify control + wxDataViewItem child((void*)root); + wxDataViewItem parent((void*)NULL); + ItemAdded(parent, child); + return child; +} + wxDataViewItem MyObjectTreeModel::AddChild(const wxDataViewItem &parent_item, wxString &name) { MyObjectTreeModelNode *root = (MyObjectTreeModelNode*)parent_item.GetID(); @@ -431,6 +442,27 @@ wxDataViewItem MyObjectTreeModel::Delete(const wxDataViewItem &item) return ret_item; } +void MyObjectTreeModel::DeleteAll() +{ + while (!m_objects.empty()) + { + auto object = m_objects.back(); +// object->RemoveAllChildren(); + Delete(wxDataViewItem(object)); + } +} + +wxDataViewItem MyObjectTreeModel::GetItemById(int obj_idx) +{ + if (obj_idx >= m_objects.size()) + { + printf("Error! Out of objects range.\n"); + return wxDataViewItem(0); + } + return wxDataViewItem(m_objects[obj_idx]); +} + + wxString MyObjectTreeModel::GetName(const wxDataViewItem &item) const { MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); @@ -475,7 +507,7 @@ void MyObjectTreeModel::GetValue(wxVariant &variant, const wxDataViewItem &item, variant = node->m_scale; break; default: - ;// wxLogError("MyMusicTreeModel::GetValue: wrong column %d", col); + ; } } diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 329eecd59..189637de5 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -137,11 +137,11 @@ class MyObjectTreeModelNode MyObjectTreeModelNode* m_parent; MyObjectTreeModelNodePtrArray m_children; public: - MyObjectTreeModelNode( const wxString &name) { + MyObjectTreeModelNode(const wxString &name, int instances_count=1, int scale=100) { m_parent = NULL; m_name = name; - m_copy = "1"; - m_scale = "100%"; + m_copy = wxString::Format("%d", instances_count); + m_scale = wxString::Format("%d%%", scale); } MyObjectTreeModelNode( MyObjectTreeModelNode* parent, @@ -195,6 +195,20 @@ public: m_container = true; m_children.Add(child); } + void RemoveAllChildren() + { + if (GetChildCount() == 0) + return; + for (size_t id = GetChildCount() - 1; id >= 0; --id) + { + if (m_children.Item(id)->GetChildCount() > 0) + m_children[id]->RemoveAllChildren(); + auto node = m_children[id]; + m_children.RemoveAt(id); + delete node; + } + } + size_t GetChildCount() const { return m_children.GetCount(); @@ -217,8 +231,11 @@ public: } wxDataViewItem Add(wxString &name); + wxDataViewItem Add(wxString &name, int instances_count, int scale); wxDataViewItem AddChild(const wxDataViewItem &parent_item, wxString &name); wxDataViewItem Delete(const wxDataViewItem &item); + void DeleteAll(); + wxDataViewItem GetItemById(int obj_idx); bool IsEmpty() { return m_objects.empty(); } // helper method for wxLog diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 905954172..b38970c09 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -122,11 +122,14 @@ void set_show_manifold_warning_icon(bool show) void update_mode() %code%{ Slic3r::GUI::update_mode(); %}; -void add_object(const char *name) - %code%{ Slic3r::GUI::add_object(name); %}; +void add_object_to_list(const char *name, int instances_count, int scale) + %code%{ Slic3r::GUI::add_object_to_list(name, instances_count, scale); %}; -void del_object() - %code%{ Slic3r::GUI::del_object(); %}; +void delete_object_from_list() + %code%{ Slic3r::GUI::delete_object_from_list(); %}; + +void delete_all_objects_from_list() + %code%{ Slic3r::GUI::delete_all_objects_from_list(); %}; std::string fold_utf8_to_ascii(const char *src) %code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %}; From bb27d62ba8029dc8ca81bd820d89fc289d354f3d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 5 Jun 2018 09:13:03 +0200 Subject: [PATCH 027/119] Try to fix compilation bug --- xs/src/slic3r/GUI/GUI.cpp | 17 +++-- xs/src/slic3r/GUI/wxExtensions.cpp | 113 ++++++++++++++--------------- 2 files changed, 67 insertions(+), 63 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 7f26816f0..9473dd23c 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -142,12 +142,8 @@ wxDataViewCtrl *m_objects_ctrl = nullptr; MyObjectTreeModel *m_objects_model = nullptr; PrusaCollapsiblePane *m_collpane_settings = nullptr; -wxFont g_small_font{ wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; -wxFont g_bold_font{ wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold() }; -#ifdef __WXMAC__ -g_small_font.SetPointSize(11); -g_bold_font.SetPointSize(11); -#endif /*__WXMAC__*/ +wxFont g_small_font { wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; +wxFont g_bold_font { wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold() }; static void init_label_colours() { @@ -177,10 +173,19 @@ void update_label_colours_from_appconfig() } } +static void init_fonts() +{ +#ifdef __WXMAC__ + g_small_font.SetPointSize(11); + g_bold_font.SetPointSize(11); +#endif /*__WXMAC__*/ +} + void set_wxapp(wxApp *app) { g_wxApp = app; init_label_colours(); + init_fonts(); } void set_main_frame(wxFrame *main_frame) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 268267cd2..970102ec0 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -257,63 +257,6 @@ void PrusaCollapsiblePane::UpdateBtnBmp() Layout(); } -void PrusaCollapsiblePane::OnStateChange_(const wxSize& sz) -{ - SetSize(sz); - - if (this->HasFlag(wxCP_NO_TLW_RESIZE)) - { - // the user asked to explicitly handle the resizing itself... - return; - } - - auto top = GetParent(); //right_panel - if (!top) - return; - - wxSizer *sizer = top->GetSizer(); - if (!sizer) - return; - - const wxSize newBestSize = sizer->ComputeFittingClientSize(top); - top->SetMinClientSize(newBestSize); - - wxWindowUpdateLocker noUpdates_p(top->GetParent()); - // we shouldn't attempt to resize a maximized window, whatever happens -// if (!top->IsMaximized()) -// top->SetClientSize(newBestSize); - top->GetParent()->Layout(); - top->Refresh(); -} - - -void PrusaCollapsiblePane::Collapse(bool collapse) -{ - // optimization - if (IsCollapsed() == collapse) - return; - - InvalidateBestSize(); - - // update our state - m_pPane->Show(!collapse); - - // update button label -#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__) - m_pButton->SetOpen(!collapse); -#else -#ifdef __WXMSW__ - // update button bitmap - UpdateBtnBmp(); -#else - // NB: this must be done after updating our "state" - m_pButton->SetLabel(GetBtnLabel()); -#endif //__WXMSW__ -#endif - - OnStateChange_(GetBestSize()); -} - void PrusaCollapsiblePane::SetLabel(const wxString &label) { m_strLabel = label; @@ -347,6 +290,62 @@ bool PrusaCollapsiblePane::Layout() } #endif //__WXMSW__ +void PrusaCollapsiblePane::OnStateChange_(const wxSize& sz) +{ + SetSize(sz); + + if (this->HasFlag(wxCP_NO_TLW_RESIZE)) + { + // the user asked to explicitly handle the resizing itself... + return; + } + + auto top = GetParent(); //right_panel + if (!top) + return; + + wxSizer *sizer = top->GetSizer(); + if (!sizer) + return; + + const wxSize newBestSize = sizer->ComputeFittingClientSize(top); + top->SetMinClientSize(newBestSize); + + wxWindowUpdateLocker noUpdates_p(top->GetParent()); + // we shouldn't attempt to resize a maximized window, whatever happens +// if (!top->IsMaximized()) +// top->SetClientSize(newBestSize); + top->GetParent()->Layout(); + top->Refresh(); +} + +void PrusaCollapsiblePane::Collapse(bool collapse) +{ + // optimization + if (IsCollapsed() == collapse) + return; + + InvalidateBestSize(); + + // update our state + m_pPane->Show(!collapse); + + // update button label +#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__) + m_pButton->SetOpen(!collapse); +#else +#ifdef __WXMSW__ + // update button bitmap + UpdateBtnBmp(); +#else + // NB: this must be done after updating our "state" + m_pButton->SetLabel(GetBtnLabel()); +#endif //__WXMSW__ +#endif + + OnStateChange_(GetBestSize()); +} + // ***************************************************************************** // ---------------------------------------------------------------------------- // MyObjectTreeModel From 72541ad13e3c8580a57512d02a5c2a90d584837e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 5 Jun 2018 10:41:20 +0200 Subject: [PATCH 028/119] Next try to fix OSX/Linux compilation bug --- xs/src/slic3r/GUI/GUI.cpp | 22 +++++++++++++--------- xs/src/slic3r/GUI/wxExtensions.cpp | 8 ++++++++ xs/src/slic3r/GUI/wxExtensions.hpp | 27 ++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 9473dd23c..b0a7751a5 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -140,7 +140,7 @@ wxSizer *m_sizer_object_buttons = nullptr; wxSizer *m_sizer_part_buttons = nullptr; wxDataViewCtrl *m_objects_ctrl = nullptr; MyObjectTreeModel *m_objects_model = nullptr; -PrusaCollapsiblePane *m_collpane_settings = nullptr; +wxCollapsiblePane *m_collpane_settings = nullptr; wxFont g_small_font { wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; wxFont g_bold_font { wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold() }; @@ -836,10 +836,14 @@ wxString from_u8(const std::string &str) return wxString::FromUTF8(str.c_str()); } -// add PrusaCollapsiblePane to sizer -PrusaCollapsiblePane* add_prusa_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, const wxString& name, std::function content_function) +// add Collapsible Pane to sizer +wxCollapsiblePane* add_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, const wxString& name, std::function content_function) { +#ifdef __WXMSW__ auto *collpane = new PrusaCollapsiblePane(parent, wxID_ANY, name); +#else + auto *collpane = new wxCollapsiblePane(parent, wxID_ANY, name); +#endif // __WXMSW__ // add the pane with a zero proportion value to the sizer which contains it sizer_parent->Add(collpane, 0, wxGROW | wxALL, 0); @@ -899,7 +903,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_sizer_object_buttons->Show(show_obj_sizer); m_sizer_part_buttons->Show(!show_obj_sizer); m_collpane_settings->SetLabelText((show_obj_sizer ? _(L("Object Settings")) : _(L("Part Settings"))) + ":"); - m_collpane_settings->show_it(true); + m_collpane_settings->Show(true); }); return objects_sz; @@ -1058,13 +1062,13 @@ void delete_object_from_list() m_objects_model->Delete(item); if (m_objects_model->IsEmpty()) - m_collpane_settings->show_it(false); + m_collpane_settings->Show(false); } void delete_all_objects_from_list() { m_objects_model->DeleteAll(); - m_collpane_settings->show_it(false); + m_collpane_settings->Show(false); } void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) @@ -1091,14 +1095,14 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) btn_grid_sizer->Add(del_all_btn, 0, wxEXPAND, 0); // *** Objects List *** - auto collpane = add_prusa_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); + auto collpane = add_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([collpane](wxCommandEvent& e){ e.Skip(); wxWindowUpdateLocker noUpdates(g_right_panel); if (collpane->IsCollapsed()) { m_sizer_object_buttons->Show(false); m_sizer_part_buttons->Show(false); - m_collpane_settings->show_it(false); + m_collpane_settings->Show(false); } else m_objects_ctrl->UnselectAll(); @@ -1107,7 +1111,7 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) })); // *** Object/Part Settings *** - m_collpane_settings = add_prusa_collapsible_pane(parent, sizer, "Settings:", content_settings); + m_collpane_settings = add_collapsible_pane(parent, sizer, "Settings:", content_settings); m_collpane_settings->Hide(); // ? TODO why doesn't work? add_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 970102ec0..b7bc58ed6 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -533,6 +533,14 @@ bool MyObjectTreeModel::SetValue(const wxVariant &variant, const wxDataViewItem return false; } +bool MyObjectTreeModel::SetValue(const wxVariant &variant, const int item_idx, unsigned int col) +{ + if (item_idx < 0 || item_idx >= m_objects.size()) + return false; + + return m_objects[item_idx]->SetValue(variant, col); +} + // bool MyObjectTreeModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const // { // diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 189637de5..c677db80d 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -120,7 +120,11 @@ public: #endif //__WXMSW__ void Collapse(bool collapse) override; void OnStateChange_(const wxSize& sz); //override of OnStateChange - void show_it(bool show) { Show(show); OnStateChange_(GetBestSize()); } + virtual bool Show(bool show=true) override { + wxCollapsiblePane::Show(show); + OnStateChange_(GetBestSize()); + return true; + } }; @@ -213,6 +217,26 @@ public: { return m_children.GetCount(); } + + bool SetValue(const wxVariant &variant, unsigned int col) + { + switch (col) + { + case 0: + m_name = variant.GetString(); + return true; + case 1: + m_copy = variant.GetString(); + return true; + case 2: + m_scale = variant.GetString(); + return true; + + default: + printf("MyObjectTreeModel::SetValue: wrong column"); + } + return false; + } }; // ---------------------------------------------------------------------------- @@ -253,6 +277,7 @@ public: const wxDataViewItem &item, unsigned int col) const override; virtual bool SetValue(const wxVariant &variant, const wxDataViewItem &item, unsigned int col) override; + bool SetValue(const wxVariant &variant, const int item_idx, unsigned int col); // virtual bool IsEnabled(const wxDataViewItem &item, // unsigned int col) const override; From dcf0b432cbce5cc5418f552a3aae2ca5c87d627b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 5 Jun 2018 11:17:37 +0200 Subject: [PATCH 029/119] PrusaCollapsiblePane is used only on MSW --- xs/src/slic3r/GUI/wxExtensions.cpp | 14 ++------------ xs/src/slic3r/GUI/wxExtensions.hpp | 13 +++---------- 2 files changed, 5 insertions(+), 22 deletions(-) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index b7bc58ed6..662369e05 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -190,7 +190,7 @@ void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& e } // ---------------------------------------------------------------------------- -// *** PrusaCollapsiblePane *** +// *** PrusaCollapsiblePane *** used only #ifdef __WXMSW__ // ---------------------------------------------------------------------------- #ifdef __WXMSW__ bool PrusaCollapsiblePane::Create(wxWindow *parent, wxWindowID id, const wxString& label, @@ -288,7 +288,6 @@ bool PrusaCollapsiblePane::Layout() return true; } -#endif //__WXMSW__ void PrusaCollapsiblePane::OnStateChange_(const wxSize& sz) { @@ -330,21 +329,12 @@ void PrusaCollapsiblePane::Collapse(bool collapse) // update our state m_pPane->Show(!collapse); - // update button label -#if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__) - m_pButton->SetOpen(!collapse); -#else -#ifdef __WXMSW__ // update button bitmap UpdateBtnBmp(); -#else - // NB: this must be done after updating our "state" - m_pButton->SetLabel(GetBtnLabel()); -#endif //__WXMSW__ -#endif OnStateChange_(GetBestSize()); } +#endif //__WXMSW__ // ***************************************************************************** // ---------------------------------------------------------------------------- diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index c677db80d..078ea48ed 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -75,15 +75,14 @@ public: -// *** PrusaCollapsiblePane *** +// *** PrusaCollapsiblePane *** used only #ifdef __WXMSW__ // ---------------------------------------------------------------------------- +#ifdef __WXMSW__ class PrusaCollapsiblePane : public wxCollapsiblePane { -#ifdef __WXMSW__ wxButton* m_pDisclosureTriangleButton = nullptr; wxBitmap m_bmp_close; wxBitmap m_bmp_open; -#endif //__WXMSW__ public: PrusaCollapsiblePane() {} PrusaCollapsiblePane( wxWindow *parent, @@ -95,16 +94,11 @@ public: const wxValidator& val = wxDefaultValidator, const wxString& name = wxCollapsiblePaneNameStr) { -#ifdef __WXMSW__ Create(parent, winid, label, pos, size, style, val, name); -#else - Create(parent, winid, label); -#endif //__WXMSW__ } ~PrusaCollapsiblePane() {} -#ifdef __WXMSW__ bool Create(wxWindow *parent, wxWindowID id, const wxString& label, @@ -117,7 +111,6 @@ public: void UpdateBtnBmp(); void SetLabel(const wxString &label) override; bool Layout() override; -#endif //__WXMSW__ void Collapse(bool collapse) override; void OnStateChange_(const wxSize& sz); //override of OnStateChange virtual bool Show(bool show=true) override { @@ -126,7 +119,7 @@ public: return true; } }; - +#endif //__WXMSW__ // ***************************************************************************** // ---------------------------------------------------------------------------- From 5f82d01f19e3fde3dcc300492492b1b8c0e3032b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 5 Jun 2018 13:17:24 +0200 Subject: [PATCH 030/119] Porting object list manipulation from Perl to c++: * Set count and scale to the objects on c++ side * Select/unselect object --- lib/Slic3r/GUI/Plater.pm | 11 +++++++++++ xs/src/slic3r/GUI/GUI.cpp | 22 ++++++++++++++++++++++ xs/src/slic3r/GUI/GUI.hpp | 8 ++++++++ xs/src/slic3r/GUI/wxExtensions.cpp | 17 +---------------- xs/xsp/GUI.xsp | 12 ++++++++++++ 5 files changed, 54 insertions(+), 16 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index a3f381e5c..7f0dbedb0 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -949,6 +949,8 @@ sub increase { $self->{print}->objects->[$obj_idx]->add_copy($instance->offset); } $self->{list}->SetItem($obj_idx, 1, $model_object->instances_count); + # Set conut of object on c++ side + Slic3r::GUI::set_object_count($obj_idx, $model_object->instances_count); # only autoarrange if user has autocentering enabled $self->stop_background_process; @@ -975,6 +977,8 @@ sub decrease { $self->{print}->objects->[$obj_idx]->delete_last_copy; } $self->{list}->SetItem($obj_idx, 1, $model_object->instances_count); + # Set conut of object on c++ side + Slic3r::GUI::set_object_count($obj_idx, $model_object->instances_count); } elsif (defined $copies_asked) { # The "decrease" came from the "set number of copies" dialog. $self->remove; @@ -1168,6 +1172,8 @@ sub changescale { } $self->{list}->SetItem($obj_idx, 2, "$scale%"); + # Set object scale on c++ side + Slic3r::GUI::set_object_scale($obj_idx, $scale); $scale /= 100; # turn percent into factor my $variation = $scale / $model_instance->scaling_factor; @@ -2096,6 +2102,9 @@ sub select_object { $self->{list}->Select($o, 0); $PreventListEvents = 0; } + + # Unselect all objects in the list on c++ side + Slic3r::GUI::unselect_objects(); if (defined $obj_idx) { $self->{objects}->[$obj_idx]->selected(1); @@ -2105,6 +2114,8 @@ sub select_object { $PreventListEvents = 1; $self->{list}->Select($obj_idx, 1); $PreventListEvents = 0; + # Select current object in the list on c++ side + Slic3r::GUI::select_current_object($obj_idx); } else { # TODO: deselect all in list } diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index b0a7751a5..9179710fd 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1071,6 +1071,28 @@ void delete_all_objects_from_list() m_collpane_settings->Show(false); } +void set_object_count(int idx, int count) +{ + m_objects_model->SetValue(wxString::Format("%d", count), idx, 1); + m_objects_ctrl->Refresh(); +} + +void set_object_scale(int idx, int scale) +{ + m_objects_model->SetValue(wxString::Format("%d%%", scale), idx, 2); + m_objects_ctrl->Refresh(); +} + +void unselect_objects() +{ + m_objects_ctrl->UnselectAll(); +} + +void select_current_object(int idx) +{ + m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); +} + void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) { wxWindowUpdateLocker noUpdates(parent); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 293183e7d..6cb8ac1f0 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -181,6 +181,14 @@ void add_object_to_list(const std::string &name, int instances_count=1, int scal void delete_object_from_list(); // Delete all objects from the list void delete_all_objects_from_list(); +// Set count of object on c++ side +void set_object_count(int idx, int count); +// Set object scale on c++ side +void set_object_scale(int idx, int scale); +// Unselect all objects in the list on c++ side +void unselect_objects(); +// Select current object in the list on c++ side +void select_current_object(int idx); void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 662369e05..351c631db 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -505,22 +505,7 @@ bool MyObjectTreeModel::SetValue(const wxVariant &variant, const wxDataViewItem wxASSERT(item.IsOk()); MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); - switch (col) - { - case 0: - node->m_name = variant.GetString(); - return true; - case 1: - node->m_copy = variant.GetString(); - return true; - case 2: - node->m_scale = variant.GetString(); - return true; - - default:; - // wxLogError("MyObjectTreeModel::SetValue: wrong column"); - } - return false; + return node->SetValue(variant, col); } bool MyObjectTreeModel::SetValue(const wxVariant &variant, const int item_idx, unsigned int col) diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index b38970c09..51eb36fa8 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -131,6 +131,18 @@ void delete_object_from_list() void delete_all_objects_from_list() %code%{ Slic3r::GUI::delete_all_objects_from_list(); %}; +void set_object_count(int idx, int count) + %code%{ Slic3r::GUI::set_object_count(idx, count); %}; + +void set_object_scale(int idx, int scale) + %code%{ Slic3r::GUI::set_object_scale(idx, scale); %}; + +void unselect_objects() + %code%{ Slic3r::GUI::unselect_objects(); %}; + +void select_current_object(int idx) + %code%{ Slic3r::GUI::select_current_object(idx); %}; + std::string fold_utf8_to_ascii(const char *src) %code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %}; From bc6e6492af91b2162752dbfc73c8e5a8e60bdf5c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 5 Jun 2018 14:38:22 +0200 Subject: [PATCH 031/119] Move font initialization to init_fonts --- xs/src/slic3r/GUI/GUI.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 9179710fd..4a8fbb6e7 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -142,8 +142,8 @@ wxDataViewCtrl *m_objects_ctrl = nullptr; MyObjectTreeModel *m_objects_model = nullptr; wxCollapsiblePane *m_collpane_settings = nullptr; -wxFont g_small_font { wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; -wxFont g_bold_font { wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold() }; +wxFont g_small_font; +wxFont g_bold_font; static void init_label_colours() { @@ -175,6 +175,8 @@ void update_label_colours_from_appconfig() static void init_fonts() { + g_small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + g_bold_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); #ifdef __WXMAC__ g_small_font.SetPointSize(11); g_bold_font.SetPointSize(11); From 9e0d2793cbc4c0808ad9f293ee0f36ca87d74d3a Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 7 Jun 2018 00:55:09 +0200 Subject: [PATCH 032/119] CallBack from C++ to Perl to manipulations with object list --- lib/Slic3r/GUI/MainFrame.pm | 20 ++++++++++++- lib/Slic3r/GUI/Plater.pm | 23 ++++++++++++--- xs/src/slic3r/GUI/GUI.cpp | 45 ++++++++++++++++++++++++++---- xs/src/slic3r/GUI/GUI.hpp | 2 +- xs/src/slic3r/GUI/wxExtensions.cpp | 12 ++++++++ xs/src/slic3r/GUI/wxExtensions.hpp | 1 + xs/xsp/GUI.xsp | 4 +-- 7 files changed, 94 insertions(+), 13 deletions(-) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 074609659..df2812102 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -25,6 +25,8 @@ our $last_config; our $VALUE_CHANGE_EVENT = Wx::NewEventType; # 2) To inform about a preset selection change or a "modified" status change. our $PRESETS_CHANGED_EVENT = Wx::NewEventType; +# 3) To inform about a change of object selection +our $OBJECT_SELECTION_CHANGED_EVENT = Wx::NewEventType; sub new { my ($class, %params) = @_; @@ -113,7 +115,9 @@ sub _init_tabpanel { }); if (!$self->{no_plater}) { - $panel->AddPage($self->{plater} = Slic3r::GUI::Plater->new($panel), L("Plater")); + $panel->AddPage($self->{plater} = Slic3r::GUI::Plater->new($panel, + event_object_selection_changed => $OBJECT_SELECTION_CHANGED_EVENT, + ), L("Plater")); if (!$self->{no_controller}) { $panel->AddPage($self->{controller} = Slic3r::GUI::Controller->new($panel), L("Controller")); } @@ -168,6 +172,20 @@ sub _init_tabpanel { } } }); + + # The following event is emited by the C++ Tab implementation on config value change. + EVT_COMMAND($self, -1, $OBJECT_SELECTION_CHANGED_EVENT, sub { + my ($self, $event) = @_; + my $obj_idx = $event->GetInt; + print "obj_idx = $obj_idx\n"; + $self->{plater}->select_object($obj_idx < 0 ? undef: $obj_idx); + + $self->{plater}->{canvas}->Refresh; + $self->{plater}->{canvas3D}->deselect_volumes if $self->{canvas3D}; + $self->{plater}->{canvas3D}->Render if $self->{canvas3D}; + }); + + Slic3r::GUI::create_preset_tabs($self->{no_controller}, $VALUE_CHANGE_EVENT, $PRESETS_CHANGED_EVENT); $self->{options_tabs} = {}; for my $tab_name (qw(print filament printer)) { diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 7f0dbedb0..94975e60b 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -47,7 +47,7 @@ use constant PROCESS_DELAY => 0.5 * 1000; # milliseconds my $PreventListEvents = 0; sub new { - my ($class, $parent) = @_; + my ($class, $parent, %params) = @_; my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); $self->{config} = Slic3r::Config::new_from_defaults_keys([qw( bed_shape complete_objects extruder_clearance_radius skirts skirt_distance brim_width variable_layer_height @@ -55,6 +55,10 @@ sub new { nozzle_diameter single_extruder_multi_material wipe_tower wipe_tower_x wipe_tower_y wipe_tower_width wipe_tower_rotation_angle extruder_colour filament_colour max_print_height )]); + + # store input params + $self->{event_object_selection_changed} = $params{event_object_selection_changed}; + # C++ Slic3r::Model with Perl extensions in Slic3r/Model.pm $self->{model} = Slic3r::Model->new; # C++ Slic3r::Print with Perl extensions in Slic3r/Print.pm @@ -411,8 +415,16 @@ sub new { my $frequently_changed_parameters_sizer = Wx::BoxSizer->new(wxVERTICAL); Slic3r::GUI::add_frequently_changed_parameters($self->{right_panel}, $frequently_changed_parameters_sizer, $presets); + my $expert_mode_part_sizer = Wx::BoxSizer->new(wxVERTICAL); - Slic3r::GUI::add_expert_mode_part($self->{right_panel}, $expert_mode_part_sizer); + print "Plater event = ".$self->{event_object_selection_changed}."\n"; + Slic3r::GUI::add_expert_mode_part($self->{right_panel}, $expert_mode_part_sizer, $self->{event_object_selection_changed}); + if ($expert_mode_part_sizer->IsShown(2)==1) + { + $expert_mode_part_sizer->Layout; + $expert_mode_part_sizer->Show(2, 0); # ? Why doesn't work + $self->{right_panel}->Layout; + } my $object_info_sizer; { @@ -535,7 +547,7 @@ sub new { } }; # Show the box initially, let it be shown after the slicing is finished. - $self->{"print_info_box_show"}->(0); + #$self->{"print_info_box_show"}->(0); my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL); $hsizer->Add($self->{preview_notebook}, 1, wxEXPAND | wxTOP, 1); @@ -2095,6 +2107,7 @@ sub selection_changed { sub select_object { my ($self, $obj_idx) = @_; + print "obj_idx = $obj_idx\n"; # remove current selection foreach my $o (0..$#{$self->{objects}}) { $PreventListEvents = 1; @@ -2104,7 +2117,7 @@ sub select_object { } # Unselect all objects in the list on c++ side - Slic3r::GUI::unselect_objects(); + #Slic3r::GUI::unselect_objects(); if (defined $obj_idx) { $self->{objects}->[$obj_idx]->selected(1); @@ -2118,6 +2131,7 @@ sub select_object { Slic3r::GUI::select_current_object($obj_idx); } else { # TODO: deselect all in list + Slic3r::GUI::unselect_objects(); } $self->selection_changed(1); } @@ -2125,6 +2139,7 @@ sub select_object { sub selected_object { my ($self) = @_; my $obj_idx = first { $self->{objects}[$_]->selected } 0..$#{ $self->{objects} }; + print "selected obj_idx = $obj_idx\n"; return defined $obj_idx ? ($obj_idx, $self->{objects}[$obj_idx]) : undef; } diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 4a8fbb6e7..9f119a956 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -141,6 +141,7 @@ wxSizer *m_sizer_part_buttons = nullptr; wxDataViewCtrl *m_objects_ctrl = nullptr; MyObjectTreeModel *m_objects_model = nullptr; wxCollapsiblePane *m_collpane_settings = nullptr; +int m_event_object_selection_changed = 0; wxFont g_small_font; wxFont g_bold_font; @@ -895,11 +896,24 @@ wxBoxSizer* content_objects_list(wxWindow *win) wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); m_objects_ctrl->AppendColumn(column02); - m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& evt) + m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { wxWindowUpdateLocker noUpdates(g_right_panel); auto item = m_objects_ctrl->GetSelection(); - if (!item) return; + int obj_idx = -1; + if (!item) + unselect_objects(); + else + obj_idx = m_objects_model->GetIdByItem(item); + + if (m_event_object_selection_changed > 0) { + wxCommandEvent event(m_event_object_selection_changed); + event.SetInt(obj_idx); + g_wxMainFrame->ProcessWindowEvent(event); + } + + if (obj_idx < 0) return; + // m_objects_ctrl->SetSize(m_objects_ctrl->GetBestSize()); // TODO override GetBestSize(), than use it auto show_obj_sizer = m_objects_model->GetParent(item) == wxDataViewItem(0); m_sizer_object_buttons->Show(show_obj_sizer); @@ -908,6 +922,14 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_collpane_settings->Show(true); }); + m_objects_ctrl->Bind(wxEVT_KEY_DOWN, [](wxKeyEvent& event) + { + if (event.GetKeyCode() == WXK_TAB) + m_objects_ctrl->Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward); + else + event.Skip(); + }); + return objects_sz; } @@ -1088,15 +1110,29 @@ void set_object_scale(int idx, int scale) void unselect_objects() { m_objects_ctrl->UnselectAll(); + if (m_sizer_object_buttons->IsShown(1)) + m_sizer_object_buttons->Show(false); + if (m_sizer_part_buttons->IsShown(1)) + m_sizer_part_buttons->Show(false); + if (m_collpane_settings->IsShown()) + m_collpane_settings->Show(false); } void select_current_object(int idx) { + m_objects_ctrl->UnselectAll(); + if (idx < 0) return; m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); + + if (!m_sizer_object_buttons->IsShown(1)) + m_sizer_object_buttons->Show(true); + if (!m_collpane_settings->IsShown()) + m_collpane_settings->Show(true); } -void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) +void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed) { + m_event_object_selection_changed = event_object_selection_changed; wxWindowUpdateLocker noUpdates(parent); auto btn_grid_sizer = new wxGridSizer(1, 3, 2, 2); @@ -1135,8 +1171,7 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) })); // *** Object/Part Settings *** - m_collpane_settings = add_collapsible_pane(parent, sizer, "Settings:", content_settings); - m_collpane_settings->Hide(); // ? TODO why doesn't work? + m_collpane_settings = add_collapsible_pane(parent, sizer, "Settings", content_settings); add_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) { diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 6cb8ac1f0..4c01622f0 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -190,7 +190,7 @@ void unselect_objects(); // Select current object in the list on c++ side void select_current_object(int idx); -void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer); +void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); // Update view mode according to selected menu void update_mode(); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 351c631db..cf232847b 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -452,6 +452,18 @@ wxDataViewItem MyObjectTreeModel::GetItemById(int obj_idx) } +int MyObjectTreeModel::GetIdByItem(wxDataViewItem& item) +{ + wxASSERT(item.IsOk()); + + MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + auto it = find(m_objects.begin(), m_objects.end(), node); + if (it == m_objects.end()) + return -1; + + return it - m_objects.begin(); +} + wxString MyObjectTreeModel::GetName(const wxDataViewItem &item) const { MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 078ea48ed..2ae5cf6d1 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -253,6 +253,7 @@ public: wxDataViewItem Delete(const wxDataViewItem &item); void DeleteAll(); wxDataViewItem GetItemById(int obj_idx); + int GetIdByItem(wxDataViewItem& item); bool IsEmpty() { return m_objects.empty(); } // helper method for wxLog diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 51eb36fa8..a744e6dcd 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -87,9 +87,9 @@ void add_frequently_changed_parameters(SV *ui_parent, SV *ui_sizer, SV *ui_p_siz (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), (wxFlexGridSizer*)wxPli_sv_2_object(aTHX_ ui_p_sizer, "Wx::FlexGridSizer")); %}; -void add_expert_mode_part(SV *ui_parent, SV *ui_sizer) +void add_expert_mode_part(SV *ui_parent, SV *ui_sizer, int event) %code%{ Slic3r::GUI::add_expert_mode_part((wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), - (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer")); %}; + (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), event); %}; void set_objects_from_perl( SV *ui_parent, SV *frequently_changed_parameters_sizer, From b31e696edcdcbddd673f21da7f85ada7b8f15e90 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 7 Jun 2018 11:12:09 +0200 Subject: [PATCH 033/119] ListView doesn't used now. (Whole logic of the object list manipulation is on c++ side) Remove experimental add/del buttons --- lib/Slic3r/GUI/MainFrame.pm | 7 +-- lib/Slic3r/GUI/Plater.pm | 104 +++++++----------------------------- xs/src/slic3r/GUI/GUI.cpp | 60 ++++++++------------- 3 files changed, 41 insertions(+), 130 deletions(-) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index df2812102..c48186c76 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -177,12 +177,9 @@ sub _init_tabpanel { EVT_COMMAND($self, -1, $OBJECT_SELECTION_CHANGED_EVENT, sub { my ($self, $event) = @_; my $obj_idx = $event->GetInt; - print "obj_idx = $obj_idx\n"; + $self->{plater}->select_object($obj_idx < 0 ? undef: $obj_idx); - - $self->{plater}->{canvas}->Refresh; - $self->{plater}->{canvas3D}->deselect_volumes if $self->{canvas3D}; - $self->{plater}->{canvas3D}->Render if $self->{canvas3D}; + $self->{plater}->item_changed_selection($obj_idx); }); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 94975e60b..58673937e 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -44,8 +44,6 @@ our $PROCESS_COMPLETED_EVENT : shared = Wx::NewEventType; use constant FILAMENT_CHOOSERS_SPACING => 0; use constant PROCESS_DELAY => 0.5 * 1000; # milliseconds -my $PreventListEvents = 0; - sub new { my ($class, $parent, %params) = @_; my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); @@ -234,23 +232,6 @@ sub new { $self->{right_panel} = Wx::ScrolledWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); $self->{right_panel}->SetScrollbars(0, 1, 1, 1); - $self->{list} = Wx::ListView->new($self->{right_panel}, -1, wxDefaultPosition, wxDefaultSize, - wxLC_SINGLE_SEL | wxLC_REPORT | wxBORDER_SUNKEN | wxTAB_TRAVERSAL | wxWANTS_CHARS ); - $self->{list}->InsertColumn(0, L("Name"), wxLIST_FORMAT_LEFT, 145); - $self->{list}->InsertColumn(1, L("Copies"), wxLIST_FORMAT_CENTER, 45); - $self->{list}->InsertColumn(2, L("Scale"), wxLIST_FORMAT_CENTER, wxLIST_AUTOSIZE_USEHEADER); - EVT_LIST_ITEM_SELECTED($self, $self->{list}, \&list_item_selected); - EVT_LIST_ITEM_DESELECTED($self, $self->{list}, \&list_item_deselected); - EVT_LIST_ITEM_ACTIVATED($self, $self->{list}, \&list_item_activated); - EVT_KEY_DOWN($self->{list}, sub { - my ($list, $event) = @_; - if ($event->GetKeyCode == WXK_TAB) { - $list->Navigate($event->ShiftDown ? &Wx::wxNavigateBackward : &Wx::wxNavigateForward); - } else { - $event->Skip; - } - }); - # right pane buttons $self->{btn_export_gcode} = Wx::Button->new($self->{right_panel}, -1, L("Export G-code…"), wxDefaultPosition, [-1, 30], wxNO_BORDER);#, wxBU_LEFT); $self->{btn_reslice} = Wx::Button->new($self->{right_panel}, -1, L("Slice now"), wxDefaultPosition, [-1, 30], wxBU_LEFT); @@ -335,7 +316,7 @@ sub new { $_->SetDropTarget(Slic3r::GUI::Plater::DropTarget->new($self)) for grep defined($_), - $self, $self->{canvas}, $self->{canvas3D}, $self->{preview3D}, $self->{list}; + $self, $self->{canvas}, $self->{canvas3D}, $self->{preview3D}; EVT_COMMAND($self, -1, $PROGRESS_BAR_EVENT, sub { my ($self, $event) = @_; @@ -417,7 +398,6 @@ sub new { Slic3r::GUI::add_frequently_changed_parameters($self->{right_panel}, $frequently_changed_parameters_sizer, $presets); my $expert_mode_part_sizer = Wx::BoxSizer->new(wxVERTICAL); - print "Plater event = ".$self->{event_object_selection_changed}."\n"; Slic3r::GUI::add_expert_mode_part($self->{right_panel}, $expert_mode_part_sizer, $self->{event_object_selection_changed}); if ($expert_mode_part_sizer->IsShown(2)==1) { @@ -519,7 +499,6 @@ sub new { ### Sizer for info boxes my $info_sizer = Wx::BoxSizer->new(wxVERTICAL); $info_sizer->SetMinSize([310, -1]); - $info_sizer->Add($self->{list}, 1, wxEXPAND, 5); $info_sizer->Add($object_info_sizer, 0, wxEXPAND | wxBOTTOM, 5); $info_sizer->Add($print_info_sizer, 0, wxEXPAND | wxBOTTOM, 5); @@ -527,21 +506,17 @@ sub new { $self->{right_panel}->SetSizer($right_sizer); $right_sizer->SetMinSize([320, -1]); $right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets; - $right_sizer->Add($frequently_changed_parameters_sizer, 2, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; - $right_sizer->Add($expert_mode_part_sizer, 0, wxEXPAND | wxTOP, 0) if defined $expert_mode_part_sizer; - $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5); - $right_sizer->Add($info_sizer, 1, wxEXPAND | wxLEFT, 20); + $right_sizer->Add($frequently_changed_parameters_sizer, 1, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; + $right_sizer->Add($expert_mode_part_sizer, 0, wxEXPAND | wxTOP, 10) if defined $expert_mode_part_sizer; + $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM | wxTOP, 10); + $right_sizer->Add($info_sizer, 0, wxEXPAND | wxLEFT, 20); $right_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 20); # Callback for showing / hiding the print info box. $self->{"print_info_box_show"} = sub { -# if ($right_sizer->IsShown(5) != $_[0]) { -# $right_sizer->Show(5, $_[0]); -# $self->Layout -# } - if ($info_sizer->IsShown(2) != $_[0]) { + if ($info_sizer->IsShown(1) != $_[0]) { Slic3r::GUI::set_show_print_info($_[0]); return if (wxTheApp->{app_config}->get("view_mode") eq "simple"); - $info_sizer->Show(2, $_[0]); + $info_sizer->Show(1, $_[0]); $self->Layout; $self->{right_panel}->Refresh; } @@ -853,12 +828,6 @@ sub load_model_objects { foreach my $obj_idx (@obj_idx) { my $object = $self->{objects}[$obj_idx]; my $model_object = $self->{model}->objects->[$obj_idx]; - $self->{list}->InsertStringItem($obj_idx, $object->name); - $self->{list}->SetItemFont($obj_idx, Wx::Font->new(10, wxDEFAULT, wxNORMAL, wxNORMAL)) - if $self->{list}->can('SetItemFont'); # legacy code for wxPerl < 0.9918 not supporting SetItemFont() - - $self->{list}->SetItem($obj_idx, 1, $model_object->instances_count); - $self->{list}->SetItem($obj_idx, 2, ($model_object->instances->[0]->scaling_factor * 100) . "%"); # Add object to list on c++ side Slic3r::GUI::add_object_to_list($object->name, $model_object->instances_count, ($model_object->instances->[0]->scaling_factor * 100)); @@ -872,8 +841,6 @@ sub load_model_objects { $self->{canvas3D}->zoom_to_volumes if $self->{canvas3D}; - $self->{list}->Update; - $self->{list}->Select($obj_idx[-1], 1); $self->object_list_changed; $self->schedule_background_process; @@ -908,7 +875,6 @@ sub remove { splice @{$self->{objects}}, $obj_idx, 1; $self->{model}->delete_object($obj_idx); $self->{print}->delete_object($obj_idx); - $self->{list}->DeleteItem($obj_idx); # Delete object from list on c++ side Slic3r::GUI::delete_object_from_list(); $self->object_list_changed; @@ -933,7 +899,6 @@ sub reset { @{$self->{objects}} = (); $self->{model}->clear_objects; $self->{print}->clear_objects; - $self->{list}->DeleteAllItems; # Delete all objects from list on c++ side Slic3r::GUI::delete_all_objects_from_list(); $self->object_list_changed; @@ -960,7 +925,6 @@ sub increase { ); $self->{print}->objects->[$obj_idx]->add_copy($instance->offset); } - $self->{list}->SetItem($obj_idx, 1, $model_object->instances_count); # Set conut of object on c++ side Slic3r::GUI::set_object_count($obj_idx, $model_object->instances_count); @@ -988,7 +952,6 @@ sub decrease { $model_object->delete_last_instance; $self->{print}->objects->[$obj_idx]->delete_last_copy; } - $self->{list}->SetItem($obj_idx, 1, $model_object->instances_count); # Set conut of object on c++ side Slic3r::GUI::set_object_count($obj_idx, $model_object->instances_count); } elsif (defined $copies_asked) { @@ -999,11 +962,7 @@ sub decrease { $self->resume_background_process; return; } - - if ($self->{objects}[$obj_idx]) { - $self->{list}->Select($obj_idx, 0); - $self->{list}->Select($obj_idx, 1); - } + $self->update; $self->schedule_background_process; } @@ -1182,8 +1141,7 @@ sub changescale { $scale = $self->_get_number_from_user(L('Enter the scale % for the selected object:'), L('Scale'), L('Invalid scaling value entered'), $model_instance->scaling_factor*100, 1); return if ! defined($scale) || $scale eq ''; } - - $self->{list}->SetItem($obj_idx, 2, "$scale%"); + # Set object scale on c++ side Slic3r::GUI::set_object_scale($obj_idx, $scale); $scale /= 100; # turn percent into factor @@ -1887,31 +1845,19 @@ sub on_config_change { $self->schedule_background_process; } -sub list_item_deselected { - my ($self, $event) = @_; - return if $PreventListEvents; - $self->{_lecursor} = Wx::BusyCursor->new(); - if ($self->{list}->GetFirstSelected == -1) { - $self->select_object(undef); - $self->{canvas}->Refresh; - $self->{canvas3D}->deselect_volumes if $self->{canvas3D}; - $self->{canvas3D}->Render if $self->{canvas3D}; - } - undef $self->{_lecursor}; -} +sub item_changed_selection{ + my ($self, $obj_idx) = @_; -sub list_item_selected { - my ($self, $event) = @_; - return if $PreventListEvents; - $self->{_lecursor} = Wx::BusyCursor->new(); - my $obj_idx = $event->GetIndex; - $self->select_object($obj_idx); $self->{canvas}->Refresh; - $self->{canvas3D}->update_volumes_selection if $self->{canvas3D}; + if ($self->{canvas3D}){ + $self->{canvas3D}->deselect_volumes; + if ($obj_idx >= 0) { + $self->{canvas3D}->update_volumes_selection}; + } $self->{canvas3D}->Render if $self->{canvas3D}; - undef $self->{_lecursor}; } +# doesn't used now sub list_item_activated { my ($self, $event, $obj_idx) = @_; @@ -2107,30 +2053,17 @@ sub selection_changed { sub select_object { my ($self, $obj_idx) = @_; - print "obj_idx = $obj_idx\n"; # remove current selection foreach my $o (0..$#{$self->{objects}}) { - $PreventListEvents = 1; $self->{objects}->[$o]->selected(0); - $self->{list}->Select($o, 0); - $PreventListEvents = 0; } - # Unselect all objects in the list on c++ side - #Slic3r::GUI::unselect_objects(); - if (defined $obj_idx) { $self->{objects}->[$obj_idx]->selected(1); - # We use this flag to avoid circular event handling - # Select() happens to fire a wxEVT_LIST_ITEM_SELECTED on Windows, - # whose event handler calls this method again and again and again - $PreventListEvents = 1; - $self->{list}->Select($obj_idx, 1); - $PreventListEvents = 0; # Select current object in the list on c++ side Slic3r::GUI::select_current_object($obj_idx); } else { - # TODO: deselect all in list + # Unselect all objects in the list on c++ side Slic3r::GUI::unselect_objects(); } $self->selection_changed(1); @@ -2139,7 +2072,6 @@ sub select_object { sub selected_object { my ($self) = @_; my $obj_idx = first { $self->{objects}[$_]->selected } 0..$#{ $self->{objects} }; - print "selected obj_idx = $obj_idx\n"; return defined $obj_idx ? ($obj_idx, $self->{objects}[$obj_idx]) : undef; } diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 9f119a956..2e27efcdd 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -904,7 +904,12 @@ wxBoxSizer* content_objects_list(wxWindow *win) if (!item) unselect_objects(); else - obj_idx = m_objects_model->GetIdByItem(item); + { + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) + obj_idx = m_objects_model->GetIdByItem(item); + else + obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetParent(item)); // TODO Temporary decision for sub-objects selection + } if (m_event_object_selection_changed > 0) { wxCommandEvent event(m_event_object_selection_changed); @@ -915,6 +920,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) if (obj_idx < 0) return; // m_objects_ctrl->SetSize(m_objects_ctrl->GetBestSize()); // TODO override GetBestSize(), than use it + auto show_obj_sizer = m_objects_model->GetParent(item) == wxDataViewItem(0); m_sizer_object_buttons->Show(show_obj_sizer); m_sizer_part_buttons->Show(!show_obj_sizer); @@ -1135,25 +1141,6 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer, int event_object_ m_event_object_selection_changed = event_object_selection_changed; wxWindowUpdateLocker noUpdates(parent); - auto btn_grid_sizer = new wxGridSizer(1, 3, 2, 2); - sizer->Add(btn_grid_sizer, 0, wxALIGN_LEFT | wxLEFT, 20); - - // Experiments with new UI - auto add_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - if (wxMSW) add_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - add_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG)); - btn_grid_sizer->Add(add_btn, 0, wxEXPAND, 0); - - auto del_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - if (wxMSW) del_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - del_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_delete.png")), wxBITMAP_TYPE_PNG)); - btn_grid_sizer->Add(del_btn, 0, wxEXPAND, 0); - - auto del_all_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - if (wxMSW) del_all_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - del_all_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("delete.png")), wxBITMAP_TYPE_PNG)); - btn_grid_sizer->Add(del_all_btn, 0, wxEXPAND, 0); - // *** Objects List *** auto collpane = add_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([collpane](wxCommandEvent& e){ @@ -1171,17 +1158,7 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer, int event_object_ })); // *** Object/Part Settings *** - m_collpane_settings = add_collapsible_pane(parent, sizer, "Settings", content_settings); - - add_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) - { - wxString name = "Object"; - m_objects_ctrl->Select(m_objects_model->Add(name)); - }); - - del_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) { delete_object_from_list(); }); - - del_all_btn->Bind(wxEVT_BUTTON, [](wxEvent&) { delete_all_objects_from_list(); }); + m_collpane_settings = add_collapsible_pane(parent, sizer, "Object Settings", content_settings); // More experiments with UI // auto listctrl = new wxDataViewListCtrl(main_page, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); @@ -1386,31 +1363,36 @@ void show_buttons(bool show) } } -void show_scrolled_window_sizer(bool show) +void show_info_sizer(bool show) { - g_scrolled_window_sizer->Show(static_cast(0), /*false*/show); //don't used now - g_scrolled_window_sizer->Show(1, show); - g_scrolled_window_sizer->Show(2, show && g_show_print_info); + g_scrolled_window_sizer->Show(static_cast(0), show); + g_scrolled_window_sizer->Show(1, show && g_show_print_info); g_manifold_warning_icon->Show(show && g_show_manifold_warning_icon); } void update_mode() { - //TODO There is a not the best place of it! + wxWindowUpdateLocker noUpdates(g_right_panel); + + // TODO There is a not the best place of it! //*** Update style of the "Export G-code" button**** if (g_btn_export_gcode->GetFont() != bold_font()){ g_btn_export_gcode->SetBackgroundColour(wxColour(252, 77, 1)); g_btn_export_gcode->SetFont(bold_font()); } - //************************************ + // *********************************** - wxWindowUpdateLocker noUpdates(g_right_panel); ConfigMenuIDs mode = get_view_mode(); // show_frequently_changed_parameters(mode >= ConfigMenuModeRegular); g_expert_mode_part_sizer->Show(mode == ConfigMenuModeExpert); - show_scrolled_window_sizer(mode == ConfigMenuModeExpert); + show_info_sizer(mode == ConfigMenuModeExpert); show_buttons(mode == ConfigMenuModeExpert); + + // TODO There is a not the best place of it! + // *** Update showing of the collpane_settings + m_collpane_settings->Show(mode == ConfigMenuModeExpert && !m_objects_model->IsEmpty()); + // ************************* g_right_panel->GetParent()->Layout(); g_right_panel->Layout(); } From 49f0a1a824173b9615e9f98053b35f95528e42e0 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 7 Jun 2018 11:54:42 +0200 Subject: [PATCH 034/119] Fixed OSX compilation bug Changed info_box (more place to the manifold information) --- lib/Slic3r/GUI/Plater.pm | 14 +++++++++----- xs/src/slic3r/GUI/GUI.cpp | 6 ++++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 58673937e..689ccff28 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -412,7 +412,8 @@ sub new { $box->SetFont($Slic3r::GUI::small_bold_font); $object_info_sizer = Wx::StaticBoxSizer->new($box, wxVERTICAL); $object_info_sizer->SetMinSize([300,-1]); - my $grid_sizer = Wx::FlexGridSizer->new(3, 4, 5, 5); + #!my $grid_sizer = Wx::FlexGridSizer->new(3, 4, 5, 5); + my $grid_sizer = Wx::FlexGridSizer->new(2, 4, 5, 5); $grid_sizer->SetFlexibleDirection(wxHORIZONTAL); $grid_sizer->AddGrowableCol(1, 1); $grid_sizer->AddGrowableCol(3, 1); @@ -429,7 +430,7 @@ sub new { my $label = shift @info; my $text = Wx::StaticText->new($self->{right_panel}, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); $text->SetFont($Slic3r::GUI::small_font); - $grid_sizer->Add($text, 0); + #!$grid_sizer->Add($text, 0); $self->{"object_info_$field"} = Wx::StaticText->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); $self->{"object_info_$field"}->SetFont($Slic3r::GUI::small_font); @@ -448,10 +449,13 @@ sub new { $self->{"object_info_manifold_warning_icon_show"}->(0); my $h_sizer = Wx::BoxSizer->new(wxHORIZONTAL); - $h_sizer->Add($self->{object_info_manifold_warning_icon}, 0); - $h_sizer->Add($self->{"object_info_$field"}, 0); - $grid_sizer->Add($h_sizer, 0, wxEXPAND); + $h_sizer->Add($text, 0); + $h_sizer->Add($self->{object_info_manifold_warning_icon}, 0, wxLEFT, 2); + $h_sizer->Add($self->{"object_info_$field"}, 0, wxLEFT, 2); + #!$grid_sizer->Add($h_sizer, 0, wxEXPAND); + $object_info_sizer->Add($h_sizer, 0, wxEXPAND|wxTOP, 4); } else { + $grid_sizer->Add($text, 0); $grid_sizer->Add($self->{"object_info_$field"}, 0); } } diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 2e27efcdd..d2bcc7b58 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -907,8 +907,10 @@ wxBoxSizer* content_objects_list(wxWindow *win) { if (m_objects_model->GetParent(item) == wxDataViewItem(0)) obj_idx = m_objects_model->GetIdByItem(item); - else - obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetParent(item)); // TODO Temporary decision for sub-objects selection + else { + auto parent = m_objects_model->GetParent(item); + obj_idx = m_objects_model->GetIdByItem(parent); // TODO Temporary decision for sub-objects selection + } } if (m_event_object_selection_changed > 0) { From ebe5ee3b1f41ecac8c5e13d80280acde9befe3bb Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 7 Jun 2018 14:57:45 +0200 Subject: [PATCH 035/119] Fixed uncorrected Settings sizer showing --- xs/src/slic3r/GUI/GUI.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index d2bcc7b58..898edc365 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1132,10 +1132,12 @@ void select_current_object(int idx) if (idx < 0) return; m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); - if (!m_sizer_object_buttons->IsShown(1)) - m_sizer_object_buttons->Show(true); - if (!m_collpane_settings->IsShown()) - m_collpane_settings->Show(true); + if (get_view_mode() == ConfigMenuModeExpert){ + if (!m_sizer_object_buttons->IsShown(1)) + m_sizer_object_buttons->Show(true); + if (!m_collpane_settings->IsShown()) + m_collpane_settings->Show(true); + } } void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed) From e2a7bd4a149f5f20969dee6d6c171ae7bdc04b53 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 7 Jun 2018 15:52:35 +0200 Subject: [PATCH 036/119] Added MessageBoxes for experimenting on OSX --- lib/Slic3r/GUI/MainFrame.pm | 1 + lib/Slic3r/GUI/Plater.pm | 3 +++ xs/src/slic3r/GUI/GUI.cpp | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index c48186c76..e36bf4a5e 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -179,6 +179,7 @@ sub _init_tabpanel { my $obj_idx = $event->GetInt; $self->{plater}->select_object($obj_idx < 0 ? undef: $obj_idx); + Wx::MessageBox("Before item_changed_selection", "Slic3r Info", wxOK | wxICON_INFORMATION, $self); $self->{plater}->item_changed_selection($obj_idx); }); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 689ccff28..a12b2aa8e 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1852,6 +1852,8 @@ sub on_config_change { sub item_changed_selection{ my ($self, $obj_idx) = @_; + Wx::MessageBox("Inside item_changed_selection", "Slic3r Info", wxOK | wxICON_INFORMATION, $self); + $self->{canvas}->Refresh; if ($self->{canvas3D}){ $self->{canvas3D}->deselect_volumes; @@ -2065,6 +2067,7 @@ sub select_object { if (defined $obj_idx) { $self->{objects}->[$obj_idx]->selected(1); # Select current object in the list on c++ side + Wx::MessageBox("Before select_current_object", "Slic3r Info", wxOK | wxICON_INFORMATION, $self); Slic3r::GUI::select_current_object($obj_idx); } else { # Unselect all objects in the list on c++ side diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 898edc365..11c868326 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1128,9 +1128,12 @@ void unselect_objects() void select_current_object(int idx) { + wxMessageBox("Inside select_current_object", "Info"); m_objects_ctrl->UnselectAll(); + wxMessageBox("UnselectAll", "Info"); if (idx < 0) return; m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); + wxMessageBox("Item is selected", "Info"); if (get_view_mode() == ConfigMenuModeExpert){ if (!m_sizer_object_buttons->IsShown(1)) @@ -1138,6 +1141,7 @@ void select_current_object(int idx) if (!m_collpane_settings->IsShown()) m_collpane_settings->Show(true); } + wxMessageBox("Updated sizer showing", "Info"); } void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed) From 7ba2093a9bbdf2ad58961748ec6ee07f81c8c9c4 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 8 Jun 2018 09:03:46 +0200 Subject: [PATCH 037/119] Try to fix the circular event handling Select() on OSX --- xs/src/slic3r/GUI/GUI.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 11c868326..d0064d0a2 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -142,6 +142,9 @@ wxDataViewCtrl *m_objects_ctrl = nullptr; MyObjectTreeModel *m_objects_model = nullptr; wxCollapsiblePane *m_collpane_settings = nullptr; int m_event_object_selection_changed = 0; +bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select() + // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler + // calls this method again and again and again wxFont g_small_font; wxFont g_bold_font; @@ -898,6 +901,8 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { + if (g_prevent_list_events) return; + wxWindowUpdateLocker noUpdates(g_right_panel); auto item = m_objects_ctrl->GetSelection(); int obj_idx = -1; @@ -1129,10 +1134,15 @@ void unselect_objects() void select_current_object(int idx) { wxMessageBox("Inside select_current_object", "Info"); + g_prevent_list_events = true; m_objects_ctrl->UnselectAll(); wxMessageBox("UnselectAll", "Info"); - if (idx < 0) return; + if (idx < 0) { + g_prevent_list_events = false; + return; + } m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); + g_prevent_list_events = false; wxMessageBox("Item is selected", "Info"); if (get_view_mode() == ConfigMenuModeExpert){ From da9b0a9b7da08224b53de76570b0d35567b8d9a1 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 8 Jun 2018 09:55:27 +0200 Subject: [PATCH 038/119] Deleted debugging messages --- lib/Slic3r/GUI/Plater.pm | 3 --- xs/src/slic3r/GUI/GUI.cpp | 4 ---- 2 files changed, 7 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index a12b2aa8e..689ccff28 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1852,8 +1852,6 @@ sub on_config_change { sub item_changed_selection{ my ($self, $obj_idx) = @_; - Wx::MessageBox("Inside item_changed_selection", "Slic3r Info", wxOK | wxICON_INFORMATION, $self); - $self->{canvas}->Refresh; if ($self->{canvas3D}){ $self->{canvas3D}->deselect_volumes; @@ -2067,7 +2065,6 @@ sub select_object { if (defined $obj_idx) { $self->{objects}->[$obj_idx]->selected(1); # Select current object in the list on c++ side - Wx::MessageBox("Before select_current_object", "Slic3r Info", wxOK | wxICON_INFORMATION, $self); Slic3r::GUI::select_current_object($obj_idx); } else { # Unselect all objects in the list on c++ side diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index d0064d0a2..442acd3e4 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1133,17 +1133,14 @@ void unselect_objects() void select_current_object(int idx) { - wxMessageBox("Inside select_current_object", "Info"); g_prevent_list_events = true; m_objects_ctrl->UnselectAll(); - wxMessageBox("UnselectAll", "Info"); if (idx < 0) { g_prevent_list_events = false; return; } m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); g_prevent_list_events = false; - wxMessageBox("Item is selected", "Info"); if (get_view_mode() == ConfigMenuModeExpert){ if (!m_sizer_object_buttons->IsShown(1)) @@ -1151,7 +1148,6 @@ void select_current_object(int idx) if (!m_collpane_settings->IsShown()) m_collpane_settings->Show(true); } - wxMessageBox("Updated sizer showing", "Info"); } void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed) From 08ccf85a616f12577dab96fde9bc73ef2f1fed41 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 8 Jun 2018 12:43:39 +0200 Subject: [PATCH 039/119] Overrided OnStateChange() function to CollapsiblePane --- lib/Slic3r/GUI/MainFrame.pm | 1 - xs/src/slic3r/GUI/GUI.cpp | 20 ++++---- xs/src/slic3r/GUI/wxExtensions.cpp | 75 ++++++++++++++++-------------- xs/src/slic3r/GUI/wxExtensions.hpp | 44 +++++++++++++----- 4 files changed, 82 insertions(+), 58 deletions(-) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index e36bf4a5e..c48186c76 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -179,7 +179,6 @@ sub _init_tabpanel { my $obj_idx = $event->GetInt; $self->{plater}->select_object($obj_idx < 0 ? undef: $obj_idx); - Wx::MessageBox("Before item_changed_selection", "Slic3r Info", wxOK | wxICON_INFORMATION, $self); $self->{plater}->item_changed_selection($obj_idx); }); diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 22a080355..3114622fb 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -858,9 +858,9 @@ wxString from_u8(const std::string &str) wxCollapsiblePane* add_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, const wxString& name, std::function content_function) { #ifdef __WXMSW__ - auto *collpane = new PrusaCollapsiblePane(parent, wxID_ANY, name); + auto *collpane = new PrusaCollapsiblePaneMSW(parent, wxID_ANY, name); #else - auto *collpane = new wxCollapsiblePane(parent, wxID_ANY, name); + auto *collpane = new PrusaCollapsiblePane/*wxCollapsiblePane*/(parent, wxID_ANY, name); #endif // __WXMSW__ // add the pane with a zero proportion value to the sizer which contains it sizer_parent->Add(collpane, 0, wxGROW | wxALL, 0); @@ -962,9 +962,9 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) { auto sizer = new wxBoxSizer(wxVERTICAL); - auto btn_load_part = new wxButton(win, wxID_ANY, /*Load */"part…", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); - auto btn_load_modifier = new wxButton(win, wxID_ANY, /*Load */"modifier…", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); - auto btn_load_lambda_modifier = new wxButton(win, wxID_ANY, /*Load */"generic…", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_load_part = new wxButton(win, wxID_ANY, /*Load */"part"+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_load_modifier = new wxButton(win, wxID_ANY, /*Load */"modifier" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_load_lambda_modifier = new wxButton(win, wxID_ANY, /*Load */"generic" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); auto btn_delete = new wxButton(win, wxID_ANY, "Delete"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); auto btn_split = new wxButton(win, wxID_ANY, "Split"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); auto btn_move_up = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); @@ -1170,17 +1170,17 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer, int event_object_ // *** Objects List *** auto collpane = add_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([collpane](wxCommandEvent& e){ - e.Skip(); - wxWindowUpdateLocker noUpdates(g_right_panel); +// wxWindowUpdateLocker noUpdates(g_right_panel); if (collpane->IsCollapsed()) { m_sizer_object_buttons->Show(false); m_sizer_part_buttons->Show(false); m_collpane_settings->Show(false); } - else - m_objects_ctrl->UnselectAll(); +// else +// m_objects_ctrl->UnselectAll(); - g_right_panel->Layout(); +// e.Skip(); +// g_right_panel->Layout(); })); // *** Object/Part Settings *** diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index cf232847b..b0c60d4c1 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -190,10 +190,42 @@ void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& e } // ---------------------------------------------------------------------------- -// *** PrusaCollapsiblePane *** used only #ifdef __WXMSW__ +// *** PrusaCollapsiblePane *** +// ---------------------------------------------------------------------------- +void PrusaCollapsiblePane::OnStateChange(const wxSize& sz) +{ + SetSize(sz); + + if (this->HasFlag(wxCP_NO_TLW_RESIZE)) + { + // the user asked to explicitly handle the resizing itself... + return; + } + + auto top = GetParent(); //right_panel + if (!top) + return; + + wxSizer *sizer = top->GetSizer(); + if (!sizer) + return; + + const wxSize newBestSize = sizer->ComputeFittingClientSize(top); + top->SetMinClientSize(newBestSize); + + wxWindowUpdateLocker noUpdates_p(top->GetParent()); + // we shouldn't attempt to resize a maximized window, whatever happens + // if (!top->IsMaximized()) + // top->SetClientSize(newBestSize); + top->GetParent()->Layout(); + top->Refresh(); +} + +// ---------------------------------------------------------------------------- +// *** PrusaCollapsiblePaneMSW *** used only #ifdef __WXMSW__ // ---------------------------------------------------------------------------- #ifdef __WXMSW__ -bool PrusaCollapsiblePane::Create(wxWindow *parent, wxWindowID id, const wxString& label, +bool PrusaCollapsiblePaneMSW::Create(wxWindow *parent, wxWindowID id, const wxString& label, const wxPoint& pos, const wxSize& size, long style, const wxValidator& val, const wxString& name) { if (!wxControl::Create(parent, id, pos, size, style, val, name)) @@ -242,7 +274,7 @@ bool PrusaCollapsiblePane::Create(wxWindow *parent, wxWindowID id, const wxStrin return true; } -void PrusaCollapsiblePane::UpdateBtnBmp() +void PrusaCollapsiblePaneMSW::UpdateBtnBmp() { if (IsCollapsed()) m_pDisclosureTriangleButton->SetBitmap(m_bmp_close); @@ -257,14 +289,14 @@ void PrusaCollapsiblePane::UpdateBtnBmp() Layout(); } -void PrusaCollapsiblePane::SetLabel(const wxString &label) +void PrusaCollapsiblePaneMSW::SetLabel(const wxString &label) { m_strLabel = label; m_pDisclosureTriangleButton->SetLabel(m_strLabel); Layout(); } -bool PrusaCollapsiblePane::Layout() +bool PrusaCollapsiblePaneMSW::Layout() { if (!m_pDisclosureTriangleButton || !m_pPane || !m_sz) return false; // we need to complete the creation first! @@ -289,36 +321,7 @@ bool PrusaCollapsiblePane::Layout() return true; } -void PrusaCollapsiblePane::OnStateChange_(const wxSize& sz) -{ - SetSize(sz); - - if (this->HasFlag(wxCP_NO_TLW_RESIZE)) - { - // the user asked to explicitly handle the resizing itself... - return; - } - - auto top = GetParent(); //right_panel - if (!top) - return; - - wxSizer *sizer = top->GetSizer(); - if (!sizer) - return; - - const wxSize newBestSize = sizer->ComputeFittingClientSize(top); - top->SetMinClientSize(newBestSize); - - wxWindowUpdateLocker noUpdates_p(top->GetParent()); - // we shouldn't attempt to resize a maximized window, whatever happens -// if (!top->IsMaximized()) -// top->SetClientSize(newBestSize); - top->GetParent()->Layout(); - top->Refresh(); -} - -void PrusaCollapsiblePane::Collapse(bool collapse) +void PrusaCollapsiblePaneMSW::Collapse(bool collapse) { // optimization if (IsCollapsed() == collapse) @@ -332,7 +335,7 @@ void PrusaCollapsiblePane::Collapse(bool collapse) // update button bitmap UpdateBtnBmp(); - OnStateChange_(GetBestSize()); + OnStateChange(GetBestSize()); } #endif //__WXMSW__ diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 2ae5cf6d1..d3330a827 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -75,17 +75,45 @@ public: -// *** PrusaCollapsiblePane *** used only #ifdef __WXMSW__ +// *** PrusaCollapsiblePane *** +// ---------------------------------------------------------------------------- +class PrusaCollapsiblePane : public wxCollapsiblePane +{ +public: + PrusaCollapsiblePane() {} + PrusaCollapsiblePane(wxWindow *parent, + wxWindowID winid, + const wxString& label, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxCP_DEFAULT_STYLE, + const wxValidator& val = wxDefaultValidator, + const wxString& name = wxCollapsiblePaneNameStr) + { + Create(parent, winid, label, pos, size, style, val, name); + } + ~PrusaCollapsiblePane() {} + + void OnStateChange(const wxSize& sz); //override/hide of OnStateChange from wxCollapsiblePane + virtual bool Show(bool show = true) override { + wxCollapsiblePane::Show(show); + OnStateChange(GetBestSize()); + return true; + } +}; + + +// *** PrusaCollapsiblePaneMSW *** used only #ifdef __WXMSW__ // ---------------------------------------------------------------------------- #ifdef __WXMSW__ -class PrusaCollapsiblePane : public wxCollapsiblePane +class PrusaCollapsiblePaneMSW : public PrusaCollapsiblePane//wxCollapsiblePane { wxButton* m_pDisclosureTriangleButton = nullptr; wxBitmap m_bmp_close; wxBitmap m_bmp_open; public: - PrusaCollapsiblePane() {} - PrusaCollapsiblePane( wxWindow *parent, + PrusaCollapsiblePaneMSW() {} + PrusaCollapsiblePaneMSW( wxWindow *parent, wxWindowID winid, const wxString& label, const wxPoint& pos = wxDefaultPosition, @@ -97,7 +125,7 @@ public: Create(parent, winid, label, pos, size, style, val, name); } - ~PrusaCollapsiblePane() {} + ~PrusaCollapsiblePaneMSW() {} bool Create(wxWindow *parent, wxWindowID id, @@ -112,12 +140,6 @@ public: void SetLabel(const wxString &label) override; bool Layout() override; void Collapse(bool collapse) override; - void OnStateChange_(const wxSize& sz); //override of OnStateChange - virtual bool Show(bool show=true) override { - wxCollapsiblePane::Show(show); - OnStateChange_(GetBestSize()); - return true; - } }; #endif //__WXMSW__ From f5ef6728158c0f7051c61678a5473a207f20d129 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 12 Jun 2018 19:15:03 +0200 Subject: [PATCH 040/119] Prepared callback from c++ to Perl to inform about a change of object settings --- lib/Slic3r/GUI/MainFrame.pm | 18 +++++++++++++++-- lib/Slic3r/GUI/Plater.pm | 40 ++++++++++++++++++++++++++++++------- xs/src/slic3r/GUI/GUI.cpp | 6 +++++- xs/src/slic3r/GUI/GUI.hpp | 4 +++- xs/xsp/GUI.xsp | 10 +++++++--- 5 files changed, 64 insertions(+), 14 deletions(-) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index c48186c76..626bdef81 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -27,6 +27,8 @@ our $VALUE_CHANGE_EVENT = Wx::NewEventType; our $PRESETS_CHANGED_EVENT = Wx::NewEventType; # 3) To inform about a change of object selection our $OBJECT_SELECTION_CHANGED_EVENT = Wx::NewEventType; +# 4) To inform about a change of object settings +our $OBJECT_SETTINGS_CHANGED_EVENT = Wx::NewEventType; sub new { my ($class, %params) = @_; @@ -117,6 +119,7 @@ sub _init_tabpanel { if (!$self->{no_plater}) { $panel->AddPage($self->{plater} = Slic3r::GUI::Plater->new($panel, event_object_selection_changed => $OBJECT_SELECTION_CHANGED_EVENT, + event_object_settings_changed => $OBJECT_SETTINGS_CHANGED_EVENT, ), L("Plater")); if (!$self->{no_controller}) { $panel->AddPage($self->{controller} = Slic3r::GUI::Controller->new($panel), L("Controller")); @@ -173,14 +176,25 @@ sub _init_tabpanel { } }); - # The following event is emited by the C++ Tab implementation on config value change. + # The following event is emited by the C++ Tab implementation on object selection change. EVT_COMMAND($self, -1, $OBJECT_SELECTION_CHANGED_EVENT, sub { my ($self, $event) = @_; my $obj_idx = $event->GetInt; $self->{plater}->select_object($obj_idx < 0 ? undef: $obj_idx); $self->{plater}->item_changed_selection($obj_idx); - }); + }); + + # The following event is emited by the C++ Tab implementation on object settings change. + EVT_COMMAND($self, -1, $OBJECT_SETTINGS_CHANGED_EVENT, sub { + my ($self, $event) = @_; + my $obj_idx = $event->GetInt; + + #my $line = $event->GetString; + #my ($parts_changed, $part_settings_changed) = split('',$line); + + #$self->{plater}->changed_object_settings($obj_idx, $parts_changed, $part_settings_changed); + }); Slic3r::GUI::create_preset_tabs($self->{no_controller}, $VALUE_CHANGE_EVENT, $PRESETS_CHANGED_EVENT); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 689ccff28..bc149a828 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -56,6 +56,7 @@ sub new { # store input params $self->{event_object_selection_changed} = $params{event_object_selection_changed}; + $self->{event_object_settings_changed} = $params{event_object_settings_changed}; # C++ Slic3r::Model with Perl extensions in Slic3r/Model.pm $self->{model} = Slic3r::Model->new; @@ -398,13 +399,15 @@ sub new { Slic3r::GUI::add_frequently_changed_parameters($self->{right_panel}, $frequently_changed_parameters_sizer, $presets); my $expert_mode_part_sizer = Wx::BoxSizer->new(wxVERTICAL); - Slic3r::GUI::add_expert_mode_part($self->{right_panel}, $expert_mode_part_sizer, $self->{event_object_selection_changed}); - if ($expert_mode_part_sizer->IsShown(2)==1) - { - $expert_mode_part_sizer->Layout; - $expert_mode_part_sizer->Show(2, 0); # ? Why doesn't work - $self->{right_panel}->Layout; - } + Slic3r::GUI::add_expert_mode_part( $self->{right_panel}, $expert_mode_part_sizer, + $self->{event_object_selection_changed}, + $self->{event_object_settings_changed}); +# if ($expert_mode_part_sizer->IsShown(2)==1) +# { +# $expert_mode_part_sizer->Layout; +# $expert_mode_part_sizer->Show(2, 0); # ? Why doesn't work +# $self->{right_panel}->Layout; +# } my $object_info_sizer; { @@ -1960,6 +1963,29 @@ sub object_settings_dialog { } } +sub changed_object_settings { + my ($self, $obj_idx, $parts_changed, $part_settings_changed) = @_; + + # update thumbnail since parts may have changed + if ($parts_changed) { + # recenter and re-align to Z = 0 + my $model_object = $self->{model}->objects->[$obj_idx]; + $model_object->center_around_origin; + $self->reset_thumbnail($obj_idx); + } + + # update print + if ($parts_changed || $part_settings_changed) { + $self->stop_background_process; + $self->{print}->reload_object($obj_idx); + $self->schedule_background_process; + $self->{canvas}->reload_scene if $self->{canvas}; + $self->{canvas3D}->reload_scene if $self->{canvas3D}; + } else { + $self->resume_background_process; + } +} + # Called to update various buttons depending on whether there are any objects or # whether background processing (export of a G-code, sending to Octoprint, forced background re-slicing) is active. sub object_list_changed { diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index a34b6f1d7..01a61ff51 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -143,6 +143,7 @@ wxDataViewCtrl *m_objects_ctrl = nullptr; MyObjectTreeModel *m_objects_model = nullptr; wxCollapsiblePane *m_collpane_settings = nullptr; int m_event_object_selection_changed = 0; +int m_event_object_settings_changed = 0; bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select() // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler // calls this method again and again and again @@ -1163,9 +1164,12 @@ void select_current_object(int idx) } } -void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed) +void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, + int event_object_selection_changed, + int event_object_settings_changed) { m_event_object_selection_changed = event_object_selection_changed; + m_event_object_settings_changed = event_object_settings_changed; wxWindowUpdateLocker noUpdates(parent); // *** Objects List *** diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 894751f61..277729ab0 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -202,7 +202,9 @@ void unselect_objects(); // Select current object in the list on c++ side void select_current_object(int idx); -void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed); +void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, + int event_object_selection_changed, + int event_object_settings_changed); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); // Update view mode according to selected menu void update_mode(); diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index ba4c2e7fd..ba800f38a 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -83,9 +83,13 @@ void add_frequently_changed_parameters(SV *ui_parent, SV *ui_sizer, SV *ui_p_siz (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), (wxFlexGridSizer*)wxPli_sv_2_object(aTHX_ ui_p_sizer, "Wx::FlexGridSizer")); %}; -void add_expert_mode_part(SV *ui_parent, SV *ui_sizer, int event) - %code%{ Slic3r::GUI::add_expert_mode_part((wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), - (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), event); %}; +void add_expert_mode_part( SV *ui_parent, SV *ui_sizer, + int event_object_selection_changed, + int event_object_settings_changed) + %code%{ Slic3r::GUI::add_expert_mode_part( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), + (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), + event_object_selection_changed, + event_object_settings_changed); %}; void set_objects_from_perl( SV *ui_parent, SV *frequently_changed_parameters_sizer, From 1c695fd97eb4d987bdf2914ed97ee491f4ab3a80 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 12 Jun 2018 23:42:01 +0200 Subject: [PATCH 041/119] Added object movers to the object settings. Added SliderControl to Field. --- xs/src/slic3r/GUI/Field.cpp | 64 ++++++++++++++++++++++++++++++ xs/src/slic3r/GUI/Field.hpp | 32 +++++++++++++++ xs/src/slic3r/GUI/GUI.cpp | 46 ++++++++++++++++++++- xs/src/slic3r/GUI/GUI.hpp | 1 + xs/src/slic3r/GUI/OptionsGroup.cpp | 3 +- 5 files changed, 144 insertions(+), 2 deletions(-) diff --git a/xs/src/slic3r/GUI/Field.cpp b/xs/src/slic3r/GUI/Field.cpp index 43c9e7db9..acab4f4b6 100644 --- a/xs/src/slic3r/GUI/Field.cpp +++ b/xs/src/slic3r/GUI/Field.cpp @@ -665,6 +665,70 @@ boost::any& PointCtrl::get_value() return m_value = ret_point; } +void SliderCtrl::BUILD() +{ + auto size = wxSize(wxDefaultSize); + if (m_opt.height >= 0) size.SetHeight(m_opt.height); + if (m_opt.width >= 0) size.SetWidth(m_opt.width); + + auto temp = new wxBoxSizer(wxHORIZONTAL); + + auto default = static_cast(m_opt.default_value)->value; + auto min = m_opt.min == INT_MIN ? 0 : m_opt.min; + auto max = m_opt.max == INT_MAX ? 100 : m_opt.max; + + m_slider = new wxSlider(m_parent, wxID_ANY, default * m_scale, + min * m_scale, max * m_scale, + wxDefaultPosition, size); + wxSize field_size(40, -1); + + m_textctrl = new wxTextCtrl(m_parent, wxID_ANY, wxString::Format("%d", m_slider->GetValue()/m_scale), + wxDefaultPosition, field_size); + + temp->Add(m_slider, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL, 0); + temp->Add(m_textctrl, 0, wxALIGN_CENTER_VERTICAL, 0); + + m_slider->Bind(wxEVT_SLIDER, ([this](wxCommandEvent e) { + if (!m_disable_change_event){ + int val = boost::any_cast(get_value()); + m_textctrl->SetLabel(wxString::Format("%d", val)); + on_change_field(); + } + }), m_slider->GetId()); + + m_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { + std::string value = e.GetString().utf8_str().data(); + if (is_matched(value, "^-?\\d+(\\.\\d*)?$")){ + m_disable_change_event = true; + m_slider->SetValue(stoi(value)*m_scale); + m_disable_change_event = false; + on_change_field(); + } + }), m_textctrl->GetId()); + + // // recast as a wxWindow to fit the calling convention + m_sizer = dynamic_cast(temp); +} + +void SliderCtrl::set_value(const boost::any& value, bool change_event) +{ + m_disable_change_event = !change_event; + + m_slider->SetValue(boost::any_cast(value)*m_scale); + int val = boost::any_cast(get_value()); + m_textctrl->SetLabel(wxString::Format("%d", val)); + + m_disable_change_event = false; +} + +boost::any& SliderCtrl::get_value() +{ +// int ret_val; +// x_textctrl->GetValue().ToDouble(&val); + return m_value = int(m_slider->GetValue()/m_scale); +} + + } // GUI } // Slic3r diff --git a/xs/src/slic3r/GUI/Field.hpp b/xs/src/slic3r/GUI/Field.hpp index 948178d3e..40f56c0d3 100644 --- a/xs/src/slic3r/GUI/Field.hpp +++ b/xs/src/slic3r/GUI/Field.hpp @@ -384,6 +384,38 @@ public: wxSizer* getSizer() override { return sizer; } }; +class SliderCtrl : public Field { + using Field::Field; +public: + SliderCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {} + SliderCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {} + ~SliderCtrl() {} + + wxSizer* m_sizer{ nullptr }; + wxTextCtrl* m_textctrl{ nullptr }; + wxSlider* m_slider{ nullptr }; + + int m_scale = 10; + + void BUILD() override; + + void set_value(const int value, bool change_event = false); + void set_value(const boost::any& value, bool change_event = false); + boost::any& get_value() override; + + void enable() override { + m_slider->Enable(); + m_textctrl->Enable(); + m_textctrl->SetEditable(true); + } + void disable() override{ + m_slider->Disable(); + m_textctrl->Disable(); + m_textctrl->SetEditable(false); + } + wxSizer* getSizer() override { return m_sizer; } +}; + } // GUI } // Slic3r diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 01a61ff51..d897b6d29 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -139,6 +139,7 @@ bool g_show_print_info = false; bool g_show_manifold_warning_icon = false; wxSizer *m_sizer_object_buttons = nullptr; wxSizer *m_sizer_part_buttons = nullptr; +wxSizer *m_sizer_object_movers = nullptr; wxDataViewCtrl *m_objects_ctrl = nullptr; MyObjectTreeModel *m_objects_model = nullptr; wxCollapsiblePane *m_collpane_settings = nullptr; @@ -1032,6 +1033,42 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) return sizer; } +wxSizer* object_movers(wxWindow *win) +{ + DynamicPrintConfig* config = &g_PresetBundle->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume + std::shared_ptr optgroup = std::make_shared(win, "Move", config); + optgroup->label_width = 20; + + ConfigOptionDef def; + def.label = L("X"); + def.type = coInt; + def.gui_type = "slider"; + def.default_value = new ConfigOptionInt(0); +// def.min = -(model_object->bounding_box->size->x) * 4; +// def.max = model_object->bounding_box->size->x * 4; + + Option option = Option(def, "x"); + option.opt.full_width = true; + optgroup->append_single_option_line(option); + + def.label = L("Y"); +// def.min = -(model_object->bounding_box->size->y) * 4; +// def.max = model_object->bounding_box->size->y * 4; + option = Option(def, "y"); + optgroup->append_single_option_line(option); + + def.label = L("Z"); +// def.min = -(model_object->bounding_box->size->z) * 4; +// def.max = model_object->bounding_box->size->z * 4; + option = Option(def, "z"); + optgroup->append_single_option_line(option); + + m_optgroups.push_back(optgroup); // ogObjectMovers + m_sizer_object_movers = optgroup->sizer; + m_sizer_object_movers->Show(false); + return optgroup->sizer; +} + Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value=0) { Line line = { _(option_name), "" }; @@ -1075,7 +1112,7 @@ Line add_og_to_object_settings(const std::string& option_name, const std::string wxBoxSizer* content_settings(wxWindow *win) { - DynamicPrintConfig* config = &g_PresetBundle->printers.get_edited_preset().config; // TODO get config from Model_volume + DynamicPrintConfig* config = &g_PresetBundle->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume std::shared_ptr optgroup = std::make_shared(win, "Extruders", config); optgroup->label_width = m_label_width; @@ -1095,6 +1132,8 @@ wxBoxSizer* content_settings(wxWindow *win) add_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG)); sizer->Add(add_btn, 0, wxALIGN_LEFT | wxLEFT, 20); + sizer->Add(object_movers(win), 0, wxEXPAND | wxLEFT, 20); + return sizer; } @@ -1141,6 +1180,8 @@ void unselect_objects() m_sizer_object_buttons->Show(false); if (m_sizer_part_buttons->IsShown(1)) m_sizer_part_buttons->Show(false); + if (m_sizer_object_movers->IsShown(1)) + m_sizer_object_movers->Show(false); if (m_collpane_settings->IsShown()) m_collpane_settings->Show(false); } @@ -1159,6 +1200,8 @@ void select_current_object(int idx) if (get_view_mode() == ConfigMenuModeExpert){ if (!m_sizer_object_buttons->IsShown(1)) m_sizer_object_buttons->Show(true); + if (!m_sizer_object_movers->IsShown(1)) + m_sizer_object_movers->Show(true); if (!m_collpane_settings->IsShown()) m_collpane_settings->Show(true); } @@ -1179,6 +1222,7 @@ void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, if (collpane->IsCollapsed()) { m_sizer_object_buttons->Show(false); m_sizer_part_buttons->Show(false); + m_sizer_object_movers->Show(false); m_collpane_settings->Show(false); } // else diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 277729ab0..6e975f953 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -61,6 +61,7 @@ enum ogGroup{ ogFrequentlyChangingParameters, ogFrequentlyObjectSettings, ogObjectSettings, + ogObjectMovers, ogPartSettings }; diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index 52882afda..4778047be 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -30,6 +30,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co opt.gui_type.compare("i_enum_closed") == 0) { m_fields.emplace(id, STDMOVE(Choice::Create(parent(), opt, id))); } else if (opt.gui_type.compare("slider") == 0) { + m_fields.emplace(id, STDMOVE(SliderCtrl::Create(parent(), opt, id))); } else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl } else { switch (opt.type) { @@ -189,7 +190,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* sizer->Add(field->getWindow(), option.opt.full_width ? 1 : 0, (option.opt.full_width ? wxEXPAND : 0) | wxBOTTOM | wxTOP | wxALIGN_CENTER_VERTICAL, (wxOSX||!staticbox) ? 0 : 2); if (is_sizer_field(field)) - sizer->Add(field->getSizer(), 0, (option.opt.full_width ? wxEXPAND : 0) | wxALIGN_CENTER_VERTICAL, 0); + sizer->Add(field->getSizer(), 1, (option.opt.full_width ? wxEXPAND : 0) | wxALIGN_CENTER_VERTICAL, 0); return; } From 8899be8cca7d2528babb19ee7f9a540df23b755f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 13 Jun 2018 16:39:33 +0200 Subject: [PATCH 042/119] Started porting of the functions for object settings editing --- xs/CMakeLists.txt | 2 ++ xs/src/slic3r/GUI/GUI.cpp | 34 +++++++++++++++++++++ xs/src/slic3r/GUI/GUI.hpp | 2 ++ xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 43 +++++++++++++++++++++++++++ xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 12 ++++++++ 5 files changed, 93 insertions(+) create mode 100644 xs/src/slic3r/GUI/GUI_ObjectParts.cpp create mode 100644 xs/src/slic3r/GUI/GUI_ObjectParts.hpp diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index 9c61fa729..8555fb015 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -192,6 +192,8 @@ add_library(libslic3r_gui STATIC ${LIBDIR}/slic3r/GUI/PresetHints.hpp ${LIBDIR}/slic3r/GUI/GUI.cpp ${LIBDIR}/slic3r/GUI/GUI.hpp + ${LIBDIR}/slic3r/GUI/GUI_ObjectParts.cpp + ${LIBDIR}/slic3r/GUI/GUI_ObjectParts.hpp ${LIBDIR}/slic3r/GUI/Tab.cpp ${LIBDIR}/slic3r/GUI/Tab.hpp ${LIBDIR}/slic3r/GUI/TabIface.cpp diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index d897b6d29..dec2c7d7c 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -55,6 +55,7 @@ #include "PresetBundle.hpp" #include "UpdateDialogs.hpp" #include "FirmwareDialog.hpp" +#include "GUI_ObjectParts.hpp" #include "../Utils/PresetUpdater.hpp" #include "../Config/Snapshot.hpp" @@ -495,6 +496,27 @@ void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_languag add_config_menu(menu, event_preferences_changed, event_language_change); } +wxArrayString* open_model(wxWindow *parent){ + t_file_wild_card vec_FILE_WILDCARDS = get_file_wild_card(); + std::vector file_types = { "known", "stl", "obj", "amf", "3mf", "prusa" }; + wxString MODEL_WILDCARD; + for (auto file_type : file_types) + MODEL_WILDCARD += vec_FILE_WILDCARDS.at(file_type) + "|"; + + auto dlg_title = _(L("Choose one or more files (STL/OBJ/AMF/3MF/PRUSA):")); + auto dialog = new wxFileDialog(parent /*? parent : GetTopWindow(g_wxMainFrame)*/, dlg_title, + g_AppConfig->get_last_dir(), "", + MODEL_WILDCARD, wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST); + if (dialog->ShowModal() != wxID_OK) { + dialog->Destroy(); + return nullptr; + } + wxArrayString input_files; + dialog->GetPaths(input_files); + dialog->Destroy(); + return &input_files; +} + // This is called when closing the application, when loading a config file or when starting the config wizard // to notify the user whether he is aware that some preset changes will be lost. bool check_unsaved_changes() @@ -985,6 +1007,18 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) m_objects_ctrl->Select(m_objects_model->AddChild(item, name)); }); + btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) + { + on_btn_load(win, true); +// auto item = m_objects_ctrl->GetSelection(); +// if (!item) return; +// if (m_objects_model->GetParent(item) != wxDataViewItem(0)) +// item = m_objects_model->GetParent(item); +// if (!item) return; +// wxString name = "Part"; +// m_objects_ctrl->Select(m_objects_model->AddChild(item, name)); + }); + btn_delete->Bind(wxEVT_BUTTON, [](wxEvent&) { auto item = m_objects_ctrl->GetSelection(); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 6e975f953..22b41fb20 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -124,6 +124,8 @@ void set_label_clr_sys(const wxColour& clr); const wxFont& small_font(); const wxFont& bold_font(); +wxArrayString* open_model(wxWindow *parent); + extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change); // This is called when closing the application, when loading a config file or when starting the config wizard diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp new file mode 100644 index 000000000..a5abf2af6 --- /dev/null +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -0,0 +1,43 @@ +#include "GUI.hpp" +#include "GUI_ObjectParts.hpp" + +#include + +namespace Slic3r +{ +namespace GUI +{ +void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/) +{ + auto input_files = open_model(parent); +// for(auto input_file : input_files) { +// my $model = eval{ Slic3r::Model->read_from_file($input_file) }; +// if ($@) { +// Slic3r::GUI::show_error($self, $@); +// next; +// } + +// foreach my $object(@{$model->objects}) { +// foreach my $volume(@{$object->volumes}) { +// my $new_volume = $self->{model_object}->add_volume($volume); +// $new_volume->set_modifier($is_modifier); +// $new_volume->set_name(basename($input_file)); +// +// # apply the same translation we applied to the object +// $new_volume->mesh->translate(@{$self->{model_object}->origin_translation}); +// +// # set a default extruder value, since user can't add it manually +// $new_volume->config->set_ifndef('extruder', 0); +// +// $self->{parts_changed} = 1; +// } +// } +// } + + parts_changed(); +} + +void parts_changed(){ ; } + +} //namespace GUI +} //namespace Slic3r \ No newline at end of file diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp new file mode 100644 index 000000000..ffbda35bf --- /dev/null +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -0,0 +1,12 @@ +#ifndef slic3r_GUI_ObjectParts_hpp_ +#define slic3r_GUI_ObjectParts_hpp_ + +namespace Slic3r +{ +namespace GUI +{ +void on_btn_load(wxWindow* parent, bool is_modifier = false); +void parts_changed(); +} //namespace GUI +} //namespace Slic3r +#endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file From 9504780ef4155d2fe15c5b56945e171c13227911 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 14 Jun 2018 15:33:42 +0200 Subject: [PATCH 043/119] Buttons "Add Part" and "Add Modifier" (in the Object Settings) works now --- lib/Slic3r/GUI/MainFrame.pm | 7 +- lib/Slic3r/GUI/Plater.pm | 2 +- xs/src/slic3r/GUI/GUI.cpp | 50 +++++++------ xs/src/slic3r/GUI/GUI.hpp | 14 +++- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 104 +++++++++++++++++++------- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 5 ++ xs/xsp/GUI.xsp | 6 +- 7 files changed, 133 insertions(+), 55 deletions(-) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 626bdef81..fd2844783 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -188,12 +188,11 @@ sub _init_tabpanel { # The following event is emited by the C++ Tab implementation on object settings change. EVT_COMMAND($self, -1, $OBJECT_SETTINGS_CHANGED_EVENT, sub { my ($self, $event) = @_; - my $obj_idx = $event->GetInt; - #my $line = $event->GetString; - #my ($parts_changed, $part_settings_changed) = split('',$line); + my $line = $event->GetString; + my ($obj_idx, $parts_changed, $part_settings_changed) = split('',$line); - #$self->{plater}->changed_object_settings($obj_idx, $parts_changed, $part_settings_changed); + $self->{plater}->changed_object_settings($obj_idx, $parts_changed, $part_settings_changed); }); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index bc149a828..1d2168fe8 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -837,7 +837,7 @@ sub load_model_objects { my $model_object = $self->{model}->objects->[$obj_idx]; # Add object to list on c++ side - Slic3r::GUI::add_object_to_list($object->name, $model_object->instances_count, ($model_object->instances->[0]->scaling_factor * 100)); + Slic3r::GUI::add_object_to_list($object->name, $model_object); $self->reset_thumbnail($obj_idx); } diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index dec2c7d7c..46e1a96d6 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -59,6 +59,7 @@ #include "../Utils/PresetUpdater.hpp" #include "../Config/Snapshot.hpp" +#include "Model.hpp" namespace Slic3r { namespace GUI { @@ -149,6 +150,7 @@ int m_event_object_settings_changed = 0; bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select() // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler // calls this method again and again and again +ModelObjectPtrs m_objects; wxFont g_small_font; wxFont g_bold_font; @@ -496,7 +498,7 @@ void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_languag add_config_menu(menu, event_preferences_changed, event_language_change); } -wxArrayString* open_model(wxWindow *parent){ +void open_model(wxWindow *parent, wxArrayString& input_files){ t_file_wild_card vec_FILE_WILDCARDS = get_file_wild_card(); std::vector file_types = { "known", "stl", "obj", "amf", "3mf", "prusa" }; wxString MODEL_WILDCARD; @@ -509,12 +511,11 @@ wxArrayString* open_model(wxWindow *parent){ MODEL_WILDCARD, wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST); if (dialog->ShowModal() != wxID_OK) { dialog->Destroy(); - return nullptr; + return ; } - wxArrayString input_files; + dialog->GetPaths(input_files); dialog->Destroy(); - return &input_files; } // This is called when closing the application, when loading a config file or when starting the config wizard @@ -810,6 +811,24 @@ unsigned get_colour_approx_luma(const wxColour &colour) b * b * .068 )); } +wxDataViewCtrl* get_objects_ctrl() { + return m_objects_ctrl; +} +MyObjectTreeModel* get_objects_model() { + return m_objects_model; +} + +ModelObjectPtrs& get_objects() { + return m_objects; +} + +const int& get_event_object_settings_changed() { + return m_event_object_settings_changed; +} + +wxFrame* get_main_frame() { + return g_wxMainFrame; +} void create_combochecklist(wxComboCtrl* comboCtrl, std::string text, std::string items, bool initial_value) { @@ -996,27 +1015,14 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) auto btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); //*** button's functions - btn_load_part->Bind(wxEVT_BUTTON, [](wxEvent&) + btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) { - auto item = m_objects_ctrl->GetSelection(); - if (!item) return; - if (m_objects_model->GetParent(item) != wxDataViewItem(0)) - item = m_objects_model->GetParent(item); - if (!item) return; - wxString name = "Part"; - m_objects_ctrl->Select(m_objects_model->AddChild(item, name)); + on_btn_load(win); }); btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) { on_btn_load(win, true); -// auto item = m_objects_ctrl->GetSelection(); -// if (!item) return; -// if (m_objects_model->GetParent(item) != wxDataViewItem(0)) -// item = m_objects_model->GetParent(item); -// if (!item) return; -// wxString name = "Part"; -// m_objects_ctrl->Select(m_objects_model->AddChild(item, name)); }); btn_delete->Bind(wxEVT_BUTTON, [](wxEvent&) @@ -1171,10 +1177,12 @@ wxBoxSizer* content_settings(wxWindow *win) return sizer; } -void add_object_to_list(const std::string &name, int instances_count, int scale) +void add_object_to_list(const std::string &name, ModelObject* model_object) { wxString item = name; - m_objects_ctrl->Select(m_objects_model->Add(item, instances_count, scale)); + int scale = model_object->instances[0]->scaling_factor * 100; + m_objects_ctrl->Select(m_objects_model->Add(item, model_object->instances.size(), scale)); + m_objects.push_back(model_object); } void delete_object_from_list() diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 22b41fb20..5c5a1a6a9 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -25,6 +25,8 @@ class wxButton; class wxFileDialog; class wxStaticBitmap; class wxFont; +class wxDataViewCtrl; +class MyObjectTreeModel; namespace Slic3r { @@ -34,6 +36,7 @@ class AppConfig; class PresetUpdater; class DynamicPrintConfig; class TabIface; +class ModelObject; #define _(s) Slic3r::translate((s)) inline wxString translate(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)); } @@ -67,6 +70,7 @@ enum ogGroup{ class Tab; class ConfigOptionsGroup; +typedef std::vector ModelObjectPtrs; // Map from an file_type name to full file wildcard name. typedef std::map t_file_wild_card; inline t_file_wild_card& get_file_wild_card() { @@ -124,7 +128,13 @@ void set_label_clr_sys(const wxColour& clr); const wxFont& small_font(); const wxFont& bold_font(); -wxArrayString* open_model(wxWindow *parent); +void open_model(wxWindow *parent, wxArrayString& input_files); + +wxDataViewCtrl* get_objects_ctrl (); +MyObjectTreeModel* get_objects_model(); +ModelObjectPtrs& get_objects(); +const int& get_event_object_settings_changed(); +wxFrame* get_main_frame(); extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change); @@ -191,7 +201,7 @@ wxString from_u8(const std::string &str); // Add object to the list //void add_object(const std::string &name); -void add_object_to_list(const std::string &name, int instances_count=1, int scale=100); +void add_object_to_list(const std::string &name, ModelObject* model_object); // Delete object from the list void delete_object_from_list(); // Delete all objects from the list diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index a5abf2af6..57d46c977 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -1,42 +1,96 @@ #include "GUI.hpp" #include "GUI_ObjectParts.hpp" +#include "Model.hpp" +#include "wxExtensions.hpp" #include +#include +#include namespace Slic3r { namespace GUI { -void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/) -{ - auto input_files = open_model(parent); -// for(auto input_file : input_files) { -// my $model = eval{ Slic3r::Model->read_from_file($input_file) }; -// if ($@) { -// Slic3r::GUI::show_error($self, $@); -// next; -// } +bool m_parts_changed = false; +bool m_part_settings_changed = false; -// foreach my $object(@{$model->objects}) { -// foreach my $volume(@{$object->volumes}) { -// my $new_volume = $self->{model_object}->add_volume($volume); -// $new_volume->set_modifier($is_modifier); -// $new_volume->set_name(basename($input_file)); -// -// # apply the same translation we applied to the object -// $new_volume->mesh->translate(@{$self->{model_object}->origin_translation}); -// -// # set a default extruder value, since user can't add it manually -// $new_volume->config->set_ifndef('extruder', 0); -// -// $self->{parts_changed} = 1; -// } -// } -// } +bool is_parts_changed(){return m_parts_changed;} +bool is_part_settings_changed(){ return m_part_settings_changed; } + +void load_part(wxWindow* parent, ModelObject* model_object, wxArrayString& part_names, bool is_modifier) +{ + wxArrayString input_files; + open_model(parent, input_files); + for (int i = 0; i < input_files.size(); ++i) { + std::string input_file = input_files.Item(i).ToStdString(); + + Model model; + try { + model = Model::read_from_file(input_file); + } + catch (std::exception &e) { + auto msg = _(L("Error! ")) + input_file + " : " + e.what() + "."; + show_error(parent, msg); + exit(1); + } + + for ( auto object : model.objects) { + for (auto volume : object->volumes) { + auto new_volume = model_object->add_volume(*volume); + new_volume->modifier = is_modifier; + boost::filesystem::path(input_file).filename().string(); + new_volume->name = boost::filesystem::path(input_file).filename().string(); + + part_names.Add(new_volume->name); + + // apply the same translation we applied to the object + new_volume->mesh.translate( model_object->origin_translation.x, + model_object->origin_translation.y, + model_object->origin_translation.y ); + + // set a default extruder value, since user can't add it manually + new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); + + m_parts_changed = true; + } + } + } parts_changed(); } +void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/) +{ + auto objects_ctrl = get_objects_ctrl(); + auto item = objects_ctrl->GetSelection(); + if (!item) + return; + int obj_idx = -1; + auto objects_model = get_objects_model(); + if (objects_model->GetParent(item) == wxDataViewItem(0)) + obj_idx = objects_model->GetIdByItem(item); + else + return; + + if (obj_idx < 0) return; + wxArrayString part_names; + ModelObjectPtrs& objects = get_objects(); + load_part(parent, objects[obj_idx], part_names, is_modifier); + + auto event = get_event_object_settings_changed(); + if (event > 0) { + wxCommandEvent e(event); + auto event_str = wxString::Format("%d %d %d", obj_idx, + is_parts_changed() ? 1 : 0, + is_part_settings_changed() ? 1 : 0); + e.SetString(event_str); + get_main_frame()->ProcessWindowEvent(e); + } + + for (int i = 0; i < part_names.size(); ++i) + objects_ctrl->Select(objects_model->AddChild(item, part_names.Item(i))); +} + void parts_changed(){ ; } } //namespace GUI diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index ffbda35bf..9ee982b96 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -5,6 +5,11 @@ namespace Slic3r { namespace GUI { +bool is_parts_changed(); +bool is_part_settings_changed(); + +void load_part( wxWindow* parent, ModelObject* model_object, + wxArrayString& part_names, bool is_modifier); void on_btn_load(wxWindow* parent, bool is_modifier = false); void parts_changed(); } //namespace GUI diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index ba800f38a..2c5e7fccd 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -122,8 +122,10 @@ void set_show_manifold_warning_icon(bool show) void update_mode() %code%{ Slic3r::GUI::update_mode(); %}; -void add_object_to_list(const char *name, int instances_count, int scale) - %code%{ Slic3r::GUI::add_object_to_list(name, instances_count, scale); %}; +void add_object_to_list(const char *name, SV *object_model) + %code%{ Slic3r::GUI::add_object_to_list( + name, + (ModelObject *)wxPli_sv_2_object(aTHX_ object_model, "Slic3r::Model::Object") ); %}; void delete_object_from_list() %code%{ Slic3r::GUI::delete_object_from_list(); %}; From 3e0ff5e9efe545493e20837269ba96b8834a244c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 14 Jun 2018 21:48:06 +0200 Subject: [PATCH 044/119] Added LambdaObjectDialog --- xs/CMakeLists.txt | 2 + xs/src/slic3r/GUI/GUI.cpp | 7 ++ xs/src/slic3r/GUI/GUI.hpp | 11 ++ xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 26 ++-- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 2 +- xs/src/slic3r/GUI/LambdaObjectDialog.cpp | 151 +++++++++++++++++++++++ xs/src/slic3r/GUI/LambdaObjectDialog.hpp | 34 +++++ 7 files changed, 220 insertions(+), 13 deletions(-) create mode 100644 xs/src/slic3r/GUI/LambdaObjectDialog.cpp create mode 100644 xs/src/slic3r/GUI/LambdaObjectDialog.hpp diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index 8555fb015..46072b091 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -194,6 +194,8 @@ add_library(libslic3r_gui STATIC ${LIBDIR}/slic3r/GUI/GUI.hpp ${LIBDIR}/slic3r/GUI/GUI_ObjectParts.cpp ${LIBDIR}/slic3r/GUI/GUI_ObjectParts.hpp + ${LIBDIR}/slic3r/GUI/LambdaObjectDialog.cpp + ${LIBDIR}/slic3r/GUI/LambdaObjectDialog.hpp ${LIBDIR}/slic3r/GUI/Tab.cpp ${LIBDIR}/slic3r/GUI/Tab.hpp ${LIBDIR}/slic3r/GUI/TabIface.cpp diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 46e1a96d6..6b4195e94 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -60,6 +60,7 @@ #include "../Utils/PresetUpdater.hpp" #include "../Config/Snapshot.hpp" #include "Model.hpp" +#include "LambdaObjectDialog.hpp" namespace Slic3r { namespace GUI { @@ -1025,6 +1026,12 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) on_btn_load(win, true); }); + btn_load_lambda_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) + { + auto dlg = new LambdaObjectDialog(win); + dlg->ShowModal(); + }); + btn_delete->Bind(wxEVT_BUTTON, [](wxEvent&) { auto item = m_objects_ctrl->GetSelection(); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 5c5a1a6a9..12eef0b62 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -89,6 +89,17 @@ inline t_file_wild_card& get_file_wild_card() { return FILE_WILDCARDS; } +struct OBJECT_PARAMETERS +{ + std::string type = "box"; + double dim[3];// = { 1.0, 1.0, 1.0 }; + int cyl_r = 1; + int cyl_h = 1; + double sph_rho = 1.0; + double slab_h = 1.0; + double slab_z = 0.0; +}; + void disable_screensaver(); void enable_screensaver(); bool debugged(); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 57d46c977..2f88b58f7 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -55,8 +55,6 @@ void load_part(wxWindow* parent, ModelObject* model_object, wxArrayString& part_ } } } - - parts_changed(); } void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/) @@ -77,21 +75,25 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/) ModelObjectPtrs& objects = get_objects(); load_part(parent, objects[obj_idx], part_names, is_modifier); - auto event = get_event_object_settings_changed(); - if (event > 0) { - wxCommandEvent e(event); - auto event_str = wxString::Format("%d %d %d", obj_idx, - is_parts_changed() ? 1 : 0, - is_part_settings_changed() ? 1 : 0); - e.SetString(event_str); - get_main_frame()->ProcessWindowEvent(e); - } + parts_changed(obj_idx); for (int i = 0; i < part_names.size(); ++i) objects_ctrl->Select(objects_model->AddChild(item, part_names.Item(i))); } -void parts_changed(){ ; } +void parts_changed(int obj_idx) +{ + auto event = get_event_object_settings_changed(); + if (event <= 0) + return; + + wxCommandEvent e(event); + auto event_str = wxString::Format("%d %d %d", obj_idx, + is_parts_changed() ? 1 : 0, + is_part_settings_changed() ? 1 : 0); + e.SetString(event_str); + get_main_frame()->ProcessWindowEvent(e); +} } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 9ee982b96..cf07bb242 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -11,7 +11,7 @@ bool is_part_settings_changed(); void load_part( wxWindow* parent, ModelObject* model_object, wxArrayString& part_names, bool is_modifier); void on_btn_load(wxWindow* parent, bool is_modifier = false); -void parts_changed(); +void parts_changed(int obj_idx); } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.cpp b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp new file mode 100644 index 000000000..5657c7a71 --- /dev/null +++ b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp @@ -0,0 +1,151 @@ +#include "LambdaObjectDialog.hpp" + +#include +#include +#include "OptionsGroup.hpp" + +namespace Slic3r +{ +namespace GUI +{ +static wxString dots("…", wxConvUTF8); + +LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) +{ + Create(parent, wxID_ANY, _(L("Lambda Object")), + wxDefaultPosition, wxSize(500, 500), + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + + // instead of double dim[3] = { 1.0, 1.0, 1.0 }; + object_parameters.dim[0] = 1.0; + object_parameters.dim[1] = 1.0; + object_parameters.dim[2] = 1.0; + + sizer = new wxBoxSizer(wxVERTICAL); + + // modificator options + m_modificator_options_book = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxSize(300, -1), wxCHB_TOP); + sizer->Add(m_modificator_options_book, 1, wxEXPAND| wxALL, 10); + + auto optgroup = init_modificator_options_page(_(L("Box"))); + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ + int opt_id = opt_key == "L" ? 0 : + opt_key == "W" ? 1 : + opt_key == "L" ? 2 : -1; + if (opt_id < 0) return; + object_parameters.dim[opt_id] = boost::any_cast(value); + }; + + ConfigOptionDef def; + def.type = coFloat; + def.default_value = new ConfigOptionFloat{ 1.0 }; + def.label = L("L"); + Option option(def, "l"); + optgroup->append_single_option_line(option); + + def.label = L("W"); + option = Option(def, "w"); + optgroup->append_single_option_line(option); + + def.label = L("H"); + option = Option(def, "h"); + optgroup->append_single_option_line(option); + + optgroup = init_modificator_options_page(_(L("Cylinder"))); + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ + int val = boost::any_cast(value); + if (opt_key == "cyl_r") + object_parameters.cyl_r = val; + else if (opt_key == "cyl_h") + object_parameters.cyl_h = val; + else return; + }; + + def.type = coInt; + def.default_value = new ConfigOptionInt{ 1 }; + def.label = L("Radius"); + option = Option(def, "cyl_r"); + optgroup->append_single_option_line(option); + + def.label = L("Height"); + option = Option(def, "cyl_h"); + optgroup->append_single_option_line(option); + + optgroup = init_modificator_options_page(_(L("Sphere"))); + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ + if (opt_key == "sph_rho") + object_parameters.sph_rho = boost::any_cast(value); + else return; + }; + + def.type = coFloat; + def.default_value = new ConfigOptionFloat{ 1.0 }; + def.label = L("Rho"); + option = Option(def, "sph_rho"); + optgroup->append_single_option_line(option); + + optgroup = init_modificator_options_page(_(L("Slab"))); + optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ + double val = boost::any_cast(value); + if (opt_key == "slab_z") + object_parameters.slab_z = val; + else if (opt_key == "slab_h") + object_parameters.slab_h = val; + else return; + }; + + def.label = L("H"); + option = Option(def, "slab_h"); + optgroup->append_single_option_line(option); + + def.label = L("Initial Z"); + option = Option(def, "slab_z"); + optgroup->append_single_option_line(option); + + + auto button_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL); + + wxButton* btn_OK = static_cast(FindWindowById(wxID_OK, this)); + btn_OK->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + // validate user input + if (!CanClose())return; + EndModal(wxID_OK); + Destroy(); + }); + + wxButton* btn_CANCEL = static_cast(FindWindowById(wxID_CANCEL, this)); + btn_CANCEL->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { + // validate user input + if (!CanClose())return; + EndModal(wxID_CANCEL); + Destroy(); + }); + + sizer->Add(button_sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10); + + SetSizer(sizer); + sizer->Fit(this); + sizer->SetSizeHints(this); +} + +// Called from the constructor. +// Create a panel for a rectangular / circular / custom bed shape. +ConfigOptionsGroupShp LambdaObjectDialog::init_modificator_options_page(wxString title){ + + auto panel = new wxPanel(m_modificator_options_book); + + ConfigOptionsGroupShp optgroup; + optgroup = std::make_shared(panel, _(L("Add")) + " " +title + " " +dots); + optgroup->label_width = 100; + + m_optgroups.push_back(optgroup); + + panel->SetSizerAndFit(optgroup->sizer); + m_modificator_options_book->AddPage(panel, title); + + return optgroup; +} + + +} //namespace GUI +} //namespace Slic3r diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.hpp b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp new file mode 100644 index 000000000..712722b2d --- /dev/null +++ b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp @@ -0,0 +1,34 @@ +#ifndef slic3r_LambdaObjectDialog_hpp_ +#define slic3r_LambdaObjectDialog_hpp_ + +#include "GUI.hpp" + +#include +#include +#include + +namespace Slic3r +{ +namespace GUI +{ +using ConfigOptionsGroupShp = std::shared_ptr; +class LambdaObjectDialog : public wxDialog +{ + wxChoicebook* m_modificator_options_book; + std::vector m_optgroups; +public: + LambdaObjectDialog(wxWindow* parent); + ~LambdaObjectDialog(){} + + bool CanClose() { return true; } // ??? + + ConfigOptionsGroupShp init_modificator_options_page(wxString title); + + // Note whether the window was already closed, so a pending update is not executed. + bool m_already_closed = false; + OBJECT_PARAMETERS object_parameters; + wxBoxSizer* sizer = nullptr; +}; +} //namespace GUI +} //namespace Slic3r +#endif //slic3r_LambdaObjectDialog_hpp_ From a0090fccb5c8ba0484df721a5b5376a2dd92cf8b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 14 Jun 2018 23:31:15 +0200 Subject: [PATCH 045/119] Button "Load Lambda" (in the Object Settings) works now --- xs/src/slic3r/GUI/GUI.cpp | 3 +- xs/src/slic3r/GUI/GUI.hpp | 21 +++++--- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 61 ++++++++++++++++++++++-- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 9 +++- xs/src/slic3r/GUI/LambdaObjectDialog.cpp | 29 ++++++++++- xs/src/slic3r/GUI/LambdaObjectDialog.hpp | 1 + 6 files changed, 107 insertions(+), 17 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 6b4195e94..f738ca693 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1028,8 +1028,7 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) btn_load_lambda_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) { - auto dlg = new LambdaObjectDialog(win); - dlg->ShowModal(); + on_btn_load(win, true, true); }); btn_delete->Bind(wxEVT_BUTTON, [](wxEvent&) diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 12eef0b62..fdad1e291 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -68,6 +68,13 @@ enum ogGroup{ ogPartSettings }; +enum LambdaTypeIDs{ + LambdaTypeBox, + LambdaTypeCylinder, + LambdaTypeSphere, + LambdaTypeSlab +}; + class Tab; class ConfigOptionsGroup; typedef std::vector ModelObjectPtrs; @@ -91,13 +98,13 @@ inline t_file_wild_card& get_file_wild_card() { struct OBJECT_PARAMETERS { - std::string type = "box"; - double dim[3];// = { 1.0, 1.0, 1.0 }; - int cyl_r = 1; - int cyl_h = 1; - double sph_rho = 1.0; - double slab_h = 1.0; - double slab_z = 0.0; + LambdaTypeIDs type = LambdaTypeBox; + double dim[3];// = { 1.0, 1.0, 1.0 }; + int cyl_r = 1; + int cyl_h = 1; + double sph_rho = 1.0; + double slab_h = 1.0; + double slab_z = 0.0; }; void disable_screensaver(); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 2f88b58f7..5aa0d8b15 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "LambdaObjectDialog.hpp" namespace Slic3r { @@ -17,7 +18,8 @@ bool m_part_settings_changed = false; bool is_parts_changed(){return m_parts_changed;} bool is_part_settings_changed(){ return m_part_settings_changed; } -void load_part(wxWindow* parent, ModelObject* model_object, wxArrayString& part_names, bool is_modifier) +void load_part( wxWindow* parent, ModelObject* model_object, + wxArrayString& part_names, const bool is_modifier) { wxArrayString input_files; open_model(parent, input_files); @@ -47,7 +49,6 @@ void load_part(wxWindow* parent, ModelObject* model_object, wxArrayString& part_ new_volume->mesh.translate( model_object->origin_translation.x, model_object->origin_translation.y, model_object->origin_translation.y ); - // set a default extruder value, since user can't add it manually new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); @@ -57,7 +58,56 @@ void load_part(wxWindow* parent, ModelObject* model_object, wxArrayString& part_ } } -void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/) +void load_lambda( wxWindow* parent, ModelObject* model_object, + wxArrayString& part_names, const bool is_modifier) +{ + auto dlg = new LambdaObjectDialog(parent); + if (dlg->ShowModal() == wxID_CANCEL) { + return; + } + + std::string name = "lambda-"; + TriangleMesh mesh; + + auto params = dlg->ObjectParameters(); + switch (params.type) + { + case LambdaTypeBox:{ + mesh = make_cube(params.dim[0], params.dim[1], params.dim[2]); + name += "Box"; + break;} + case LambdaTypeCylinder:{ + mesh = make_cylinder(params.cyl_r, params.cyl_h); + name += "Cylinder"; + break;} + case LambdaTypeSphere:{ + mesh = make_sphere(params.sph_rho); + name += "Sphere"; + break;} + case LambdaTypeSlab:{ + const auto& size = model_object->bounding_box().size(); + mesh = make_cube(size.x*1.5, size.y*1.5, params.slab_h); + // box sets the base coordinate at 0, 0, move to center of plate and move it up to initial_z + mesh.translate(-size.x*1.5 / 2.0, -size.y*1.5 / 2.0, params.slab_z); + name += "Slab"; + break; } + default: + break; + } + mesh.repair(); + + auto new_volume = model_object->add_volume(mesh); + new_volume->modifier = is_modifier; + new_volume->name = name; + // set a default extruder value, since user can't add it manually + new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); + + part_names.Add(name); + + m_parts_changed = true; +} + +void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/* = false*/) { auto objects_ctrl = get_objects_ctrl(); auto item = objects_ctrl->GetSelection(); @@ -73,7 +123,10 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/) if (obj_idx < 0) return; wxArrayString part_names; ModelObjectPtrs& objects = get_objects(); - load_part(parent, objects[obj_idx], part_names, is_modifier); + if (is_lambda) + load_lambda(parent, objects[obj_idx], part_names, is_modifier); + else + load_part(parent, objects[obj_idx], part_names, is_modifier); parts_changed(obj_idx); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index cf07bb242..40bcc012e 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -9,8 +9,13 @@ bool is_parts_changed(); bool is_part_settings_changed(); void load_part( wxWindow* parent, ModelObject* model_object, - wxArrayString& part_names, bool is_modifier); -void on_btn_load(wxWindow* parent, bool is_modifier = false); + wxArrayString& part_names, const bool is_modifier); + +void load_lambda(wxWindow* parent, ModelObject* model_object, + wxArrayString& part_names, const bool is_modifier); + +void on_btn_load(wxWindow* parent, bool is_modifier = false, bool is_lambda = false); + void parts_changed(int obj_idx); } //namespace GUI } //namespace Slic3r diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.cpp b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp index 5657c7a71..b5479fb12 100644 --- a/xs/src/slic3r/GUI/LambdaObjectDialog.cpp +++ b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp @@ -13,7 +13,7 @@ static wxString dots("…", wxConvUTF8); LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) { Create(parent, wxID_ANY, _(L("Lambda Object")), - wxDefaultPosition, wxSize(500, 500), + wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); // instead of double dim[3] = { 1.0, 1.0, 1.0 }; @@ -24,7 +24,8 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) sizer = new wxBoxSizer(wxVERTICAL); // modificator options - m_modificator_options_book = new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxSize(300, -1), wxCHB_TOP); + m_modificator_options_book = new wxChoicebook( this, wxID_ANY, wxDefaultPosition, + wxDefaultSize, wxCHB_TOP); sizer->Add(m_modificator_options_book, 1, wxEXPAND| wxALL, 10); auto optgroup = init_modificator_options_page(_(L("Box"))); @@ -37,6 +38,7 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) }; ConfigOptionDef def; + def.width = 70; def.type = coFloat; def.default_value = new ConfigOptionFloat{ 1.0 }; def.label = L("L"); @@ -102,6 +104,29 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) option = Option(def, "slab_z"); optgroup->append_single_option_line(option); + Bind(wxEVT_CHOICEBOOK_PAGE_CHANGED, ([this](wxCommandEvent e) + { + auto page_idx = m_modificator_options_book->GetSelection(); + if (page_idx < 0) return; + switch (page_idx) + { + case 0: + object_parameters.type = LambdaTypeBox; + break; + case 1: + object_parameters.type = LambdaTypeCylinder; + break; + case 2: + object_parameters.type = LambdaTypeSphere; + break; + case 3: + object_parameters.type = LambdaTypeSlab; + break; + default: + break; + } + })); + auto button_sizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL); diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.hpp b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp index 712722b2d..a70c12449 100644 --- a/xs/src/slic3r/GUI/LambdaObjectDialog.hpp +++ b/xs/src/slic3r/GUI/LambdaObjectDialog.hpp @@ -21,6 +21,7 @@ public: ~LambdaObjectDialog(){} bool CanClose() { return true; } // ??? + OBJECT_PARAMETERS& ObjectParameters(){ return object_parameters; } ConfigOptionsGroupShp init_modificator_options_page(wxString title); From 942a3340aae6f71943691beb0ea042d1c2f4d1f0 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 14 Jun 2018 23:56:44 +0200 Subject: [PATCH 046/119] Added a check for the correctness of the entered characters in numerical fields. --- xs/src/slic3r/GUI/Field.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/Field.cpp b/xs/src/slic3r/GUI/Field.cpp index acab4f4b6..a50094662 100644 --- a/xs/src/slic3r/GUI/Field.cpp +++ b/xs/src/slic3r/GUI/Field.cpp @@ -105,7 +105,11 @@ namespace Slic3r { namespace GUI { break; } double val; - str.ToCDouble(&val); + if(!str.ToCDouble(&val)) + { + show_error(m_parent, _(L("Input value contains incorrect symbol(s).\nUse, please, only digits"))); + set_value(double_to_string(val), true); + } if (m_opt.min > val || val > m_opt.max) { show_error(m_parent, _(L("Input value is out of range"))); From a91cb5b267df4f4209c78a3ce8bed977e0472f7d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 15 Jun 2018 22:42:51 +0200 Subject: [PATCH 047/119] Upgraded object_control to use icons near the name Renamed some classes Deleted unused classes --- xs/src/slic3r/GUI/Field.cpp | 4 +- xs/src/slic3r/GUI/GUI.cpp | 31 +-- xs/src/slic3r/GUI/GUI.hpp | 4 +- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 7 +- xs/src/slic3r/GUI/wxExtensions.cpp | 357 +++----------------------- xs/src/slic3r/GUI/wxExtensions.hpp | 252 +++--------------- 6 files changed, 99 insertions(+), 556 deletions(-) diff --git a/xs/src/slic3r/GUI/Field.cpp b/xs/src/slic3r/GUI/Field.cpp index a50094662..dcb251be6 100644 --- a/xs/src/slic3r/GUI/Field.cpp +++ b/xs/src/slic3r/GUI/Field.cpp @@ -677,11 +677,11 @@ void SliderCtrl::BUILD() auto temp = new wxBoxSizer(wxHORIZONTAL); - auto default = static_cast(m_opt.default_value)->value; + auto def_val = static_cast(m_opt.default_value)->value; auto min = m_opt.min == INT_MIN ? 0 : m_opt.min; auto max = m_opt.max == INT_MAX ? 100 : m_opt.max; - m_slider = new wxSlider(m_parent, wxID_ANY, default * m_scale, + m_slider = new wxSlider(m_parent, wxID_ANY, def_val * m_scale, min * m_scale, max * m_scale, wxDefaultPosition, size); wxSize field_size(40, -1); diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index f738ca693..3e76c99f7 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -144,7 +144,7 @@ wxSizer *m_sizer_object_buttons = nullptr; wxSizer *m_sizer_part_buttons = nullptr; wxSizer *m_sizer_object_movers = nullptr; wxDataViewCtrl *m_objects_ctrl = nullptr; -MyObjectTreeModel *m_objects_model = nullptr; +PrusaObjectDataViewModel *m_objects_model = nullptr; wxCollapsiblePane *m_collpane_settings = nullptr; int m_event_object_selection_changed = 0; int m_event_object_settings_changed = 0; @@ -815,7 +815,7 @@ unsigned get_colour_approx_luma(const wxColour &colour) wxDataViewCtrl* get_objects_ctrl() { return m_objects_ctrl; } -MyObjectTreeModel* get_objects_model() { +PrusaObjectDataViewModel* get_objects_model() { return m_objects_model; } @@ -925,36 +925,28 @@ wxBoxSizer* content_objects_list(wxWindow *win) { m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); m_objects_ctrl->SetInitialSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects + auto objects_sz = new wxBoxSizer(wxVERTICAL); objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT, 20); - m_objects_model = new MyObjectTreeModel; + m_objects_model = new PrusaObjectDataViewModel; m_objects_ctrl->AssociateModel(m_objects_model); #if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE m_objects_ctrl->EnableDragSource(wxDF_UNICODETEXT); m_objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT); #endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE - // column 0 of the view control: - - wxDataViewTextRenderer *tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); - wxDataViewColumn *column00 = new wxDataViewColumn("Name", tr, 0, 110, wxALIGN_LEFT, - wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); - m_objects_ctrl->AppendColumn(column00); + // column 0(Icon+Text) of the view control: + m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 150, + wxALIGN_LEFT, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); // column 1 of the view control: - - tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); - wxDataViewColumn *column01 = new wxDataViewColumn("Copy", tr, 1, 75, wxALIGN_CENTER_HORIZONTAL, - wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); - m_objects_ctrl->AppendColumn(column01); + m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 65, + wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); // column 2 of the view control: - - tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); - wxDataViewColumn *column02 = new wxDataViewColumn("Scale", tr, 2, 80, wxALIGN_CENTER_HORIZONTAL, - wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); - m_objects_ctrl->AppendColumn(column02); + m_objects_ctrl->AppendTextColumn(_(L("Scale")), 2, wxDATAVIEW_CELL_INERT, 70, + wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { @@ -988,6 +980,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) auto show_obj_sizer = m_objects_model->GetParent(item) == wxDataViewItem(0); m_sizer_object_buttons->Show(show_obj_sizer); m_sizer_part_buttons->Show(!show_obj_sizer); + m_sizer_object_movers->Show(!show_obj_sizer); m_collpane_settings->SetLabelText((show_obj_sizer ? _(L("Object Settings")) : _(L("Part Settings"))) + ":"); m_collpane_settings->Show(true); }); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index fdad1e291..ef34d2bf8 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -26,7 +26,7 @@ class wxFileDialog; class wxStaticBitmap; class wxFont; class wxDataViewCtrl; -class MyObjectTreeModel; +class PrusaObjectDataViewModel; namespace Slic3r { @@ -149,7 +149,7 @@ const wxFont& bold_font(); void open_model(wxWindow *parent, wxArrayString& input_files); wxDataViewCtrl* get_objects_ctrl (); -MyObjectTreeModel* get_objects_model(); +PrusaObjectDataViewModel* get_objects_model(); ModelObjectPtrs& get_objects(); const int& get_event_object_settings_changed(); wxFrame* get_main_frame(); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 5aa0d8b15..8783471a5 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -2,11 +2,12 @@ #include "GUI_ObjectParts.hpp" #include "Model.hpp" #include "wxExtensions.hpp" +#include "LambdaObjectDialog.hpp" +#include "../../libslic3r/Utils.hpp" #include #include #include -#include "LambdaObjectDialog.hpp" namespace Slic3r { @@ -130,8 +131,10 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/ parts_changed(obj_idx); + const std::string icon_name = is_modifier ? "plugin.png" : "package.png"; + auto icon = wxIcon(Slic3r::GUI::from_u8(Slic3r::var(icon_name)), wxBITMAP_TYPE_PNG); for (int i = 0; i < part_names.size(); ++i) - objects_ctrl->Select(objects_model->AddChild(item, part_names.Item(i))); + objects_ctrl->Select(objects_model->AddChild(item, part_names.Item(i), icon)); } void parts_changed(int obj_idx) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index b0c60d4c1..36801634e 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -341,12 +341,12 @@ void PrusaCollapsiblePaneMSW::Collapse(bool collapse) // ***************************************************************************** // ---------------------------------------------------------------------------- -// MyObjectTreeModel +// PrusaObjectDataViewModel // ---------------------------------------------------------------------------- -wxDataViewItem MyObjectTreeModel::Add(wxString &name) +wxDataViewItem PrusaObjectDataViewModel::Add(wxString &name) { - auto root = new MyObjectTreeModelNode(name); + auto root = new PrusaObjectDataViewModelNode(name); m_objects.push_back(root); // notify control wxDataViewItem child((void*)root); @@ -355,9 +355,9 @@ wxDataViewItem MyObjectTreeModel::Add(wxString &name) return child; } -wxDataViewItem MyObjectTreeModel::Add(wxString &name, int instances_count, int scale) +wxDataViewItem PrusaObjectDataViewModel::Add(wxString &name, int instances_count, int scale) { - auto root = new MyObjectTreeModelNode(name, instances_count, scale); + auto root = new PrusaObjectDataViewModelNode(name, instances_count, scale); m_objects.push_back(root); // notify control wxDataViewItem child((void*)root); @@ -366,21 +366,24 @@ wxDataViewItem MyObjectTreeModel::Add(wxString &name, int instances_count, int s return child; } -wxDataViewItem MyObjectTreeModel::AddChild(const wxDataViewItem &parent_item, wxString &name) +wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_item, + const wxString &name, + const wxIcon& icon) { - MyObjectTreeModelNode *root = (MyObjectTreeModelNode*)parent_item.GetID(); + PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID(); if (!root) return wxDataViewItem(0); if (root->GetChildren().Count() == 0) { - auto node = new MyObjectTreeModelNode(root, root->m_name); + auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); + auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh); root->Append(node); // notify control wxDataViewItem child((void*)node); ItemAdded(parent_item, child); } - auto node = new MyObjectTreeModelNode(root, name); + auto node = new PrusaObjectDataViewModelNode(root, name, icon); root->Append(node); // notify control wxDataViewItem child((void*)node); @@ -388,10 +391,10 @@ wxDataViewItem MyObjectTreeModel::AddChild(const wxDataViewItem &parent_item, wx return child; } -wxDataViewItem MyObjectTreeModel::Delete(const wxDataViewItem &item) +wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) { auto ret_item = wxDataViewItem(0); - MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); if (!node) // happens if item.IsOk()==false return ret_item; @@ -434,7 +437,7 @@ wxDataViewItem MyObjectTreeModel::Delete(const wxDataViewItem &item) return ret_item; } -void MyObjectTreeModel::DeleteAll() +void PrusaObjectDataViewModel::DeleteAll() { while (!m_objects.empty()) { @@ -444,7 +447,7 @@ void MyObjectTreeModel::DeleteAll() } } -wxDataViewItem MyObjectTreeModel::GetItemById(int obj_idx) +wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx) { if (obj_idx >= m_objects.size()) { @@ -455,11 +458,11 @@ wxDataViewItem MyObjectTreeModel::GetItemById(int obj_idx) } -int MyObjectTreeModel::GetIdByItem(wxDataViewItem& item) +int PrusaObjectDataViewModel::GetIdByItem(wxDataViewItem& item) { wxASSERT(item.IsOk()); - MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); auto it = find(m_objects.begin(), m_objects.end(), node); if (it == m_objects.end()) return -1; @@ -467,43 +470,44 @@ int MyObjectTreeModel::GetIdByItem(wxDataViewItem& item) return it - m_objects.begin(); } -wxString MyObjectTreeModel::GetName(const wxDataViewItem &item) const +wxString PrusaObjectDataViewModel::GetName(const wxDataViewItem &item) const { - MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); if (!node) // happens if item.IsOk()==false return wxEmptyString; return node->m_name; } -wxString MyObjectTreeModel::GetCopy(const wxDataViewItem &item) const +wxString PrusaObjectDataViewModel::GetCopy(const wxDataViewItem &item) const { - MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); if (!node) // happens if item.IsOk()==false return wxEmptyString; return node->m_copy; } -wxString MyObjectTreeModel::GetScale(const wxDataViewItem &item) const +wxString PrusaObjectDataViewModel::GetScale(const wxDataViewItem &item) const { - MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); if (!node) // happens if item.IsOk()==false return wxEmptyString; return node->m_scale; } -void MyObjectTreeModel::GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned int col) const +void PrusaObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned int col) const { wxASSERT(item.IsOk()); - MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); switch (col) { - case 0: - variant = node->m_name; - break; + case 0:{ + const wxDataViewIconText data(node->m_name, node->m_icon); + variant << data; + break;} case 1: variant = node->m_copy; break; @@ -515,15 +519,15 @@ void MyObjectTreeModel::GetValue(wxVariant &variant, const wxDataViewItem &item, } } -bool MyObjectTreeModel::SetValue(const wxVariant &variant, const wxDataViewItem &item, unsigned int col) +bool PrusaObjectDataViewModel::SetValue(const wxVariant &variant, const wxDataViewItem &item, unsigned int col) { wxASSERT(item.IsOk()); - MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); return node->SetValue(variant, col); } -bool MyObjectTreeModel::SetValue(const wxVariant &variant, const int item_idx, unsigned int col) +bool PrusaObjectDataViewModel::SetValue(const wxVariant &variant, const int item_idx, unsigned int col) { if (item_idx < 0 || item_idx >= m_objects.size()) return false; @@ -536,13 +540,13 @@ bool MyObjectTreeModel::SetValue(const wxVariant &variant, const int item_idx, u // // } -wxDataViewItem MyObjectTreeModel::GetParent(const wxDataViewItem &item) const +wxDataViewItem PrusaObjectDataViewModel::GetParent(const wxDataViewItem &item) const { // the invisible root node has no parent if (!item.IsOk()) return wxDataViewItem(0); - MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); // objects nodes has no parent too if (find(m_objects.begin(), m_objects.end(),node) != m_objects.end()) @@ -551,19 +555,19 @@ wxDataViewItem MyObjectTreeModel::GetParent(const wxDataViewItem &item) const return wxDataViewItem((void*)node->GetParent()); } -bool MyObjectTreeModel::IsContainer(const wxDataViewItem &item) const +bool PrusaObjectDataViewModel::IsContainer(const wxDataViewItem &item) const { // the invisible root node can have children if (!item.IsOk()) return true; - MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); return node->IsContainer(); } -unsigned int MyObjectTreeModel::GetChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const +unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent, wxDataViewItemArray &array) const { - MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)parent.GetID(); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)parent.GetID(); if (!node) { for (auto object : m_objects) @@ -579,288 +583,7 @@ unsigned int MyObjectTreeModel::GetChildren(const wxDataViewItem &parent, wxData unsigned int count = node->GetChildren().GetCount(); for (unsigned int pos = 0; pos < count; pos++) { - MyObjectTreeModelNode *child = node->GetChildren().Item(pos); - array.Add(wxDataViewItem((void*)child)); - } - - return count; -} - -// ***************************************************************************** -// ---------------------------------------------------------------------------- -// MyMusicTreeModel -// ---------------------------------------------------------------------------- - -MyMusicTreeModel::MyMusicTreeModel() -{ - m_root = new MyMusicTreeModelNode(NULL, "");// , "My Music"); - - // setup pop music - m_pop = new MyMusicTreeModelNode(m_root, "Pop music"); - m_pop->Append( - new MyMusicTreeModelNode(m_pop, "You are not alone", "Michael Jackson", 1995)); - m_pop->Append( - new MyMusicTreeModelNode(m_pop, "Take a bow", "Madonna", 1994)); - m_root->Append(m_pop); - - // setup classical music - m_classical = new MyMusicTreeModelNode(m_root, "Classical music"); - m_ninth = new MyMusicTreeModelNode(m_classical, "Ninth symphony", - "Ludwig van Beethoven", 1824); - m_classical->Append(m_ninth); - m_classical->Append(new MyMusicTreeModelNode(m_classical, "German Requiem", - "Johannes Brahms", 1868)); - m_root->Append(m_classical); - - m_classicalMusicIsKnownToControl = false; -} - -wxString MyMusicTreeModel::GetTitle(const wxDataViewItem &item) const -{ - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - if (!node) // happens if item.IsOk()==false - return wxEmptyString; - - return node->m_title; -} - -wxString MyMusicTreeModel::GetArtist(const wxDataViewItem &item) const -{ - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - if (!node) // happens if item.IsOk()==false - return wxEmptyString; - - return node->m_artist; -} - -int MyMusicTreeModel::GetYear(const wxDataViewItem &item) const -{ - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - if (!node) // happens if item.IsOk()==false - return 2000; - - return node->m_year; -} - -void MyMusicTreeModel::AddToClassical(const wxString &title, const wxString &artist, - unsigned int year) -{ - if (!m_classical) - { - wxASSERT(m_root); - - // it was removed: restore it - m_classical = new MyMusicTreeModelNode(m_root, "Classical music"); - m_root->Append(m_classical); - - // notify control - wxDataViewItem child((void*)m_classical); - wxDataViewItem parent((void*)m_root); - ItemAdded(parent, child); - } - - // add to the classical music node a new node: - MyMusicTreeModelNode *child_node = - new MyMusicTreeModelNode(m_classical, title, artist, year); - m_classical->Append(child_node); - - // FIXME: what's m_classicalMusicIsKnownToControl for? - if (m_classicalMusicIsKnownToControl) - { - // notify control - wxDataViewItem child((void*)child_node); - wxDataViewItem parent((void*)m_classical); - ItemAdded(parent, child); - } -} - -void MyMusicTreeModel::Delete(const wxDataViewItem &item) -{ - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - if (!node) // happens if item.IsOk()==false - return; - - wxDataViewItem parent(node->GetParent()); - if (!parent.IsOk()) - { - wxASSERT(node == m_root); - - // don't make the control completely empty: - //wxLogError("Cannot remove the root item!"); - return; - } - - // is the node one of those we keep stored in special pointers? - if (node == m_pop) - m_pop = NULL; - else if (node == m_classical) - m_classical = NULL; - else if (node == m_ninth) - m_ninth = NULL; - - // first remove the node from the parent's array of children; - // NOTE: MyMusicTreeModelNodePtrArray is only an array of _pointers_ - // thus removing the node from it doesn't result in freeing it - node->GetParent()->GetChildren().Remove(node); - - // free the node - delete node; - - // notify control - ItemDeleted(parent, item); -} - -int MyMusicTreeModel::Compare(const wxDataViewItem &item1, const wxDataViewItem &item2, - unsigned int column, bool ascending) const -{ - wxASSERT(item1.IsOk() && item2.IsOk()); - // should never happen - - if (IsContainer(item1) && IsContainer(item2)) - { - wxVariant value1, value2; - GetValue(value1, item1, 0); - GetValue(value2, item2, 0); - - wxString str1 = value1.GetString(); - wxString str2 = value2.GetString(); - int res = str1.Cmp(str2); - if (res) return res; - - // items must be different - wxUIntPtr litem1 = (wxUIntPtr)item1.GetID(); - wxUIntPtr litem2 = (wxUIntPtr)item2.GetID(); - - return litem1 - litem2; - } - - return wxDataViewModel::Compare(item1, item2, column, ascending); -} - -void MyMusicTreeModel::GetValue(wxVariant &variant, - const wxDataViewItem &item, unsigned int col) const -{ - wxASSERT(item.IsOk()); - - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - switch (col) - { - case 0: - variant = node->m_title; - break; - case 1: - variant = node->m_artist; - break; - case 2: - variant = (long)node->m_year; - break; - case 3: - variant = node->m_quality; - break; - case 4: - variant = 80L; // all music is very 80% popular - break; - case 5: - if (GetYear(item) < 1900) - variant = "old"; - else - variant = "new"; - break; - - default: - ;// wxLogError("MyMusicTreeModel::GetValue: wrong column %d", col); - } -} - -bool MyMusicTreeModel::SetValue(const wxVariant &variant, - const wxDataViewItem &item, unsigned int col) -{ - wxASSERT(item.IsOk()); - - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - switch (col) - { - case 0: - node->m_title = variant.GetString(); - return true; - case 1: - node->m_artist = variant.GetString(); - return true; - case 2: - node->m_year = variant.GetLong(); - return true; - case 3: - node->m_quality = variant.GetString(); - return true; - - default:; -// wxLogError("MyMusicTreeModel::SetValue: wrong column"); - } - return false; -} - -bool MyMusicTreeModel::IsEnabled(const wxDataViewItem &item, - unsigned int col) const -{ - wxASSERT(item.IsOk()); - - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - - // disable Beethoven's ratings, his pieces can only be good - return !(col == 3 && node->m_artist.EndsWith("Beethoven")); -} - -wxDataViewItem MyMusicTreeModel::GetParent(const wxDataViewItem &item) const -{ - // the invisible root node has no parent - if (!item.IsOk()) - return wxDataViewItem(0); - - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - - // "MyMusic" also has no parent - if (node == m_root) - return wxDataViewItem(0); - - return wxDataViewItem((void*)node->GetParent()); -} - -bool MyMusicTreeModel::IsContainer(const wxDataViewItem &item) const -{ - // the invisble root node can have children - // (in our model always "MyMusic") - if (!item.IsOk()) - return true; - - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - return node->IsContainer(); -} - -unsigned int MyMusicTreeModel::GetChildren(const wxDataViewItem &parent, - wxDataViewItemArray &array) const -{ - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)parent.GetID(); - if (!node) - { - array.Add(wxDataViewItem((void*)m_root)); - return 1; - } - - if (node == m_classical) - { - MyMusicTreeModel *model = (MyMusicTreeModel*)(const MyMusicTreeModel*) this; - model->m_classicalMusicIsKnownToControl = true; - } - - if (node->GetChildCount() == 0) - { - return 0; - } - - unsigned int count = node->GetChildren().GetCount(); - for (unsigned int pos = 0; pos < count; pos++) - { - MyMusicTreeModelNode *child = node->GetChildren().Item(pos); + PrusaObjectDataViewModelNode *child = node->GetChildren().Item(pos); array.Add(wxDataViewItem((void*)child)); } diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index d3330a827..dc7ecb4fd 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -145,25 +145,25 @@ public: // ***************************************************************************** // ---------------------------------------------------------------------------- -// MyObjectTreeModelNode: a node inside MyObjectTreeModel +// PrusaObjectDataViewModelNode: a node inside PrusaObjectDataViewModel // ---------------------------------------------------------------------------- -class MyObjectTreeModelNode; -WX_DEFINE_ARRAY_PTR(MyObjectTreeModelNode*, MyObjectTreeModelNodePtrArray); +class PrusaObjectDataViewModelNode; +WX_DEFINE_ARRAY_PTR(PrusaObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray); -class MyObjectTreeModelNode +class PrusaObjectDataViewModelNode { - MyObjectTreeModelNode* m_parent; + PrusaObjectDataViewModelNode* m_parent; MyObjectTreeModelNodePtrArray m_children; public: - MyObjectTreeModelNode(const wxString &name, int instances_count=1, int scale=100) { + PrusaObjectDataViewModelNode(const wxString &name, int instances_count=1, int scale=100) { m_parent = NULL; m_name = name; m_copy = wxString::Format("%d", instances_count); m_scale = wxString::Format("%d%%", scale); } - MyObjectTreeModelNode( MyObjectTreeModelNode* parent, + PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, const wxString& sub_obj) { m_parent = parent; m_name = sub_obj; @@ -171,18 +171,25 @@ public: m_scale = wxEmptyString; } - ~MyObjectTreeModelNode() + PrusaObjectDataViewModelNode(PrusaObjectDataViewModelNode* parent, + const wxString& sub_obj, const wxIcon& icon): + PrusaObjectDataViewModelNode(parent, sub_obj){ + m_icon = icon; + } + + ~PrusaObjectDataViewModelNode() { // free all our children nodes size_t count = m_children.GetCount(); for (size_t i = 0; i < count; i++) { - MyObjectTreeModelNode *child = m_children[i]; + PrusaObjectDataViewModelNode *child = m_children[i]; delete child; } } wxString m_name; + wxIcon m_icon; wxString m_copy; wxString m_scale; bool m_container = false; @@ -192,7 +199,7 @@ public: return m_container; } - MyObjectTreeModelNode* GetParent() + PrusaObjectDataViewModelNode* GetParent() { return m_parent; } @@ -200,15 +207,15 @@ public: { return m_children; } - MyObjectTreeModelNode* GetNthChild(unsigned int n) + PrusaObjectDataViewModelNode* GetNthChild(unsigned int n) { return m_children.Item(n); } - void Insert(MyObjectTreeModelNode* child, unsigned int n) + void Insert(PrusaObjectDataViewModelNode* child, unsigned int n) { m_children.Insert(child, n); } - void Append(MyObjectTreeModelNode* child) + void Append(PrusaObjectDataViewModelNode* child) { if (!m_container) m_container = true; @@ -237,33 +244,39 @@ public: { switch (col) { - case 0: - m_name = variant.GetString(); - return true; + case 0:{ + wxDataViewIconText data; + data << variant; + m_icon = data.GetIcon(); + m_name = data.GetText(); + return true;} case 1: m_copy = variant.GetString(); return true; case 2: m_scale = variant.GetString(); return true; - default: printf("MyObjectTreeModel::SetValue: wrong column"); } return false; } + void SetIcon(const wxIcon &icon) + { + m_icon = icon; + } }; // ---------------------------------------------------------------------------- -// MyObjectTreeModel +// PrusaObjectDataViewModel // ---------------------------------------------------------------------------- -class MyObjectTreeModel :public wxDataViewModel +class PrusaObjectDataViewModel :public wxDataViewModel { - std::vector m_objects; + std::vector m_objects; public: - MyObjectTreeModel(){} - ~MyObjectTreeModel() + PrusaObjectDataViewModel(){} + ~PrusaObjectDataViewModel() { for (auto object : m_objects) delete object; @@ -271,7 +284,9 @@ public: wxDataViewItem Add(wxString &name); wxDataViewItem Add(wxString &name, int instances_count, int scale); - wxDataViewItem AddChild(const wxDataViewItem &parent_item, wxString &name); + wxDataViewItem AddChild(const wxDataViewItem &parent_item, + const wxString &name, + const wxIcon& icon); wxDataViewItem Delete(const wxDataViewItem &item); void DeleteAll(); wxDataViewItem GetItemById(int obj_idx); @@ -310,197 +325,6 @@ public: - -// ***************************************************************************** -// ---------------------------------------------------------------------------- -// MyMusicTreeModelNode: a node inside MyMusicTreeModel -// ---------------------------------------------------------------------------- - -class MyMusicTreeModelNode; -WX_DEFINE_ARRAY_PTR(MyMusicTreeModelNode*, MyMusicTreeModelNodePtrArray); - -class MyMusicTreeModelNode -{ -public: - MyMusicTreeModelNode(MyMusicTreeModelNode* parent, - const wxString &title, const wxString &artist, - unsigned int year) - { - m_parent = parent; - - m_title = title; - m_artist = artist; - m_year = year; - m_quality = "good"; - - m_container = false; - } - - MyMusicTreeModelNode(MyMusicTreeModelNode* parent, - const wxString &branch) - { - m_parent = parent; - - m_title = branch; - m_year = -1; - - m_container = true; - } - - ~MyMusicTreeModelNode() - { - // free all our children nodes - size_t count = m_children.GetCount(); - for (size_t i = 0; i < count; i++) - { - MyMusicTreeModelNode *child = m_children[i]; - delete child; - } - } - - bool IsContainer() const - { - return m_container; - } - - MyMusicTreeModelNode* GetParent() - { - return m_parent; - } - MyMusicTreeModelNodePtrArray& GetChildren() - { - return m_children; - } - MyMusicTreeModelNode* GetNthChild(unsigned int n) - { - return m_children.Item(n); - } - void Insert(MyMusicTreeModelNode* child, unsigned int n) - { - m_children.Insert(child, n); - } - void Append(MyMusicTreeModelNode* child) - { - m_children.Add(child); - } - unsigned int GetChildCount() const - { - return m_children.GetCount(); - } - -public: // public to avoid getters/setters - wxString m_title; - wxString m_artist; - int m_year; - wxString m_quality; - - // TODO/FIXME: - // the GTK version of wxDVC (in particular wxDataViewCtrlInternal::ItemAdded) - // needs to know in advance if a node is or _will be_ a container. - // Thus implementing: - // bool IsContainer() const - // { return m_children.GetCount()>0; } - // doesn't work with wxGTK when MyMusicTreeModel::AddToClassical is called - // AND the classical node was removed (a new node temporary without children - // would be added to the control) - bool m_container; - -private: - MyMusicTreeModelNode *m_parent; - MyMusicTreeModelNodePtrArray m_children; -}; - - -// ---------------------------------------------------------------------------- -// MyMusicTreeModel -// ---------------------------------------------------------------------------- - -/* -Implement this data model -Title Artist Year Judgement --------------------------------------------------------------------------- -1: My Music: -2: Pop music -3: You are not alone Michael Jackson 1995 good -4: Take a bow Madonna 1994 good -5: Classical music -6: Ninth Symphony Ludwig v. Beethoven 1824 good -7: German Requiem Johannes Brahms 1868 good -*/ - -class MyMusicTreeModel : public wxDataViewModel -{ -public: - MyMusicTreeModel(); - ~MyMusicTreeModel() - { - if (m_root) - delete m_root; - - } - - // helper method for wxLog - - wxString GetTitle(const wxDataViewItem &item) const; - wxString GetArtist(const wxDataViewItem &item) const; - int GetYear(const wxDataViewItem &item) const; - - // helper methods to change the model - - void AddToClassical(const wxString &title, const wxString &artist, - unsigned int year); - void Delete(const wxDataViewItem &item); - - wxDataViewItem GetNinthItem() const - { - return wxDataViewItem(m_ninth); - } - - // override sorting to always sort branches ascendingly - - int Compare(const wxDataViewItem &item1, const wxDataViewItem &item2, - unsigned int column, bool ascending) const override/*wxOVERRIDE*/; - - // implementation of base class virtuals to define model - - virtual unsigned int GetColumnCount() const override/*wxOVERRIDE*/ - { - return 6; - } - - virtual wxString GetColumnType(unsigned int col) const override/*wxOVERRIDE*/ - { - if (col == 2) - return wxT("long"); - - return wxT("string"); - } - - virtual void GetValue(wxVariant &variant, - const wxDataViewItem &item, unsigned int col) const override/*wxOVERRIDE*/; - virtual bool SetValue(const wxVariant &variant, - const wxDataViewItem &item, unsigned int col) override/*wxOVERRIDE*/; - - virtual bool IsEnabled(const wxDataViewItem &item, - unsigned int col) const override/*wxOVERRIDE*/; - - virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override/*wxOVERRIDE*/; - virtual bool IsContainer(const wxDataViewItem &item) const override/*wxOVERRIDE*/; - virtual unsigned int GetChildren(const wxDataViewItem &parent, - wxDataViewItemArray &array) const override/*wxOVERRIDE*/; - -private: - MyMusicTreeModelNode* m_root; - - // pointers to some "special" nodes of the tree: - MyMusicTreeModelNode* m_pop; - MyMusicTreeModelNode* m_classical; - MyMusicTreeModelNode* m_ninth; - - // ?? - bool m_classicalMusicIsKnownToControl; -}; - // ---------------------------------------------------------------------------- // MyCustomRenderer // ---------------------------------------------------------------------------- From 54975a4e364705f058564b318d7bb2be1303d71e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Sat, 16 Jun 2018 01:21:25 +0200 Subject: [PATCH 048/119] Some changes in GUI-files All functions of object settings are moved to GUI_ObjectParts --- xs/src/slic3r/GUI/GUI.cpp | 401 ++------------------------ xs/src/slic3r/GUI/GUI.hpp | 66 +---- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 387 ++++++++++++++++++++++++- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 61 +++- 4 files changed, 465 insertions(+), 450 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 3e76c99f7..ec8eec091 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -140,18 +140,6 @@ wxButton *g_btn_send_gcode = nullptr; wxStaticBitmap *g_manifold_warning_icon = nullptr; bool g_show_print_info = false; bool g_show_manifold_warning_icon = false; -wxSizer *m_sizer_object_buttons = nullptr; -wxSizer *m_sizer_part_buttons = nullptr; -wxSizer *m_sizer_object_movers = nullptr; -wxDataViewCtrl *m_objects_ctrl = nullptr; -PrusaObjectDataViewModel *m_objects_model = nullptr; -wxCollapsiblePane *m_collpane_settings = nullptr; -int m_event_object_selection_changed = 0; -int m_event_object_settings_changed = 0; -bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select() - // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler - // calls this method again and again and again -ModelObjectPtrs m_objects; wxFont g_small_font; wxFont g_bold_font; @@ -812,25 +800,19 @@ unsigned get_colour_approx_luma(const wxColour &colour) b * b * .068 )); } -wxDataViewCtrl* get_objects_ctrl() { - return m_objects_ctrl; -} -PrusaObjectDataViewModel* get_objects_model() { - return m_objects_model; -} -ModelObjectPtrs& get_objects() { - return m_objects; -} - -const int& get_event_object_settings_changed() { - return m_event_object_settings_changed; +wxWindow* get_right_panel(){ + return g_right_panel; } wxFrame* get_main_frame() { return g_wxMainFrame; } +const int& label_width(){ + return m_label_width; +} + void create_combochecklist(wxComboCtrl* comboCtrl, std::string text, std::string items, bool initial_value) { if (comboCtrl == nullptr) @@ -899,216 +881,18 @@ wxString from_u8(const std::string &str) return wxString::FromUTF8(str.c_str()); } -// add Collapsible Pane to sizer -wxCollapsiblePane* add_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, const wxString& name, std::function content_function) +void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, + int event_object_selection_changed, + int event_object_settings_changed) { -#ifdef __WXMSW__ - auto *collpane = new PrusaCollapsiblePaneMSW(parent, wxID_ANY, name); -#else - auto *collpane = new PrusaCollapsiblePane/*wxCollapsiblePane*/(parent, wxID_ANY, name); -#endif // __WXMSW__ - // add the pane with a zero proportion value to the sizer which contains it - sizer_parent->Add(collpane, 0, wxGROW | wxALL, 0); + set_event_object_selection_changed(event_object_selection_changed); + set_event_object_settings_changed(event_object_settings_changed); + wxWindowUpdateLocker noUpdates(parent); - wxWindow *win = collpane->GetPane(); - - wxSizer *sizer = content_function(win); - - wxSizer *sizer_pane = new wxBoxSizer(wxVERTICAL); - sizer_pane->Add(sizer, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); - win->SetSizer(sizer_pane); -// sizer_pane->SetSizeHints(win); - return collpane; + add_collapsible_panes(parent, sizer); } -wxBoxSizer* content_objects_list(wxWindow *win) -{ - m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); - m_objects_ctrl->SetInitialSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects - - auto objects_sz = new wxBoxSizer(wxVERTICAL); - objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT, 20); - - m_objects_model = new PrusaObjectDataViewModel; - m_objects_ctrl->AssociateModel(m_objects_model); -#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE - m_objects_ctrl->EnableDragSource(wxDF_UNICODETEXT); - m_objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT); -#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE - - // column 0(Icon+Text) of the view control: - m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 150, - wxALIGN_LEFT, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); - - // column 1 of the view control: - m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 65, - wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); - - // column 2 of the view control: - m_objects_ctrl->AppendTextColumn(_(L("Scale")), 2, wxDATAVIEW_CELL_INERT, 70, - wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); - - m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) - { - if (g_prevent_list_events) return; - - wxWindowUpdateLocker noUpdates(g_right_panel); - auto item = m_objects_ctrl->GetSelection(); - int obj_idx = -1; - if (!item) - unselect_objects(); - else - { - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) - obj_idx = m_objects_model->GetIdByItem(item); - else { - auto parent = m_objects_model->GetParent(item); - obj_idx = m_objects_model->GetIdByItem(parent); // TODO Temporary decision for sub-objects selection - } - } - - if (m_event_object_selection_changed > 0) { - wxCommandEvent event(m_event_object_selection_changed); - event.SetInt(obj_idx); - g_wxMainFrame->ProcessWindowEvent(event); - } - - if (obj_idx < 0) return; - -// m_objects_ctrl->SetSize(m_objects_ctrl->GetBestSize()); // TODO override GetBestSize(), than use it - - auto show_obj_sizer = m_objects_model->GetParent(item) == wxDataViewItem(0); - m_sizer_object_buttons->Show(show_obj_sizer); - m_sizer_part_buttons->Show(!show_obj_sizer); - m_sizer_object_movers->Show(!show_obj_sizer); - m_collpane_settings->SetLabelText((show_obj_sizer ? _(L("Object Settings")) : _(L("Part Settings"))) + ":"); - m_collpane_settings->Show(true); - }); - - m_objects_ctrl->Bind(wxEVT_KEY_DOWN, [](wxKeyEvent& event) - { - if (event.GetKeyCode() == WXK_TAB) - m_objects_ctrl->Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward); - else - event.Skip(); - }); - - return objects_sz; -} - -wxBoxSizer* content_edit_object_buttons(wxWindow* win) -{ - auto sizer = new wxBoxSizer(wxVERTICAL); - - auto btn_load_part = new wxButton(win, wxID_ANY, /*Load */"part"+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); - auto btn_load_modifier = new wxButton(win, wxID_ANY, /*Load */"modifier" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); - auto btn_load_lambda_modifier = new wxButton(win, wxID_ANY, /*Load */"generic" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); - auto btn_delete = new wxButton(win, wxID_ANY, "Delete"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); - auto btn_split = new wxButton(win, wxID_ANY, "Split"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); - auto btn_move_up = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); - auto btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); - - //*** button's functions - btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) - { - on_btn_load(win); - }); - - btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) - { - on_btn_load(win, true); - }); - - btn_load_lambda_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) - { - on_btn_load(win, true, true); - }); - - btn_delete->Bind(wxEVT_BUTTON, [](wxEvent&) - { - auto item = m_objects_ctrl->GetSelection(); - if (!item) return; - m_objects_ctrl->Select(m_objects_model->Delete(item)); - }); - //*** - - btn_move_up->SetMinSize(wxSize(20, -1)); - btn_move_down->SetMinSize(wxSize(20, -1)); - btn_load_part->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); - btn_load_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); - btn_load_lambda_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); - btn_delete->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_delete.png")), wxBITMAP_TYPE_PNG)); - btn_split->SetBitmap(wxBitmap(from_u8(Slic3r::var("shape_ungroup.png")), wxBITMAP_TYPE_PNG)); - btn_move_up->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_up.png")), wxBITMAP_TYPE_PNG)); - btn_move_down->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_down.png")), wxBITMAP_TYPE_PNG)); - - m_sizer_object_buttons = new wxGridSizer(1, 3, 0, 0); - m_sizer_object_buttons->Add(btn_load_part, 0, wxEXPAND); - m_sizer_object_buttons->Add(btn_load_modifier, 0, wxEXPAND); - m_sizer_object_buttons->Add(btn_load_lambda_modifier, 0, wxEXPAND); - m_sizer_object_buttons->Show(false); - - m_sizer_part_buttons = new wxGridSizer(1, 3, 0, 0); - m_sizer_part_buttons->Add(btn_delete, 0, wxEXPAND); - m_sizer_part_buttons->Add(btn_split, 0, wxEXPAND); - { - auto up_down_sizer = new wxGridSizer(1, 2, 0, 0); - up_down_sizer->Add(btn_move_up, 1, wxEXPAND); - up_down_sizer->Add(btn_move_down, 1, wxEXPAND); - m_sizer_part_buttons->Add(up_down_sizer, 0, wxEXPAND); - } - m_sizer_part_buttons->Show(false); - - btn_load_part->SetFont(Slic3r::GUI::small_font()); - btn_load_modifier->SetFont(Slic3r::GUI::small_font()); - btn_load_lambda_modifier->SetFont(Slic3r::GUI::small_font()); - btn_delete->SetFont(Slic3r::GUI::small_font()); - btn_split->SetFont(Slic3r::GUI::small_font()); - btn_move_up->SetFont(Slic3r::GUI::small_font()); - btn_move_down->SetFont(Slic3r::GUI::small_font()); - - sizer->Add(m_sizer_object_buttons, 0, wxEXPAND|wxLEFT, 20); - sizer->Add(m_sizer_part_buttons, 0, wxEXPAND|wxLEFT, 20); - return sizer; -} - -wxSizer* object_movers(wxWindow *win) -{ - DynamicPrintConfig* config = &g_PresetBundle->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume - std::shared_ptr optgroup = std::make_shared(win, "Move", config); - optgroup->label_width = 20; - - ConfigOptionDef def; - def.label = L("X"); - def.type = coInt; - def.gui_type = "slider"; - def.default_value = new ConfigOptionInt(0); -// def.min = -(model_object->bounding_box->size->x) * 4; -// def.max = model_object->bounding_box->size->x * 4; - - Option option = Option(def, "x"); - option.opt.full_width = true; - optgroup->append_single_option_line(option); - - def.label = L("Y"); -// def.min = -(model_object->bounding_box->size->y) * 4; -// def.max = model_object->bounding_box->size->y * 4; - option = Option(def, "y"); - optgroup->append_single_option_line(option); - - def.label = L("Z"); -// def.min = -(model_object->bounding_box->size->z) * 4; -// def.max = model_object->bounding_box->size->z * 4; - option = Option(def, "z"); - optgroup->append_single_option_line(option); - - m_optgroups.push_back(optgroup); // ogObjectMovers - m_sizer_object_movers = optgroup->sizer; - m_sizer_object_movers->Show(false); - return optgroup->sizer; -} - -Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value=0) +Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value = 0) { Line line = { _(option_name), "" }; ConfigOptionDef def; @@ -1117,7 +901,7 @@ Line add_og_to_object_settings(const std::string& option_name, const std::string def.type = coInt; def.default_value = new ConfigOptionInt(def_value); def.sidetext = sidetext; - def.width = 70; + def.width = 70; const std::string lower_name = boost::algorithm::to_lower_copy(option_name); @@ -1149,152 +933,6 @@ Line add_og_to_object_settings(const std::string& option_name, const std::string return line; } -wxBoxSizer* content_settings(wxWindow *win) -{ - DynamicPrintConfig* config = &g_PresetBundle->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume - std::shared_ptr optgroup = std::make_shared(win, "Extruders", config); - optgroup->label_width = m_label_width; - - Option option = optgroup->get_option("extruder"); - option.opt.default_value = new ConfigOptionInt(1); - optgroup->append_single_option_line(option); - - m_optgroups.push_back(optgroup); // ogObjectSettings - - auto sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(content_edit_object_buttons(win), 0, wxEXPAND, 0); // *** Edit Object Buttons*** - - sizer->Add(optgroup->sizer, 1, wxEXPAND | wxLEFT, 20); - - auto add_btn = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); - if (wxMSW) add_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - add_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG)); - sizer->Add(add_btn, 0, wxALIGN_LEFT | wxLEFT, 20); - - sizer->Add(object_movers(win), 0, wxEXPAND | wxLEFT, 20); - - return sizer; -} - -void add_object_to_list(const std::string &name, ModelObject* model_object) -{ - wxString item = name; - int scale = model_object->instances[0]->scaling_factor * 100; - m_objects_ctrl->Select(m_objects_model->Add(item, model_object->instances.size(), scale)); - m_objects.push_back(model_object); -} - -void delete_object_from_list() -{ - auto item = m_objects_ctrl->GetSelection(); - if (!item || m_objects_model->GetParent(item) != wxDataViewItem(0)) - return; -// m_objects_ctrl->Select(m_objects_model->Delete(item)); - m_objects_model->Delete(item); - - if (m_objects_model->IsEmpty()) - m_collpane_settings->Show(false); -} - -void delete_all_objects_from_list() -{ - m_objects_model->DeleteAll(); - m_collpane_settings->Show(false); -} - -void set_object_count(int idx, int count) -{ - m_objects_model->SetValue(wxString::Format("%d", count), idx, 1); - m_objects_ctrl->Refresh(); -} - -void set_object_scale(int idx, int scale) -{ - m_objects_model->SetValue(wxString::Format("%d%%", scale), idx, 2); - m_objects_ctrl->Refresh(); -} - -void unselect_objects() -{ - m_objects_ctrl->UnselectAll(); - if (m_sizer_object_buttons->IsShown(1)) - m_sizer_object_buttons->Show(false); - if (m_sizer_part_buttons->IsShown(1)) - m_sizer_part_buttons->Show(false); - if (m_sizer_object_movers->IsShown(1)) - m_sizer_object_movers->Show(false); - if (m_collpane_settings->IsShown()) - m_collpane_settings->Show(false); -} - -void select_current_object(int idx) -{ - g_prevent_list_events = true; - m_objects_ctrl->UnselectAll(); - if (idx < 0) { - g_prevent_list_events = false; - return; - } - m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); - g_prevent_list_events = false; - - if (get_view_mode() == ConfigMenuModeExpert){ - if (!m_sizer_object_buttons->IsShown(1)) - m_sizer_object_buttons->Show(true); - if (!m_sizer_object_movers->IsShown(1)) - m_sizer_object_movers->Show(true); - if (!m_collpane_settings->IsShown()) - m_collpane_settings->Show(true); - } -} - -void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, - int event_object_selection_changed, - int event_object_settings_changed) -{ - m_event_object_selection_changed = event_object_selection_changed; - m_event_object_settings_changed = event_object_settings_changed; - wxWindowUpdateLocker noUpdates(parent); - - // *** Objects List *** - auto collpane = add_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); - collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([collpane](wxCommandEvent& e){ -// wxWindowUpdateLocker noUpdates(g_right_panel); - if (collpane->IsCollapsed()) { - m_sizer_object_buttons->Show(false); - m_sizer_part_buttons->Show(false); - m_sizer_object_movers->Show(false); - m_collpane_settings->Show(false); - } -// else -// m_objects_ctrl->UnselectAll(); - -// e.Skip(); -// g_right_panel->Layout(); - })); - - // *** Object/Part Settings *** - m_collpane_settings = add_collapsible_pane(parent, sizer, "Object Settings", content_settings); - - // More experiments with UI -// auto listctrl = new wxDataViewListCtrl(main_page, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); -// listctrl->AppendToggleColumn("Toggle"); -// listctrl->AppendTextColumn("Text"); -// wxVector data; -// data.push_back(wxVariant(true)); -// data.push_back(wxVariant("row 1")); -// listctrl->AppendItem(data); -// data.clear(); -// data.push_back(wxVariant(false)); -// data.push_back(wxVariant("row 3")); -// listctrl->AppendItem(data); -// data.clear(); -// data.push_back(wxVariant(false)); -// data.push_back(wxVariant("row 2")); -// listctrl->AppendItem(data); -// main_sizer->Add(listctrl, 0, wxEXPAND | wxALL, 1); -} - void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer) { DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config; @@ -1507,17 +1145,24 @@ void update_mode() // TODO There is a not the best place of it! // *** Update showing of the collpane_settings - m_collpane_settings->Show(mode == ConfigMenuModeExpert && !m_objects_model->IsEmpty()); + show_collpane_settings(mode == ConfigMenuModeExpert); // ************************* g_right_panel->GetParent()->Layout(); g_right_panel->Layout(); } +bool is_expert_mode(){ + return get_view_mode() == ConfigMenuModeExpert; +} + ConfigOptionsGroup* get_optgroup(size_t i) { return m_optgroups[i].get(); } +std::vector >& get_optgroups() { + return m_optgroups; +} wxButton* get_wiping_dialog_button() { diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index ef34d2bf8..8e1be3216 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -4,6 +4,7 @@ #include #include #include "Config.hpp" +#include "GUI_ObjectParts.hpp" #include #include @@ -11,7 +12,6 @@ class wxApp; class wxWindow; class wxFrame; -class wxWindow; class wxMenuBar; class wxNotebook; class wxComboCtrl; @@ -25,8 +25,6 @@ class wxButton; class wxFileDialog; class wxStaticBitmap; class wxFont; -class wxDataViewCtrl; -class PrusaObjectDataViewModel; namespace Slic3r { @@ -36,7 +34,6 @@ class AppConfig; class PresetUpdater; class DynamicPrintConfig; class TabIface; -class ModelObject; #define _(s) Slic3r::translate((s)) inline wxString translate(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)); } @@ -60,24 +57,8 @@ inline wxString translate(const std::wstring &s) { return wxGetTranslation(s.c_s namespace GUI { -enum ogGroup{ - ogFrequentlyChangingParameters, - ogFrequentlyObjectSettings, - ogObjectSettings, - ogObjectMovers, - ogPartSettings -}; - -enum LambdaTypeIDs{ - LambdaTypeBox, - LambdaTypeCylinder, - LambdaTypeSphere, - LambdaTypeSlab -}; - class Tab; class ConfigOptionsGroup; -typedef std::vector ModelObjectPtrs; // Map from an file_type name to full file wildcard name. typedef std::map t_file_wild_card; inline t_file_wild_card& get_file_wild_card() { @@ -96,17 +77,6 @@ inline t_file_wild_card& get_file_wild_card() { return FILE_WILDCARDS; } -struct OBJECT_PARAMETERS -{ - LambdaTypeIDs type = LambdaTypeBox; - double dim[3];// = { 1.0, 1.0, 1.0 }; - int cyl_r = 1; - int cyl_h = 1; - double sph_rho = 1.0; - double slab_h = 1.0; - double slab_z = 0.0; -}; - void disable_screensaver(); void enable_screensaver(); bool debugged(); @@ -132,9 +102,10 @@ void set_objects_from_perl( wxWindow* parent, void set_show_print_info(bool show); void set_show_manifold_warning_icon(bool show); -AppConfig* get_app_config(); -wxApp* get_app(); -PresetBundle* get_preset_bundle(); +AppConfig* get_app_config(); +wxApp* get_app(); +PresetBundle* get_preset_bundle(); +wxFrame* get_main_frame(); const wxColour& get_label_clr_modified(); const wxColour& get_label_clr_sys(); @@ -148,11 +119,8 @@ const wxFont& bold_font(); void open_model(wxWindow *parent, wxArrayString& input_files); -wxDataViewCtrl* get_objects_ctrl (); -PrusaObjectDataViewModel* get_objects_model(); -ModelObjectPtrs& get_objects(); -const int& get_event_object_settings_changed(); -wxFrame* get_main_frame(); +wxWindow* get_right_panel(); +const int& label_width(); extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change); @@ -217,30 +185,16 @@ wxString L_str(const std::string &str); // Return wxString from std::string in UTF8 wxString from_u8(const std::string &str); -// Add object to the list -//void add_object(const std::string &name); -void add_object_to_list(const std::string &name, ModelObject* model_object); -// Delete object from the list -void delete_object_from_list(); -// Delete all objects from the list -void delete_all_objects_from_list(); -// Set count of object on c++ side -void set_object_count(int idx, int count); -// Set object scale on c++ side -void set_object_scale(int idx, int scale); -// Unselect all objects in the list on c++ side -void unselect_objects(); -// Select current object in the list on c++ side -void select_current_object(int idx); - void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed, int event_object_settings_changed); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); // Update view mode according to selected menu void update_mode(); +bool is_expert_mode(); -ConfigOptionsGroup* get_optgroup(size_t i); +ConfigOptionsGroup* get_optgroup(size_t i); +std::vector >& get_optgroups(); wxButton* get_wiping_dialog_button(); void add_export_option(wxFileDialog* dlg, const std::string& format); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 8783471a5..f1c5df1e7 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -1,4 +1,6 @@ #include "GUI.hpp" +#include "OptionsGroup.hpp" +#include "PresetBundle.hpp" #include "GUI_ObjectParts.hpp" #include "Model.hpp" #include "wxExtensions.hpp" @@ -8,17 +10,381 @@ #include #include #include +#include namespace Slic3r { namespace GUI { +wxSizer *m_sizer_object_buttons = nullptr; +wxSizer *m_sizer_part_buttons = nullptr; +wxSizer *m_sizer_object_movers = nullptr; +wxDataViewCtrl *m_objects_ctrl = nullptr; +PrusaObjectDataViewModel *m_objects_model = nullptr; +wxCollapsiblePane *m_collpane_settings = nullptr; + +bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select() + // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler + // calls this method again and again and again +ModelObjectPtrs m_objects; + +int m_event_object_selection_changed = 0; +int m_event_object_settings_changed = 0; + bool m_parts_changed = false; bool m_part_settings_changed = false; +void set_event_object_selection_changed(const int& event){ + m_event_object_selection_changed = event; +} +void set_event_object_settings_changed(const int& event){ + m_event_object_settings_changed = event; +} + bool is_parts_changed(){return m_parts_changed;} bool is_part_settings_changed(){ return m_part_settings_changed; } +static wxString dots("…", wxConvUTF8); + +// ****** from GUI.cpp +wxBoxSizer* content_objects_list(wxWindow *win) +{ + m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); + m_objects_ctrl->SetInitialSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects + + auto objects_sz = new wxBoxSizer(wxVERTICAL); + objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT, 20); + + m_objects_model = new PrusaObjectDataViewModel; + m_objects_ctrl->AssociateModel(m_objects_model); +#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE + m_objects_ctrl->EnableDragSource(wxDF_UNICODETEXT); + m_objects_ctrl->EnableDropTarget(wxDF_UNICODETEXT); +#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE + + // column 0(Icon+Text) of the view control: + m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 150, + wxALIGN_LEFT, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); + + // column 1 of the view control: + m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 65, + wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); + + // column 2 of the view control: + m_objects_ctrl->AppendTextColumn(_(L("Scale")), 2, wxDATAVIEW_CELL_INERT, 70, + wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); + + m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) + { + if (g_prevent_list_events) return; + + wxWindowUpdateLocker noUpdates(get_right_panel()); + auto item = m_objects_ctrl->GetSelection(); + int obj_idx = -1; + if (!item) + unselect_objects(); + else + { + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) + obj_idx = m_objects_model->GetIdByItem(item); + else { + auto parent = m_objects_model->GetParent(item); + obj_idx = m_objects_model->GetIdByItem(parent); // TODO Temporary decision for sub-objects selection + } + } + + if (m_event_object_selection_changed > 0) { + wxCommandEvent event(m_event_object_selection_changed); + event.SetInt(obj_idx); + get_main_frame()->ProcessWindowEvent(event); + } + + if (obj_idx < 0) return; + +// m_objects_ctrl->SetSize(m_objects_ctrl->GetBestSize()); // TODO override GetBestSize(), than use it + + auto show_obj_sizer = m_objects_model->GetParent(item) == wxDataViewItem(0); + m_sizer_object_buttons->Show(show_obj_sizer); + m_sizer_part_buttons->Show(!show_obj_sizer); + m_sizer_object_movers->Show(!show_obj_sizer); + m_collpane_settings->SetLabelText((show_obj_sizer ? _(L("Object Settings")) : _(L("Part Settings"))) + ":"); + m_collpane_settings->Show(true); + }); + + m_objects_ctrl->Bind(wxEVT_KEY_DOWN, [](wxKeyEvent& event) + { + if (event.GetKeyCode() == WXK_TAB) + m_objects_ctrl->Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward); + else + event.Skip(); + }); + + return objects_sz; +} + +wxBoxSizer* content_edit_object_buttons(wxWindow* win) +{ + auto sizer = new wxBoxSizer(wxVERTICAL); + + auto btn_load_part = new wxButton(win, wxID_ANY, /*Load */"part" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_load_modifier = new wxButton(win, wxID_ANY, /*Load */"modifier" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_load_lambda_modifier = new wxButton(win, wxID_ANY, /*Load */"generic" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_delete = new wxButton(win, wxID_ANY, "Delete"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_split = new wxButton(win, wxID_ANY, "Split"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); + auto btn_move_up = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); + auto btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); + + //*** button's functions + btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) + { + on_btn_load(win); + }); + + btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) + { + on_btn_load(win, true); + }); + + btn_load_lambda_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) + { + on_btn_load(win, true, true); + }); + + btn_delete->Bind(wxEVT_BUTTON, [](wxEvent&) + { + auto item = m_objects_ctrl->GetSelection(); + if (!item) return; + m_objects_ctrl->Select(m_objects_model->Delete(item)); + }); + //*** + + btn_move_up->SetMinSize(wxSize(20, -1)); + btn_move_down->SetMinSize(wxSize(20, -1)); + btn_load_part->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); + btn_load_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); + btn_load_lambda_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); + btn_delete->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_delete.png")), wxBITMAP_TYPE_PNG)); + btn_split->SetBitmap(wxBitmap(from_u8(Slic3r::var("shape_ungroup.png")), wxBITMAP_TYPE_PNG)); + btn_move_up->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_up.png")), wxBITMAP_TYPE_PNG)); + btn_move_down->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_down.png")), wxBITMAP_TYPE_PNG)); + + m_sizer_object_buttons = new wxGridSizer(1, 3, 0, 0); + m_sizer_object_buttons->Add(btn_load_part, 0, wxEXPAND); + m_sizer_object_buttons->Add(btn_load_modifier, 0, wxEXPAND); + m_sizer_object_buttons->Add(btn_load_lambda_modifier, 0, wxEXPAND); + m_sizer_object_buttons->Show(false); + + m_sizer_part_buttons = new wxGridSizer(1, 3, 0, 0); + m_sizer_part_buttons->Add(btn_delete, 0, wxEXPAND); + m_sizer_part_buttons->Add(btn_split, 0, wxEXPAND); + { + auto up_down_sizer = new wxGridSizer(1, 2, 0, 0); + up_down_sizer->Add(btn_move_up, 1, wxEXPAND); + up_down_sizer->Add(btn_move_down, 1, wxEXPAND); + m_sizer_part_buttons->Add(up_down_sizer, 0, wxEXPAND); + } + m_sizer_part_buttons->Show(false); + + btn_load_part->SetFont(Slic3r::GUI::small_font()); + btn_load_modifier->SetFont(Slic3r::GUI::small_font()); + btn_load_lambda_modifier->SetFont(Slic3r::GUI::small_font()); + btn_delete->SetFont(Slic3r::GUI::small_font()); + btn_split->SetFont(Slic3r::GUI::small_font()); + btn_move_up->SetFont(Slic3r::GUI::small_font()); + btn_move_down->SetFont(Slic3r::GUI::small_font()); + + sizer->Add(m_sizer_object_buttons, 0, wxEXPAND | wxLEFT, 20); + sizer->Add(m_sizer_part_buttons, 0, wxEXPAND | wxLEFT, 20); + return sizer; +} + +wxSizer* object_movers(wxWindow *win) +{ + DynamicPrintConfig* config = &get_preset_bundle()->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume + std::shared_ptr optgroup = std::make_shared(win, "Move", config); + optgroup->label_width = 20; + + ConfigOptionDef def; + def.label = L("X"); + def.type = coInt; + def.gui_type = "slider"; + def.default_value = new ConfigOptionInt(0); + // def.min = -(model_object->bounding_box->size->x) * 4; + // def.max = model_object->bounding_box->size->x * 4; + + Option option = Option(def, "x"); + option.opt.full_width = true; + optgroup->append_single_option_line(option); + + def.label = L("Y"); + // def.min = -(model_object->bounding_box->size->y) * 4; + // def.max = model_object->bounding_box->size->y * 4; + option = Option(def, "y"); + optgroup->append_single_option_line(option); + + def.label = L("Z"); + // def.min = -(model_object->bounding_box->size->z) * 4; + // def.max = model_object->bounding_box->size->z * 4; + option = Option(def, "z"); + optgroup->append_single_option_line(option); + + get_optgroups().push_back(optgroup); // ogObjectMovers + m_sizer_object_movers = optgroup->sizer; + m_sizer_object_movers->Show(false); + return optgroup->sizer; +} + +wxBoxSizer* content_settings(wxWindow *win) +{ + DynamicPrintConfig* config = &get_preset_bundle()->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume + std::shared_ptr optgroup = std::make_shared(win, "Extruders", config); + optgroup->label_width = label_width(); + + Option option = optgroup->get_option("extruder"); + option.opt.default_value = new ConfigOptionInt(1); + optgroup->append_single_option_line(option); + + get_optgroups().push_back(optgroup); // ogObjectSettings + + auto sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(content_edit_object_buttons(win), 0, wxEXPAND, 0); // *** Edit Object Buttons*** + + sizer->Add(optgroup->sizer, 1, wxEXPAND | wxLEFT, 20); + + auto add_btn = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + if (wxMSW) add_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + add_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG)); + sizer->Add(add_btn, 0, wxALIGN_LEFT | wxLEFT, 20); + + sizer->Add(object_movers(win), 0, wxEXPAND | wxLEFT, 20); + + return sizer; +} + + +// add Collapsible Pane to sizer +wxCollapsiblePane* add_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, const wxString& name, std::function content_function) +{ +#ifdef __WXMSW__ + auto *collpane = new PrusaCollapsiblePaneMSW(parent, wxID_ANY, name); +#else + auto *collpane = new PrusaCollapsiblePane/*wxCollapsiblePane*/(parent, wxID_ANY, name); +#endif // __WXMSW__ + // add the pane with a zero proportion value to the sizer which contains it + sizer_parent->Add(collpane, 0, wxGROW | wxALL, 0); + + wxWindow *win = collpane->GetPane(); + + wxSizer *sizer = content_function(win); + + wxSizer *sizer_pane = new wxBoxSizer(wxVERTICAL); + sizer_pane->Add(sizer, 1, wxGROW | wxEXPAND | wxBOTTOM, 2); + win->SetSizer(sizer_pane); + // sizer_pane->SetSizeHints(win); + return collpane; +} + +void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer) +{ + // *** Objects List *** + auto collpane = add_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); + collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([collpane](wxCommandEvent& e){ + // wxWindowUpdateLocker noUpdates(g_right_panel); + if (collpane->IsCollapsed()) { + m_sizer_object_buttons->Show(false); + m_sizer_part_buttons->Show(false); + m_sizer_object_movers->Show(false); + m_collpane_settings->Show(false); + } +// else +// m_objects_ctrl->UnselectAll(); + +// e.Skip(); +// g_right_panel->Layout(); + })); + + // *** Object/Part Settings *** + m_collpane_settings = add_collapsible_pane(parent, sizer, "Object Settings", content_settings); +} + +void show_collpane_settings(bool expert_mode) +{ + m_collpane_settings->Show(expert_mode && !m_objects_model->IsEmpty()); +} + +void add_object_to_list(const std::string &name, ModelObject* model_object) +{ + wxString item = name; + int scale = model_object->instances[0]->scaling_factor * 100; + m_objects_ctrl->Select(m_objects_model->Add(item, model_object->instances.size(), scale)); + m_objects.push_back(model_object); +} + +void delete_object_from_list() +{ + auto item = m_objects_ctrl->GetSelection(); + if (!item || m_objects_model->GetParent(item) != wxDataViewItem(0)) + return; +// m_objects_ctrl->Select(m_objects_model->Delete(item)); + m_objects_model->Delete(item); + + if (m_objects_model->IsEmpty()) + m_collpane_settings->Show(false); +} + +void delete_all_objects_from_list() +{ + m_objects_model->DeleteAll(); + m_collpane_settings->Show(false); +} + +void set_object_count(int idx, int count) +{ + m_objects_model->SetValue(wxString::Format("%d", count), idx, 1); + m_objects_ctrl->Refresh(); +} + +void set_object_scale(int idx, int scale) +{ + m_objects_model->SetValue(wxString::Format("%d%%", scale), idx, 2); + m_objects_ctrl->Refresh(); +} + +void unselect_objects() +{ + m_objects_ctrl->UnselectAll(); + if (m_sizer_object_buttons->IsShown(1)) + m_sizer_object_buttons->Show(false); + if (m_sizer_part_buttons->IsShown(1)) + m_sizer_part_buttons->Show(false); + if (m_sizer_object_movers->IsShown(1)) + m_sizer_object_movers->Show(false); + if (m_collpane_settings->IsShown()) + m_collpane_settings->Show(false); +} + +void select_current_object(int idx) +{ + g_prevent_list_events = true; + m_objects_ctrl->UnselectAll(); + if (idx < 0) { + g_prevent_list_events = false; + return; + } + m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); + g_prevent_list_events = false; + + if (is_expert_mode()){ + if (!m_sizer_object_buttons->IsShown(1)) + m_sizer_object_buttons->Show(true); + if (!m_sizer_object_movers->IsShown(1)) + m_sizer_object_movers->Show(true); + if (!m_collpane_settings->IsShown()) + m_collpane_settings->Show(true); + } +} +// ****** + void load_part( wxWindow* parent, ModelObject* model_object, wxArrayString& part_names, const bool is_modifier) { @@ -110,40 +476,35 @@ void load_lambda( wxWindow* parent, ModelObject* model_object, void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/* = false*/) { - auto objects_ctrl = get_objects_ctrl(); - auto item = objects_ctrl->GetSelection(); + auto item = m_objects_ctrl->GetSelection(); if (!item) return; int obj_idx = -1; - auto objects_model = get_objects_model(); - if (objects_model->GetParent(item) == wxDataViewItem(0)) - obj_idx = objects_model->GetIdByItem(item); + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) + obj_idx = m_objects_model->GetIdByItem(item); else return; if (obj_idx < 0) return; wxArrayString part_names; - ModelObjectPtrs& objects = get_objects(); if (is_lambda) - load_lambda(parent, objects[obj_idx], part_names, is_modifier); + load_lambda(parent, m_objects[obj_idx], part_names, is_modifier); else - load_part(parent, objects[obj_idx], part_names, is_modifier); + load_part(parent, m_objects[obj_idx], part_names, is_modifier); parts_changed(obj_idx); const std::string icon_name = is_modifier ? "plugin.png" : "package.png"; auto icon = wxIcon(Slic3r::GUI::from_u8(Slic3r::var(icon_name)), wxBITMAP_TYPE_PNG); for (int i = 0; i < part_names.size(); ++i) - objects_ctrl->Select(objects_model->AddChild(item, part_names.Item(i), icon)); + m_objects_ctrl->Select(m_objects_model->AddChild(item, part_names.Item(i), icon)); } void parts_changed(int obj_idx) { - auto event = get_event_object_settings_changed(); - if (event <= 0) - return; + if (m_event_object_settings_changed <= 0) return; - wxCommandEvent e(event); + wxCommandEvent e(m_event_object_settings_changed); auto event_str = wxString::Format("%d %d %d", obj_idx, is_parts_changed() ? 1 : 0, is_part_settings_changed() ? 1 : 0); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 40bcc012e..4cbd9ba7f 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -1,10 +1,65 @@ #ifndef slic3r_GUI_ObjectParts_hpp_ #define slic3r_GUI_ObjectParts_hpp_ -namespace Slic3r -{ -namespace GUI +class wxWindow; +class wxSizer; +class wxBoxSizer; +class wxString; +class wxArrayString; + +namespace Slic3r { +class ModelObject; + +namespace GUI { + +enum ogGroup{ + ogFrequentlyChangingParameters, + ogFrequentlyObjectSettings, + ogObjectSettings, + ogObjectMovers, + ogPartSettings +}; + +enum LambdaTypeIDs{ + LambdaTypeBox, + LambdaTypeCylinder, + LambdaTypeSphere, + LambdaTypeSlab +}; + +struct OBJECT_PARAMETERS { + LambdaTypeIDs type = LambdaTypeBox; + double dim[3];// = { 1.0, 1.0, 1.0 }; + int cyl_r = 1; + int cyl_h = 1; + double sph_rho = 1.0; + double slab_h = 1.0; + double slab_z = 0.0; +}; + +void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer); +void show_collpane_settings(bool expert_mode); + +// Add object to the list +//void add_object(const std::string &name); +void add_object_to_list(const std::string &name, ModelObject* model_object); +// Delete object from the list +void delete_object_from_list(); +// Delete all objects from the list +void delete_all_objects_from_list(); +// Set count of object on c++ side +void set_object_count(int idx, int count); +// Set object scale on c++ side +void set_object_scale(int idx, int scale); +// Unselect all objects in the list on c++ side +void unselect_objects(); +// Select current object in the list on c++ side +void select_current_object(int idx); + +void set_event_object_selection_changed(const int& event); +void set_event_object_settings_changed (const int& event); + bool is_parts_changed(); bool is_part_settings_changed(); From fb9ba1a55c2bca2650f10bb8afd1df21853e3233 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Sat, 16 Jun 2018 03:04:59 +0200 Subject: [PATCH 049/119] Set correct man/max value for movers --- lib/Slic3r/GUI/MainFrame.pm | 5 ++-- lib/Slic3r/GUI/Plater.pm | 7 +++--- xs/src/slic3r/GUI/Field.cpp | 1 - xs/src/slic3r/GUI/Field.hpp | 3 ++- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 36 ++++++++++++++++++++------- 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index fd2844783..7f14c4068 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -179,9 +179,10 @@ sub _init_tabpanel { # The following event is emited by the C++ Tab implementation on object selection change. EVT_COMMAND($self, -1, $OBJECT_SELECTION_CHANGED_EVENT, sub { my ($self, $event) = @_; - my $obj_idx = $event->GetInt; + my $obj_idx = $event->GetId; + my $child = $event->GetInt == 1 ? 1 : undef; - $self->{plater}->select_object($obj_idx < 0 ? undef: $obj_idx); + $self->{plater}->select_object($obj_idx < 0 ? undef: $obj_idx, $child); $self->{plater}->item_changed_selection($obj_idx); }); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 1d2168fe8..3905228bc 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -2081,7 +2081,7 @@ sub selection_changed { } sub select_object { - my ($self, $obj_idx) = @_; + my ($self, $obj_idx, $child) = @_; # remove current selection foreach my $o (0..$#{$self->{objects}}) { @@ -2090,8 +2090,9 @@ sub select_object { if (defined $obj_idx) { $self->{objects}->[$obj_idx]->selected(1); - # Select current object in the list on c++ side - Slic3r::GUI::select_current_object($obj_idx); + # Select current object in the list on c++ side, if item isn't child + if (!defined $child){ + Slic3r::GUI::select_current_object($obj_idx);} } else { # Unselect all objects in the list on c++ side Slic3r::GUI::unselect_objects(); diff --git a/xs/src/slic3r/GUI/Field.cpp b/xs/src/slic3r/GUI/Field.cpp index dcb251be6..1b4aef033 100644 --- a/xs/src/slic3r/GUI/Field.cpp +++ b/xs/src/slic3r/GUI/Field.cpp @@ -710,7 +710,6 @@ void SliderCtrl::BUILD() } }), m_textctrl->GetId()); - // // recast as a wxWindow to fit the calling convention m_sizer = dynamic_cast(temp); } diff --git a/xs/src/slic3r/GUI/Field.hpp b/xs/src/slic3r/GUI/Field.hpp index 40f56c0d3..04ee8c87b 100644 --- a/xs/src/slic3r/GUI/Field.hpp +++ b/xs/src/slic3r/GUI/Field.hpp @@ -213,7 +213,7 @@ protected: inline bool is_bad_field(const t_field& obj) { return obj->getSizer() == nullptr && obj->getWindow() == nullptr; } /// Covenience function to determine whether this field is a valid window field. -inline bool is_window_field(const t_field& obj) { return !is_bad_field(obj) && obj->getWindow() != nullptr; } +inline bool is_window_field(const t_field& obj) { return !is_bad_field(obj) && obj->getWindow() != nullptr && obj->getSizer() == nullptr; } /// Covenience function to determine whether this field is a valid sizer field. inline bool is_sizer_field(const t_field& obj) { return !is_bad_field(obj) && obj->getSizer() != nullptr; } @@ -414,6 +414,7 @@ public: m_textctrl->SetEditable(false); } wxSizer* getSizer() override { return m_sizer; } + wxWindow* getWindow() override { return dynamic_cast(m_slider); } }; } // GUI diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index f1c5df1e7..77cacadff 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -23,6 +23,10 @@ wxDataViewCtrl *m_objects_ctrl = nullptr; PrusaObjectDataViewModel *m_objects_model = nullptr; wxCollapsiblePane *m_collpane_settings = nullptr; +wxSlider* mover_x = nullptr; +wxSlider* mover_y = nullptr; +wxSlider* mover_z = nullptr; + bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select() // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler // calls this method again and again and again @@ -95,7 +99,8 @@ wxBoxSizer* content_objects_list(wxWindow *win) if (m_event_object_selection_changed > 0) { wxCommandEvent event(m_event_object_selection_changed); - event.SetInt(obj_idx); + event.SetInt(int(m_objects_model->GetParent(item) != wxDataViewItem(0))); + event.SetId(obj_idx); get_main_frame()->ProcessWindowEvent(event); } @@ -107,6 +112,22 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_sizer_object_buttons->Show(show_obj_sizer); m_sizer_part_buttons->Show(!show_obj_sizer); m_sizer_object_movers->Show(!show_obj_sizer); + + if (!show_obj_sizer) + { + auto bb_size = m_objects[obj_idx]->bounding_box().size(); + int scale = 10; //?? + + mover_x->SetMin(-bb_size.x * 4*scale); + mover_x->SetMax( bb_size.x * 4*scale); + + mover_y->SetMin(-bb_size.y * 4*scale); + mover_y->SetMax( bb_size.y * 4*scale); + + mover_z->SetMin(-bb_size.z * 4 * scale); + mover_z->SetMax( bb_size.z * 4 * scale); + } + m_collpane_settings->SetLabelText((show_obj_sizer ? _(L("Object Settings")) : _(L("Part Settings"))) + ":"); m_collpane_settings->Show(true); }); @@ -200,8 +221,8 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) wxSizer* object_movers(wxWindow *win) { - DynamicPrintConfig* config = &get_preset_bundle()->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume - std::shared_ptr optgroup = std::make_shared(win, "Move", config); +// DynamicPrintConfig* config = &get_preset_bundle()->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume + std::shared_ptr optgroup = std::make_shared(win, "Move"/*, config*/); optgroup->label_width = 20; ConfigOptionDef def; @@ -209,24 +230,21 @@ wxSizer* object_movers(wxWindow *win) def.type = coInt; def.gui_type = "slider"; def.default_value = new ConfigOptionInt(0); - // def.min = -(model_object->bounding_box->size->x) * 4; - // def.max = model_object->bounding_box->size->x * 4; Option option = Option(def, "x"); option.opt.full_width = true; optgroup->append_single_option_line(option); + mover_x = dynamic_cast(optgroup->get_field("x")->getWindow()); def.label = L("Y"); - // def.min = -(model_object->bounding_box->size->y) * 4; - // def.max = model_object->bounding_box->size->y * 4; option = Option(def, "y"); optgroup->append_single_option_line(option); + mover_y = dynamic_cast(optgroup->get_field("y")->getWindow()); def.label = L("Z"); - // def.min = -(model_object->bounding_box->size->z) * 4; - // def.max = model_object->bounding_box->size->z * 4; option = Option(def, "z"); optgroup->append_single_option_line(option); + mover_z = dynamic_cast(optgroup->get_field("z")->getWindow()); get_optgroups().push_back(optgroup); // ogObjectMovers m_sizer_object_movers = optgroup->sizer; From 99082bfe67e7d7b9059d0745250df923aa3db4e0 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 18 Jun 2018 14:20:29 +0200 Subject: [PATCH 050/119] Modifiers are moving now --- xs/src/slic3r/GUI/GUI.cpp | 2 + xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 215 +++++++++++++++++++++----- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 2 + xs/src/slic3r/GUI/wxExtensions.cpp | 15 +- xs/src/slic3r/GUI/wxExtensions.hpp | 31 +++- 5 files changed, 213 insertions(+), 52 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index ec8eec091..10dafe13e 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -887,6 +887,8 @@ void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, { set_event_object_selection_changed(event_object_selection_changed); set_event_object_settings_changed(event_object_settings_changed); + init_mesh_icons(); + wxWindowUpdateLocker noUpdates(parent); add_collapsible_panes(parent, sizer); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 77cacadff..3f183c8d3 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -23,9 +23,17 @@ wxDataViewCtrl *m_objects_ctrl = nullptr; PrusaObjectDataViewModel *m_objects_model = nullptr; wxCollapsiblePane *m_collpane_settings = nullptr; -wxSlider* mover_x = nullptr; -wxSlider* mover_y = nullptr; -wxSlider* mover_z = nullptr; +wxIcon m_icon_modifiermesh; +wxIcon m_icon_solidmesh; + +wxSlider* m_mover_x = nullptr; +wxSlider* m_mover_y = nullptr; +wxSlider* m_mover_z = nullptr; +wxButton* m_btn_move_up = nullptr; +wxButton* m_btn_move_down = nullptr; +Point3 m_move_options; +Point3 m_last_coords; +int m_selected_object_id = -1; bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select() // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler @@ -45,6 +53,11 @@ void set_event_object_settings_changed(const int& event){ m_event_object_settings_changed = event; } +void init_mesh_icons(){ + m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); + m_icon_solidmesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); +} + bool is_parts_changed(){return m_parts_changed;} bool is_part_settings_changed(){ return m_part_settings_changed; } @@ -96,6 +109,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) obj_idx = m_objects_model->GetIdByItem(parent); // TODO Temporary decision for sub-objects selection } } + m_selected_object_id = obj_idx; if (m_event_object_selection_changed > 0) { wxCommandEvent event(m_event_object_selection_changed); @@ -107,29 +121,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) if (obj_idx < 0) return; // m_objects_ctrl->SetSize(m_objects_ctrl->GetBestSize()); // TODO override GetBestSize(), than use it - - auto show_obj_sizer = m_objects_model->GetParent(item) == wxDataViewItem(0); - m_sizer_object_buttons->Show(show_obj_sizer); - m_sizer_part_buttons->Show(!show_obj_sizer); - m_sizer_object_movers->Show(!show_obj_sizer); - - if (!show_obj_sizer) - { - auto bb_size = m_objects[obj_idx]->bounding_box().size(); - int scale = 10; //?? - - mover_x->SetMin(-bb_size.x * 4*scale); - mover_x->SetMax( bb_size.x * 4*scale); - - mover_y->SetMin(-bb_size.y * 4*scale); - mover_y->SetMax( bb_size.y * 4*scale); - - mover_z->SetMin(-bb_size.z * 4 * scale); - mover_z->SetMax( bb_size.z * 4 * scale); - } - - m_collpane_settings->SetLabelText((show_obj_sizer ? _(L("Object Settings")) : _(L("Part Settings"))) + ":"); - m_collpane_settings->Show(true); + part_selection_changed(); }); m_objects_ctrl->Bind(wxEVT_KEY_DOWN, [](wxKeyEvent& event) @@ -152,8 +144,8 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) auto btn_load_lambda_modifier = new wxButton(win, wxID_ANY, /*Load */"generic" + dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); auto btn_delete = new wxButton(win, wxID_ANY, "Delete"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); auto btn_split = new wxButton(win, wxID_ANY, "Split"/*" part"*/, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER/*wxBU_LEFT*/); - auto btn_move_up = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); - auto btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); + m_btn_move_up = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); + m_btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); //*** button's functions btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) @@ -176,18 +168,19 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) auto item = m_objects_ctrl->GetSelection(); if (!item) return; m_objects_ctrl->Select(m_objects_model->Delete(item)); + parts_changed(m_selected_object_id); }); //*** - btn_move_up->SetMinSize(wxSize(20, -1)); - btn_move_down->SetMinSize(wxSize(20, -1)); + m_btn_move_up->SetMinSize(wxSize(20, -1)); + m_btn_move_down->SetMinSize(wxSize(20, -1)); btn_load_part->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); btn_load_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); btn_load_lambda_modifier->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_add.png")), wxBITMAP_TYPE_PNG)); btn_delete->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_delete.png")), wxBITMAP_TYPE_PNG)); btn_split->SetBitmap(wxBitmap(from_u8(Slic3r::var("shape_ungroup.png")), wxBITMAP_TYPE_PNG)); - btn_move_up->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_up.png")), wxBITMAP_TYPE_PNG)); - btn_move_down->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_down.png")), wxBITMAP_TYPE_PNG)); + m_btn_move_up->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_up.png")), wxBITMAP_TYPE_PNG)); + m_btn_move_down->SetBitmap(wxBitmap(from_u8(Slic3r::var("bullet_arrow_down.png")), wxBITMAP_TYPE_PNG)); m_sizer_object_buttons = new wxGridSizer(1, 3, 0, 0); m_sizer_object_buttons->Add(btn_load_part, 0, wxEXPAND); @@ -200,8 +193,8 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) m_sizer_part_buttons->Add(btn_split, 0, wxEXPAND); { auto up_down_sizer = new wxGridSizer(1, 2, 0, 0); - up_down_sizer->Add(btn_move_up, 1, wxEXPAND); - up_down_sizer->Add(btn_move_down, 1, wxEXPAND); + up_down_sizer->Add(m_btn_move_up, 1, wxEXPAND); + up_down_sizer->Add(m_btn_move_down, 1, wxEXPAND); m_sizer_part_buttons->Add(up_down_sizer, 0, wxEXPAND); } m_sizer_part_buttons->Show(false); @@ -211,19 +204,58 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) btn_load_lambda_modifier->SetFont(Slic3r::GUI::small_font()); btn_delete->SetFont(Slic3r::GUI::small_font()); btn_split->SetFont(Slic3r::GUI::small_font()); - btn_move_up->SetFont(Slic3r::GUI::small_font()); - btn_move_down->SetFont(Slic3r::GUI::small_font()); + m_btn_move_up->SetFont(Slic3r::GUI::small_font()); + m_btn_move_down->SetFont(Slic3r::GUI::small_font()); sizer->Add(m_sizer_object_buttons, 0, wxEXPAND | wxLEFT, 20); sizer->Add(m_sizer_part_buttons, 0, wxEXPAND | wxLEFT, 20); return sizer; } +void update_after_moving() +{ + auto item = m_objects_ctrl->GetSelection(); + if (!item || m_selected_object_id<0) + return; + + auto volume_id = m_objects_model->GetVolumeIdByItem(item); + if (volume_id < 0) + return; + + Point3 m = m_move_options; + Point3 l = m_last_coords; + + auto d = Pointf3(m.x - l.x, m.y - l.y, m.z - l.z); + auto volume = m_objects[m_selected_object_id]->volumes[volume_id]; + volume->mesh.translate(d.x,d.y,d.z); + m_last_coords = m; + + m_parts_changed = true; + parts_changed(m_selected_object_id); +} + wxSizer* object_movers(wxWindow *win) { // DynamicPrintConfig* config = &get_preset_bundle()->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume std::shared_ptr optgroup = std::make_shared(win, "Move"/*, config*/); optgroup->label_width = 20; + optgroup->m_on_change = [](t_config_option_key opt_key, boost::any value){ + int val = boost::any_cast(value); + bool update = false; + if (opt_key == "x" && m_move_options.x != val){ + update = true; + m_move_options.x = val; + } + else if (opt_key == "y" && m_move_options.y != val){ + update = true; + m_move_options.y = val; + } + else if (opt_key == "z" && m_move_options.z != val){ + update = true; + m_move_options.z = val; + } + if (update) update_after_moving(); + }; ConfigOptionDef def; def.label = L("X"); @@ -234,21 +266,26 @@ wxSizer* object_movers(wxWindow *win) Option option = Option(def, "x"); option.opt.full_width = true; optgroup->append_single_option_line(option); - mover_x = dynamic_cast(optgroup->get_field("x")->getWindow()); + m_mover_x = dynamic_cast(optgroup->get_field("x")->getWindow()); def.label = L("Y"); option = Option(def, "y"); optgroup->append_single_option_line(option); - mover_y = dynamic_cast(optgroup->get_field("y")->getWindow()); + m_mover_y = dynamic_cast(optgroup->get_field("y")->getWindow()); def.label = L("Z"); option = Option(def, "z"); optgroup->append_single_option_line(option); - mover_z = dynamic_cast(optgroup->get_field("z")->getWindow()); + m_mover_z = dynamic_cast(optgroup->get_field("z")->getWindow()); get_optgroups().push_back(optgroup); // ogObjectMovers + m_sizer_object_movers = optgroup->sizer; m_sizer_object_movers->Show(false); + + m_move_options = Point3(0, 0, 0); + m_last_coords = Point3(0, 0, 0); + return optgroup->sizer; } @@ -512,10 +549,9 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/ parts_changed(obj_idx); - const std::string icon_name = is_modifier ? "plugin.png" : "package.png"; - auto icon = wxIcon(Slic3r::GUI::from_u8(Slic3r::var(icon_name)), wxBITMAP_TYPE_PNG); for (int i = 0; i < part_names.size(); ++i) - m_objects_ctrl->Select(m_objects_model->AddChild(item, part_names.Item(i), icon)); + m_objects_ctrl->Select( m_objects_model->AddChild(item, part_names.Item(i), + is_modifier ? m_icon_modifiermesh : m_icon_solidmesh)); } void parts_changed(int obj_idx) @@ -530,5 +566,100 @@ void parts_changed(int obj_idx) get_main_frame()->ProcessWindowEvent(e); } +void part_selection_changed() +{ + m_move_options = Point3(0, 0, 0); + m_last_coords = Point3(0, 0, 0); + // reset move sliders + std::vector opt_keys = {"x", "y", "z"}; + auto og = get_optgroup(ogObjectMovers); + for (auto opt_key: opt_keys) + og->set_value(opt_key, int(0)); + + auto item = m_objects_ctrl->GetSelection(); + if (!item || m_selected_object_id < 0){ + m_sizer_object_buttons->Show(false); + m_sizer_part_buttons->Show(false); + m_sizer_object_movers->Show(false); + m_collpane_settings->Show(false); + return; + } + + m_collpane_settings->Show(true); + + auto volume_id = m_objects_model->GetVolumeIdByItem(item); + if (volume_id < 0){ + m_sizer_object_buttons->Show(true); + m_sizer_part_buttons->Show(false); + m_sizer_object_movers->Show(false); + m_collpane_settings->SetLabelText(_(L("Object Settings")) + ":"); + +// elsif($itemData->{type} eq 'object') { +// # select nothing in 3D preview +// +// # attach object config to settings panel +// $self->{optgroup_movers}->disable; +// $self->{staticbox}->SetLabel('Object Settings'); +// @opt_keys = (map @{$_->get_keys}, Slic3r::Config::PrintObject->new, Slic3r::Config::PrintRegion->new); +// $config = $self->{model_object}->config; +// } + + return; + } + + m_collpane_settings->SetLabelText(_(L("Part Settings")) + ":"); + + m_sizer_object_buttons->Show(false); + m_sizer_part_buttons->Show(true); + m_sizer_object_movers->Show(true); + + auto bb_size = m_objects[m_selected_object_id]->bounding_box().size(); + int scale = 10; //?? + + m_mover_x->SetMin(-bb_size.x * 4 * scale); + m_mover_x->SetMax(bb_size.x * 4 * scale); + + m_mover_y->SetMin(-bb_size.y * 4 * scale); + m_mover_y->SetMax(bb_size.y * 4 * scale); + + m_mover_z->SetMin(-bb_size.z * 4 * scale); + m_mover_z->SetMax(bb_size.z * 4 * scale); + + + +// my ($config, @opt_keys); + m_btn_move_up->Enable(volume_id > 0); + m_btn_move_down->Enable(volume_id + 1 < m_objects[m_selected_object_id]->volumes.size()); + + // attach volume config to settings panel + auto volume = m_objects[m_selected_object_id]->volumes[volume_id]; + + if (volume->modifier) + og->enable(); + else + og->disable(); + +// auto config = volume->config; + + // get default values +// @opt_keys = @{Slic3r::Config::PrintRegion->new->get_keys}; +// } +/* + # get default values + my $default_config = Slic3r::Config::new_from_defaults_keys(\@opt_keys); + + # append default extruder + push @opt_keys, 'extruder'; + $default_config->set('extruder', 0); + $config->set_ifndef('extruder', 0); + $self->{settings_panel}->set_default_config($default_config); + $self->{settings_panel}->set_config($config); + $self->{settings_panel}->set_opt_keys(\@opt_keys); + $self->{settings_panel}->set_fixed_options([qw(extruder)]); + $self->{settings_panel}->enable; + } + */ +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 4cbd9ba7f..9f1afc861 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -57,6 +57,7 @@ void unselect_objects(); // Select current object in the list on c++ side void select_current_object(int idx); +void init_mesh_icons(); void set_event_object_selection_changed(const int& event); void set_event_object_settings_changed (const int& event); @@ -72,6 +73,7 @@ void load_lambda(wxWindow* parent, ModelObject* model_object, void on_btn_load(wxWindow* parent, bool is_modifier = false, bool is_lambda = false); void parts_changed(int obj_idx); +void part_selection_changed(); } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 36801634e..f8d8cfc20 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -376,14 +376,15 @@ wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_ if (root->GetChildren().Count() == 0) { auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); - auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh); + auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, 0); root->Append(node); // notify control wxDataViewItem child((void*)node); ItemAdded(parent_item, child); } - auto node = new PrusaObjectDataViewModelNode(root, name, icon); + auto volume_id = root->GetChildCount(); + auto node = new PrusaObjectDataViewModelNode(root, name, icon, volume_id); root->Append(node); // notify control wxDataViewItem child((void*)node); @@ -470,6 +471,16 @@ int PrusaObjectDataViewModel::GetIdByItem(wxDataViewItem& item) return it - m_objects.begin(); } +int PrusaObjectDataViewModel::GetVolumeIdByItem(wxDataViewItem& item) +{ + wxASSERT(item.IsOk()); + + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return -1; + return node->GetVolumeId(); +} + wxString PrusaObjectDataViewModel::GetName(const wxDataViewItem &item) const { PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index dc7ecb4fd..b8df8c98f 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -153,7 +153,7 @@ WX_DEFINE_ARRAY_PTR(PrusaObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray class PrusaObjectDataViewModelNode { - PrusaObjectDataViewModelNode* m_parent; + PrusaObjectDataViewModelNode* m_parent; MyObjectTreeModelNodePtrArray m_children; public: PrusaObjectDataViewModelNode(const wxString &name, int instances_count=1, int scale=100) { @@ -161,20 +161,21 @@ public: m_name = name; m_copy = wxString::Format("%d", instances_count); m_scale = wxString::Format("%d%%", scale); + m_type = "object"; + m_volume_id = -1; } PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, - const wxString& sub_obj) { + const wxString& sub_obj, + const wxIcon& icon, + int volume_id=-1) { m_parent = parent; m_name = sub_obj; m_copy = wxEmptyString; m_scale = wxEmptyString; - } - - PrusaObjectDataViewModelNode(PrusaObjectDataViewModelNode* parent, - const wxString& sub_obj, const wxIcon& icon): - PrusaObjectDataViewModelNode(parent, sub_obj){ - m_icon = icon; + m_icon = icon; + m_type = "volume"; + m_volume_id = volume_id; } ~PrusaObjectDataViewModelNode() @@ -192,6 +193,8 @@ public: wxIcon m_icon; wxString m_copy; wxString m_scale; + std::string m_type; + int m_volume_id; bool m_container = false; bool IsContainer() const @@ -265,6 +268,17 @@ public: { m_icon = icon; } + + void SetType(const std::string& type){ + m_type = type; + } + const std::string& GetType(){ + return m_type; + } + + const int GetVolumeId(){ + return m_volume_id; + } }; // ---------------------------------------------------------------------------- @@ -291,6 +305,7 @@ public: void DeleteAll(); wxDataViewItem GetItemById(int obj_idx); int GetIdByItem(wxDataViewItem& item); + int GetVolumeIdByItem(wxDataViewItem& item); bool IsEmpty() { return m_objects.empty(); } // helper method for wxLog From 12232f1a6db753ccc1171380ed2fbbde7ea18cb5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 18 Jun 2018 15:26:09 +0200 Subject: [PATCH 051/119] "Delete part" button works correctly Prepared functions for "Split", "MoveUp" & "MoveDown" buttons (update_model function is missing) --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 96 +++++++++++++++++++++++---- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 4 ++ xs/src/slic3r/GUI/wxExtensions.cpp | 10 +++ xs/src/slic3r/GUI/wxExtensions.hpp | 5 +- 4 files changed, 101 insertions(+), 14 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 3f183c8d3..deb303c1a 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -148,28 +148,22 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) m_btn_move_down = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize/*wxSize(30, -1)*/, wxBU_LEFT); //*** button's functions - btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) - { + btn_load_part->Bind(wxEVT_BUTTON, [win](wxEvent&) { on_btn_load(win); }); - btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) - { + btn_load_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) { on_btn_load(win, true); }); - btn_load_lambda_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) - { + btn_load_lambda_modifier->Bind(wxEVT_BUTTON, [win](wxEvent&) { on_btn_load(win, true, true); }); - btn_delete->Bind(wxEVT_BUTTON, [](wxEvent&) - { - auto item = m_objects_ctrl->GetSelection(); - if (!item) return; - m_objects_ctrl->Select(m_objects_model->Delete(item)); - parts_changed(m_selected_object_id); - }); + btn_delete ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_del(); }); + btn_split ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_split(); }); + m_btn_move_up ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_move_up(); }); + m_btn_move_down ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_move_down(); }); //*** m_btn_move_up->SetMinSize(wxSize(20, -1)); @@ -554,6 +548,82 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/ is_modifier ? m_icon_modifiermesh : m_icon_solidmesh)); } +void on_btn_del() +{ + auto item = m_objects_ctrl->GetSelection(); + if (!item) return; + + auto volume_id = m_objects_model->GetVolumeIdByItem(item); + if (volume_id < 0) + return; + auto volume = m_objects[m_selected_object_id]->volumes[volume_id]; + + // if user is deleting the last solid part, throw error + int solid_cnt = 0; + for (auto vol : m_objects[m_selected_object_id]->volumes) + if (!vol->modifier) + ++solid_cnt; + if (!volume->modifier && solid_cnt == 1) { + Slic3r::GUI::show_error(nullptr, _(L("You can't delete the last solid part from this object."))); + return; + } + + m_objects_ctrl->Select(m_objects_model->Delete(item)); + m_objects[m_selected_object_id]->delete_volume(volume_id); + m_parts_changed = true; + + parts_changed(m_selected_object_id); +} + +void on_btn_split() +{ + auto item = m_objects_ctrl->GetSelection(); + if (!item) + return; + auto volume_id = m_objects_model->GetVolumeIdByItem(item); + if (volume_id < 0) + return; + + auto volume = m_objects[m_selected_object_id]->volumes[volume_id]; + DynamicPrintConfig& config = get_preset_bundle()->prints.get_edited_preset().config; + auto nozzle_dmrs_cnt = config.option("nozzle_diameter")->values.size(); + if (volume->split(nozzle_dmrs_cnt) > 1) { + // TODO update model + m_parts_changed = true; + parts_changed(m_selected_object_id); + } +} + +void on_btn_move_up(){ + auto item = m_objects_ctrl->GetSelection(); + if (!item) + return; + auto volume_id = m_objects_model->GetVolumeIdByItem(item); + if (volume_id < 0) + return; + auto& volumes = m_objects[m_selected_object_id]->volumes; + if (0 < volume_id && volume_id < volumes.size()) { + std::swap(volumes[volume_id - 1], volumes[volume_id]); + m_parts_changed = true; + // TODO update model ($volume_id - 1); + } +} + +void on_btn_move_down(){ + auto item = m_objects_ctrl->GetSelection(); + if (!item) + return; + auto volume_id = m_objects_model->GetVolumeIdByItem(item); + if (volume_id < 0) + return; + auto& volumes = m_objects[m_selected_object_id]->volumes; + if (0 <= volume_id && volume_id+1 < volumes.size()) { + std::swap(volumes[volume_id + 1], volumes[volume_id - 1]); + m_parts_changed = true; + // TODO update model ($volume_id - 1); + } +} + void parts_changed(int obj_idx) { if (m_event_object_settings_changed <= 0) return; diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 9f1afc861..77552c495 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -71,6 +71,10 @@ void load_lambda(wxWindow* parent, ModelObject* model_object, wxArrayString& part_names, const bool is_modifier); void on_btn_load(wxWindow* parent, bool is_modifier = false, bool is_lambda = false); +void on_btn_del(); +void on_btn_split(); +void on_btn_move_up(); +void on_btn_move_down(); void parts_changed(int obj_idx); void part_selection_changed(); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index f8d8cfc20..63c20e086 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -407,11 +407,21 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) // thus removing the node from it doesn't result in freeing it if (node_parent){ auto id = node_parent->GetChildren().Index(node); + auto v_id = node->GetVolumeId(); node_parent->GetChildren().Remove(node); if (id > 0){ if(id == node_parent->GetChildCount()) id--; ret_item = wxDataViewItem(node_parent->GetChildren().Item(id)); } + + //update volume_id value for remaining child-nodes + auto children = node_parent->GetChildren(); + for (size_t i = 0; i < node_parent->GetChildCount(); i++) + { + auto volume_id = children[i]->GetVolumeId(); + if (volume_id > v_id) + children[i]->SetVolumeId(volume_id-1); + } } else { diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index b8df8c98f..c28be59b3 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -276,7 +276,10 @@ public: return m_type; } - const int GetVolumeId(){ + void SetVolumeId(const int& volume_id){ + m_volume_id = volume_id; + } + const int& GetVolumeId(){ return m_volume_id; } }; From a772a19915667bde484ed66a75ba8ccc68a6c611 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 19 Jun 2018 12:24:16 +0200 Subject: [PATCH 052/119] "MoveUp" & "MoveDown" work correctly --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 15 +++++---- xs/src/slic3r/GUI/wxExtensions.cpp | 48 +++++++++++++++++++++++++++ xs/src/slic3r/GUI/wxExtensions.hpp | 30 +++++++++++++++++ 3 files changed, 86 insertions(+), 7 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index deb303c1a..c4dc631a2 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -81,15 +81,15 @@ wxBoxSizer* content_objects_list(wxWindow *win) // column 0(Icon+Text) of the view control: m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 150, - wxALIGN_LEFT, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); + wxALIGN_LEFT, /*wxDATAVIEW_COL_SORTABLE | */wxDATAVIEW_COL_RESIZABLE); // column 1 of the view control: m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 65, - wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); + wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); // column 2 of the view control: m_objects_ctrl->AppendTextColumn(_(L("Scale")), 2, wxDATAVIEW_CELL_INERT, 70, - wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); + wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { @@ -106,7 +106,8 @@ wxBoxSizer* content_objects_list(wxWindow *win) obj_idx = m_objects_model->GetIdByItem(item); else { auto parent = m_objects_model->GetParent(item); - obj_idx = m_objects_model->GetIdByItem(parent); // TODO Temporary decision for sub-objects selection + // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene + obj_idx = m_objects_model->GetIdByItem(parent); } } m_selected_object_id = obj_idx; @@ -605,7 +606,7 @@ void on_btn_move_up(){ if (0 < volume_id && volume_id < volumes.size()) { std::swap(volumes[volume_id - 1], volumes[volume_id]); m_parts_changed = true; - // TODO update model ($volume_id - 1); + m_objects_ctrl->Select(m_objects_model->MoveChildUp(item)); } } @@ -618,9 +619,9 @@ void on_btn_move_down(){ return; auto& volumes = m_objects[m_selected_object_id]->volumes; if (0 <= volume_id && volume_id+1 < volumes.size()) { - std::swap(volumes[volume_id + 1], volumes[volume_id - 1]); + std::swap(volumes[volume_id + 1], volumes[volume_id]); m_parts_changed = true; - // TODO update model ($volume_id - 1); + m_objects_ctrl->Select(m_objects_model->MoveChildDown(item)); } } diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 63c20e086..7b35ce9a0 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -556,6 +556,54 @@ bool PrusaObjectDataViewModel::SetValue(const wxVariant &variant, const int item return m_objects[item_idx]->SetValue(variant, col); } +wxDataViewItem PrusaObjectDataViewModel::MoveChildUp(const wxDataViewItem &item) +{ + auto ret_item = wxDataViewItem(0); + wxASSERT(item.IsOk()); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return ret_item; + + auto node_parent = node->GetParent(); + if (!node_parent) // If isn't part, but object + return ret_item; + + auto volume_id = node->GetVolumeId(); + if (0 < volume_id && volume_id < node_parent->GetChildCount()){ + node_parent->SwapChildrens(volume_id - 1, volume_id); + ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id - 1)); + ItemChanged(item); + ItemChanged(ret_item); + } + else + ret_item = wxDataViewItem(node_parent->GetNthChild(0)); + return ret_item; +} + +wxDataViewItem PrusaObjectDataViewModel::MoveChildDown(const wxDataViewItem &item) +{ + auto ret_item = wxDataViewItem(0); + wxASSERT(item.IsOk()); + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return ret_item; + + auto node_parent = node->GetParent(); + if (!node_parent) // If isn't part, but object + return ret_item; + + auto volume_id = node->GetVolumeId(); + if (0 <= volume_id && volume_id+1 < node_parent->GetChildCount()){ + node_parent->SwapChildrens(volume_id + 1, volume_id); + ret_item = wxDataViewItem(node_parent->GetNthChild(volume_id + 1)); + ItemChanged(item); + ItemChanged(ret_item); + } + else + ret_item = wxDataViewItem(node_parent->GetNthChild(node_parent->GetChildCount()-1)); + return ret_item; +} + // bool MyObjectTreeModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const // { // diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index c28be59b3..54631e14a 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -282,6 +282,33 @@ public: const int& GetVolumeId(){ return m_volume_id; } + + // use this function only for childrens + void AssignAllVal(PrusaObjectDataViewModelNode& from_node) + { + // ! Don't overwrite other values because of equality of this values for all children -- + m_name = from_node.m_name; + m_icon = from_node.m_icon; + m_volume_id = from_node.m_volume_id; + } + + bool SwapChildrens(int frst_id, int scnd_id) { + if (GetChildCount() < 2 || + frst_id < 0 || frst_id >= GetChildCount() || + scnd_id < 0 || scnd_id >= GetChildCount()) + return false; + + PrusaObjectDataViewModelNode new_scnd = *GetNthChild(frst_id); + PrusaObjectDataViewModelNode new_frst = *GetNthChild(scnd_id); + + new_scnd.m_volume_id = m_children.Item(scnd_id)->m_volume_id; + new_frst.m_volume_id = m_children.Item(frst_id)->m_volume_id; + + m_children.Item(frst_id)->AssignAllVal(new_frst); + m_children.Item(scnd_id)->AssignAllVal(new_scnd); + return true; + } + }; // ---------------------------------------------------------------------------- @@ -328,6 +355,9 @@ public: const wxDataViewItem &item, unsigned int col) override; bool SetValue(const wxVariant &variant, const int item_idx, unsigned int col); + wxDataViewItem MoveChildUp(const wxDataViewItem &item); + wxDataViewItem MoveChildDown(const wxDataViewItem &item); + // virtual bool IsEnabled(const wxDataViewItem &item, // unsigned int col) const override; From 8a3cf3f71d2b2ef68887ff312f5b41a0d22aa0f1 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 19 Jun 2018 16:24:49 +0200 Subject: [PATCH 053/119] Correct selection update on MSW --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 113 ++++++++++++++------------ xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 2 + 2 files changed, 61 insertions(+), 54 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index c4dc631a2..fe8efaedd 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -93,36 +93,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { - if (g_prevent_list_events) return; - - wxWindowUpdateLocker noUpdates(get_right_panel()); - auto item = m_objects_ctrl->GetSelection(); - int obj_idx = -1; - if (!item) - unselect_objects(); - else - { - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) - obj_idx = m_objects_model->GetIdByItem(item); - else { - auto parent = m_objects_model->GetParent(item); - // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene - obj_idx = m_objects_model->GetIdByItem(parent); - } - } - m_selected_object_id = obj_idx; - - if (m_event_object_selection_changed > 0) { - wxCommandEvent event(m_event_object_selection_changed); - event.SetInt(int(m_objects_model->GetParent(item) != wxDataViewItem(0))); - event.SetId(obj_idx); - get_main_frame()->ProcessWindowEvent(event); - } - - if (obj_idx < 0) return; - -// m_objects_ctrl->SetSize(m_objects_ctrl->GetBestSize()); // TODO override GetBestSize(), than use it - part_selection_changed(); + object_ctrl_selection_changed(); }); m_objects_ctrl->Bind(wxEVT_KEY_DOWN, [](wxKeyEvent& event) @@ -344,13 +315,9 @@ void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer) m_sizer_object_buttons->Show(false); m_sizer_part_buttons->Show(false); m_sizer_object_movers->Show(false); - m_collpane_settings->Show(false); + if (!m_objects_ctrl->HasSelection()) + m_collpane_settings->Show(false); } -// else -// m_objects_ctrl->UnselectAll(); - -// e.Skip(); -// g_right_panel->Layout(); })); // *** Object/Part Settings *** @@ -367,6 +334,10 @@ void add_object_to_list(const std::string &name, ModelObject* model_object) wxString item = name; int scale = model_object->instances[0]->scaling_factor * 100; m_objects_ctrl->Select(m_objects_model->Add(item, model_object->instances.size(), scale)); +// part_selection_changed(); +#ifdef __WXMSW__ + object_ctrl_selection_changed(); +#endif //__WXMSW__ m_objects.push_back(model_object); } @@ -403,14 +374,7 @@ void set_object_scale(int idx, int scale) void unselect_objects() { m_objects_ctrl->UnselectAll(); - if (m_sizer_object_buttons->IsShown(1)) - m_sizer_object_buttons->Show(false); - if (m_sizer_part_buttons->IsShown(1)) - m_sizer_part_buttons->Show(false); - if (m_sizer_object_movers->IsShown(1)) - m_sizer_object_movers->Show(false); - if (m_collpane_settings->IsShown()) - m_collpane_settings->Show(false); + part_selection_changed(); } void select_current_object(int idx) @@ -422,17 +386,26 @@ void select_current_object(int idx) return; } m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); + part_selection_changed(); g_prevent_list_events = false; +} - if (is_expert_mode()){ - if (!m_sizer_object_buttons->IsShown(1)) - m_sizer_object_buttons->Show(true); - if (!m_sizer_object_movers->IsShown(1)) - m_sizer_object_movers->Show(true); - if (!m_collpane_settings->IsShown()) - m_collpane_settings->Show(true); +void object_ctrl_selection_changed() +{ + if (g_prevent_list_events) return; + + part_selection_changed(); + + if (m_selected_object_id < 0) return; + + if (m_event_object_selection_changed > 0) { + wxCommandEvent event(m_event_object_selection_changed); + event.SetInt(int(m_objects_model->GetParent(/*item*/ m_objects_ctrl->GetSelection()) != wxDataViewItem(0))); + event.SetId(m_selected_object_id); + get_main_frame()->ProcessWindowEvent(event); } } + // ****** void load_part( wxWindow* parent, ModelObject* model_object, @@ -547,6 +520,10 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/ for (int i = 0; i < part_names.size(); ++i) m_objects_ctrl->Select( m_objects_model->AddChild(item, part_names.Item(i), is_modifier ? m_icon_modifiermesh : m_icon_solidmesh)); +// part_selection_changed(); +#ifdef __WXMSW__ + object_ctrl_selection_changed(); +#endif //__WXMSW__ } void on_btn_del() @@ -569,11 +546,16 @@ void on_btn_del() return; } - m_objects_ctrl->Select(m_objects_model->Delete(item)); m_objects[m_selected_object_id]->delete_volume(volume_id); m_parts_changed = true; parts_changed(m_selected_object_id); + + m_objects_ctrl->Select(m_objects_model->Delete(item)); + part_selection_changed(); +// #ifdef __WXMSW__ +// object_ctrl_selection_changed(); +// #endif //__WXMSW__ } void on_btn_split() @@ -607,6 +589,10 @@ void on_btn_move_up(){ std::swap(volumes[volume_id - 1], volumes[volume_id]); m_parts_changed = true; m_objects_ctrl->Select(m_objects_model->MoveChildUp(item)); + part_selection_changed(); +// #ifdef __WXMSW__ +// object_ctrl_selection_changed(); +// #endif //__WXMSW__ } } @@ -622,6 +608,10 @@ void on_btn_move_down(){ std::swap(volumes[volume_id + 1], volumes[volume_id]); m_parts_changed = true; m_objects_ctrl->Select(m_objects_model->MoveChildDown(item)); + part_selection_changed(); +// #ifdef __WXMSW__ +// object_ctrl_selection_changed(); +// #endif //__WXMSW__ } } @@ -639,6 +629,22 @@ void parts_changed(int obj_idx) void part_selection_changed() { + auto item = m_objects_ctrl->GetSelection(); + int obj_idx = -1; + if (item) + { + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) + obj_idx = m_objects_model->GetIdByItem(item); + else { + auto parent = m_objects_model->GetParent(item); + // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene + obj_idx = m_objects_model->GetIdByItem(parent); + } + } + m_selected_object_id = obj_idx; + + wxWindowUpdateLocker noUpdates(get_right_panel()); + m_move_options = Point3(0, 0, 0); m_last_coords = Point3(0, 0, 0); // reset move sliders @@ -647,8 +653,7 @@ void part_selection_changed() for (auto opt_key: opt_keys) og->set_value(opt_key, int(0)); - auto item = m_objects_ctrl->GetSelection(); - if (!item || m_selected_object_id < 0){ + if (/*!item || */m_selected_object_id < 0){ m_sizer_object_buttons->Show(false); m_sizer_part_buttons->Show(false); m_sizer_object_movers->Show(false); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 77552c495..bece5f0f8 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -57,6 +57,8 @@ void unselect_objects(); // Select current object in the list on c++ side void select_current_object(int idx); +void object_ctrl_selection_changed(); + void init_mesh_icons(); void set_event_object_selection_changed(const int& event); void set_event_object_settings_changed (const int& event); From c1724f45c933c252ff410e4dbd0fe5a0aacb6caa Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 26 Jun 2018 13:34:25 +0200 Subject: [PATCH 054/119] Fixed post-merge bugs --- lib/Slic3r/GUI/Plater.pm | 23 ++++++++--------------- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 2 +- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index f3ef531ad..2b6fa4b3f 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1927,25 +1927,16 @@ sub on_config_change { $self->schedule_background_process; } -sub list_item_deselected { - my ($self, $event) = @_; - return if $PreventListEvents; - $self->{_lecursor} = Wx::BusyCursor->new(); - if ($self->{list}->GetFirstSelected == -1) { - $self->select_object(undef); - $self->{canvas}->Refresh; - Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas3D}) if $self->{canvas3D}; - Slic3r::GUI::_3DScene::render($self->{canvas3D}) if $self->{canvas3D}; - } - undef $self->{_lecursor}; -} sub item_changed_selection{ my ($self, $obj_idx) = @_; $self->{canvas}->Refresh; if ($self->{canvas3D}) { - my $selections = $self->collect_selections; - Slic3r::GUI::_3DScene::update_volumes_selection($self->{canvas3D}, \@$selections); + Slic3r::GUI::_3DScene::deselect_volumes($self->{canvas3D}); + if ($obj_idx >= 0){ + my $selections = $self->collect_selections; + Slic3r::GUI::_3DScene::update_volumes_selection($self->{canvas3D}, \@$selections); + } Slic3r::GUI::_3DScene::render($self->{canvas3D}); } } @@ -2077,7 +2068,9 @@ sub changed_object_settings { $self->{print}->reload_object($obj_idx); $self->schedule_background_process; $self->{canvas}->reload_scene if $self->{canvas}; - $self->{canvas3D}->reload_scene if $self->{canvas3D}; + my $selections = $self->collect_selections; + Slic3r::GUI::_3DScene::set_objects_selections($self->{canvas3D}, \@$selections); + Slic3r::GUI::_3DScene::reload_scene($self->{canvas3D}, 0); } else { $self->resume_background_process; } diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index fe8efaedd..331fde749 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -396,7 +396,7 @@ void object_ctrl_selection_changed() part_selection_changed(); - if (m_selected_object_id < 0) return; +// if (m_selected_object_id < 0) return; if (m_event_object_selection_changed > 0) { wxCommandEvent event(m_event_object_selection_changed); From f8ab8b43de1eccc6faa4bf73480083ea6cd8a5ea Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 29 Jun 2018 13:07:58 +0200 Subject: [PATCH 055/119] Experiment with Toolpits of selected preset on OSX --- xs/src/slic3r/GUI/Preset.cpp | 11 ++++++++--- xs/src/slic3r/GUI/PresetBundle.cpp | 7 +++++-- xs/src/slic3r/GUI/wxExtensions.cpp | 4 ++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/xs/src/slic3r/GUI/Preset.cpp b/xs/src/slic3r/GUI/Preset.cpp index 68982185b..536c37002 100644 --- a/xs/src/slic3r/GUI/Preset.cpp +++ b/xs/src/slic3r/GUI/Preset.cpp @@ -601,6 +601,7 @@ void PresetCollection::update_platter_ui(wxBitmapComboBox *ui) // Otherwise fill in the list from scratch. ui->Freeze(); ui->Clear(); + size_t selected_preset_item = 0; const Preset &selected_preset = this->get_selected_preset(); // Show wide icons if the currently selected preset is not compatible with the current printer, @@ -641,7 +642,7 @@ void PresetCollection::update_platter_ui(wxBitmapComboBox *ui) ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); if (i == m_idx_selected) - ui->SetSelection(ui->GetCount() - 1); + selected_preset_item = ui->GetCount() - 1; } else { @@ -658,10 +659,13 @@ void PresetCollection::update_platter_ui(wxBitmapComboBox *ui) for (std::map::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { ui->Append(it->first, *it->second); if (it->first == selected) - ui->SetSelection(ui->GetCount() - 1); + selected_preset_item = ui->GetCount() - 1; } } - ui->Thaw(); + + ui->SetSelection(selected_preset_item); + ui->SetToolTip(ui->GetString(selected_preset_item)); + ui->Thaw(); } size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible) @@ -719,6 +723,7 @@ size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompati } } ui->SetSelection(selected_preset_item); + ui->SetToolTip(ui->GetString(selected_preset_item)); ui->Thaw(); return selected_preset_item; } diff --git a/xs/src/slic3r/GUI/PresetBundle.cpp b/xs/src/slic3r/GUI/PresetBundle.cpp index d36ef7b6f..5914637bb 100644 --- a/xs/src/slic3r/GUI/PresetBundle.cpp +++ b/xs/src/slic3r/GUI/PresetBundle.cpp @@ -1108,6 +1108,7 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitma // Fill in the list from scratch. ui->Freeze(); ui->Clear(); + size_t selected_preset_item = 0; const Preset *selected_preset = this->filaments.find_preset(this->filament_presets[idx_extruder]); // Show wide icons if the currently selected preset is not compatible with the current printer, // and draw a red flag in front of the selected preset. @@ -1159,7 +1160,7 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitma ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), (bitmap == 0) ? wxNullBitmap : *bitmap); if (selected) - ui->SetSelection(ui->GetCount() - 1); + selected_preset_item = ui->GetCount() - 1; } else { @@ -1178,9 +1179,11 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitma for (std::map::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { ui->Append(it->first, *it->second); if (it->first == selected_str) - ui->SetSelection(ui->GetCount() - 1); + selected_preset_item = ui->GetCount() - 1; } } + ui->SetSelection(selected_preset_item); + ui->SetToolTip(ui->GetString(selected_preset_item)); ui->Thaw(); } diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 7b35ce9a0..d0e394996 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -194,6 +194,9 @@ void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& e // ---------------------------------------------------------------------------- void PrusaCollapsiblePane::OnStateChange(const wxSize& sz) { +#ifndef __WXOSX__ + wxCollapsiblePane::OnStateChange(sz); +#else SetSize(sz); if (this->HasFlag(wxCP_NO_TLW_RESIZE)) @@ -219,6 +222,7 @@ void PrusaCollapsiblePane::OnStateChange(const wxSize& sz) // top->SetClientSize(newBestSize); top->GetParent()->Layout(); top->Refresh(); +#endif //__WXOSX__ } // ---------------------------------------------------------------------------- From 678498bed637765b405cda974a75fb22201e9320 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 29 Jun 2018 14:00:22 +0200 Subject: [PATCH 056/119] Typo fixed --- xs/src/slic3r/GUI/wxExtensions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index d0e394996..725edbd87 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -194,7 +194,7 @@ void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& e // ---------------------------------------------------------------------------- void PrusaCollapsiblePane::OnStateChange(const wxSize& sz) { -#ifndef __WXOSX__ +#ifdef __WXOSX__ wxCollapsiblePane::OnStateChange(sz); #else SetSize(sz); From 54298c8e61c18bec738b61e2311f029be17470a8 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 4 Jul 2018 08:54:30 +0200 Subject: [PATCH 057/119] First right-panel reorganization: * Replaced Object list from CollapsiblePane * Sub-object are adding by context menu from list * (sub)objects can be deleted by only one "Delete" button * Added extruder selection to list --- lib/Slic3r/GUI/MainFrame.pm | 9 ++ lib/Slic3r/GUI/Plater.pm | 11 ++- xs/src/slic3r/GUI/GUI.cpp | 14 ++- xs/src/slic3r/GUI/GUI.hpp | 4 +- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 127 ++++++++++++++++++++++++-- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 10 +- xs/src/slic3r/GUI/Tab.cpp | 1 + xs/src/slic3r/GUI/wxExtensions.cpp | 18 ++++ xs/src/slic3r/GUI/wxExtensions.hpp | 20 +++- xs/xsp/GUI.xsp | 9 +- 10 files changed, 202 insertions(+), 21 deletions(-) diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 553e287bf..1465c1215 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -29,6 +29,8 @@ our $PRESETS_CHANGED_EVENT = Wx::NewEventType; our $OBJECT_SELECTION_CHANGED_EVENT = Wx::NewEventType; # 4) To inform about a change of object settings our $OBJECT_SETTINGS_CHANGED_EVENT = Wx::NewEventType; +# 5) To inform about a remove of object +our $OBJECT_REMOVE_EVENT = Wx::NewEventType; sub new { my ($class, %params) = @_; @@ -122,6 +124,7 @@ sub _init_tabpanel { $panel->AddPage($self->{plater} = Slic3r::GUI::Plater->new($panel, event_object_selection_changed => $OBJECT_SELECTION_CHANGED_EVENT, event_object_settings_changed => $OBJECT_SETTINGS_CHANGED_EVENT, + event_remove_object => $OBJECT_REMOVE_EVENT, ), L("Plater")); if (!$self->{no_controller}) { $panel->AddPage($self->{controller} = Slic3r::GUI::Controller->new($panel), L("Controller")); @@ -197,6 +200,12 @@ sub _init_tabpanel { $self->{plater}->changed_object_settings($obj_idx, $parts_changed, $part_settings_changed); }); + + # The following event is emited by the C++ Tab implementation on object settings change. + EVT_COMMAND($self, -1, $OBJECT_REMOVE_EVENT, sub { + my ($self, $event) = @_; + $self->{plater}->remove(); + }); Slic3r::GUI::create_preset_tabs($self->{no_controller}, $VALUE_CHANGE_EVENT, $PRESETS_CHANGED_EVENT); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 2b6fa4b3f..2da273780 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -57,6 +57,7 @@ sub new { # store input params $self->{event_object_selection_changed} = $params{event_object_selection_changed}; $self->{event_object_settings_changed} = $params{event_object_settings_changed}; + $self->{event_remove_object} = $params{event_remove_object}; # C++ Slic3r::Model with Perl extensions in Slic3r/Model.pm $self->{model} = Slic3r::Model->new; @@ -151,6 +152,7 @@ sub new { Slic3r::GUI::_3DScene::register_on_increase_objects_callback($self->{canvas3D}, sub { $self->increase() }); Slic3r::GUI::_3DScene::register_on_decrease_objects_callback($self->{canvas3D}, sub { $self->decrease() }); Slic3r::GUI::_3DScene::register_on_remove_object_callback($self->{canvas3D}, sub { $self->remove() }); +# Slic3r::GUI::_3DScene::register_on_remove_object_callback($self->{canvas3D}, sub { Slic3r::GUI::remove_obj() }); Slic3r::GUI::_3DScene::register_on_instance_moved_callback($self->{canvas3D}, $on_instances_moved); Slic3r::GUI::_3DScene::register_on_enable_action_buttons_callback($self->{canvas3D}, $enable_action_buttons); Slic3r::GUI::_3DScene::register_on_gizmo_scale_uniformly_callback($self->{canvas3D}, $on_gizmo_scale_uniformly); @@ -328,7 +330,8 @@ sub new { if ($self->{htoolbar}) { EVT_TOOL($self, TB_ADD, sub { $self->add; }); - EVT_TOOL($self, TB_REMOVE, sub { $self->remove() }); # explicitly pass no argument to remove +# EVT_TOOL($self, TB_REMOVE, sub { $self->remove() }); # explicitly pass no argument to remove + EVT_TOOL($self, TB_REMOVE, sub { Slic3r::GUI::remove_obj() }); # explicitly pass no argument to remove EVT_TOOL($self, TB_RESET, sub { $self->reset; }); EVT_TOOL($self, TB_ARRANGE, sub { $self->arrange; }); EVT_TOOL($self, TB_MORE, sub { $self->increase; }); @@ -346,7 +349,8 @@ sub new { }); } else { EVT_BUTTON($self, $self->{btn_add}, sub { $self->add; }); - EVT_BUTTON($self, $self->{btn_remove}, sub { $self->remove() }); # explicitly pass no argument to remove +# EVT_BUTTON($self, $self->{btn_remove}, sub { $self->remove() }); # explicitly pass no argument to remove + EVT_BUTTON($self, $self->{btn_remove}, sub { Slic3r::GUI::remove_obj() }); # explicitly pass no argument to remove EVT_BUTTON($self, $self->{btn_reset}, sub { $self->reset; }); EVT_BUTTON($self, $self->{btn_arrange}, sub { $self->arrange; }); EVT_BUTTON($self, $self->{btn_increase}, sub { $self->increase; }); @@ -446,7 +450,8 @@ sub new { my $expert_mode_part_sizer = Wx::BoxSizer->new(wxVERTICAL); Slic3r::GUI::add_expert_mode_part( $self->{right_panel}, $expert_mode_part_sizer, $self->{event_object_selection_changed}, - $self->{event_object_settings_changed}); + $self->{event_object_settings_changed}, + $self->{event_remove_object}); # if ($expert_mode_part_sizer->IsShown(2)==1) # { # $expert_mode_part_sizer->Layout; diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 487ede655..6997592c4 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -811,6 +811,10 @@ wxFrame* get_main_frame() { return g_wxMainFrame; } +wxNotebook * get_tab_panel() { + return g_wxTabPanel; +} + const int& label_width(){ return m_label_width; } @@ -885,15 +889,19 @@ wxString from_u8(const std::string &str) void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed, - int event_object_settings_changed) + int event_object_settings_changed, + int event_remove_object) { set_event_object_selection_changed(event_object_selection_changed); set_event_object_settings_changed(event_object_settings_changed); + set_event_remove_object(event_remove_object); init_mesh_icons(); wxWindowUpdateLocker noUpdates(parent); - add_collapsible_panes(parent, sizer); + add_objects_list(parent, sizer); + +// add_collapsible_panes(parent, sizer); } Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value = 0) @@ -1149,7 +1157,7 @@ void update_mode() // TODO There is a not the best place of it! // *** Update showing of the collpane_settings - show_collpane_settings(mode == ConfigMenuModeExpert); +// show_collpane_settings(mode == ConfigMenuModeExpert); // ************************* g_right_panel->GetParent()->Layout(); g_right_panel->Layout(); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 8e1be3216..0a8d9072b 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -106,6 +106,7 @@ AppConfig* get_app_config(); wxApp* get_app(); PresetBundle* get_preset_bundle(); wxFrame* get_main_frame(); +wxNotebook * get_tab_panel(); const wxColour& get_label_clr_modified(); const wxColour& get_label_clr_sys(); @@ -187,7 +188,8 @@ wxString from_u8(const std::string &str); void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, int event_object_selection_changed, - int event_object_settings_changed); + int event_object_settings_changed, + int event_remove_object); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); // Update view mode according to selected menu void update_mode(); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 331fde749..69738e7f8 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -42,6 +42,7 @@ ModelObjectPtrs m_objects; int m_event_object_selection_changed = 0; int m_event_object_settings_changed = 0; +int m_event_remove_object = 0; bool m_parts_changed = false; bool m_part_settings_changed = false; @@ -52,6 +53,9 @@ void set_event_object_selection_changed(const int& event){ void set_event_object_settings_changed(const int& event){ m_event_object_settings_changed = event; } +void set_event_remove_object(const int& event){ + m_event_remove_object = event; +} void init_mesh_icons(){ m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); @@ -80,15 +84,30 @@ wxBoxSizer* content_objects_list(wxWindow *win) #endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE // column 0(Icon+Text) of the view control: - m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 150, + m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 120, wxALIGN_LEFT, /*wxDATAVIEW_COL_SORTABLE | */wxDATAVIEW_COL_RESIZABLE); // column 1 of the view control: - m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 65, + m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 45, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); // column 2 of the view control: - m_objects_ctrl->AppendTextColumn(_(L("Scale")), 2, wxDATAVIEW_CELL_INERT, 70, + m_objects_ctrl->AppendTextColumn(_(L("Scale")), 2, wxDATAVIEW_CELL_INERT, 55, + wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); + + // column 2 of the view control: + wxArrayString choices; + choices.Add("1"); + choices.Add("2"); + choices.Add("3"); + choices.Add("4"); + wxDataViewChoiceRenderer *c = + new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_CENTER_HORIZONTAL); + wxDataViewColumn *column3 = + new wxDataViewColumn(_(L("Extruder")), c, 3, 60, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); + m_objects_ctrl->AppendColumn(column3); + + m_objects_ctrl->AppendBitmapColumn("", 4, wxDATAVIEW_CELL_INERT, 25, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) @@ -96,6 +115,13 @@ wxBoxSizer* content_objects_list(wxWindow *win) object_ctrl_selection_changed(); }); + m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxEvent& event) + { + event.Skip(); + object_ctrl_context_menu(); + + }); + m_objects_ctrl->Bind(wxEVT_KEY_DOWN, [](wxKeyEvent& event) { if (event.GetKeyCode() == WXK_TAB) @@ -305,6 +331,11 @@ wxCollapsiblePane* add_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_pare return collpane; } +void add_objects_list(wxWindow* parent, wxBoxSizer* sizer) +{ + sizer->Add(content_objects_list(parent), 1, wxEXPAND | wxALL, 0); +} + void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer) { // *** Objects List *** @@ -349,14 +380,14 @@ void delete_object_from_list() // m_objects_ctrl->Select(m_objects_model->Delete(item)); m_objects_model->Delete(item); - if (m_objects_model->IsEmpty()) - m_collpane_settings->Show(false); +// if (m_objects_model->IsEmpty()) +// m_collpane_settings->Show(false); } void delete_all_objects_from_list() { m_objects_model->DeleteAll(); - m_collpane_settings->Show(false); +// m_collpane_settings->Show(false); } void set_object_count(int idx, int count) @@ -375,6 +406,8 @@ void unselect_objects() { m_objects_ctrl->UnselectAll(); part_selection_changed(); + + get_optgroup(ogFrequentlyObjectSettings)->disable(); } void select_current_object(int idx) @@ -388,6 +421,25 @@ void select_current_object(int idx) m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); part_selection_changed(); g_prevent_list_events = false; + + get_optgroup(ogFrequentlyObjectSettings)->enable(); +} + +void remove() +{ + auto item = m_objects_ctrl->GetSelection(); + if (!item) + return; + + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { + if (m_event_remove_object > 0) { + wxCommandEvent event(m_event_remove_object); + get_main_frame()->ProcessWindowEvent(event); + } +// delete_object_from_list(); + } + else + on_btn_del(); } void object_ctrl_selection_changed() @@ -406,6 +458,59 @@ void object_ctrl_selection_changed() } } +wxMenu *CreateAddPartPopupMenu(){ + wxMenu *menu = new wxMenu; + wxWindowID config_id_base = wxWindow::NewControlId(3); + + menu->Append(config_id_base, _(L("Add part"))); + menu->AppendSeparator(); + menu->Append(config_id_base + 1, _(L("Add modifier"))); + menu->AppendSeparator(); + menu->AppendCheckItem(config_id_base + 2, _(L("Add generic"))); + + wxWindow* win = get_tab_panel()->GetPage(0); + + menu->Bind(wxEVT_MENU, [config_id_base, win](wxEvent &event){ + switch (event.GetId() - config_id_base) { + case 0: + on_btn_load(win); + break; + case 1: + on_btn_load(win, true); + break; + case 2: + on_btn_load(win, true, true); + break; + default: + break; + } + }); + return menu; +} + +void object_ctrl_context_menu() +{ +// auto cur_column = m_objects_ctrl->GetCurrentColumn(); +// auto action_column = m_objects_ctrl->GetColumn(4); +// if (cur_column == action_column) + { + auto item = m_objects_ctrl->GetSelection(); + if (item) + { + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { + auto menu = CreateAddPartPopupMenu(); + get_tab_panel()->GetPage(0)->PopupMenu(menu); +// wxMessageBox(m_objects_model->GetName(item)); + } + // else { + // auto parent = m_objects_model->GetParent(item); + // // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene + // obj_idx = m_objects_model->GetIdByItem(parent); + // } + } + } +} + // ****** void load_part( wxWindow* parent, ModelObject* model_object, @@ -643,7 +748,7 @@ void part_selection_changed() } m_selected_object_id = obj_idx; - wxWindowUpdateLocker noUpdates(get_right_panel()); +/* wxWindowUpdateLocker noUpdates(get_right_panel()); m_move_options = Point3(0, 0, 0); m_last_coords = Point3(0, 0, 0); @@ -653,7 +758,8 @@ void part_selection_changed() for (auto opt_key: opt_keys) og->set_value(opt_key, int(0)); - if (/*!item || */m_selected_object_id < 0){ +// if (!item || m_selected_object_id < 0){ + if (m_selected_object_id < 0){ m_sizer_object_buttons->Show(false); m_sizer_part_buttons->Show(false); m_sizer_object_movers->Show(false); @@ -737,5 +843,10 @@ void part_selection_changed() */ } +void set_extruder_column_hidden(bool hide) +{ + m_objects_ctrl->GetColumn(3)->SetHidden(hide); +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index bece5f0f8..a0015c146 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -39,6 +39,7 @@ struct OBJECT_PARAMETERS }; void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer); +void add_objects_list(wxWindow* parent, wxBoxSizer* sizer); void show_collpane_settings(bool expert_mode); // Add object to the list @@ -56,12 +57,16 @@ void set_object_scale(int idx, int scale); void unselect_objects(); // Select current object in the list on c++ side void select_current_object(int idx); +// Remove objects/sub-object from the list +void remove(); void object_ctrl_selection_changed(); +void object_ctrl_context_menu(); void init_mesh_icons(); void set_event_object_selection_changed(const int& event); -void set_event_object_settings_changed (const int& event); +void set_event_object_settings_changed(const int& event); +void set_event_remove_object(const int& event); bool is_parts_changed(); bool is_part_settings_changed(); @@ -80,6 +85,9 @@ void on_btn_move_down(); void parts_changed(int obj_idx); void part_selection_changed(); + +// show/hide "Extruder" column for Objects List +void set_extruder_column_hidden(bool hide); } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 712d1db03..89628d72b 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1910,6 +1910,7 @@ void Tab::load_current_preset() const Preset* parent_preset = m_presets->get_selected_preset_parent(); static_cast(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 : static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); + set_extruder_column_hidden(static_cast(this)->m_sys_extruders_count <= 1); } m_opt_status_value = (m_presets->get_selected_preset_parent() ? osSystemValue : 0) | osInitValue; init_options_list(); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 725edbd87..23a87af9e 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -343,6 +343,18 @@ void PrusaCollapsiblePaneMSW::Collapse(bool collapse) } #endif //__WXMSW__ +// ***************************************************************************** +// ---------------------------------------------------------------------------- +// PrusaObjectDataViewModelNode +// ---------------------------------------------------------------------------- + +void PrusaObjectDataViewModelNode::set_object_action_icon() { + m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG); +} +void PrusaObjectDataViewModelNode::set_part_action_icon() { + m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG); +} + // ***************************************************************************** // ---------------------------------------------------------------------------- // PrusaObjectDataViewModel @@ -539,6 +551,12 @@ void PrusaObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem case 2: variant = node->m_scale; break; + case 3: + variant = node->m_extruder; + break; + case 4: + variant << node->m_action_icon; + break; default: ; } diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 54631e14a..3d0ca8564 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -163,19 +163,21 @@ public: m_scale = wxString::Format("%d%%", scale); m_type = "object"; m_volume_id = -1; + set_object_action_icon(); } PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, - const wxString& sub_obj, + const wxString& sub_obj_name, const wxIcon& icon, int volume_id=-1) { m_parent = parent; - m_name = sub_obj; + m_name = sub_obj_name; m_copy = wxEmptyString; m_scale = wxEmptyString; m_icon = icon; m_type = "volume"; - m_volume_id = volume_id; + m_volume_id = volume_id; + set_part_action_icon(); } ~PrusaObjectDataViewModelNode() @@ -196,6 +198,8 @@ public: std::string m_type; int m_volume_id; bool m_container = false; + wxString m_extruder = "default"; + wxBitmap m_action_icon; bool IsContainer() const { @@ -259,6 +263,12 @@ public: case 2: m_scale = variant.GetString(); return true; + case 3: + m_extruder = variant.GetString(); + return true; + case 4: + m_action_icon << variant; + return true; default: printf("MyObjectTreeModel::SetValue: wrong column"); } @@ -290,6 +300,7 @@ public: m_name = from_node.m_name; m_icon = from_node.m_icon; m_volume_id = from_node.m_volume_id; + m_extruder = from_node.m_extruder; } bool SwapChildrens(int frst_id, int scnd_id) { @@ -309,6 +320,9 @@ public: return true; } + // Set action icons for node + void set_object_action_icon(); + void set_part_action_icon(); }; // ---------------------------------------------------------------------------- diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index eef7b0fd9..470bbcdd2 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -89,11 +89,13 @@ void add_frequently_changed_parameters(SV *ui_parent, SV *ui_sizer, SV *ui_p_siz void add_expert_mode_part( SV *ui_parent, SV *ui_sizer, int event_object_selection_changed, - int event_object_settings_changed) + int event_object_settings_changed, + int event_remove_object) %code%{ Slic3r::GUI::add_expert_mode_part( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), event_object_selection_changed, - event_object_settings_changed); %}; + event_object_settings_changed, + event_remove_object); %}; void set_objects_from_perl( SV *ui_parent, SV *frequently_changed_parameters_sizer, @@ -149,6 +151,9 @@ void unselect_objects() void select_current_object(int idx) %code%{ Slic3r::GUI::select_current_object(idx); %}; +void remove_obj() + %code%{ Slic3r::GUI::remove(); %}; + std::string fold_utf8_to_ascii(const char *src) %code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %}; From 38768a7bdade481265c00d6e4e247a92b3ce6de6 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 4 Jul 2018 12:38:34 +0200 Subject: [PATCH 058/119] Replaced Object list before Object(Part) Settings --- lib/Slic3r/GUI/Plater.pm | 4 ++-- xs/src/slic3r/GUI/GUI.cpp | 31 ++++++++++++++++++--------- xs/src/slic3r/GUI/GUI.hpp | 3 ++- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 4 +++- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 2da273780..661a81a64 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -519,7 +519,7 @@ sub new { my $box = Wx::StaticBox->new($self->{right_panel}, -1, L("Sliced Info")); $box->SetFont($Slic3r::GUI::small_bold_font); $print_info_sizer = Wx::StaticBoxSizer->new($box, wxVERTICAL); - $print_info_sizer->SetMinSize([300,-1]); + $print_info_sizer->SetMinSize([316,-1]); my $grid_sizer = Wx::FlexGridSizer->new(2, 2, 5, 5); $grid_sizer->SetFlexibleDirection(wxHORIZONTAL); $grid_sizer->AddGrowableCol(1, 1); @@ -555,7 +555,7 @@ sub new { ### Sizer for info boxes my $info_sizer = Wx::BoxSizer->new(wxVERTICAL); - $info_sizer->SetMinSize([310, -1]); + $info_sizer->SetMinSize([318, -1]); $info_sizer->Add($object_info_sizer, 0, wxEXPAND | wxBOTTOM, 5); $info_sizer->Add($print_info_sizer, 0, wxEXPAND | wxBOTTOM, 5); diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 6997592c4..0262e20e5 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -133,6 +133,7 @@ wxWindow *g_right_panel = nullptr; wxBoxSizer *g_frequently_changed_parameters_sizer = nullptr; wxBoxSizer *g_expert_mode_part_sizer = nullptr; wxBoxSizer *g_scrolled_window_sizer = nullptr; +wxBoxSizer *g_object_list_sizer = nullptr; wxButton *g_btn_export_gcode = nullptr; wxButton *g_btn_export_stl = nullptr; wxButton *g_btn_reslice = nullptr; @@ -244,6 +245,10 @@ void set_show_manifold_warning_icon(bool show) g_show_manifold_warning_icon = show; } +void set_objects_list_sizer(wxBoxSizer *objects_list_sizer){ + g_object_list_sizer = objects_list_sizer; +} + std::vector& get_tabs_list() { return g_tabs_list; @@ -815,7 +820,7 @@ wxNotebook * get_tab_panel() { return g_wxTabPanel; } -const int& label_width(){ +const size_t& label_width(){ return m_label_width; } @@ -899,7 +904,7 @@ void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, wxWindowUpdateLocker noUpdates(parent); - add_objects_list(parent, sizer); +// add_objects_list(parent, sizer); // add_collapsible_panes(parent, sizer); } @@ -952,6 +957,8 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl const wxArrayInt& ar = preset_sizer->GetColWidths(); m_label_width = ar.IsEmpty() ? 100 : ar.front()-4; optgroup->label_width = m_label_width; + + //Frequently changed parameters optgroup->m_on_change = [config](t_config_option_key opt_key, boost::any value){ TabPrint* tab_print = nullptr; for (size_t i = 0; i < g_wxTabPanel->GetPageCount(); ++i) { @@ -1067,17 +1074,20 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl m_optgroups.push_back(optgroup);// ogFrequentlyChangingParameters + // Object List + add_objects_list(parent, sizer); + // Frequently Object Settings optgroup = std::make_shared(parent, _(L("Object Settings")), config); optgroup->label_width = 100; optgroup->set_grid_vgap(5); - def.label = L("Name"); - def.type = coString; - def.tooltip = L("Object name"); - def.full_width = true; - def.default_value = new ConfigOptionString{ "BlaBla_object.stl" }; - optgroup->append_single_option_line(Option(def, "object_name")); +// def.label = L("Name"); +// def.type = coString; +// def.tooltip = L("Object name"); +// def.full_width = true; +// def.default_value = new ConfigOptionString{ "BlaBla_object.stl" }; +// optgroup->append_single_option_line(Option(def, "object_name")); optgroup->set_flag(ogSIDE_OPTIONS_VERTICAL); optgroup->sidetext_width = 25; @@ -1096,7 +1106,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl def.default_value = new ConfigOptionBool{ false }; optgroup->append_single_option_line(Option(def, "place_on_bed")); - sizer->Add(optgroup->sizer, 0, wxEXPAND | wxLEFT, 20); + sizer->Add(optgroup->sizer, 0, wxEXPAND | wxLEFT | wxTOP, 20); m_optgroups.push_back(optgroup); // ogFrequentlyObjectSettings } @@ -1151,7 +1161,8 @@ void update_mode() ConfigMenuIDs mode = get_view_mode(); // show_frequently_changed_parameters(mode >= ConfigMenuModeRegular); - g_expert_mode_part_sizer->Show(mode == ConfigMenuModeExpert); +// g_expert_mode_part_sizer->Show(mode == ConfigMenuModeExpert); + g_object_list_sizer->Show(mode == ConfigMenuModeExpert); show_info_sizer(mode == ConfigMenuModeExpert); show_buttons(mode == ConfigMenuModeExpert); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 0a8d9072b..8240fc7c1 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -101,6 +101,7 @@ void set_objects_from_perl( wxWindow* parent, wxStaticBitmap *manifold_warning_icon); void set_show_print_info(bool show); void set_show_manifold_warning_icon(bool show); +void set_objects_list_sizer(wxBoxSizer *objects_list_sizer); AppConfig* get_app_config(); wxApp* get_app(); @@ -121,7 +122,7 @@ const wxFont& bold_font(); void open_model(wxWindow *parent, wxArrayString& input_files); wxWindow* get_right_panel(); -const int& label_width(); +const size_t& label_width(); extern void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 69738e7f8..682ed2f26 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -333,7 +333,9 @@ wxCollapsiblePane* add_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_pare void add_objects_list(wxWindow* parent, wxBoxSizer* sizer) { - sizer->Add(content_objects_list(parent), 1, wxEXPAND | wxALL, 0); + const auto ol_sizer = content_objects_list(parent); + sizer->Add(ol_sizer, 1, wxEXPAND | wxTOP, 20); + set_objects_list_sizer(ol_sizer); } void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer) From 60f703e7c7537bc813eae1c23f1a520bb72b6dc4 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 4 Jul 2018 14:52:36 +0200 Subject: [PATCH 059/119] Added function for the sidetext changing + some code reorganization --- xs/src/slic3r/GUI/Field.cpp | 7 +- xs/src/slic3r/GUI/Field.hpp | 6 ++ xs/src/slic3r/GUI/GUI.cpp | 73 +------------------ xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 101 ++++++++++++++++++++++++-- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 1 + xs/src/slic3r/GUI/OptionsGroup.cpp | 1 + xs/src/slic3r/GUI/OptionsGroup.hpp | 8 ++ 7 files changed, 115 insertions(+), 82 deletions(-) diff --git a/xs/src/slic3r/GUI/Field.cpp b/xs/src/slic3r/GUI/Field.cpp index d4a351e74..5e33ea784 100644 --- a/xs/src/slic3r/GUI/Field.cpp +++ b/xs/src/slic3r/GUI/Field.cpp @@ -547,8 +547,11 @@ boost::any& Choice::get_value() // boost::any m_value; wxString ret_str = static_cast(window)->GetValue(); - if (m_opt_id == "support") - return m_value = boost::any(ret_str);//ret_str; + // options from right panel + std::vector right_panel_options{ "support", "scale_unit" }; + for (auto rp_option: right_panel_options) + if (m_opt_id == rp_option) + return m_value = boost::any(ret_str); if (m_opt.type != coEnum) /*m_value = */get_value_by_opt_type(ret_str); diff --git a/xs/src/slic3r/GUI/Field.hpp b/xs/src/slic3r/GUI/Field.hpp index 04ee8c87b..54dc596b5 100644 --- a/xs/src/slic3r/GUI/Field.hpp +++ b/xs/src/slic3r/GUI/Field.hpp @@ -188,6 +188,10 @@ public: return false; } + void set_side_text_ptr(wxStaticText* side_text) { + m_side_text = side_text; + } + protected: MyButton* m_Undo_btn = nullptr; // Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one. @@ -202,6 +206,8 @@ protected: // Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one. const wxColour* m_label_color = nullptr; + wxStaticText* m_side_text = nullptr; + // current value boost::any m_value; diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 0262e20e5..82cd21efe 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -909,47 +909,6 @@ void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, // add_collapsible_panes(parent, sizer); } -Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value = 0) -{ - Line line = { _(option_name), "" }; - ConfigOptionDef def; - - def.label = L("X"); - def.type = coInt; - def.default_value = new ConfigOptionInt(def_value); - def.sidetext = sidetext; - def.width = 70; - - const std::string lower_name = boost::algorithm::to_lower_copy(option_name); - - Option option = Option(def, lower_name + "_X"); - option.opt.full_width = true; - line.append_option(option); - - def.label = L("Y"); - option = Option(def, lower_name + "_Y"); - line.append_option(option); - - def.label = L("Z"); - option = Option(def, lower_name + "_Z"); - line.append_option(option); - - if (option_name == "Scale") - { - def.label = L("Units"); - def.type = coStrings; - def.gui_type = "select_open"; - def.enum_labels.push_back(L("%")); - def.enum_labels.push_back(L("mm")); - def.default_value = new ConfigOptionStrings{ "%" }; - def.sidetext = " "; - - option = Option(def, lower_name + "_unit"); - line.append_option(option); - } - return line; -} - void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer) { DynamicPrintConfig* config = &g_PresetBundle->prints.get_edited_preset().config; @@ -1078,37 +1037,7 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl add_objects_list(parent, sizer); // Frequently Object Settings - optgroup = std::make_shared(parent, _(L("Object Settings")), config); - optgroup->label_width = 100; - optgroup->set_grid_vgap(5); - -// def.label = L("Name"); -// def.type = coString; -// def.tooltip = L("Object name"); -// def.full_width = true; -// def.default_value = new ConfigOptionString{ "BlaBla_object.stl" }; -// optgroup->append_single_option_line(Option(def, "object_name")); - - optgroup->set_flag(ogSIDE_OPTIONS_VERTICAL); - optgroup->sidetext_width = 25; - - optgroup->append_line(add_og_to_object_settings(L("Position"), L("mm"))); - optgroup->append_line(add_og_to_object_settings(L("Rotation"), "°", 1)); - optgroup->append_line(add_og_to_object_settings(L("Scale"), "%", 2)); - - optgroup->set_flag(ogDEFAULT); - - def.label = L("Place on bed"); - def.type = coBool; - def.tooltip = L("Automatic placing of models on printing bed in Y axis"); - def.gui_type = ""; - def.sidetext = ""; - def.default_value = new ConfigOptionBool{ false }; - optgroup->append_single_option_line(Option(def, "place_on_bed")); - - sizer->Add(optgroup->sizer, 0, wxEXPAND | wxLEFT | wxTOP, 20); - - m_optgroups.push_back(optgroup); // ogFrequentlyObjectSettings + add_object_settings(parent, sizer); } void show_frequently_changed_parameters(bool show) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 682ed2f26..6909c274b 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -65,7 +65,7 @@ void init_mesh_icons(){ bool is_parts_changed(){return m_parts_changed;} bool is_part_settings_changed(){ return m_part_settings_changed; } -static wxString dots("…", wxConvUTF8); +static wxString dots("…", wxConvUTF8); // ****** from GUI.cpp wxBoxSizer* content_objects_list(wxWindow *win) @@ -308,6 +308,98 @@ wxBoxSizer* content_settings(wxWindow *win) return sizer; } +void add_objects_list(wxWindow* parent, wxBoxSizer* sizer) +{ + const auto ol_sizer = content_objects_list(parent); + sizer->Add(ol_sizer, 1, wxEXPAND | wxTOP, 20); + set_objects_list_sizer(ol_sizer); +} + +Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value = 0) +{ + Line line = { _(option_name), "" }; + + ConfigOptionDef def; + def.type = coInt; + def.default_value = new ConfigOptionInt(def_value); + def.sidetext = sidetext; + def.width = 70; + + const std::string lower_name = boost::algorithm::to_lower_copy(option_name); + + std::vector axes{ "x", "y", "z" }; + for (auto axis : axes) { + def.label = boost::algorithm::to_upper_copy(axis); + Option option = Option(def, lower_name + "_" + axis); + option.opt.full_width = true; + line.append_option(option); + } + + if (option_name == "Scale") + { + def.label = L("Units"); + def.type = coStrings; + def.gui_type = "select_open"; + def.enum_labels.push_back(L("%")); + def.enum_labels.push_back(L("mm")); + def.default_value = new ConfigOptionStrings{ "%" }; + def.sidetext = " "; + + Option option = Option(def, lower_name + "_unit"); + line.append_option(option); + } + return line; +} + +void add_object_settings(wxWindow* parent, wxBoxSizer* sizer) +{ + auto optgroup = std::make_shared(parent, _(L("Object Settings"))); + optgroup->label_width = 100; + optgroup->set_grid_vgap(5); + + optgroup->m_on_change = [](t_config_option_key opt_key, boost::any value){ + if (opt_key == "scale_unit"){ + const wxString& selection = boost::any_cast(value); + std::vector axes{ "x", "y", "z" }; + for (auto axis : axes) { + std::string key = "scale_" + axis; + get_optgroup(ogFrequentlyObjectSettings)->set_side_text(key, selection); + } + } + }; + +// def.label = L("Name"); +// def.type = coString; +// def.tooltip = L("Object name"); +// def.full_width = true; +// def.default_value = new ConfigOptionString{ "BlaBla_object.stl" }; +// optgroup->append_single_option_line(Option(def, "object_name")); + + optgroup->set_flag(ogSIDE_OPTIONS_VERTICAL); + optgroup->sidetext_width = 25; + + optgroup->append_line(add_og_to_object_settings(L("Position"), L("mm"))); + optgroup->append_line(add_og_to_object_settings(L("Rotation"), "°", 1)); + optgroup->append_line(add_og_to_object_settings(L("Scale"), "%", 2)); + + optgroup->set_flag(ogDEFAULT); + + ConfigOptionDef def; + def.label = L("Place on bed"); + def.type = coBool; + def.tooltip = L("Automatic placing of models on printing bed in Y axis"); + def.gui_type = ""; + def.sidetext = ""; + def.default_value = new ConfigOptionBool{ false }; + optgroup->append_single_option_line(Option(def, "place_on_bed")); + + sizer->Add(optgroup->sizer, 0, wxEXPAND | wxLEFT | wxTOP, 20); + + optgroup->disable(); + + get_optgroups().push_back(optgroup); // ogFrequentlyObjectSettings +} + // add Collapsible Pane to sizer wxCollapsiblePane* add_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_parent, const wxString& name, std::function content_function) @@ -331,13 +423,6 @@ wxCollapsiblePane* add_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_pare return collpane; } -void add_objects_list(wxWindow* parent, wxBoxSizer* sizer) -{ - const auto ol_sizer = content_objects_list(parent); - sizer->Add(ol_sizer, 1, wxEXPAND | wxTOP, 20); - set_objects_list_sizer(ol_sizer); -} - void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer) { // *** Objects List *** diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index a0015c146..8d54fa29b 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -40,6 +40,7 @@ struct OBJECT_PARAMETERS void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer); void add_objects_list(wxWindow* parent, wxBoxSizer* sizer); +void add_object_settings(wxWindow* parent, wxBoxSizer* sizer); void show_collpane_settings(bool expert_mode); // Add object to the list diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index 4778047be..ca612e95c 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -230,6 +230,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* wxSize(sidetext_width, -1)/*wxDefaultSize*/, wxALIGN_LEFT); sidetext->SetFont(sidetext_font); sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, m_flag == ogSIDE_OPTIONS_VERTICAL ? 0 : 4); + field->set_side_text_ptr(sidetext); } // add side widget if any diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index cd604fc8e..6697ed75a 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -128,6 +128,14 @@ public: return out; } + bool set_side_text(const t_config_option_key& opt_key, const wxString& side_text) { + if (m_fields.find(opt_key) == m_fields.end()) return false; + auto st = m_fields.at(opt_key)->m_side_text; + if (!st) return false; + st->SetLabel(side_text); + return true; + } + inline void enable() { for (auto& field : m_fields) field.second->enable(); } inline void disable() { for (auto& field : m_fields) field.second->disable(); } void set_flag(ogDrawFlag flag) { m_flag = flag; } From 182e4232b2e170d832ae1c87350ac4c3c825b320 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 4 Jul 2018 16:32:01 +0200 Subject: [PATCH 060/119] Added error icon before object if errors auto-repaire was detected + Added size object updating (in the object setting panel) --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 36 +++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 6909c274b..0cc5557fc 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -25,6 +25,7 @@ wxCollapsiblePane *m_collpane_settings = nullptr; wxIcon m_icon_modifiermesh; wxIcon m_icon_solidmesh; +wxIcon m_icon_manifold_warning; wxSlider* m_mover_x = nullptr; wxSlider* m_mover_y = nullptr; @@ -60,6 +61,7 @@ void set_event_remove_object(const int& event){ void init_mesh_icons(){ m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); m_icon_solidmesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); + m_icon_manifold_warning = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); } bool is_parts_changed(){return m_parts_changed;} @@ -449,9 +451,22 @@ void show_collpane_settings(bool expert_mode) void add_object_to_list(const std::string &name, ModelObject* model_object) { - wxString item = name; + wxString item_name = name; int scale = model_object->instances[0]->scaling_factor * 100; - m_objects_ctrl->Select(m_objects_model->Add(item, model_object->instances.size(), scale)); + auto item = m_objects_model->Add(item_name, model_object->instances.size(), scale); + m_objects_ctrl->Select(item); + + // Add error icon if detected auto-repaire + auto stats = model_object->volumes[0]->mesh.stl.stats; + int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + + stats.facets_added + stats.facets_reversed + stats.backwards_edges; + if (errors > 0) { + const wxDataViewIconText data(item_name, m_icon_manifold_warning); + wxVariant variant; + variant << data; + m_objects_model->SetValue(variant, item, 0); + } + // part_selection_changed(); #ifdef __WXMSW__ object_ctrl_selection_changed(); @@ -818,6 +833,21 @@ void parts_changed(int obj_idx) e.SetString(event_str); get_main_frame()->ProcessWindowEvent(e); } + +void update_settings_value() +{ + auto og = get_optgroup(ogFrequentlyObjectSettings); + if (m_selected_object_id < 0 || m_objects.size() <= m_selected_object_id) { + og->set_value("scale_x", 0); + og->set_value("scale_y", 0); + og->set_value("scale_z", 0); + return; + } + auto bb_size = m_objects[m_selected_object_id]->instance_bounding_box(0).size(); + og->set_value("scale_x", int(bb_size.x+0.5)); + og->set_value("scale_y", int(bb_size.y+0.5)); + og->set_value("scale_z", int(bb_size.z+0.5)); +} void part_selection_changed() { @@ -835,6 +865,8 @@ void part_selection_changed() } m_selected_object_id = obj_idx; + update_settings_value(); + /* wxWindowUpdateLocker noUpdates(get_right_panel()); m_move_options = Point3(0, 0, 0); From a6b1e8466d34336f903cdafdd642d556d3708c23 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 9 Jul 2018 16:42:31 +0200 Subject: [PATCH 061/119] Added popupmenu for add_settings --- xs/src/slic3r/GUI/GUI.hpp | 16 +++--- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 70 ++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 16 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 8240fc7c1..58a927cf6 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -64,15 +64,15 @@ typedef std::map t_file_wild_card; inline t_file_wild_card& get_file_wild_card() { static t_file_wild_card FILE_WILDCARDS; if (FILE_WILDCARDS.empty()){ - FILE_WILDCARDS["known"] = "Known files (*.stl, *.obj, *.amf, *.xml, *.prusa)|*.stl;*.STL;*.obj;*.OBJ;*.amf;*.AMF;*.xml;*.XML;*.prusa;*.PRUSA"; - FILE_WILDCARDS["stl"] = "STL files (*.stl)|*.stl;*.STL"; - FILE_WILDCARDS["obj"] = "OBJ files (*.obj)|*.obj;*.OBJ"; - FILE_WILDCARDS["amf"] = "AMF files (*.amf)|*.zip.amf;*.amf;*.AMF;*.xml;*.XML"; - FILE_WILDCARDS["3mf"] = "3MF files (*.3mf)|*.3mf;*.3MF;"; - FILE_WILDCARDS["prusa"] = "Prusa Control files (*.prusa)|*.prusa;*.PRUSA"; - FILE_WILDCARDS["ini"] = "INI files *.ini|*.ini;*.INI"; + FILE_WILDCARDS["known"] = "Known files (*.stl, *.obj, *.amf, *.xml, *.prusa)|*.stl;*.STL;*.obj;*.OBJ;*.amf;*.AMF;*.xml;*.XML;*.prusa;*.PRUSA"; + FILE_WILDCARDS["stl"] = "STL files (*.stl)|*.stl;*.STL"; + FILE_WILDCARDS["obj"] = "OBJ files (*.obj)|*.obj;*.OBJ"; + FILE_WILDCARDS["amf"] = "AMF files (*.amf)|*.zip.amf;*.amf;*.AMF;*.xml;*.XML"; + FILE_WILDCARDS["3mf"] = "3MF files (*.3mf)|*.3mf;*.3MF;"; + FILE_WILDCARDS["prusa"] = "Prusa Control files (*.prusa)|*.prusa;*.PRUSA"; + FILE_WILDCARDS["ini"] = "INI files *.ini|*.ini;*.INI"; FILE_WILDCARDS["gcode"] = "G-code files (*.gcode, *.gco, *.g, *.ngc)|*.gcode;*.GCODE;*.gco;*.GCO;*.g;*.G;*.ngc;*.NGC"; - FILE_WILDCARDS["svg"] = "SVG files *.svg|*.svg;*.SVG"; + FILE_WILDCARDS["svg"] = "SVG files *.svg|*.svg;*.SVG"; } return FILE_WILDCARDS; } diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 0cc5557fc..759c43156 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -48,6 +48,28 @@ int m_event_remove_object = 0; bool m_parts_changed = false; bool m_part_settings_changed = false; +// typedef std::map t_category_icon; +typedef std::map t_category_icon; +inline t_category_icon& get_category_icon() { + static t_category_icon CATEGORY_ICON; + if (CATEGORY_ICON.empty()){ + CATEGORY_ICON[L("Layers and Perimeters")] = wxBitmap(from_u8(Slic3r::var("layers.png")), wxBITMAP_TYPE_PNG); + CATEGORY_ICON[L("Infill")] = wxBitmap(from_u8(Slic3r::var("infill.png")), wxBITMAP_TYPE_PNG); + CATEGORY_ICON[L("Support material")] = wxBitmap(from_u8(Slic3r::var("building.png")), wxBITMAP_TYPE_PNG); + CATEGORY_ICON[L("Speed")] = wxBitmap(from_u8(Slic3r::var("time.png")), wxBITMAP_TYPE_PNG); + CATEGORY_ICON[L("Extruders")] = wxBitmap(from_u8(Slic3r::var("funnel.png")), wxBITMAP_TYPE_PNG); + CATEGORY_ICON[L("Extrusion Width")] = wxBitmap(from_u8(Slic3r::var("funnel.png")), wxBITMAP_TYPE_PNG); +// CATEGORY_ICON[L("Skirt and brim")] = wxBitmap(from_u8(Slic3r::var("box.png")), wxBITMAP_TYPE_PNG); +// CATEGORY_ICON[L("Speed > Acceleration")] = wxBitmap(from_u8(Slic3r::var("time.png")), wxBITMAP_TYPE_PNG); + CATEGORY_ICON[L("Advanced")] = wxBitmap(from_u8(Slic3r::var("wand.png")), wxBITMAP_TYPE_PNG); + } + return CATEGORY_ICON; +} + +// C++ class Slic3r::DynamicPrintConfig, initially empty. +std::shared_ptr default_config = std::make_shared(); +std::shared_ptr config = std::make_shared(); + void set_event_object_selection_changed(const int& event){ m_event_object_selection_changed = event; } @@ -560,7 +582,7 @@ void object_ctrl_selection_changed() } } -wxMenu *CreateAddPartPopupMenu(){ +wxMenu *create_add_part_popupmenu(){ wxMenu *menu = new wxMenu; wxWindowID config_id_base = wxWindow::NewControlId(3); @@ -590,6 +612,35 @@ wxMenu *CreateAddPartPopupMenu(){ return menu; } +wxMenu *create_add_settings_popupmenu() +{ + wxMenu *menu = new wxMenu; + + auto categories = get_category_icon(); + int category_cnt = categories.size(); + wxWindowID config_id_base = wxWindow::NewControlId(category_cnt); + + int inc = 0; + for (auto cat : categories) + { + auto menu_item = new wxMenuItem(menu, config_id_base + inc, _(cat.first)); + menu_item->SetBitmap(cat.second); + + auto sub_menu = new wxMenu; + sub_menu->AppendCheckItem(wxID_ANY, "Check#1"); + sub_menu->AppendCheckItem(wxID_ANY, "Check#2"); + sub_menu->AppendCheckItem(wxID_ANY, "Check#3"); + sub_menu->AppendCheckItem(wxID_ANY, "Check#4"); + + menu_item->SetSubMenu(sub_menu); + + menu->Append(menu_item); + inc++; + } + + return menu; +} + void object_ctrl_context_menu() { // auto cur_column = m_objects_ctrl->GetCurrentColumn(); @@ -600,15 +651,18 @@ void object_ctrl_context_menu() if (item) { if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { - auto menu = CreateAddPartPopupMenu(); + auto menu = create_add_part_popupmenu(); + get_tab_panel()->GetPage(0)->PopupMenu(menu); + } + else { +// auto parent = m_objects_model->GetParent(item); +// // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene +// obj_idx = m_objects_model->GetIdByItem(parent); +// auto volume_id = m_objects_model->GetVolumeIdByItem(item); +// if (volume_id < 0) return; + auto menu = create_add_settings_popupmenu(); get_tab_panel()->GetPage(0)->PopupMenu(menu); -// wxMessageBox(m_objects_model->GetName(item)); } - // else { - // auto parent = m_objects_model->GetParent(item); - // // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene - // obj_idx = m_objects_model->GetIdByItem(parent); - // } } } } From 36f8050d7b1f7368bd7de431b25cf693bad53126 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 23 Jul 2018 17:35:50 +0200 Subject: [PATCH 062/119] Added popup menu with multiple choice of settings --- xs/src/slic3r/GUI/GUI.cpp | 2 +- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 142 ++++++++++++++++++++------ xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 11 +- 3 files changed, 122 insertions(+), 33 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 82cd21efe..83c428ea1 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -902,7 +902,7 @@ void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, set_event_remove_object(event_remove_object); init_mesh_icons(); - wxWindowUpdateLocker noUpdates(parent); +// wxWindowUpdateLocker noUpdates(parent); // add_objects_list(parent, sizer); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 759c43156..26e4fbbf7 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -26,6 +26,7 @@ wxCollapsiblePane *m_collpane_settings = nullptr; wxIcon m_icon_modifiermesh; wxIcon m_icon_solidmesh; wxIcon m_icon_manifold_warning; +wxBitmap m_bmp_cog; wxSlider* m_mover_x = nullptr; wxSlider* m_mover_y = nullptr; @@ -66,6 +67,49 @@ inline t_category_icon& get_category_icon() { return CATEGORY_ICON; } +void get_part_options(std::vector& part_options) +{ + PrintRegionConfig config; + part_options = config.keys(); +} + +void get_object_options(std::vector& object_options) +{ + PrintRegionConfig reg_config; + object_options = reg_config.keys(); + PrintObjectConfig obj_config; + std::vector obj_options = obj_config.keys(); + object_options.insert(object_options.end(), obj_options.begin(), obj_options.end()); +} + +// category -> vector ( option ; label ) +typedef std::map< std::string, std::vector< std::pair > > settings_menu_hierarchy; +void get_options_menu(settings_menu_hierarchy& settings_menu, bool is_part) +{ + PrintRegionConfig reg_config; + auto options = reg_config.keys(); + if (!is_part) { + PrintObjectConfig obj_config; + std::vector obj_options = obj_config.keys(); + options.insert(options.end(), obj_options.begin(), obj_options.end()); + } + + DynamicPrintConfig config; + for (auto& option : options) + { + auto const opt = config.def()->get(option); + auto category = opt->category; + if (category.empty()) continue; + + std::pair option_label(option, opt->label); + std::vector< std::pair > new_category; + auto& cat_opt_label = settings_menu.find(category) == settings_menu.end() ? new_category : settings_menu.at(category); + cat_opt_label.push_back(option_label); + if (cat_opt_label.size() == 1) + settings_menu[category] = cat_opt_label; + } +} + // C++ class Slic3r::DynamicPrintConfig, initially empty. std::shared_ptr default_config = std::make_shared(); std::shared_ptr config = std::make_shared(); @@ -83,7 +127,12 @@ void set_event_remove_object(const int& event){ void init_mesh_icons(){ m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); m_icon_solidmesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); + + // init icon for manifold warning m_icon_manifold_warning = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); + + // init bitmap for "Add Settings" context menu + m_bmp_cog = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG); } bool is_parts_changed(){return m_parts_changed;} @@ -146,11 +195,17 @@ wxBoxSizer* content_objects_list(wxWindow *win) }); - m_objects_ctrl->Bind(wxEVT_KEY_DOWN, [](wxKeyEvent& event) + m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) { if (event.GetKeyCode() == WXK_TAB) m_objects_ctrl->Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward); - else + else if (event.GetKeyCode() == WXK_DELETE +#ifdef __WXOSX__ + || event.GetKeyCode() == WXK_BACK +#endif //__WXOSX__ + ) + remove(); + else event.Skip(); }); @@ -422,6 +477,8 @@ void add_object_settings(wxWindow* parent, wxBoxSizer* sizer) optgroup->disable(); get_optgroups().push_back(optgroup); // ogFrequentlyObjectSettings + +// add_current_settings(); } @@ -582,19 +639,39 @@ void object_ctrl_selection_changed() } } -wxMenu *create_add_part_popupmenu(){ +void get_settings_choice(wxMenu *menu, int id, bool is_part) +{ + auto category_name = menu->GetLabel(id); + + wxArrayString names; + + settings_menu_hierarchy settings_menu; + get_options_menu(settings_menu, is_part); + for (auto cat : settings_menu) + { + if (_(cat.first) == category_name) { + for (auto& pair : cat.second) + names.Add(_(pair.second)); + break; + } + } + + wxArrayInt selections; + auto index = wxGetMultipleChoices(selections, _(L("Select showing settings")), category_name, names); +} + +wxMenu *create_add_part_popupmenu() +{ wxMenu *menu = new wxMenu; - wxWindowID config_id_base = wxWindow::NewControlId(3); + wxWindowID config_id_base = wxWindow::NewControlId(4); menu->Append(config_id_base, _(L("Add part"))); - menu->AppendSeparator(); menu->Append(config_id_base + 1, _(L("Add modifier"))); - menu->AppendSeparator(); - menu->AppendCheckItem(config_id_base + 2, _(L("Add generic"))); + menu->Append(config_id_base + 2, _(L("Add generic"))); wxWindow* win = get_tab_panel()->GetPage(0); - menu->Bind(wxEVT_MENU, [config_id_base, win](wxEvent &event){ + menu->Bind(wxEVT_MENU, [config_id_base, win, menu](wxEvent &event){ switch (event.GetId() - config_id_base) { case 0: on_btn_load(win); @@ -605,39 +682,46 @@ wxMenu *create_add_part_popupmenu(){ case 2: on_btn_load(win, true, true); break; - default: - break; + default:{ + get_settings_choice(menu, event.GetId(), false); + break;} } }); + + menu->AppendSeparator(); + // Append settings popupmenu + auto menu_item = new wxMenuItem(menu, config_id_base + 3, _(L("Add settings"))); + menu_item->SetBitmap(m_bmp_cog); + + auto sub_menu = create_add_settings_popupmenu(false); + + menu_item->SetSubMenu(sub_menu); + menu->Append(menu_item); + return menu; } -wxMenu *create_add_settings_popupmenu() +wxMenu *create_add_settings_popupmenu(bool is_part) { wxMenu *menu = new wxMenu; - auto categories = get_category_icon(); - int category_cnt = categories.size(); - wxWindowID config_id_base = wxWindow::NewControlId(category_cnt); + auto categories = get_category_icon(); - int inc = 0; - for (auto cat : categories) + settings_menu_hierarchy settings_menu; + get_options_menu(settings_menu, is_part); + + for (auto cat : settings_menu) { - auto menu_item = new wxMenuItem(menu, config_id_base + inc, _(cat.first)); - menu_item->SetBitmap(cat.second); - - auto sub_menu = new wxMenu; - sub_menu->AppendCheckItem(wxID_ANY, "Check#1"); - sub_menu->AppendCheckItem(wxID_ANY, "Check#2"); - sub_menu->AppendCheckItem(wxID_ANY, "Check#3"); - sub_menu->AppendCheckItem(wxID_ANY, "Check#4"); - - menu_item->SetSubMenu(sub_menu); - + auto menu_item = new wxMenuItem(menu, wxID_ANY/*config_id_base + inc*/, _(cat.first)); + menu_item->SetBitmap(categories.find(cat.first) == categories.end() ? + wxNullBitmap : categories.at(cat.first)); menu->Append(menu_item); - inc++; } + menu->Bind(wxEVT_MENU, [menu](wxEvent &event) { + get_settings_choice(menu, event.GetId(), true); + }); + return menu; } @@ -660,7 +744,7 @@ void object_ctrl_context_menu() // obj_idx = m_objects_model->GetIdByItem(parent); // auto volume_id = m_objects_model->GetVolumeIdByItem(item); // if (volume_id < 0) return; - auto menu = create_add_settings_popupmenu(); + auto menu = create_add_settings_popupmenu(true); get_tab_panel()->GetPage(0)->PopupMenu(menu); } } diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 8d54fa29b..532614cab 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -6,6 +6,7 @@ class wxSizer; class wxBoxSizer; class wxString; class wxArrayString; +class wxMenu; namespace Slic3r { class ModelObject; @@ -15,9 +16,10 @@ namespace GUI { enum ogGroup{ ogFrequentlyChangingParameters, ogFrequentlyObjectSettings, - ogObjectSettings, - ogObjectMovers, - ogPartSettings + ogCurrentSettings +// ogObjectSettings, +// ogObjectMovers, +// ogPartSettings }; enum LambdaTypeIDs{ @@ -43,6 +45,9 @@ void add_objects_list(wxWindow* parent, wxBoxSizer* sizer); void add_object_settings(wxWindow* parent, wxBoxSizer* sizer); void show_collpane_settings(bool expert_mode); +wxMenu *create_add_settings_popupmenu(bool is_part); +wxMenu *create_add_part_popupmenu(); + // Add object to the list //void add_object(const std::string &name); void add_object_to_list(const std::string &name, ModelObject* model_object); From 97a25cf6080a18c6a25eb846411e1adb75568d7c Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 24 Jul 2018 12:15:36 +0200 Subject: [PATCH 063/119] Work with model objects like reference (from/to perl side) --- lib/Slic3r/GUI/Plater.pm | 1 + xs/src/slic3r/GUI/GUI.cpp | 2 ++ xs/src/slic3r/GUI/GUI.hpp | 1 + xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 30 +++++++++++++++------------ xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 2 ++ xs/xsp/GUI.xsp | 2 ++ 6 files changed, 25 insertions(+), 13 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 661a81a64..ac54e67d8 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -449,6 +449,7 @@ sub new { my $expert_mode_part_sizer = Wx::BoxSizer->new(wxVERTICAL); Slic3r::GUI::add_expert_mode_part( $self->{right_panel}, $expert_mode_part_sizer, + $self->{model}, $self->{event_object_selection_changed}, $self->{event_object_settings_changed}, $self->{event_remove_object}); diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 83c428ea1..72efd7f29 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -893,6 +893,7 @@ wxString from_u8(const std::string &str) } void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, + Model &model, int event_object_selection_changed, int event_object_settings_changed, int event_remove_object) @@ -900,6 +901,7 @@ void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, set_event_object_selection_changed(event_object_selection_changed); set_event_object_settings_changed(event_object_settings_changed); set_event_remove_object(event_remove_object); + set_objects_from_model(model); init_mesh_icons(); // wxWindowUpdateLocker noUpdates(parent); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 58a927cf6..8199a1349 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -188,6 +188,7 @@ wxString L_str(const std::string &str); wxString from_u8(const std::string &str); void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, + Model &model, int event_object_selection_changed, int event_object_settings_changed, int event_remove_object); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 26e4fbbf7..4587de6ad 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -40,7 +40,7 @@ int m_selected_object_id = -1; bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select() // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler // calls this method again and again and again -ModelObjectPtrs m_objects; +ModelObjectPtrs* m_objects; int m_event_object_selection_changed = 0; int m_event_object_settings_changed = 0; @@ -124,6 +124,10 @@ void set_event_remove_object(const int& event){ m_event_remove_object = event; } +void set_objects_from_model(Model &model) { + m_objects = &(model.objects); +} + void init_mesh_icons(){ m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); m_icon_solidmesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); @@ -297,7 +301,7 @@ void update_after_moving() Point3 l = m_last_coords; auto d = Pointf3(m.x - l.x, m.y - l.y, m.z - l.z); - auto volume = m_objects[m_selected_object_id]->volumes[volume_id]; + auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; volume->mesh.translate(d.x,d.y,d.z); m_last_coords = m; @@ -546,11 +550,11 @@ void add_object_to_list(const std::string &name, ModelObject* model_object) m_objects_model->SetValue(variant, item, 0); } + ModelObjectPtrs* objects = m_objects; // part_selection_changed(); #ifdef __WXMSW__ object_ctrl_selection_changed(); #endif //__WXMSW__ - m_objects.push_back(model_object); } void delete_object_from_list() @@ -856,9 +860,9 @@ void on_btn_load(wxWindow* parent, bool is_modifier /*= false*/, bool is_lambda/ if (obj_idx < 0) return; wxArrayString part_names; if (is_lambda) - load_lambda(parent, m_objects[obj_idx], part_names, is_modifier); + load_lambda(parent, (*m_objects)[obj_idx], part_names, is_modifier); else - load_part(parent, m_objects[obj_idx], part_names, is_modifier); + load_part(parent, (*m_objects)[obj_idx], part_names, is_modifier); parts_changed(obj_idx); @@ -879,11 +883,11 @@ void on_btn_del() auto volume_id = m_objects_model->GetVolumeIdByItem(item); if (volume_id < 0) return; - auto volume = m_objects[m_selected_object_id]->volumes[volume_id]; + auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; // if user is deleting the last solid part, throw error int solid_cnt = 0; - for (auto vol : m_objects[m_selected_object_id]->volumes) + for (auto vol : (*m_objects)[m_selected_object_id]->volumes) if (!vol->modifier) ++solid_cnt; if (!volume->modifier && solid_cnt == 1) { @@ -891,7 +895,7 @@ void on_btn_del() return; } - m_objects[m_selected_object_id]->delete_volume(volume_id); + (*m_objects)[m_selected_object_id]->delete_volume(volume_id); m_parts_changed = true; parts_changed(m_selected_object_id); @@ -912,7 +916,7 @@ void on_btn_split() if (volume_id < 0) return; - auto volume = m_objects[m_selected_object_id]->volumes[volume_id]; + auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; DynamicPrintConfig& config = get_preset_bundle()->prints.get_edited_preset().config; auto nozzle_dmrs_cnt = config.option("nozzle_diameter")->values.size(); if (volume->split(nozzle_dmrs_cnt) > 1) { @@ -929,7 +933,7 @@ void on_btn_move_up(){ auto volume_id = m_objects_model->GetVolumeIdByItem(item); if (volume_id < 0) return; - auto& volumes = m_objects[m_selected_object_id]->volumes; + auto& volumes = (*m_objects)[m_selected_object_id]->volumes; if (0 < volume_id && volume_id < volumes.size()) { std::swap(volumes[volume_id - 1], volumes[volume_id]); m_parts_changed = true; @@ -948,7 +952,7 @@ void on_btn_move_down(){ auto volume_id = m_objects_model->GetVolumeIdByItem(item); if (volume_id < 0) return; - auto& volumes = m_objects[m_selected_object_id]->volumes; + auto& volumes = (*m_objects)[m_selected_object_id]->volumes; if (0 <= volume_id && volume_id+1 < volumes.size()) { std::swap(volumes[volume_id + 1], volumes[volume_id]); m_parts_changed = true; @@ -975,13 +979,13 @@ void parts_changed(int obj_idx) void update_settings_value() { auto og = get_optgroup(ogFrequentlyObjectSettings); - if (m_selected_object_id < 0 || m_objects.size() <= m_selected_object_id) { + if (m_selected_object_id < 0 || m_objects->size() <= m_selected_object_id) { og->set_value("scale_x", 0); og->set_value("scale_y", 0); og->set_value("scale_z", 0); return; } - auto bb_size = m_objects[m_selected_object_id]->instance_bounding_box(0).size(); + auto bb_size = (*m_objects)[m_selected_object_id]->instance_bounding_box(0).size(); og->set_value("scale_x", int(bb_size.x+0.5)); og->set_value("scale_y", int(bb_size.y+0.5)); og->set_value("scale_z", int(bb_size.z+0.5)); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 532614cab..4f1c15e3a 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -10,6 +10,7 @@ class wxMenu; namespace Slic3r { class ModelObject; +class Model; namespace GUI { @@ -73,6 +74,7 @@ void init_mesh_icons(); void set_event_object_selection_changed(const int& event); void set_event_object_settings_changed(const int& event); void set_event_remove_object(const int& event); +void set_objects_from_model(Model &model); bool is_parts_changed(); bool is_part_settings_changed(); diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 470bbcdd2..98d3169bd 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -88,11 +88,13 @@ void add_frequently_changed_parameters(SV *ui_parent, SV *ui_sizer, SV *ui_p_siz (wxFlexGridSizer*)wxPli_sv_2_object(aTHX_ ui_p_sizer, "Wx::FlexGridSizer")); %}; void add_expert_mode_part( SV *ui_parent, SV *ui_sizer, + Model *model, int event_object_selection_changed, int event_object_settings_changed, int event_remove_object) %code%{ Slic3r::GUI::add_expert_mode_part( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), + *model, event_object_selection_changed, event_object_settings_changed, event_remove_object); %}; From 60224415deddd2169562b7270046383425535a66 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 24 Jul 2018 18:39:40 +0200 Subject: [PATCH 064/119] Prototype for adding object/part settings to panel --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 95 +++++++++++++++++++-------- xs/src/slic3r/GUI/OptionsGroup.cpp | 12 ++++ xs/src/slic3r/GUI/OptionsGroup.hpp | 21 ++++-- 3 files changed, 96 insertions(+), 32 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 4587de6ad..a96f8e620 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -40,7 +40,10 @@ int m_selected_object_id = -1; bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select() // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler // calls this method again and again and again -ModelObjectPtrs* m_objects; +ModelObjectPtrs* m_objects; +std::shared_ptr m_config; +std::shared_ptr m_default_config; +wxBoxSizer* m_option_sizer = nullptr; int m_event_object_selection_changed = 0; int m_event_object_settings_changed = 0; @@ -67,24 +70,7 @@ inline t_category_icon& get_category_icon() { return CATEGORY_ICON; } -void get_part_options(std::vector& part_options) -{ - PrintRegionConfig config; - part_options = config.keys(); -} - -void get_object_options(std::vector& object_options) -{ - PrintRegionConfig reg_config; - object_options = reg_config.keys(); - PrintObjectConfig obj_config; - std::vector obj_options = obj_config.keys(); - object_options.insert(object_options.end(), obj_options.begin(), obj_options.end()); -} - -// category -> vector ( option ; label ) -typedef std::map< std::string, std::vector< std::pair > > settings_menu_hierarchy; -void get_options_menu(settings_menu_hierarchy& settings_menu, bool is_part) +std::vector get_options(const bool is_part) { PrintRegionConfig reg_config; auto options = reg_config.keys(); @@ -93,6 +79,14 @@ void get_options_menu(settings_menu_hierarchy& settings_menu, bool is_part) std::vector obj_options = obj_config.keys(); options.insert(options.end(), obj_options.begin(), obj_options.end()); } + return options; +} + +// category -> vector ( option ; label ) +typedef std::map< std::string, std::vector< std::pair > > settings_menu_hierarchy; +void get_options_menu(settings_menu_hierarchy& settings_menu, bool is_part) +{ + auto options = get_options(is_part); DynamicPrintConfig config; for (auto& option : options) @@ -110,10 +104,6 @@ void get_options_menu(settings_menu_hierarchy& settings_menu, bool is_part) } } -// C++ class Slic3r::DynamicPrintConfig, initially empty. -std::shared_ptr default_config = std::make_shared(); -std::shared_ptr config = std::make_shared(); - void set_event_object_selection_changed(const int& event){ m_event_object_selection_changed = event; } @@ -476,6 +466,9 @@ void add_object_settings(wxWindow* parent, wxBoxSizer* sizer) def.default_value = new ConfigOptionBool{ false }; optgroup->append_single_option_line(Option(def, "place_on_bed")); + m_option_sizer = new wxBoxSizer(wxVERTICAL); + optgroup->sizer->Add(m_option_sizer, 1, wxEXPAND | wxLEFT, 5); + sizer->Add(optgroup->sizer, 0, wxEXPAND | wxLEFT | wxTOP, 20); optgroup->disable(); @@ -651,17 +644,55 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) settings_menu_hierarchy settings_menu; get_options_menu(settings_menu, is_part); - for (auto cat : settings_menu) + std::vector< std::pair > *settings_list = nullptr; + for (auto& cat : settings_menu) { - if (_(cat.first) == category_name) { + if (_(cat.first) == category_name) { for (auto& pair : cat.second) names.Add(_(pair.second)); + settings_list = &cat.second; break; } } + if (!settings_list) + return; wxArrayInt selections; auto index = wxGetMultipleChoices(selections, _(L("Select showing settings")), category_name, names); + + auto szr = m_option_sizer; + szr->Clear(true); + auto parent = get_optgroup(ogFrequentlyObjectSettings)->parent(); + auto config = m_config; + auto extra_column = [parent](const Line& line) + { + auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line + + auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("erase.png")), wxBITMAP_TYPE_PNG), + wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); +// EVT_BUTTON($self, $btn, sub{ +// $self->{config}->erase($opt_key); +// $self->{on_change}->() if $self->{on_change}; +// wxTheApp->CallAfter(sub{ $self->update_optgroup }); +// }); + return btn; + }; + + auto optgroup = std::make_shared(parent, category_name, m_default_config.get(), false, ogDEFAULT, extra_column); + + optgroup->label_width = 180; + + for (auto sel : selections) + { + Option option = optgroup->get_option((*settings_list)[sel].first); + option.opt.width = 70; + optgroup->append_single_option_line(option); +// auto str = new wxStaticText(parent, wxID_ANY, "la-la"); +// m_option_sizer->Add(str, /*0*/1, wxEXPAND | wxALL, 10); + } + m_option_sizer->Add(optgroup->sizer, /*0*/1, wxEXPAND | wxALL, 0); + get_right_panel()->Refresh(); + get_right_panel()->GetParent()->Layout();// Refresh(); } wxMenu *create_add_part_popupmenu() @@ -997,13 +1028,25 @@ void part_selection_changed() int obj_idx = -1; if (item) { - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) + auto og = get_optgroup(ogFrequentlyObjectSettings); + bool is_part = false; + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { obj_idx = m_objects_model->GetIdByItem(item); + og->set_name(" "+ _(L("Object Settings")) + " "); + m_config = std::make_shared((*m_objects)[obj_idx]->config); + } else { auto parent = m_objects_model->GetParent(item); // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene obj_idx = m_objects_model->GetIdByItem(parent); + og->set_name(" "+ _(L("Part Settings")) + " "); + is_part = true; + auto volume_id = m_objects_model->GetVolumeIdByItem(item); + m_config = std::make_shared((*m_objects)[obj_idx]->volumes[volume_id]->config); } + + auto config = m_config; + m_default_config = std::make_shared(*DynamicPrintConfig::new_from_defaults_keys(get_options(is_part))); } m_selected_object_id = obj_idx; diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index ca612e95c..c289f25db 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -153,6 +153,18 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* m_panel->Layout(); #endif /* __WXGTK__ */ + // if we have an extra column, build it + if (extra_column) { + if (extra_column) { + grid_sizer->Add(extra_column(line), 0, wxALIGN_CENTER_VERTICAL, 0); + } + else { + // if the callback provides no sizer for the extra cell, put a spacer + grid_sizer->AddSpacer(1); + } + } + + // Build a label if we have it wxStaticText* label=nullptr; if (label_width != 0) { diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index 6697ed75a..949f8d8b3 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -33,7 +33,6 @@ enum ogDrawFlag{ /// Widget type describes a function object that returns a wxWindow (our widget) and accepts a wxWidget (parent window). using widget_t = std::function;//!std::function; -using column_t = std::function; //auto default_label_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT); //GetSystemColour //auto modified_label_clr = *new wxColour(254, 189, 101); @@ -76,10 +75,13 @@ private: std::vector m_extra_widgets;//! {std::vector()}; }; +using column_t = std::function;//std::function; + using t_optionfield_map = std::map; using t_opt_map = std::map< std::string, std::pair >; class OptionsGroup { + wxStaticBox* stb; public: const bool staticbox {true}; const wxString title {wxString("")}; @@ -136,14 +138,20 @@ public: return true; } + void set_name(const wxString& new_name) { + stb->SetLabel(new_name); + } + inline void enable() { for (auto& field : m_fields) field.second->enable(); } inline void disable() { for (auto& field : m_fields) field.second->disable(); } void set_flag(ogDrawFlag flag) { m_flag = flag; } void set_grid_vgap(int gap) { m_grid_sizer->SetVGap(gap); } - OptionsGroup(wxWindow* _parent, const wxString& title, bool is_tab_opt=false, ogDrawFlag flag = ogDEFAULT) : - m_parent(_parent), title(title), m_is_tab_opt(is_tab_opt), staticbox(title!=""), m_flag(flag) { - auto stb = new wxStaticBox(_parent, wxID_ANY, title); + OptionsGroup( wxWindow* _parent, const wxString& title, bool is_tab_opt = false, + ogDrawFlag flag = ogDEFAULT, column_t extra_clmn = nullptr) : + m_parent(_parent), title(title), m_is_tab_opt(is_tab_opt), + staticbox(title!=""), m_flag(flag), extra_column(extra_clmn){ + stb = new wxStaticBox(_parent, wxID_ANY, title); stb->SetFont(bold_font()); sizer = (staticbox ? new wxStaticBoxSizer(stb/*new wxStaticBox(_parent, wxID_ANY, title)*/, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); auto num_columns = 1U; @@ -199,8 +207,9 @@ protected: class ConfigOptionsGroup: public OptionsGroup { public: - ConfigOptionsGroup(wxWindow* parent, const wxString& title, DynamicPrintConfig* _config = nullptr, bool is_tab_opt = false, ogDrawFlag flag = ogDEFAULT) : - OptionsGroup(parent, title, is_tab_opt, flag), m_config(_config) {} + ConfigOptionsGroup( wxWindow* parent, const wxString& title, DynamicPrintConfig* _config = nullptr, + bool is_tab_opt = false, ogDrawFlag flag = ogDEFAULT, column_t extra_clmn = nullptr) : + OptionsGroup(parent, title, is_tab_opt, flag, extra_clmn), m_config(_config) {} /// reference to libslic3r config, non-owning pointer (?). DynamicPrintConfig* m_config {nullptr}; From ac9ba61f06a75ef504612dcadc50429c302c0091 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 25 Jul 2018 16:13:20 +0200 Subject: [PATCH 065/119] Correct updating for settings list of the object/part --- resources/icons/add_object.png | Bin 0 -> 591 bytes resources/icons/lambda_.png | Bin 0 -> 422 bytes resources/icons/object.png | Bin 0 -> 618 bytes xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 174 +++++++++++++++++++------- xs/src/slic3r/GUI/wxExtensions.cpp | 4 +- 5 files changed, 132 insertions(+), 46 deletions(-) create mode 100644 resources/icons/add_object.png create mode 100644 resources/icons/lambda_.png create mode 100644 resources/icons/object.png diff --git a/resources/icons/add_object.png b/resources/icons/add_object.png new file mode 100644 index 0000000000000000000000000000000000000000..40059f5ac0de3b5c5db4ab492b4de5952fe6f25d GIT binary patch literal 591 zcmV-V0Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&0pv+UK~y+TRg+Jv zaZwb;_qpT_82B?J1BT2bLng{V$`_!ND4Cd;%D`NF4&T6gm4pnGWMV=LUdg~r`Lo{h zJg<%WtJPlnS!+GEbM{g9`(19g8$)wA{FQh-E=nnx&*#*1eYsppAP``VS@k)%*=!^n z4s$RTi%GRwW!`KypB*BL#e$lK83se45DPHaZnrFg)oLZD(@AEt8S8etovYjJ7Kg(j zDxFSKNF)-n+wGoX|Bw86I@B7ChLlPr_IJBoX|-C&6@@~f@N9h#U$56+CSW`svtL7l zPNzc=F&GS3csw2qfQOaKsAMw9Je$qpzOctI-Xn%#s9y#U zU;;zJJx=Nr25};|idCxm+$4iA27wAjIj|rivR4Ol{@9%G}=3k_d2K_Gs+%j!~9N?mOyPx#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&0Xs=VK~y+Tjgm2n zgFqOCCn9E}5j!tnX<@0wf?!CO%1S#g5EX?~!3%f?58x4UfDqDpgf!m4MfaJ1bVHD^ z4;-HVyl?zx95#GZ-}l^2S^y~I`#xiAydx3I1?6lw}FC0BpBg?w;zp4rAN4x~{{Fz;3tup0wZZ(U0eOj^o(2UDq`Nv@6s( zKyH>{7|1;yk1WgLIHuz5cC#!ChJk+T;c~gCstQw86&NZCf^fZFVMahv6spcjl4P^_ zilPVxYomoc&uMA|<|BJm(=?`Ou2w78b?^5(Dzy8t`$d3sKA*`T%>f+12Ov#TjFhGy z^4AhA@TM6+ngS!BY1(skK?G2m1LMP(BuO~9SBavCI^8HrLmc?0(919kzv>=a#6l&K Q^Z)<=07*qoM6N<$g5_(f{r~^~ literal 0 HcmV?d00001 diff --git a/resources/icons/object.png b/resources/icons/object.png new file mode 100644 index 0000000000000000000000000000000000000000..ff4974a532b083cd7e8f741b1a2c81d2d1184045 GIT binary patch literal 618 zcmV-w0+s!VP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&0sl!vK~y+TjZ?qN zfl(Ab@9ReOv6_rTgp_1pmrdb*_c^@fGkkqd zz1{2F=Q;PBdmhT;@emROD2hU=s`4J#@Aq`S-^uIsz9U4>=aW}xz~=;?qUCZ)y+CKFw+SIXz}R4f)L7!1CdL{iI{#A>w?jYdOwJRae8yG6ZT7xVcXM~uVaAX=@K z@caFI-fT9-X0zclrCP0u#bQCZT#hoC4EcP%cm7wol0!P3?j0dI9*;B_47kETAVBJN zyCt*P%%sm&0EoYVw)A>ESu7S>uh*pFmQ*T5NEDC9xdK@tzXg)w!>!$Jmv4+lqlAhR ziNx!Ia5yYxvl-f9j7B3-E|-PV=@gMjM8sk-;cz%asZ;;VkXx=~!dvL&o23i%aYPZ{TI-Mw+ z&62b;)oL}`?RI1|8p&WV@E$Rofpb2esnhAOBNh2b; m_config; +std::shared_ptr m_config; std::shared_ptr m_default_config; wxBoxSizer* m_option_sizer = nullptr; +// option groups for settings +std::vector > m_og_settings; + int m_event_object_selection_changed = 0; int m_event_object_settings_changed = 0; int m_event_remove_object = 0; @@ -119,8 +122,8 @@ void set_objects_from_model(Model &model) { } void init_mesh_icons(){ - m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); - m_icon_solidmesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); + m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("lambda_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); + m_icon_solidmesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); // init icon for manifold warning m_icon_manifold_warning = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); @@ -636,63 +639,136 @@ void object_ctrl_selection_changed() } } +//update_optgroup +void update_settings_list() +{ + auto parent = get_optgroup(ogFrequentlyObjectSettings)->parent(); +// There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/Slic3r/issues/898 and https://github.com/prusa3d/Slic3r/issues/952. +// The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason, +// we will Thaw the UI prematurely on Linux. This means destroing the no_updates object prematurely. +#ifdef __linux__ + std::unique_ptr no_updates(new wxWindowUpdateLocker(this)); +#else + wxWindowUpdateLocker noUpdates(parent); +#endif + + m_option_sizer->Clear(true); + + if (m_config) + { + auto extra_column = [parent](const Line& line) + { + auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line + + auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("erase.png")), wxBITMAP_TYPE_PNG), + wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + btn->Bind(wxEVT_BUTTON, [opt_key](wxEvent &event){ + (*m_config)->erase(opt_key); + wxTheApp->CallAfter([]() { update_settings_list(); }); + }); + return btn; + }; + + std::map> cat_options; + auto opt_keys = (*m_config)->keys(); + if (opt_keys.size() == 1 && opt_keys[0] == "extruder") + return; + + for (auto& opt_key : opt_keys) { + auto category = (*m_config)->def()->get(opt_key)->category; + if (category.empty()) continue; + + std::vector< std::string > new_category; + + auto& cat_opt = cat_options.find(category) == cat_options.end() ? new_category : cat_options.at(category); + cat_opt.push_back(opt_key); + if (cat_opt.size() == 1) + cat_options[category] = cat_opt; + } + + + m_og_settings.resize(0); + for (auto& cat : cat_options) { + if (cat.second.size() == 1 && cat.second[0] == "extruder") + continue; + + auto optgroup = std::make_shared(parent, cat.first, *m_config, false, ogDEFAULT, extra_column); + optgroup->label_width = 100; + optgroup->sidetext_width = 70; + + for (auto& opt : cat.second) + { + if (opt == "extruder") + continue; + Option option = optgroup->get_option(opt); + option.opt.width = 70; + optgroup->append_single_option_line(option); + } + optgroup->reload_config(); + m_option_sizer->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 0); + m_og_settings.push_back(optgroup); + } + } + +#ifdef __linux__ + no_updates.reset(nullptr); +#endif + + get_right_panel()->Refresh(); + get_right_panel()->GetParent()->Layout();; +} + void get_settings_choice(wxMenu *menu, int id, bool is_part) { auto category_name = menu->GetLabel(id); wxArrayString names; + wxArrayInt selections; settings_menu_hierarchy settings_menu; get_options_menu(settings_menu, is_part); std::vector< std::pair > *settings_list = nullptr; + + auto opt_keys = (*m_config)->keys(); + for (auto& cat : settings_menu) { if (_(cat.first) == category_name) { - for (auto& pair : cat.second) + int sel = 0; + for (auto& pair : cat.second) { names.Add(_(pair.second)); + if (find(opt_keys.begin(), opt_keys.end(), pair.first) != opt_keys.end()) + selections.Add(sel); + sel++; + } settings_list = &cat.second; break; } - } + } + if (!settings_list) return; - wxArrayInt selections; - auto index = wxGetMultipleChoices(selections, _(L("Select showing settings")), category_name, names); - - auto szr = m_option_sizer; - szr->Clear(true); - auto parent = get_optgroup(ogFrequentlyObjectSettings)->parent(); - auto config = m_config; - auto extra_column = [parent](const Line& line) - { - auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line - - auto btn = new wxBitmapButton(parent, wxID_ANY, wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("erase.png")), wxBITMAP_TYPE_PNG), - wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); -// EVT_BUTTON($self, $btn, sub{ -// $self->{config}->erase($opt_key); -// $self->{on_change}->() if $self->{on_change}; -// wxTheApp->CallAfter(sub{ $self->update_optgroup }); -// }); - return btn; - }; - - auto optgroup = std::make_shared(parent, category_name, m_default_config.get(), false, ogDEFAULT, extra_column); - - optgroup->label_width = 180; + if (wxGetMultipleChoices(selections, _(L("Select showing settings")), category_name, names) ==0 ) + return; + std::vector selected_options; for (auto sel : selections) + selected_options.push_back((*settings_list)[sel].first); + + for (auto& setting:(*settings_list) ) { - Option option = optgroup->get_option((*settings_list)[sel].first); - option.opt.width = 70; - optgroup->append_single_option_line(option); -// auto str = new wxStaticText(parent, wxID_ANY, "la-la"); -// m_option_sizer->Add(str, /*0*/1, wxEXPAND | wxALL, 10); + auto& opt_key = setting.first; + if (find(opt_keys.begin(), opt_keys.end(), opt_key) != opt_keys.end() && + find(selected_options.begin(), selected_options.end(), opt_key) == selected_options.end()) + (*m_config)->erase(opt_key); + + if(find(opt_keys.begin(), opt_keys.end(), opt_key) == opt_keys.end() && + find(selected_options.begin(), selected_options.end(), opt_key) != selected_options.end()) + (*m_config)->set_key_value(opt_key, m_default_config.get()->option(opt_key)->clone()); } - m_option_sizer->Add(optgroup->sizer, /*0*/1, wxEXPAND | wxALL, 0); - get_right_panel()->Refresh(); - get_right_panel()->GetParent()->Layout();// Refresh(); + + update_settings_list(); } wxMenu *create_add_part_popupmenu() @@ -700,9 +776,14 @@ wxMenu *create_add_part_popupmenu() wxMenu *menu = new wxMenu; wxWindowID config_id_base = wxWindow::NewControlId(4); - menu->Append(config_id_base, _(L("Add part"))); - menu->Append(config_id_base + 1, _(L("Add modifier"))); - menu->Append(config_id_base + 2, _(L("Add generic"))); + std::vector menu_items = { L("Add part"), L("Add modifier"), L("Add generic") }; + int i = 0; + for (auto& item : menu_items) { + auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item)); + menu_item->SetBitmap(i == 0 ? m_icon_solidmesh : m_icon_modifiermesh); + menu->Append(menu_item); + i++; + } wxWindow* win = get_tab_panel()->GetPage(0); @@ -1032,22 +1113,27 @@ void part_selection_changed() bool is_part = false; if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { obj_idx = m_objects_model->GetIdByItem(item); - og->set_name(" "+ _(L("Object Settings")) + " "); - m_config = std::make_shared((*m_objects)[obj_idx]->config); + og->set_name(" " + _(L("Object Settings")) + " "); + m_config = std::make_shared(&(*m_objects)[obj_idx]->config); } else { auto parent = m_objects_model->GetParent(item); // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene obj_idx = m_objects_model->GetIdByItem(parent); - og->set_name(" "+ _(L("Part Settings")) + " "); + og->set_name(" " + _(L("Part Settings")) + " "); is_part = true; auto volume_id = m_objects_model->GetVolumeIdByItem(item); - m_config = std::make_shared((*m_objects)[obj_idx]->volumes[volume_id]->config); + m_config = std::make_shared(&(*m_objects)[obj_idx]->volumes[volume_id]->config); } auto config = m_config; m_default_config = std::make_shared(*DynamicPrintConfig::new_from_defaults_keys(get_options(is_part))); } + else + m_config = nullptr; + + update_settings_list(); + m_selected_object_id = obj_idx; update_settings_value(); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 23a87af9e..422c999d1 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -349,7 +349,7 @@ void PrusaCollapsiblePaneMSW::Collapse(bool collapse) // ---------------------------------------------------------------------------- void PrusaObjectDataViewModelNode::set_object_action_icon() { - m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG); + m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("add_object.png")), wxBITMAP_TYPE_PNG); } void PrusaObjectDataViewModelNode::set_part_action_icon() { m_action_icon = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG); @@ -391,7 +391,7 @@ wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_ if (root->GetChildren().Count() == 0) { - auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); + auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, 0); root->Append(node); // notify control From ef0d667d6c9d87b086702f35e8d399129e95e193 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 25 Jul 2018 17:48:15 +0200 Subject: [PATCH 066/119] Extruder updating --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 45bbd9267..252dcec26 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -165,8 +165,9 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->AppendTextColumn(_(L("Scale")), 2, wxDATAVIEW_CELL_INERT, 55, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); - // column 2 of the view control: + // column 3 of the view control: wxArrayString choices; + choices.Add("default"); choices.Add("1"); choices.Add("2"); choices.Add("3"); @@ -177,6 +178,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) new wxDataViewColumn(_(L("Extruder")), c, 3, 60, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); m_objects_ctrl->AppendColumn(column3); + // column 4 of the view control: m_objects_ctrl->AppendBitmapColumn("", 4, wxDATAVIEW_CELL_INERT, 25, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); @@ -206,6 +208,23 @@ wxBoxSizer* content_objects_list(wxWindow *win) event.Skip(); }); + m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) + { + if (event.GetColumn() == 3) + { + if (!*m_config) + return; + wxVariant variant; + m_objects_model->GetValue(variant, event.GetItem(), 3); + auto str = variant.GetString(); + int extruder = str.size() > 1 ? 0 : atoi(str.c_str()); + +// if ((*m_config)->has("extruder")) + auto config = m_config; + (*m_config)->set_key_value("extruder", new ConfigOptionInt(extruder)); + } + }); + return objects_sz; } From da18e25dfb917a2e165973160b3340a46888a4a8 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 26 Jul 2018 10:59:03 +0200 Subject: [PATCH 067/119] Added callback for 3dScene updating after extruder changing --- lib/Slic3r/GUI/MainFrame.pm | 13 +++++++++-- lib/Slic3r/GUI/Plater.pm | 4 +++- resources/icons/erase.png | Bin 0 -> 488 bytes resources/icons/exclamation_mark_.png | Bin 0 -> 327 bytes xs/src/slic3r/GUI/GUI.cpp | 4 +++- xs/src/slic3r/GUI/GUI.hpp | 3 ++- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 31 ++++++++++++++------------ xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 1 + xs/xsp/GUI.xsp | 6 +++-- 9 files changed, 41 insertions(+), 21 deletions(-) create mode 100644 resources/icons/erase.png create mode 100644 resources/icons/exclamation_mark_.png diff --git a/lib/Slic3r/GUI/MainFrame.pm b/lib/Slic3r/GUI/MainFrame.pm index 1465c1215..6cf80f24a 100644 --- a/lib/Slic3r/GUI/MainFrame.pm +++ b/lib/Slic3r/GUI/MainFrame.pm @@ -31,6 +31,8 @@ our $OBJECT_SELECTION_CHANGED_EVENT = Wx::NewEventType; our $OBJECT_SETTINGS_CHANGED_EVENT = Wx::NewEventType; # 5) To inform about a remove of object our $OBJECT_REMOVE_EVENT = Wx::NewEventType; +# 6) To inform about a update of the scene +our $UPDATE_SCENE_EVENT = Wx::NewEventType; sub new { my ($class, %params) = @_; @@ -125,6 +127,7 @@ sub _init_tabpanel { event_object_selection_changed => $OBJECT_SELECTION_CHANGED_EVENT, event_object_settings_changed => $OBJECT_SETTINGS_CHANGED_EVENT, event_remove_object => $OBJECT_REMOVE_EVENT, + event_update_scene => $UPDATE_SCENE_EVENT, ), L("Plater")); if (!$self->{no_controller}) { $panel->AddPage($self->{controller} = Slic3r::GUI::Controller->new($panel), L("Controller")); @@ -191,7 +194,7 @@ sub _init_tabpanel { $self->{plater}->item_changed_selection($obj_idx); }); - # The following event is emited by the C++ Tab implementation on object settings change. + # The following event is emited by the C++ GUI implementation on object settings change. EVT_COMMAND($self, -1, $OBJECT_SETTINGS_CHANGED_EVENT, sub { my ($self, $event) = @_; @@ -201,11 +204,17 @@ sub _init_tabpanel { $self->{plater}->changed_object_settings($obj_idx, $parts_changed, $part_settings_changed); }); - # The following event is emited by the C++ Tab implementation on object settings change. + # The following event is emited by the C++ GUI implementation on object remove. EVT_COMMAND($self, -1, $OBJECT_REMOVE_EVENT, sub { my ($self, $event) = @_; $self->{plater}->remove(); }); + + # The following event is emited by the C++ GUI implementation on extruder change for object. + EVT_COMMAND($self, -1, $UPDATE_SCENE_EVENT, sub { + my ($self, $event) = @_; + $self->{plater}->update(); + }); Slic3r::GUI::create_preset_tabs($self->{no_controller}, $VALUE_CHANGE_EVENT, $PRESETS_CHANGED_EVENT); diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index ac54e67d8..ac4b9f78f 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -58,6 +58,7 @@ sub new { $self->{event_object_selection_changed} = $params{event_object_selection_changed}; $self->{event_object_settings_changed} = $params{event_object_settings_changed}; $self->{event_remove_object} = $params{event_remove_object}; + $self->{event_update_scene} = $params{event_update_scene}; # C++ Slic3r::Model with Perl extensions in Slic3r/Model.pm $self->{model} = Slic3r::Model->new; @@ -452,7 +453,8 @@ sub new { $self->{model}, $self->{event_object_selection_changed}, $self->{event_object_settings_changed}, - $self->{event_remove_object}); + $self->{event_remove_object}, + $self->{event_update_scene}); # if ($expert_mode_part_sizer->IsShown(2)==1) # { # $expert_mode_part_sizer->Layout; diff --git a/resources/icons/erase.png b/resources/icons/erase.png new file mode 100644 index 0000000000000000000000000000000000000000..4c4cfd755c17deb467a6b7724e3c99f2cdd36912 GIT binary patch literal 488 zcmVP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&0ewkCK~y+T)ssC- zLSYog&-IdXsNfYUj`4; z6zA{jH7rUcSe+aT-+?t?jQt*;s#TmOlQ_#{P|0R-Z=F3i8u%EG<8Cssc3d10d6H=8 zstSur1q@9CITQj@*Fio!griPJ+ySb{=W{!E1CTN4P?BZQ*Q8K@4@Ci_z2s;F+z1-n z6o5>3Y`%%e8?#ysw)E&Am4dg;2Bzh*b5WAGP7hoGL)nFWARPwLDBk7s!habK@zU?d zWw$H*J!$2|3Bb%-Exd|E@H&wYz9DABWv_>QSr)#%XXAba8vS4pFT!D5QC5bt*%|Na zb-XPW#oCJ#KyA12ED*p!E+>5Zu{X$hEQYU|Ce}7ifSs!1DM_*=%W8ZLz!mQ3@r|X8 e&AQL70(Y)*K0-;2lpF#}Etur4tTv9Wvl)`~5}E=9h?Fv-$dY zdpKWt3aT?pS}i}fY;&eZ&NaT4T7igvX7_K+%2SDK{LC7>IIAP2wLN#|vIEKfrzbp& zl2>KW`IB6{P=RSxY?u<0WL`Fx&BFe+1$OF_6doi#|Iqzl^#LFL1HYH4xS0j5=h(U4 zE+KxB^becOvnMDreiFV>Hm5=Qxoho*sE>aoGrV*klo$MKlsNOI#ZSQdLEV%@mwhgu zG&DXW$mh4ccKh1#$|dNnX2*u3T9R&)T2u=nPF#FjHc!@V(@Kv;Qb`q0^>@AFR*T;1 U>+j7O3iKy~r>mdKI;Vst05X$(rvLx| literal 0 HcmV?d00001 diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 72efd7f29..cef9d95ed 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -896,11 +896,13 @@ void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, Model &model, int event_object_selection_changed, int event_object_settings_changed, - int event_remove_object) + int event_remove_object, + int event_update_scene) { set_event_object_selection_changed(event_object_selection_changed); set_event_object_settings_changed(event_object_settings_changed); set_event_remove_object(event_remove_object); + set_event_update_scene(event_update_scene); set_objects_from_model(model); init_mesh_icons(); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 8199a1349..7b9d3c398 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -191,7 +191,8 @@ void add_expert_mode_part( wxWindow* parent, wxBoxSizer* sizer, Model &model, int event_object_selection_changed, int event_object_settings_changed, - int event_remove_object); + int event_remove_object, + int event_update_scene); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); // Update view mode according to selected menu void update_mode(); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 252dcec26..705d72643 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -51,6 +51,7 @@ std::vector > m_og_settings; int m_event_object_selection_changed = 0; int m_event_object_settings_changed = 0; int m_event_remove_object = 0; +int m_event_update_scene = 0; bool m_parts_changed = false; bool m_part_settings_changed = false; @@ -116,6 +117,9 @@ void set_event_object_settings_changed(const int& event){ void set_event_remove_object(const int& event){ m_event_remove_object = event; } +void set_event_update_scene(const int& event){ + m_event_update_scene = event; +} void set_objects_from_model(Model &model) { m_objects = &(model.objects); @@ -126,7 +130,7 @@ void init_mesh_icons(){ m_icon_solidmesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); // init icon for manifold warning - m_icon_manifold_warning = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); + m_icon_manifold_warning = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); // init bitmap for "Add Settings" context menu m_bmp_cog = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG); @@ -208,20 +212,19 @@ wxBoxSizer* content_objects_list(wxWindow *win) event.Skip(); }); - m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) + m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { - if (event.GetColumn() == 3) - { - if (!*m_config) - return; - wxVariant variant; - m_objects_model->GetValue(variant, event.GetItem(), 3); - auto str = variant.GetString(); - int extruder = str.size() > 1 ? 0 : atoi(str.c_str()); + if (!*m_config) + return; + auto config = m_config; -// if ((*m_config)->has("extruder")) - auto config = m_config; - (*m_config)->set_key_value("extruder", new ConfigOptionInt(extruder)); + wxString str = event.GetString(); + int extruder = str.size() > 1 ? 0 : atoi(str.c_str()); + (*m_config)->set_key_value("extruder", new ConfigOptionInt(extruder)); + + if (m_event_update_scene > 0) { + wxCommandEvent e(m_event_update_scene); + get_main_frame()->ProcessWindowEvent(e); } }); @@ -666,7 +669,7 @@ void update_settings_list() // The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason, // we will Thaw the UI prematurely on Linux. This means destroing the no_updates object prematurely. #ifdef __linux__ - std::unique_ptr no_updates(new wxWindowUpdateLocker(this)); + std::unique_ptr no_updates(new wxWindowUpdateLocker(parent)); #else wxWindowUpdateLocker noUpdates(parent); #endif diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 4f1c15e3a..aaeff7a43 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -74,6 +74,7 @@ void init_mesh_icons(); void set_event_object_selection_changed(const int& event); void set_event_object_settings_changed(const int& event); void set_event_remove_object(const int& event); +void set_event_update_scene(const int& event); void set_objects_from_model(Model &model); bool is_parts_changed(); diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 98d3169bd..8ad8c8184 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -91,13 +91,15 @@ void add_expert_mode_part( SV *ui_parent, SV *ui_sizer, Model *model, int event_object_selection_changed, int event_object_settings_changed, - int event_remove_object) + int event_remove_object, + int event_update_scene) %code%{ Slic3r::GUI::add_expert_mode_part( (wxWindow*)wxPli_sv_2_object(aTHX_ ui_parent, "Wx::Window"), (wxBoxSizer*)wxPli_sv_2_object(aTHX_ ui_sizer, "Wx::BoxSizer"), *model, event_object_selection_changed, event_object_settings_changed, - event_remove_object); %}; + event_remove_object, + event_update_scene); %}; void set_objects_from_perl( SV *ui_parent, SV *frequently_changed_parameters_sizer, From ca1a11742b6304c5c8f83eb0570305958148833a Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 26 Jul 2018 12:10:45 +0200 Subject: [PATCH 068/119] After merging bug fixes --- lib/Slic3r/GUI/Plater.pm | 82 ++++++++++-------------------- xs/src/slic3r/GUI/GLCanvas3D.cpp | 8 ++- xs/src/slic3r/GUI/GUI.cpp | 3 -- xs/src/slic3r/GUI/OptionsGroup.cpp | 2 +- xs/src/slic3r/GUI/OptionsGroup.hpp | 4 +- 5 files changed, 36 insertions(+), 63 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 3053f4326..221b1cc2e 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -135,7 +135,9 @@ sub new { } $_->set_scaling_factor($scale) for @{ $model_object->instances }; - $self->{list}->SetItem($obj_idx, 2, ($model_object->instances->[0]->scaling_factor * 100) . "%"); + # Set object scale on c++ side + Slic3r::GUI::set_object_scale($obj_idx, $model_object->instances->[0]->scaling_factor * 100); + $object->transform_thumbnail($self->{model}, $obj_idx); #update print and start background processing @@ -539,35 +541,9 @@ sub new { } } - my $print_info_sizer; - { - my $box = Wx::StaticBox->new($self->{right_panel}, -1, L("Sliced Info")); - $box->SetFont($Slic3r::GUI::small_bold_font); - $print_info_sizer = Wx::StaticBoxSizer->new($box, wxVERTICAL); - $print_info_sizer->SetMinSize([316,-1]); - my $grid_sizer = Wx::FlexGridSizer->new(2, 2, 5, 5); - $grid_sizer->SetFlexibleDirection(wxHORIZONTAL); - $grid_sizer->AddGrowableCol(1, 1); - $grid_sizer->AddGrowableCol(3, 1); - $print_info_sizer->Add($grid_sizer, 0, wxEXPAND); - my @info = ( - fil_m => L("Used Filament (m)"), - fil_mm3 => L("Used Filament (mm³)"), - fil_g => L("Used Filament (g)"), - cost => L("Cost"), - time => L("Estimated printing time"), - ); - while (my $field = shift @info) { - my $label = shift @info; - my $text = Wx::StaticText->new($self->{right_panel}, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); - $text->SetFont($Slic3r::GUI::small_font); - $grid_sizer->Add($text, 0); - - $self->{"print_info_$field"} = Wx::StaticText->new($self->{right_panel}, -1, "", wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); - $self->{"print_info_$field"}->SetFont($Slic3r::GUI::small_font); - $grid_sizer->Add($self->{"print_info_$field"}, 0); - } - } + my $print_info_sizer = $self->{print_info_sizer} = Wx::StaticBoxSizer->new( + Wx::StaticBox->new($self->{right_panel}, -1, L("Sliced Info")), wxVERTICAL); + $print_info_sizer->SetMinSize([300,-1]); my $buttons_sizer = Wx::BoxSizer->new(wxHORIZONTAL); $self->{buttons_sizer} = $buttons_sizer; @@ -579,7 +555,7 @@ sub new { #$buttons_sizer->Add($self->{btn_export_gcode}, 0, wxALIGN_RIGHT, 0); ### Sizer for info boxes - my $info_sizer = Wx::BoxSizer->new(wxVERTICAL); + my $info_sizer = $self->{info_sizer} = Wx::BoxSizer->new(wxVERTICAL); $info_sizer->SetMinSize([318, -1]); $info_sizer->Add($object_info_sizer, 0, wxEXPAND | wxBOTTOM, 5); $info_sizer->Add($print_info_sizer, 0, wxEXPAND | wxBOTTOM, 5); @@ -593,18 +569,6 @@ sub new { $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM | wxTOP, 10); $right_sizer->Add($info_sizer, 0, wxEXPAND | wxLEFT, 20); $right_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 20); - # Callback for showing / hiding the print info box. - $self->{"print_info_box_show"} = sub { - if ($info_sizer->IsShown(1) != $_[0]) { - Slic3r::GUI::set_show_print_info($_[0]); - return if (wxTheApp->{app_config}->get("view_mode") eq "simple"); - $info_sizer->Show(1, $_[0]); - $self->Layout; - $self->{right_panel}->Refresh; - } - }; - # Show the box initially, let it be shown after the slicing is finished. - #$self->{"print_info_box_show"}->(0); my $hsizer = Wx::BoxSizer->new(wxHORIZONTAL); $hsizer->Add($self->{preview_notebook}, 1, wxEXPAND | wxTOP, 1); @@ -963,9 +927,6 @@ sub remove { $self->select_object(undef); $self->update; $self->schedule_background_process; - - # Hide the slicing results if the current slicing status is no more valid. - $self->{"print_info_box_show"}->(0); } sub reset { @@ -986,9 +947,6 @@ sub reset { $self->select_object(undef); $self->update; - - # Hide the slicing results if the current slicing status is no more valid. - $self->{"print_info_box_show"}->(0); } sub increase { @@ -1664,9 +1622,15 @@ sub on_export_completed { # Fill in the "Sliced info" box with the result of the G-code generator. sub print_info_box_show { my ($self, $show) = @_; - my $scrolled_window_panel = $self->{scrolled_window_panel}; - my $scrolled_window_sizer = $self->{scrolled_window_sizer}; - return if $scrolled_window_sizer->IsShown(2) == $show; +# my $scrolled_window_panel = $self->{scrolled_window_panel}; +# my $scrolled_window_sizer = $self->{scrolled_window_sizer}; +# return if $scrolled_window_sizer->IsShown(2) == $show; + my $panel = $self->{right_panel}; + my $sizer = $self->{info_sizer}; + return if $sizer->IsShown(1) == $show; + + Slic3r::GUI::set_show_print_info($show); + return if (wxTheApp->{app_config}->get("view_mode") eq "simple"); if ($show) { my $print_info_sizer = $self->{print_info_sizer}; @@ -1693,17 +1657,23 @@ sub print_info_box_show { while ( my $label = shift @info) { my $value = shift @info; next if $value eq "N/A"; - my $text = Wx::StaticText->new($scrolled_window_panel, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); +# my $text = Wx::StaticText->new($scrolled_window_panel, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); + my $text = Wx::StaticText->new($panel, -1, "$label:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT); $text->SetFont($Slic3r::GUI::small_font); $grid_sizer->Add($text, 0); - my $field = Wx::StaticText->new($scrolled_window_panel, -1, $value, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); +# my $field = Wx::StaticText->new($scrolled_window_panel, -1, $value, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + my $field = Wx::StaticText->new($panel, -1, $value, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); $field->SetFont($Slic3r::GUI::small_font); $grid_sizer->Add($field, 0); } } - $scrolled_window_sizer->Show(2, $show); - $scrolled_window_panel->Layout; +# $scrolled_window_sizer->Show(2, $show); +# $scrolled_window_panel->Layout; + $sizer->Show(1, $show); + + $self->Layout; + $panel->Refresh; } sub do_print { diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 722f1c112..578a17b7a 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -3024,7 +3024,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) m_mouse.set_start_position_2D_as_invalid(); #endif - } + } + else if (evt.Leaving()) + { + // to remove hover when mouse goes out of this canvas + m_mouse.position = Pointf((coordf_t)pos.x, (coordf_t)pos.y); + render(); + } else if (evt.LeftDClick() && (m_hover_volume_id != -1)) m_on_double_click_callback.call(); else if (evt.LeftDown() || evt.RightDown()) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 8e0c2c0a6..088cbf80b 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -148,9 +148,6 @@ wxStaticBitmap *g_manifold_warning_icon = nullptr; bool g_show_print_info = false; bool g_show_manifold_warning_icon = false; -wxFont g_small_font; -wxFont g_bold_font; - static void init_label_colours() { auto luma = get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index c43e2c7ce..1c61de457 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -96,7 +96,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co void OptionsGroup::add_undo_buttuns_to_sizer(wxSizer* sizer, const t_field& field) { - if (!m_is_tab_opt) { + if (!m_show_modified_btns) { field->m_Undo_btn->Hide(); field->m_Undo_to_sys_btn->Hide(); return; diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index 20a532626..e5600f918 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -153,8 +153,8 @@ public: OptionsGroup( wxWindow* _parent, const wxString& title, bool is_tab_opt = false, ogDrawFlag flag = ogDEFAULT, column_t extra_clmn = nullptr) : - m_parent(_parent), title(title), m_is_tab_opt(is_tab_opt), - staticbox(title!=""), m_flag(flag), extra_column(extra_clmn){ + m_parent(_parent), title(title), m_show_modified_btns(is_tab_opt), + staticbox(title!=""), m_flag(flag), extra_column(extra_clmn){ stb = new wxStaticBox(_parent, wxID_ANY, title); stb->SetFont(bold_font()); sizer = (staticbox ? new wxStaticBoxSizer(stb/*new wxStaticBox(_parent, wxID_ANY, title)*/, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); From 36e8544df245dcd2bd7e31483086b3b35f5d6cc9 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 26 Jul 2018 16:51:18 +0200 Subject: [PATCH 069/119] Added DATAVIEW_ITEM_VALUE_CHANGED event for Linux and OSX --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 705d72643..580533d03 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -214,6 +214,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { + wxMessageBox("Ku-ku"); if (!*m_config) return; auto config = m_config; @@ -228,6 +229,29 @@ wxBoxSizer* content_objects_list(wxWindow *win) } }); +#ifndef __WXMSW__ + m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) + { + wxMessageBox("DATAVIEW_ITEM_VALUE_CHANGED"); + if (!*m_config) + return; + if (event.GetColumn() == 3) + { + wxVariant variant; + m_objects_model->GetValue(variant, event.GetItem(), 3); + auto str = variant.GetString(); + int extruder = str.size() > 1 ? 0 : atoi(str.c_str()); + + (*m_config)->set_key_value("extruder", new ConfigOptionInt(extruder)); + + if (m_event_update_scene > 0) { + wxCommandEvent e(m_event_update_scene); + get_main_frame()->ProcessWindowEvent(e); + } + } + }); +#endif //__WXMSW__ + return objects_sz; } From c19fe985e8457e0d87b0008d4b47f6e03774cb0b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 26 Jul 2018 17:22:10 +0200 Subject: [PATCH 070/119] Del information msg --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 580533d03..ca0651bce 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -232,7 +232,6 @@ wxBoxSizer* content_objects_list(wxWindow *win) #ifndef __WXMSW__ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) { - wxMessageBox("DATAVIEW_ITEM_VALUE_CHANGED"); if (!*m_config) return; if (event.GetColumn() == 3) From f7c0303acf92f8662d093c71fbb0cfcff98366d8 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 27 Jul 2018 10:42:54 +0200 Subject: [PATCH 071/119] Fixed wrong drawing of the object additional settings --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 15 ++++++++++----- xs/src/slic3r/GUI/OptionsGroup.cpp | 2 +- xs/src/slic3r/GUI/OptionsGroup.hpp | 9 +++++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index ca0651bce..03ba9198e 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -687,11 +687,16 @@ void object_ctrl_selection_changed() //update_optgroup void update_settings_list() { - auto parent = get_optgroup(ogFrequentlyObjectSettings)->parent(); +#ifdef __WXGTK__ + auto parent = get_optgroup(ogFrequentlyObjectSettings)->get_parent(); +#else + auto parent = get_optgroup(ogFrequentlyObjectSettings)->parent(); +#endif /* __WXGTK__ */ + // There is a bug related to Ubuntu overlay scrollbars, see https://github.com/prusa3d/Slic3r/issues/898 and https://github.com/prusa3d/Slic3r/issues/952. // The issue apparently manifests when Show()ing a window with overlay scrollbars while the UI is frozen. For this reason, // we will Thaw the UI prematurely on Linux. This means destroing the no_updates object prematurely. -#ifdef __linux__ +#ifdef __linux__ std::unique_ptr no_updates(new wxWindowUpdateLocker(parent)); #else wxWindowUpdateLocker noUpdates(parent); @@ -701,7 +706,7 @@ void update_settings_list() if (m_config) { - auto extra_column = [parent](const Line& line) + auto extra_column = [](wxWindow* parent, const Line& line) { auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line @@ -759,8 +764,8 @@ void update_settings_list() no_updates.reset(nullptr); #endif - get_right_panel()->Refresh(); - get_right_panel()->GetParent()->Layout();; + get_right_panel()->Layout(); + get_right_panel()->GetParent()->Layout(); } void get_settings_choice(wxMenu *menu, int id, bool is_part) diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp index 1c61de457..1ec799b2e 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.cpp +++ b/xs/src/slic3r/GUI/OptionsGroup.cpp @@ -158,7 +158,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* // if we have an extra column, build it if (extra_column) { if (extra_column) { - grid_sizer->Add(extra_column(line), 0, wxALIGN_CENTER_VERTICAL, 0); + grid_sizer->Add(extra_column(parent(), line), 0, wxALIGN_CENTER_VERTICAL, 0); } else { // if the callback provides no sizer for the extra cell, put a spacer diff --git a/xs/src/slic3r/GUI/OptionsGroup.hpp b/xs/src/slic3r/GUI/OptionsGroup.hpp index e5600f918..4f263f5e3 100644 --- a/xs/src/slic3r/GUI/OptionsGroup.hpp +++ b/xs/src/slic3r/GUI/OptionsGroup.hpp @@ -75,7 +75,7 @@ private: std::vector m_extra_widgets;//! {std::vector()}; }; -using column_t = std::function;//std::function; +using column_t = std::function;//std::function; using t_optionfield_map = std::map; using t_opt_map = std::map< std::string, std::pair >; @@ -107,6 +107,11 @@ public: return m_parent; #endif /* __WXGTK__ */ } +#ifdef __WXGTK__ + wxWindow* get_parent() const { + return m_parent; + } +#endif /* __WXGTK__ */ void append_line(const Line& line, wxStaticText** colored_Label = nullptr); Line create_single_option_line(const Option& option) const; @@ -157,7 +162,7 @@ public: staticbox(title!=""), m_flag(flag), extra_column(extra_clmn){ stb = new wxStaticBox(_parent, wxID_ANY, title); stb->SetFont(bold_font()); - sizer = (staticbox ? new wxStaticBoxSizer(stb/*new wxStaticBox(_parent, wxID_ANY, title)*/, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); + sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); auto num_columns = 1U; if (label_width != 0) num_columns++; if (extra_column != nullptr) num_columns++; From 1148c8c018846c6864cd3163c695ea6fdb4428b2 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 27 Jul 2018 10:52:16 +0200 Subject: [PATCH 072/119] Experiment on OSX to understand events order --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 03ba9198e..9b967ffe4 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -188,6 +188,9 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { +#ifdef __WXOSX__ + wxMessageBox("DATAVIEW_SELECTION_CHANGED"); +#endif //__WXOSX__ object_ctrl_selection_changed(); }); @@ -212,12 +215,11 @@ wxBoxSizer* content_objects_list(wxWindow *win) event.Skip(); }); +#ifdef __WXMSW__ m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { - wxMessageBox("Ku-ku"); - if (!*m_config) + if (!*m_config) return; - auto config = m_config; wxString str = event.GetString(); int extruder = str.size() > 1 ? 0 : atoi(str.c_str()); @@ -228,10 +230,12 @@ wxBoxSizer* content_objects_list(wxWindow *win) get_main_frame()->ProcessWindowEvent(e); } }); - -#ifndef __WXMSW__ +#else m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) { +#ifdef __WXOSX__ + wxMessageBox("DATAVIEW_ITEM_VALUE_CHANGED"); +#endif //__WXOSX__ if (!*m_config) return; if (event.GetColumn() == 3) From 575b85bfd60bad7bc9627f3504d9fb7eb4cdba35 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 27 Jul 2018 12:26:14 +0200 Subject: [PATCH 073/119] Try to fix correct extruder updating on all OS --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 55 +++++++++++++-------------- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 2 + 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 9b967ffe4..2061a5581 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -56,6 +56,10 @@ int m_event_update_scene = 0; bool m_parts_changed = false; bool m_part_settings_changed = false; +#ifdef __WXOSX__ + wxString g_selected_extruder = ""; +#endif //__WXOSX__ + // typedef std::map t_category_icon; typedef std::map t_category_icon; inline t_category_icon& get_category_icon() { @@ -188,10 +192,10 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { -#ifdef __WXOSX__ - wxMessageBox("DATAVIEW_SELECTION_CHANGED"); -#endif //__WXOSX__ object_ctrl_selection_changed(); +#ifdef __WXOSX__ + update_extruder_in_config(g_selected_extruder); +#endif //__WXOSX__ }); m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxEvent& event) @@ -218,39 +222,20 @@ wxBoxSizer* content_objects_list(wxWindow *win) #ifdef __WXMSW__ m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { - if (!*m_config) - return; - - wxString str = event.GetString(); - int extruder = str.size() > 1 ? 0 : atoi(str.c_str()); - (*m_config)->set_key_value("extruder", new ConfigOptionInt(extruder)); - - if (m_event_update_scene > 0) { - wxCommandEvent e(m_event_update_scene); - get_main_frame()->ProcessWindowEvent(e); - } + update_extruder_in_config(event.GetString()); }); #else m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) { -#ifdef __WXOSX__ - wxMessageBox("DATAVIEW_ITEM_VALUE_CHANGED"); -#endif //__WXOSX__ - if (!*m_config) - return; if (event.GetColumn() == 3) { wxVariant variant; m_objects_model->GetValue(variant, event.GetItem(), 3); - auto str = variant.GetString(); - int extruder = str.size() > 1 ? 0 : atoi(str.c_str()); - - (*m_config)->set_key_value("extruder", new ConfigOptionInt(extruder)); - - if (m_event_update_scene > 0) { - wxCommandEvent e(m_event_update_scene); - get_main_frame()->ProcessWindowEvent(e); - } +#ifdef __WXOSX__ + g_selected_extruder = variant.GetString(); +#else // --> for Linux + update_extruder_in_config(variant.GetString()); +#endif //__WXOSX__ } }); #endif //__WXMSW__ @@ -1292,5 +1277,19 @@ void set_extruder_column_hidden(bool hide) m_objects_ctrl->GetColumn(3)->SetHidden(hide); } +void update_extruder_in_config(const wxString& selection) +{ + if (!*m_config || selection.empty()) + return; + + int extruder = selection.size() > 1 ? 0 : atoi(selection.c_str()); + (*m_config)->set_key_value("extruder", new ConfigOptionInt(extruder)); + + if (m_event_update_scene > 0) { + wxCommandEvent e(m_event_update_scene); + get_main_frame()->ProcessWindowEvent(e); + } +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index aaeff7a43..b3feb7110 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -97,6 +97,8 @@ void part_selection_changed(); // show/hide "Extruder" column for Objects List void set_extruder_column_hidden(bool hide); +// update extruder in current config +void update_extruder_in_config(const wxString& selection); } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file From c2e09b5bcbf876b4b0b872d2f0ffb3b1d0afb979 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 27 Jul 2018 15:57:53 +0200 Subject: [PATCH 074/119] Added "printf"s to find of an crashing place --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 2061a5581..a1b76cf9f 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -693,6 +693,8 @@ void update_settings_list() m_option_sizer->Clear(true); + printf("update_settings_list\n"); + if (m_config) { auto extra_column = [](wxWindow* parent, const Line& line) @@ -1129,6 +1131,7 @@ void parts_changed(int obj_idx) void update_settings_value() { + printf("update_settings_value\n"); auto og = get_optgroup(ogFrequentlyObjectSettings); if (m_selected_object_id < 0 || m_objects->size() <= m_selected_object_id) { og->set_value("scale_x", 0); @@ -1144,6 +1147,7 @@ void update_settings_value() void part_selection_changed() { + printf("part_selection_changed\n"); auto item = m_objects_ctrl->GetSelection(); int obj_idx = -1; if (item) From 54f14e7ebb60936879cd23159729bc7e2b858749 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 27 Jul 2018 16:55:42 +0200 Subject: [PATCH 075/119] +1 message --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index a1b76cf9f..a0dc827cf 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -619,6 +619,7 @@ void set_object_scale(int idx, int scale) void unselect_objects() { + printf("UNSELECT OBJECTS\n"); m_objects_ctrl->UnselectAll(); part_selection_changed(); @@ -1133,10 +1134,12 @@ void update_settings_value() { printf("update_settings_value\n"); auto og = get_optgroup(ogFrequentlyObjectSettings); - if (m_selected_object_id < 0 || m_objects->size() <= m_selected_object_id) { + printf("selected_object_id = %d\n", m_selected_object_id); + if (m_selected_object_id < 0 || m_objects->size() <= m_selected_object_id) { og->set_value("scale_x", 0); og->set_value("scale_y", 0); og->set_value("scale_z", 0); + printf("return because of unselect\n"); return; } auto bb_size = (*m_objects)[m_selected_object_id]->instance_bounding_box(0).size(); From c2993de6e025b671543833fea8c78f6ef492bd3b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Sun, 29 Jul 2018 12:19:08 +0200 Subject: [PATCH 076/119] Scale and rotation from scene to value updates correctly --- lib/Slic3r/GUI/Plater.pm | 1 + xs/src/slic3r/GUI/3DScene.cpp | 5 ++ xs/src/slic3r/GUI/3DScene.hpp | 1 + xs/src/slic3r/GUI/Field.cpp | 4 +- xs/src/slic3r/GUI/Field.hpp | 4 +- xs/src/slic3r/GUI/GLCanvas3D.cpp | 9 +++ xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 80 +++++++++++++++++++++++---- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 6 ++ xs/xsp/GUI.xsp | 3 + 9 files changed, 98 insertions(+), 15 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 221b1cc2e..6d6e0591f 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1099,6 +1099,7 @@ sub rotate { $model_object->center_around_origin; $self->reset_thumbnail($obj_idx); } + Slic3r::GUI::update_rotation_value(deg2rad($angle), $axis == X ? "x" : ($axis == Y ? "y" : "z")); # update print and start background processing $self->{print}->add_model_object($model_object, $obj_idx); diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 62659033a..0c1c89b07 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -261,6 +261,11 @@ const Pointf3& GLVolume::get_origin() const return m_origin; } +float GLVolume::get_angle_z() +{ + return m_angle_z; +} + void GLVolume::set_origin(const Pointf3& origin) { m_origin = origin; diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 5409b9588..3522feeeb 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -318,6 +318,7 @@ public: void set_render_color(); const Pointf3& get_origin() const; + float get_angle_z(); void set_origin(const Pointf3& origin); void set_angle_z(float angle_z); void set_scale_factor(float scale_factor); diff --git a/xs/src/slic3r/GUI/Field.cpp b/xs/src/slic3r/GUI/Field.cpp index 2109331a4..f862679af 100644 --- a/xs/src/slic3r/GUI/Field.cpp +++ b/xs/src/slic3r/GUI/Field.cpp @@ -333,9 +333,7 @@ void SpinCtrl::BUILD() { break; } - const int min_val = m_opt_id == "standby_temperature_delta" ? - -500 : m_opt.min > 0 ? - m_opt.min : 0; + const int min_val = m_opt.min == INT_MIN ? 0: m_opt.min; const int max_val = m_opt.max < 2147483647 ? m_opt.max : 2147483647; auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, diff --git a/xs/src/slic3r/GUI/Field.hpp b/xs/src/slic3r/GUI/Field.hpp index 08b9936c7..905a24364 100644 --- a/xs/src/slic3r/GUI/Field.hpp +++ b/xs/src/slic3r/GUI/Field.hpp @@ -414,8 +414,8 @@ public: boost::any& get_value()override { return m_value; } - void enable() override { dynamic_cast(window)->Enable(); }; - void disable() override{ dynamic_cast(window)->Disable(); }; + void enable() override { dynamic_cast(window)->Enable(); }; + void disable() override{ dynamic_cast(window)->Disable(); }; wxWindow* getWindow() override { return window; } }; diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index 578a17b7a..95822a1ff 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -3243,6 +3243,8 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) const BoundingBoxf3& bb = volumes[0]->transformed_bounding_box(); const Pointf3& size = bb.size(); m_on_update_geometry_info_callback.call(size.x, size.y, size.z, m_gizmos.get_scale()); + update_scale_values(size, m_gizmos.get_scale()); + update_rotation_value(volumes[0]->get_angle_z(), "z"); } if ((m_gizmos.get_current_type() != Gizmos::Rotate) && (volumes.size() > 1)) @@ -3341,6 +3343,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) case Gizmos::Scale: { m_on_gizmo_scale_uniformly_callback.call((double)m_gizmos.get_scale()); + Slic3r::GUI::update_settings_value(); break; } case Gizmos::Rotate: @@ -3387,7 +3390,13 @@ void GLCanvas3D::on_key_down(wxKeyEvent& evt) if (key == WXK_DELETE) m_on_remove_object_callback.call(); else + { +#ifdef __WXOSX__ + if (key == WXK_BACK) + m_on_remove_object_callback.call(); +#endif evt.Skip(); + } } } diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index a0dc827cf..f573ae0d3 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -11,6 +11,7 @@ #include #include #include +#include "Geometry.hpp" namespace Slic3r { @@ -40,6 +41,9 @@ int m_selected_object_id = -1; bool g_prevent_list_events = false; // We use this flag to avoid circular event handling Select() // happens to fire a wxEVT_LIST_ITEM_SELECTED on OSX, whose event handler // calls this method again and again and again +bool g_is_percent_scale = false; // It indicates if scale unit is percentage +int g_rotation_x = 0; // Last value of the rotation around the X axis +int g_rotation_y = 0; // Last value of the rotation around the Y axis ModelObjectPtrs* m_objects; std::shared_ptr m_config; std::shared_ptr m_default_config; @@ -435,6 +439,9 @@ Line add_og_to_object_settings(const std::string& option_name, const std::string def.sidetext = sidetext; def.width = 70; + if (option_name == "Rotation") + def.min = -360; + const std::string lower_name = boost::algorithm::to_lower_copy(option_name); std::vector axes{ "x", "y", "z" }; @@ -458,6 +465,7 @@ Line add_og_to_object_settings(const std::string& option_name, const std::string Option option = Option(def, lower_name + "_unit"); line.append_option(option); } + return line; } @@ -475,6 +483,9 @@ void add_object_settings(wxWindow* parent, wxBoxSizer* sizer) std::string key = "scale_" + axis; get_optgroup(ogFrequentlyObjectSettings)->set_side_text(key, selection); } + + g_is_percent_scale = selection == _("%"); + update_scale_values(); } }; @@ -485,16 +496,25 @@ void add_object_settings(wxWindow* parent, wxBoxSizer* sizer) // def.default_value = new ConfigOptionString{ "BlaBla_object.stl" }; // optgroup->append_single_option_line(Option(def, "object_name")); + ConfigOptionDef def; + + def.label = L("Name"); +// def.type = coString; + def.gui_type = "legend"; + def.tooltip = L("Object name"); + def.full_width = true; + def.default_value = new ConfigOptionString{ "BlaBla_object.stl" }; + optgroup->append_single_option_line(Option(def, "object_name")); + optgroup->set_flag(ogSIDE_OPTIONS_VERTICAL); optgroup->sidetext_width = 25; optgroup->append_line(add_og_to_object_settings(L("Position"), L("mm"))); - optgroup->append_line(add_og_to_object_settings(L("Rotation"), "°", 1)); - optgroup->append_line(add_og_to_object_settings(L("Scale"), "%", 2)); + optgroup->append_line(add_og_to_object_settings(L("Rotation"), "°")); + optgroup->append_line(add_og_to_object_settings(L("Scale"), "%")); optgroup->set_flag(ogDEFAULT); - ConfigOptionDef def; def.label = L("Place on bed"); def.type = coBool; def.tooltip = L("Automatic placing of models on printing bed in Y axis"); @@ -1142,10 +1162,8 @@ void update_settings_value() printf("return because of unselect\n"); return; } - auto bb_size = (*m_objects)[m_selected_object_id]->instance_bounding_box(0).size(); - og->set_value("scale_x", int(bb_size.x+0.5)); - og->set_value("scale_y", int(bb_size.y+0.5)); - og->set_value("scale_z", int(bb_size.z+0.5)); + g_is_percent_scale = boost::any_cast(og->get_value("scale_unit")) == _("%"); + update_scale_values(); } void part_selection_changed() @@ -1153,9 +1171,9 @@ void part_selection_changed() printf("part_selection_changed\n"); auto item = m_objects_ctrl->GetSelection(); int obj_idx = -1; + auto og = get_optgroup(ogFrequentlyObjectSettings); if (item) { - auto og = get_optgroup(ogFrequentlyObjectSettings); bool is_part = false; if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { obj_idx = m_objects_model->GetIdByItem(item); @@ -1173,10 +1191,14 @@ void part_selection_changed() } auto config = m_config; + og->set_value("object_name", m_objects_model->GetName(item)); m_default_config = std::make_shared(*DynamicPrintConfig::new_from_defaults_keys(get_options(is_part))); } - else - m_config = nullptr; + else { + wxString empty_str = wxEmptyString; + og->set_value("object_name", empty_str); + m_config = nullptr; + } update_settings_list(); @@ -1298,5 +1320,43 @@ void update_extruder_in_config(const wxString& selection) } } +void update_scale_values() +{ + update_scale_values((*m_objects)[m_selected_object_id]->instance_bounding_box(0).size(), + (*m_objects)[m_selected_object_id]->instances[0]->scaling_factor); +} + +void update_scale_values(const Pointf3& size, float scaling_factor) +{ + auto og = get_optgroup(ogFrequentlyObjectSettings); + + if (g_is_percent_scale) { + auto scale = scaling_factor * 100; + og->set_value("scale_x", int(scale)); + og->set_value("scale_y", int(scale)); + og->set_value("scale_z", int(scale)); + } + else { + og->set_value("scale_x", int(size.x + 0.5)); + og->set_value("scale_y", int(size.y + 0.5)); + og->set_value("scale_z", int(size.z + 0.5)); + } +} + +void update_rotation_value() +{ +// update_rotation_values(0, 0, (*m_objects)[m_selected_object_id]->volumes[0]->get_angle_z()); +} + +void update_rotation_value(const double angle, const std::string& axis) +{ + auto og = get_optgroup(ogFrequentlyObjectSettings); + + int deg = int(Geometry::rad2deg(angle)); + if (deg>180) deg -= 360; + + og->set_value("rotation_"+axis, deg); +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index b3feb7110..95a818091 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -95,10 +95,16 @@ void on_btn_move_down(); void parts_changed(int obj_idx); void part_selection_changed(); +void update_settings_value(); // show/hide "Extruder" column for Objects List void set_extruder_column_hidden(bool hide); // update extruder in current config void update_extruder_in_config(const wxString& selection); +// update scale values after scale unit changing or "gizmos" +void update_scale_values(); +void update_scale_values(const Pointf3& size, float scale); +// update rotation values after "gizmos" +void update_rotation_value(const double angle, const std::string& axis); } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 3d919a663..5bee1b318 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -158,6 +158,9 @@ void select_current_object(int idx) void remove_obj() %code%{ Slic3r::GUI::remove(); %}; +void update_rotation_value(double angle, const char *axis) + %code%{ Slic3r::GUI::update_rotation_value(angle, axis); %}; + std::string fold_utf8_to_ascii(const char *src) %code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %}; From b6d1d10502b645f690bf375526155fe402e85e06 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 30 Jul 2018 10:48:40 +0200 Subject: [PATCH 077/119] Added updating for the Z_rotation after object selection changing --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 16 +++++++++++++--- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 4 +++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index f573ae0d3..39e49bcba 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -503,7 +503,7 @@ void add_object_settings(wxWindow* parent, wxBoxSizer* sizer) def.gui_type = "legend"; def.tooltip = L("Object name"); def.full_width = true; - def.default_value = new ConfigOptionString{ "BlaBla_object.stl" }; + def.default_value = new ConfigOptionString{ " " }; optgroup->append_single_option_line(Option(def, "object_name")); optgroup->set_flag(ogSIDE_OPTIONS_VERTICAL); @@ -1164,6 +1164,7 @@ void update_settings_value() } g_is_percent_scale = boost::any_cast(og->get_value("scale_unit")) == _("%"); update_scale_values(); + update_rotation_values(); } void part_selection_changed() @@ -1343,9 +1344,18 @@ void update_scale_values(const Pointf3& size, float scaling_factor) } } -void update_rotation_value() +void update_rotation_values() { -// update_rotation_values(0, 0, (*m_objects)[m_selected_object_id]->volumes[0]->get_angle_z()); + auto og = get_optgroup(ogFrequentlyObjectSettings); + + og->set_value("rotation_x", 0); + og->set_value("rotation_y", 0); + + auto rotation_z = (*m_objects)[m_selected_object_id]->instances[0]->rotation; + auto deg = int(Geometry::rad2deg(rotation_z)); + if (deg > 180) deg -= 360; + + og->set_value("rotation_z", deg); } void update_rotation_value(const double angle, const std::string& axis) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 95a818091..9728f77d8 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -103,7 +103,9 @@ void update_extruder_in_config(const wxString& selection); // update scale values after scale unit changing or "gizmos" void update_scale_values(); void update_scale_values(const Pointf3& size, float scale); -// update rotation values after "gizmos" +// update rotation values object selection changing +void update_rotation_values(); +// update rotation value after "gizmos" void update_rotation_value(const double angle, const std::string& axis); } //namespace GUI } //namespace Slic3r From 460021f7d088645df079a3650b99f0937d1abf6d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 30 Jul 2018 12:17:32 +0200 Subject: [PATCH 078/119] EXPERIMENTS for Linux --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 117 +++++++++++ xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 4 + xs/src/slic3r/GUI/wxExtensions.cpp | 284 +++++++++++++++++++++++++- xs/src/slic3r/GUI/wxExtensions.hpp | 188 ++++++++++++++++- 4 files changed, 589 insertions(+), 4 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 39e49bcba..31c6742c6 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -427,6 +427,8 @@ void add_objects_list(wxWindow* parent, wxBoxSizer* sizer) const auto ol_sizer = content_objects_list(parent); sizer->Add(ol_sizer, 1, wxEXPAND | wxTOP, 20); set_objects_list_sizer(ol_sizer); + + sizer->Add(get_experimental_sizer(parent), 0, wxEXPAND | wxTOP, 20); } Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value = 0) @@ -1368,5 +1370,120 @@ void update_rotation_value(const double angle, const std::string& axis) og->set_value("rotation_"+axis, deg); } + +// **************************************** EXPERIMENRS **************************************** +// wxDataViewCtrl *tmp_ctrl = nullptr; +// MyMusicTreeModel *m_music_model = nullptr; + +wxSizer* get_experimental_sizer(wxWindow* parent) +{ + auto tmp_ctrl = new wxDataViewCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize); + tmp_ctrl->SetInitialSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects +// tmp_ctrl->Connect(wxEVT_CHAR, +// wxKeyEventHandler(MyFrame::OnDataViewChar), +// NULL, this); + + auto m_music_model = new MyMusicTreeModel; + tmp_ctrl->AssociateModel(m_music_model); + +#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE + tmp_ctrl->EnableDragSource(wxDF_UNICODETEXT); + tmp_ctrl->EnableDropTarget(wxDF_UNICODETEXT); +#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE + + // column 0 of the view control: + + wxDataViewTextRenderer *tr = + new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); + wxDataViewColumn *column0 = + new wxDataViewColumn("title", tr, 0, 200, wxALIGN_LEFT, + wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); + tmp_ctrl->AppendColumn(column0); +#if 0 + // Call this and sorting is enabled + // immediately upon start up. + column0->SetAsSortKey(); +#endif + + // column 1 of the view control: + + tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_EDITABLE); + wxDataViewColumn *column1 = + new wxDataViewColumn("artist", tr, 1, 150, wxALIGN_LEFT, + wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE | + wxDATAVIEW_COL_RESIZABLE); + column1->SetMinWidth(150); // this column can't be resized to be smaller + tmp_ctrl->AppendColumn(column1); + + // column 2 of the view control: + + wxDataViewSpinRenderer *sr = + new wxDataViewSpinRenderer(0, 2010, wxDATAVIEW_CELL_EDITABLE, + wxALIGN_RIGHT | wxALIGN_CENTRE_VERTICAL); + wxDataViewColumn *column2 = + new wxDataViewColumn("year", sr, 2, 60, wxALIGN_LEFT, + wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE); + tmp_ctrl->AppendColumn(column2); + + // column 3 of the view control: + + wxArrayString choices; + choices.Add("good"); + choices.Add("bad"); + choices.Add("lousy"); + wxDataViewChoiceRenderer *c = + new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, + wxALIGN_RIGHT | wxALIGN_CENTRE_VERTICAL); + wxDataViewColumn *column3 = + new wxDataViewColumn("rating", c, 3, 100, wxALIGN_LEFT, + wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE); + tmp_ctrl->AppendColumn(column3); + + // column 4 of the view control: + + tmp_ctrl->AppendProgressColumn("popularity", 4, wxDATAVIEW_CELL_INERT, 80); + + // column 5 of the view control: + + MyCustomRenderer *cr = new MyCustomRenderer(wxDATAVIEW_CELL_ACTIVATABLE); + wxDataViewColumn *column5 = + new wxDataViewColumn("custom", cr, 5, -1, wxALIGN_LEFT, + wxDATAVIEW_COL_RESIZABLE); + tmp_ctrl->AppendColumn(column5); + + + // select initially the ninth symphony: + tmp_ctrl->Select(m_music_model->GetNinthItem()); + + + const wxSizerFlags border = wxSizerFlags().DoubleBorder(); + + wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL); + auto add_btn = new wxButton(parent, wxID_ANY, "Add Mozart"); + auto del_btn = new wxButton(parent, wxID_ANY, "Delete selected"); + button_sizer->Add(add_btn, border); + button_sizer->Add(del_btn, border); + + add_btn->Bind(wxEVT_BUTTON, [m_music_model](wxCommandEvent&) + { + m_music_model->AddToClassical("Eine kleine Nachtmusik", "Wolfgang Mozart", 1787); + }); + + del_btn->Bind(wxEVT_BUTTON, [tmp_ctrl, m_music_model](wxCommandEvent&){ + wxDataViewItemArray items; + int len = tmp_ctrl->GetSelections(items); + for (int i = 0; i < len; i++) + if (items[i].IsOk()) + m_music_model->Delete(items[i]); + }); + + auto sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(tmp_ctrl, 0, wxEXPAND | wxLEFT, 20); + sizer->Add(button_sizer); + return sizer; +} + +// **************************************** EXPERIMENRS **************************************** + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 9728f77d8..f8d7821c1 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -107,6 +107,10 @@ void update_scale_values(const Pointf3& size, float scale); void update_rotation_values(); // update rotation value after "gizmos" void update_rotation_value(const double angle, const std::string& axis); + + +wxSizer* get_experimental_sizer(wxWindow* parent); + } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 422c999d1..0690ecee2 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -682,7 +682,285 @@ unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent, } +// ************************************** EXPERIMENTS *************************************** +// ---------------------------------------------------------------------------- +// MyMusicTreeModel +// ---------------------------------------------------------------------------- + +MyMusicTreeModel::MyMusicTreeModel() +{ + m_root = new MyMusicTreeModelNode(NULL, "My Music"); + + // setup pop music + m_pop = new MyMusicTreeModelNode(m_root, "Pop music"); + m_pop->Append( + new MyMusicTreeModelNode(m_pop, "You are not alone", "Michael Jackson", 1995)); + m_pop->Append( + new MyMusicTreeModelNode(m_pop, "Take a bow", "Madonna", 1994)); + m_root->Append(m_pop); + + // setup classical music + m_classical = new MyMusicTreeModelNode(m_root, "Classical music"); + m_ninth = new MyMusicTreeModelNode(m_classical, "Ninth symphony", + "Ludwig van Beethoven", 1824); + m_classical->Append(m_ninth); + m_classical->Append(new MyMusicTreeModelNode(m_classical, "German Requiem", + "Johannes Brahms", 1868)); + m_root->Append(m_classical); + + m_classicalMusicIsKnownToControl = false; +} + +wxString MyMusicTreeModel::GetTitle(const wxDataViewItem &item) const +{ + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return wxEmptyString; + + return node->m_title; +} + +wxString MyMusicTreeModel::GetArtist(const wxDataViewItem &item) const +{ + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return wxEmptyString; + + return node->m_artist; +} + +int MyMusicTreeModel::GetYear(const wxDataViewItem &item) const +{ + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return 2000; + + return node->m_year; +} + +void MyMusicTreeModel::AddToClassical(const wxString &title, const wxString &artist, + unsigned int year) +{ + if (!m_classical) + { + wxASSERT(m_root); + + // it was removed: restore it + m_classical = new MyMusicTreeModelNode(m_root, "Classical music"); + m_root->Append(m_classical); + + // notify control + wxDataViewItem child((void*)m_classical); + wxDataViewItem parent((void*)m_root); + ItemAdded(parent, child); + } + + // add to the classical music node a new node: + MyMusicTreeModelNode *child_node = + new MyMusicTreeModelNode(m_classical, title, artist, year); + m_classical->Append(child_node); + + // FIXME: what's m_classicalMusicIsKnownToControl for? + if (m_classicalMusicIsKnownToControl) + { + // notify control + wxDataViewItem child((void*)child_node); + wxDataViewItem parent((void*)m_classical); + ItemAdded(parent, child); + } +} + +void MyMusicTreeModel::Delete(const wxDataViewItem &item) +{ + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + if (!node) // happens if item.IsOk()==false + return; + + wxDataViewItem parent(node->GetParent()); + if (!parent.IsOk()) + { + wxASSERT(node == m_root); + + // don't make the control completely empty: + printf("Cannot remove the root item!"); + return; + } + + // is the node one of those we keep stored in special pointers? + if (node == m_pop) + m_pop = NULL; + else if (node == m_classical) + m_classical = NULL; + else if (node == m_ninth) + m_ninth = NULL; + + // first remove the node from the parent's array of children; + // NOTE: MyMusicTreeModelNodePtrArray is only an array of _pointers_ + // thus removing the node from it doesn't result in freeing it + node->GetParent()->GetChildren().Remove(node); + + // free the node + delete node; + + // notify control + ItemDeleted(parent, item); +} + +int MyMusicTreeModel::Compare(const wxDataViewItem &item1, const wxDataViewItem &item2, + unsigned int column, bool ascending) const +{ + wxASSERT(item1.IsOk() && item2.IsOk()); + // should never happen + + if (IsContainer(item1) && IsContainer(item2)) + { + wxVariant value1, value2; + GetValue(value1, item1, 0); + GetValue(value2, item2, 0); + + wxString str1 = value1.GetString(); + wxString str2 = value2.GetString(); + int res = str1.Cmp(str2); + if (res) return res; + + // items must be different + wxUIntPtr litem1 = (wxUIntPtr)item1.GetID(); + wxUIntPtr litem2 = (wxUIntPtr)item2.GetID(); + + return litem1 - litem2; + } + + return wxDataViewModel::Compare(item1, item2, column, ascending); +} + +void MyMusicTreeModel::GetValue(wxVariant &variant, + const wxDataViewItem &item, unsigned int col) const +{ + wxASSERT(item.IsOk()); + + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + switch (col) + { + case 0: + variant = node->m_title; + break; + case 1: + variant = node->m_artist; + break; + case 2: + variant = (long)node->m_year; + break; + case 3: + variant = node->m_quality; + break; + case 4: + variant = 80L; // all music is very 80% popular + break; + case 5: + if (GetYear(item) < 1900) + variant = "old"; + else + variant = "new"; + break; + + default: + printf("MyMusicTreeModel::GetValue: wrong column %d", col); + } +} + +bool MyMusicTreeModel::SetValue(const wxVariant &variant, + const wxDataViewItem &item, unsigned int col) +{ + wxASSERT(item.IsOk()); + + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + switch (col) + { + case 0: + node->m_title = variant.GetString(); + return true; + case 1: + node->m_artist = variant.GetString(); + return true; + case 2: + node->m_year = variant.GetLong(); + return true; + case 3: + node->m_quality = variant.GetString(); + return true; + + default: + printf("MyMusicTreeModel::SetValue: wrong column"); + } + return false; +} + +bool MyMusicTreeModel::IsEnabled(const wxDataViewItem &item, + unsigned int col) const +{ + wxASSERT(item.IsOk()); + + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + + // disable Beethoven's ratings, his pieces can only be good + return !(col == 3 && node->m_artist.EndsWith("Beethoven")); +} + +wxDataViewItem MyMusicTreeModel::GetParent(const wxDataViewItem &item) const +{ + // the invisible root node has no parent + if (!item.IsOk()) + return wxDataViewItem(0); + + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + + // "MyMusic" also has no parent + if (node == m_root) + return wxDataViewItem(0); + + return wxDataViewItem((void*)node->GetParent()); +} + +bool MyMusicTreeModel::IsContainer(const wxDataViewItem &item) const +{ + // the invisble root node can have children + // (in our model always "MyMusic") + if (!item.IsOk()) + return true; + + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); + return node->IsContainer(); +} + +unsigned int MyMusicTreeModel::GetChildren(const wxDataViewItem &parent, + wxDataViewItemArray &array) const +{ + MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)parent.GetID(); + if (!node) + { + array.Add(wxDataViewItem((void*)m_root)); + return 1; + } + + if (node == m_classical) + { + MyMusicTreeModel *model = (MyMusicTreeModel*)(const MyMusicTreeModel*) this; + model->m_classicalMusicIsKnownToControl = true; + } + + if (node->GetChildCount() == 0) + { + return 0; + } + + unsigned int count = node->GetChildren().GetCount(); + for (unsigned int pos = 0; pos < count; pos++) + { + MyMusicTreeModelNode *child = node->GetChildren().Item(pos); + array.Add(wxDataViewItem((void*)child)); + } + + return count; +} + // ***************************************************************************** - - - diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 3d0ca8564..8b4000d55 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -477,8 +477,194 @@ public: private: wxString m_value; }; -// ***************************************************************************** +// ******************************* EXPERIMENTS ********************************************** +// ---------------------------------------------------------------------------- +// MyMusicTreeModelNode: a node inside MyMusicTreeModel +// ---------------------------------------------------------------------------- +class MyMusicTreeModelNode; +WX_DEFINE_ARRAY_PTR(MyMusicTreeModelNode*, MyMusicTreeModelNodePtrArray); +class MyMusicTreeModelNode +{ +public: + MyMusicTreeModelNode(MyMusicTreeModelNode* parent, + const wxString &title, const wxString &artist, + unsigned int year) + { + m_parent = parent; + + m_title = title; + m_artist = artist; + m_year = year; + m_quality = "good"; + + m_container = false; + } + + MyMusicTreeModelNode(MyMusicTreeModelNode* parent, + const wxString &branch) + { + m_parent = parent; + + m_title = branch; + m_year = -1; + + m_container = true; + } + + ~MyMusicTreeModelNode() + { + // free all our children nodes + size_t count = m_children.GetCount(); + for (size_t i = 0; i < count; i++) + { + MyMusicTreeModelNode *child = m_children[i]; + delete child; + } + } + + bool IsContainer() const + { + return m_container; + } + + MyMusicTreeModelNode* GetParent() + { + return m_parent; + } + MyMusicTreeModelNodePtrArray& GetChildren() + { + return m_children; + } + MyMusicTreeModelNode* GetNthChild(unsigned int n) + { + return m_children.Item(n); + } + void Insert(MyMusicTreeModelNode* child, unsigned int n) + { + m_children.Insert(child, n); + } + void Append(MyMusicTreeModelNode* child) + { + m_children.Add(child); + } + unsigned int GetChildCount() const + { + return m_children.GetCount(); + } + +public: // public to avoid getters/setters + wxString m_title; + wxString m_artist; + int m_year; + wxString m_quality; + + // TODO/FIXME: + // the GTK version of wxDVC (in particular wxDataViewCtrlInternal::ItemAdded) + // needs to know in advance if a node is or _will be_ a container. + // Thus implementing: + // bool IsContainer() const + // { return m_children.GetCount()>0; } + // doesn't work with wxGTK when MyMusicTreeModel::AddToClassical is called + // AND the classical node was removed (a new node temporary without children + // would be added to the control) + bool m_container; + +private: + MyMusicTreeModelNode *m_parent; + MyMusicTreeModelNodePtrArray m_children; +}; + + +// ---------------------------------------------------------------------------- +// MyMusicTreeModel +// ---------------------------------------------------------------------------- + +/* +Implement this data model +Title Artist Year Judgement +-------------------------------------------------------------------------- +1: My Music: +2: Pop music +3: You are not alone Michael Jackson 1995 good +4: Take a bow Madonna 1994 good +5: Classical music +6: Ninth Symphony Ludwig v. Beethoven 1824 good +7: German Requiem Johannes Brahms 1868 good +*/ + +class MyMusicTreeModel : public wxDataViewModel +{ +public: + MyMusicTreeModel(); + ~MyMusicTreeModel() + { + delete m_root; + } + + // helper method for wxLog + + wxString GetTitle(const wxDataViewItem &item) const; + wxString GetArtist(const wxDataViewItem &item) const; + int GetYear(const wxDataViewItem &item) const; + + // helper methods to change the model + + void AddToClassical(const wxString &title, const wxString &artist, + unsigned int year); + void Delete(const wxDataViewItem &item); + + wxDataViewItem GetNinthItem() const + { + return wxDataViewItem(m_ninth); + } + + // override sorting to always sort branches ascendingly + + int Compare(const wxDataViewItem &item1, const wxDataViewItem &item2, + unsigned int column, bool ascending) const override;//; + + // implementation of base class virtuals to define model + + virtual unsigned int GetColumnCount() const override//wxOVERRIDE + { + return 6; + } + + virtual wxString GetColumnType(unsigned int col) const override//wxOVERRIDE + { + if (col == 2) + return wxT("long"); + + return wxT("string"); + } + + virtual void GetValue(wxVariant &variant, + const wxDataViewItem &item, unsigned int col) const override;//wxOVERRIDE; + virtual bool SetValue(const wxVariant &variant, + const wxDataViewItem &item, unsigned int col) override;//wxOVERRIDE; + + virtual bool IsEnabled(const wxDataViewItem &item, + unsigned int col) const override;//wxOVERRIDE; + + virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override;//wxOVERRIDE; + virtual bool IsContainer(const wxDataViewItem &item) const override;//wxOVERRIDE; + virtual unsigned int GetChildren(const wxDataViewItem &parent, + wxDataViewItemArray &array) const override;//wxOVERRIDE; + +private: + MyMusicTreeModelNode* m_root; + + // pointers to some "special" nodes of the tree: + MyMusicTreeModelNode* m_pop; + MyMusicTreeModelNode* m_classical; + MyMusicTreeModelNode* m_ninth; + + // ?? + bool m_classicalMusicIsKnownToControl; +}; + +// ****************************************************************************************** #endif // slic3r_GUI_wxExtensions_hpp_ From 085ae68e6db7959b8dcb6299b29ee609abcedf3b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 30 Jul 2018 13:19:31 +0200 Subject: [PATCH 079/119] +1 experiment --- xs/src/slic3r/GUI/wxExtensions.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 0690ecee2..ae381366d 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -692,21 +692,21 @@ MyMusicTreeModel::MyMusicTreeModel() m_root = new MyMusicTreeModelNode(NULL, "My Music"); // setup pop music - m_pop = new MyMusicTreeModelNode(m_root, "Pop music"); - m_pop->Append( - new MyMusicTreeModelNode(m_pop, "You are not alone", "Michael Jackson", 1995)); - m_pop->Append( - new MyMusicTreeModelNode(m_pop, "Take a bow", "Madonna", 1994)); - m_root->Append(m_pop); - - // setup classical music - m_classical = new MyMusicTreeModelNode(m_root, "Classical music"); - m_ninth = new MyMusicTreeModelNode(m_classical, "Ninth symphony", - "Ludwig van Beethoven", 1824); - m_classical->Append(m_ninth); - m_classical->Append(new MyMusicTreeModelNode(m_classical, "German Requiem", - "Johannes Brahms", 1868)); - m_root->Append(m_classical); +// m_pop = new MyMusicTreeModelNode(m_root, "Pop music"); +// m_pop->Append( +// new MyMusicTreeModelNode(m_pop, "You are not alone", "Michael Jackson", 1995)); +// m_pop->Append( +// new MyMusicTreeModelNode(m_pop, "Take a bow", "Madonna", 1994)); +// m_root->Append(m_pop); +// +// // setup classical music +// m_classical = new MyMusicTreeModelNode(m_root, "Classical music"); +// m_ninth = new MyMusicTreeModelNode(m_classical, "Ninth symphony", +// "Ludwig van Beethoven", 1824); +// m_classical->Append(m_ninth); +// m_classical->Append(new MyMusicTreeModelNode(m_classical, "German Requiem", +// "Johannes Brahms", 1868)); +// m_root->Append(m_classical); m_classicalMusicIsKnownToControl = false; } From 2142070331459cf25afab0d5011ae5d15a24a4e6 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 30 Jul 2018 14:25:09 +0200 Subject: [PATCH 080/119] Fixed Linux-bug : "Add part" => segmentation fault. Deleted experimental code --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 117 ----------- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 3 - xs/src/slic3r/GUI/wxExtensions.cpp | 281 -------------------------- xs/src/slic3r/GUI/wxExtensions.hpp | 191 +---------------- 4 files changed, 6 insertions(+), 586 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 31c6742c6..39e49bcba 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -427,8 +427,6 @@ void add_objects_list(wxWindow* parent, wxBoxSizer* sizer) const auto ol_sizer = content_objects_list(parent); sizer->Add(ol_sizer, 1, wxEXPAND | wxTOP, 20); set_objects_list_sizer(ol_sizer); - - sizer->Add(get_experimental_sizer(parent), 0, wxEXPAND | wxTOP, 20); } Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value = 0) @@ -1370,120 +1368,5 @@ void update_rotation_value(const double angle, const std::string& axis) og->set_value("rotation_"+axis, deg); } - -// **************************************** EXPERIMENRS **************************************** -// wxDataViewCtrl *tmp_ctrl = nullptr; -// MyMusicTreeModel *m_music_model = nullptr; - -wxSizer* get_experimental_sizer(wxWindow* parent) -{ - auto tmp_ctrl = new wxDataViewCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize); - tmp_ctrl->SetInitialSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects -// tmp_ctrl->Connect(wxEVT_CHAR, -// wxKeyEventHandler(MyFrame::OnDataViewChar), -// NULL, this); - - auto m_music_model = new MyMusicTreeModel; - tmp_ctrl->AssociateModel(m_music_model); - -#if wxUSE_DRAG_AND_DROP && wxUSE_UNICODE - tmp_ctrl->EnableDragSource(wxDF_UNICODETEXT); - tmp_ctrl->EnableDropTarget(wxDF_UNICODETEXT); -#endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE - - // column 0 of the view control: - - wxDataViewTextRenderer *tr = - new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_INERT); - wxDataViewColumn *column0 = - new wxDataViewColumn("title", tr, 0, 200, wxALIGN_LEFT, - wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_RESIZABLE); - tmp_ctrl->AppendColumn(column0); -#if 0 - // Call this and sorting is enabled - // immediately upon start up. - column0->SetAsSortKey(); -#endif - - // column 1 of the view control: - - tr = new wxDataViewTextRenderer("string", wxDATAVIEW_CELL_EDITABLE); - wxDataViewColumn *column1 = - new wxDataViewColumn("artist", tr, 1, 150, wxALIGN_LEFT, - wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE | - wxDATAVIEW_COL_RESIZABLE); - column1->SetMinWidth(150); // this column can't be resized to be smaller - tmp_ctrl->AppendColumn(column1); - - // column 2 of the view control: - - wxDataViewSpinRenderer *sr = - new wxDataViewSpinRenderer(0, 2010, wxDATAVIEW_CELL_EDITABLE, - wxALIGN_RIGHT | wxALIGN_CENTRE_VERTICAL); - wxDataViewColumn *column2 = - new wxDataViewColumn("year", sr, 2, 60, wxALIGN_LEFT, - wxDATAVIEW_COL_SORTABLE | wxDATAVIEW_COL_REORDERABLE); - tmp_ctrl->AppendColumn(column2); - - // column 3 of the view control: - - wxArrayString choices; - choices.Add("good"); - choices.Add("bad"); - choices.Add("lousy"); - wxDataViewChoiceRenderer *c = - new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, - wxALIGN_RIGHT | wxALIGN_CENTRE_VERTICAL); - wxDataViewColumn *column3 = - new wxDataViewColumn("rating", c, 3, 100, wxALIGN_LEFT, - wxDATAVIEW_COL_REORDERABLE | wxDATAVIEW_COL_RESIZABLE); - tmp_ctrl->AppendColumn(column3); - - // column 4 of the view control: - - tmp_ctrl->AppendProgressColumn("popularity", 4, wxDATAVIEW_CELL_INERT, 80); - - // column 5 of the view control: - - MyCustomRenderer *cr = new MyCustomRenderer(wxDATAVIEW_CELL_ACTIVATABLE); - wxDataViewColumn *column5 = - new wxDataViewColumn("custom", cr, 5, -1, wxALIGN_LEFT, - wxDATAVIEW_COL_RESIZABLE); - tmp_ctrl->AppendColumn(column5); - - - // select initially the ninth symphony: - tmp_ctrl->Select(m_music_model->GetNinthItem()); - - - const wxSizerFlags border = wxSizerFlags().DoubleBorder(); - - wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL); - auto add_btn = new wxButton(parent, wxID_ANY, "Add Mozart"); - auto del_btn = new wxButton(parent, wxID_ANY, "Delete selected"); - button_sizer->Add(add_btn, border); - button_sizer->Add(del_btn, border); - - add_btn->Bind(wxEVT_BUTTON, [m_music_model](wxCommandEvent&) - { - m_music_model->AddToClassical("Eine kleine Nachtmusik", "Wolfgang Mozart", 1787); - }); - - del_btn->Bind(wxEVT_BUTTON, [tmp_ctrl, m_music_model](wxCommandEvent&){ - wxDataViewItemArray items; - int len = tmp_ctrl->GetSelections(items); - for (int i = 0; i < len; i++) - if (items[i].IsOk()) - m_music_model->Delete(items[i]); - }); - - auto sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(tmp_ctrl, 0, wxEXPAND | wxLEFT, 20); - sizer->Add(button_sizer); - return sizer; -} - -// **************************************** EXPERIMENRS **************************************** - } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index f8d7821c1..e4484e72a 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -108,9 +108,6 @@ void update_rotation_values(); // update rotation value after "gizmos" void update_rotation_value(const double angle, const std::string& axis); - -wxSizer* get_experimental_sizer(wxWindow* parent); - } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index ae381366d..c52448ed6 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -680,287 +680,6 @@ unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent, return count; } - - // ************************************** EXPERIMENTS *************************************** -// ---------------------------------------------------------------------------- -// MyMusicTreeModel -// ---------------------------------------------------------------------------- - -MyMusicTreeModel::MyMusicTreeModel() -{ - m_root = new MyMusicTreeModelNode(NULL, "My Music"); - - // setup pop music -// m_pop = new MyMusicTreeModelNode(m_root, "Pop music"); -// m_pop->Append( -// new MyMusicTreeModelNode(m_pop, "You are not alone", "Michael Jackson", 1995)); -// m_pop->Append( -// new MyMusicTreeModelNode(m_pop, "Take a bow", "Madonna", 1994)); -// m_root->Append(m_pop); -// -// // setup classical music -// m_classical = new MyMusicTreeModelNode(m_root, "Classical music"); -// m_ninth = new MyMusicTreeModelNode(m_classical, "Ninth symphony", -// "Ludwig van Beethoven", 1824); -// m_classical->Append(m_ninth); -// m_classical->Append(new MyMusicTreeModelNode(m_classical, "German Requiem", -// "Johannes Brahms", 1868)); -// m_root->Append(m_classical); - - m_classicalMusicIsKnownToControl = false; -} - -wxString MyMusicTreeModel::GetTitle(const wxDataViewItem &item) const -{ - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - if (!node) // happens if item.IsOk()==false - return wxEmptyString; - - return node->m_title; -} - -wxString MyMusicTreeModel::GetArtist(const wxDataViewItem &item) const -{ - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - if (!node) // happens if item.IsOk()==false - return wxEmptyString; - - return node->m_artist; -} - -int MyMusicTreeModel::GetYear(const wxDataViewItem &item) const -{ - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - if (!node) // happens if item.IsOk()==false - return 2000; - - return node->m_year; -} - -void MyMusicTreeModel::AddToClassical(const wxString &title, const wxString &artist, - unsigned int year) -{ - if (!m_classical) - { - wxASSERT(m_root); - - // it was removed: restore it - m_classical = new MyMusicTreeModelNode(m_root, "Classical music"); - m_root->Append(m_classical); - - // notify control - wxDataViewItem child((void*)m_classical); - wxDataViewItem parent((void*)m_root); - ItemAdded(parent, child); - } - - // add to the classical music node a new node: - MyMusicTreeModelNode *child_node = - new MyMusicTreeModelNode(m_classical, title, artist, year); - m_classical->Append(child_node); - - // FIXME: what's m_classicalMusicIsKnownToControl for? - if (m_classicalMusicIsKnownToControl) - { - // notify control - wxDataViewItem child((void*)child_node); - wxDataViewItem parent((void*)m_classical); - ItemAdded(parent, child); - } -} - -void MyMusicTreeModel::Delete(const wxDataViewItem &item) -{ - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - if (!node) // happens if item.IsOk()==false - return; - - wxDataViewItem parent(node->GetParent()); - if (!parent.IsOk()) - { - wxASSERT(node == m_root); - - // don't make the control completely empty: - printf("Cannot remove the root item!"); - return; - } - - // is the node one of those we keep stored in special pointers? - if (node == m_pop) - m_pop = NULL; - else if (node == m_classical) - m_classical = NULL; - else if (node == m_ninth) - m_ninth = NULL; - - // first remove the node from the parent's array of children; - // NOTE: MyMusicTreeModelNodePtrArray is only an array of _pointers_ - // thus removing the node from it doesn't result in freeing it - node->GetParent()->GetChildren().Remove(node); - - // free the node - delete node; - - // notify control - ItemDeleted(parent, item); -} - -int MyMusicTreeModel::Compare(const wxDataViewItem &item1, const wxDataViewItem &item2, - unsigned int column, bool ascending) const -{ - wxASSERT(item1.IsOk() && item2.IsOk()); - // should never happen - - if (IsContainer(item1) && IsContainer(item2)) - { - wxVariant value1, value2; - GetValue(value1, item1, 0); - GetValue(value2, item2, 0); - - wxString str1 = value1.GetString(); - wxString str2 = value2.GetString(); - int res = str1.Cmp(str2); - if (res) return res; - - // items must be different - wxUIntPtr litem1 = (wxUIntPtr)item1.GetID(); - wxUIntPtr litem2 = (wxUIntPtr)item2.GetID(); - - return litem1 - litem2; - } - - return wxDataViewModel::Compare(item1, item2, column, ascending); -} - -void MyMusicTreeModel::GetValue(wxVariant &variant, - const wxDataViewItem &item, unsigned int col) const -{ - wxASSERT(item.IsOk()); - - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - switch (col) - { - case 0: - variant = node->m_title; - break; - case 1: - variant = node->m_artist; - break; - case 2: - variant = (long)node->m_year; - break; - case 3: - variant = node->m_quality; - break; - case 4: - variant = 80L; // all music is very 80% popular - break; - case 5: - if (GetYear(item) < 1900) - variant = "old"; - else - variant = "new"; - break; - - default: - printf("MyMusicTreeModel::GetValue: wrong column %d", col); - } -} - -bool MyMusicTreeModel::SetValue(const wxVariant &variant, - const wxDataViewItem &item, unsigned int col) -{ - wxASSERT(item.IsOk()); - - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - switch (col) - { - case 0: - node->m_title = variant.GetString(); - return true; - case 1: - node->m_artist = variant.GetString(); - return true; - case 2: - node->m_year = variant.GetLong(); - return true; - case 3: - node->m_quality = variant.GetString(); - return true; - - default: - printf("MyMusicTreeModel::SetValue: wrong column"); - } - return false; -} - -bool MyMusicTreeModel::IsEnabled(const wxDataViewItem &item, - unsigned int col) const -{ - wxASSERT(item.IsOk()); - - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - - // disable Beethoven's ratings, his pieces can only be good - return !(col == 3 && node->m_artist.EndsWith("Beethoven")); -} - -wxDataViewItem MyMusicTreeModel::GetParent(const wxDataViewItem &item) const -{ - // the invisible root node has no parent - if (!item.IsOk()) - return wxDataViewItem(0); - - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - - // "MyMusic" also has no parent - if (node == m_root) - return wxDataViewItem(0); - - return wxDataViewItem((void*)node->GetParent()); -} - -bool MyMusicTreeModel::IsContainer(const wxDataViewItem &item) const -{ - // the invisble root node can have children - // (in our model always "MyMusic") - if (!item.IsOk()) - return true; - - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)item.GetID(); - return node->IsContainer(); -} - -unsigned int MyMusicTreeModel::GetChildren(const wxDataViewItem &parent, - wxDataViewItemArray &array) const -{ - MyMusicTreeModelNode *node = (MyMusicTreeModelNode*)parent.GetID(); - if (!node) - { - array.Add(wxDataViewItem((void*)m_root)); - return 1; - } - - if (node == m_classical) - { - MyMusicTreeModel *model = (MyMusicTreeModel*)(const MyMusicTreeModel*) this; - model->m_classicalMusicIsKnownToControl = true; - } - - if (node->GetChildCount() == 0) - { - return 0; - } - - unsigned int count = node->GetChildren().GetCount(); - for (unsigned int pos = 0; pos < count; pos++) - { - MyMusicTreeModelNode *child = node->GetChildren().Item(pos); - array.Add(wxDataViewItem((void*)child)); - } - - return count; -} // ***************************************************************************** diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 8b4000d55..12bb156cb 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -163,6 +163,12 @@ public: m_scale = wxString::Format("%d%%", scale); m_type = "object"; m_volume_id = -1; +#ifdef __WXGTK__ + // it's necessary on GTK because of control have to know if this item will be container + // in another case you couldn't to add subitem for this item + // it will be produce "segmentation fault" + m_container = true; +#endif //__WXGTK__ set_object_action_icon(); } @@ -478,191 +484,6 @@ private: wxString m_value; }; // ******************************* EXPERIMENTS ********************************************** -// ---------------------------------------------------------------------------- -// MyMusicTreeModelNode: a node inside MyMusicTreeModel -// ---------------------------------------------------------------------------- -class MyMusicTreeModelNode; -WX_DEFINE_ARRAY_PTR(MyMusicTreeModelNode*, MyMusicTreeModelNodePtrArray); - -class MyMusicTreeModelNode -{ -public: - MyMusicTreeModelNode(MyMusicTreeModelNode* parent, - const wxString &title, const wxString &artist, - unsigned int year) - { - m_parent = parent; - - m_title = title; - m_artist = artist; - m_year = year; - m_quality = "good"; - - m_container = false; - } - - MyMusicTreeModelNode(MyMusicTreeModelNode* parent, - const wxString &branch) - { - m_parent = parent; - - m_title = branch; - m_year = -1; - - m_container = true; - } - - ~MyMusicTreeModelNode() - { - // free all our children nodes - size_t count = m_children.GetCount(); - for (size_t i = 0; i < count; i++) - { - MyMusicTreeModelNode *child = m_children[i]; - delete child; - } - } - - bool IsContainer() const - { - return m_container; - } - - MyMusicTreeModelNode* GetParent() - { - return m_parent; - } - MyMusicTreeModelNodePtrArray& GetChildren() - { - return m_children; - } - MyMusicTreeModelNode* GetNthChild(unsigned int n) - { - return m_children.Item(n); - } - void Insert(MyMusicTreeModelNode* child, unsigned int n) - { - m_children.Insert(child, n); - } - void Append(MyMusicTreeModelNode* child) - { - m_children.Add(child); - } - unsigned int GetChildCount() const - { - return m_children.GetCount(); - } - -public: // public to avoid getters/setters - wxString m_title; - wxString m_artist; - int m_year; - wxString m_quality; - - // TODO/FIXME: - // the GTK version of wxDVC (in particular wxDataViewCtrlInternal::ItemAdded) - // needs to know in advance if a node is or _will be_ a container. - // Thus implementing: - // bool IsContainer() const - // { return m_children.GetCount()>0; } - // doesn't work with wxGTK when MyMusicTreeModel::AddToClassical is called - // AND the classical node was removed (a new node temporary without children - // would be added to the control) - bool m_container; - -private: - MyMusicTreeModelNode *m_parent; - MyMusicTreeModelNodePtrArray m_children; -}; - - -// ---------------------------------------------------------------------------- -// MyMusicTreeModel -// ---------------------------------------------------------------------------- - -/* -Implement this data model -Title Artist Year Judgement --------------------------------------------------------------------------- -1: My Music: -2: Pop music -3: You are not alone Michael Jackson 1995 good -4: Take a bow Madonna 1994 good -5: Classical music -6: Ninth Symphony Ludwig v. Beethoven 1824 good -7: German Requiem Johannes Brahms 1868 good -*/ - -class MyMusicTreeModel : public wxDataViewModel -{ -public: - MyMusicTreeModel(); - ~MyMusicTreeModel() - { - delete m_root; - } - - // helper method for wxLog - - wxString GetTitle(const wxDataViewItem &item) const; - wxString GetArtist(const wxDataViewItem &item) const; - int GetYear(const wxDataViewItem &item) const; - - // helper methods to change the model - - void AddToClassical(const wxString &title, const wxString &artist, - unsigned int year); - void Delete(const wxDataViewItem &item); - - wxDataViewItem GetNinthItem() const - { - return wxDataViewItem(m_ninth); - } - - // override sorting to always sort branches ascendingly - - int Compare(const wxDataViewItem &item1, const wxDataViewItem &item2, - unsigned int column, bool ascending) const override;//; - - // implementation of base class virtuals to define model - - virtual unsigned int GetColumnCount() const override//wxOVERRIDE - { - return 6; - } - - virtual wxString GetColumnType(unsigned int col) const override//wxOVERRIDE - { - if (col == 2) - return wxT("long"); - - return wxT("string"); - } - - virtual void GetValue(wxVariant &variant, - const wxDataViewItem &item, unsigned int col) const override;//wxOVERRIDE; - virtual bool SetValue(const wxVariant &variant, - const wxDataViewItem &item, unsigned int col) override;//wxOVERRIDE; - - virtual bool IsEnabled(const wxDataViewItem &item, - unsigned int col) const override;//wxOVERRIDE; - - virtual wxDataViewItem GetParent(const wxDataViewItem &item) const override;//wxOVERRIDE; - virtual bool IsContainer(const wxDataViewItem &item) const override;//wxOVERRIDE; - virtual unsigned int GetChildren(const wxDataViewItem &parent, - wxDataViewItemArray &array) const override;//wxOVERRIDE; - -private: - MyMusicTreeModelNode* m_root; - - // pointers to some "special" nodes of the tree: - MyMusicTreeModelNode* m_pop; - MyMusicTreeModelNode* m_classical; - MyMusicTreeModelNode* m_ninth; - - // ?? - bool m_classicalMusicIsKnownToControl; -}; // ****************************************************************************************** From 814d255c7785dbc7ccd7cb5a8e9a850a563fa257 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 30 Jul 2018 17:03:14 +0200 Subject: [PATCH 081/119] Added split-function for the object in list. Updated adding of amf-objects. --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 42 +++++++++++++++++++-------- xs/src/slic3r/GUI/wxExtensions.cpp | 5 ++-- xs/src/slic3r/GUI/wxExtensions.hpp | 3 +- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 39e49bcba..3bfbfe736 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -28,6 +28,7 @@ wxIcon m_icon_modifiermesh; wxIcon m_icon_solidmesh; wxIcon m_icon_manifold_warning; wxBitmap m_bmp_cog; +wxBitmap m_bmp_split; wxSlider* m_mover_x = nullptr; wxSlider* m_mover_y = nullptr; @@ -140,6 +141,9 @@ void init_mesh_icons(){ // init icon for manifold warning m_icon_manifold_warning = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("exclamation_mark_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("error.png")), wxBITMAP_TYPE_PNG); + // init bitmap for "Split to sub-objects" context menu + m_bmp_split = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("split.png")), wxBITMAP_TYPE_PNG); + // init bitmap for "Add Settings" context menu m_bmp_cog = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("cog.png")), wxBITMAP_TYPE_PNG); } @@ -600,6 +604,10 @@ void add_object_to_list(const std::string &name, ModelObject* model_object) m_objects_model->SetValue(variant, item, 0); } + if (model_object->volumes.size() > 1) + for (auto id = 0; id < model_object->volumes.size(); id++) + m_objects_model->AddChild(item, model_object->volumes[id]->name, m_icon_solidmesh, false); + ModelObjectPtrs* objects = m_objects; // part_selection_changed(); #ifdef __WXMSW__ @@ -836,16 +844,22 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) wxMenu *create_add_part_popupmenu() { wxMenu *menu = new wxMenu; - wxWindowID config_id_base = wxWindow::NewControlId(4); - std::vector menu_items = { L("Add part"), L("Add modifier"), L("Add generic") }; + + wxWindowID config_id_base = wxWindow::NewControlId(menu_items.size()+2); + int i = 0; for (auto& item : menu_items) { auto menu_item = new wxMenuItem(menu, config_id_base + i, _(item)); menu_item->SetBitmap(i == 0 ? m_icon_solidmesh : m_icon_modifiermesh); menu->Append(menu_item); i++; - } + } + + menu->AppendSeparator(); + auto menu_item = new wxMenuItem(menu, config_id_base + 3, _(L("Split to sub-objects"))); + menu_item->SetBitmap(m_bmp_split); + menu->Append(menu_item); wxWindow* win = get_tab_panel()->GetPage(0); @@ -860,6 +874,9 @@ wxMenu *create_add_part_popupmenu() case 2: on_btn_load(win, true, true); break; + case 3: + on_btn_split(); + break; default:{ get_settings_choice(menu, event.GetId(), false); break;} @@ -868,7 +885,7 @@ wxMenu *create_add_part_popupmenu() menu->AppendSeparator(); // Append settings popupmenu - auto menu_item = new wxMenuItem(menu, config_id_base + 3, _(L("Add settings"))); + menu_item = new wxMenuItem(menu, config_id_base + 4, _(L("Add settings"))); menu_item->SetBitmap(m_bmp_cog); auto sub_menu = create_add_settings_popupmenu(false); @@ -1087,16 +1104,17 @@ void on_btn_split() if (!item) return; auto volume_id = m_objects_model->GetVolumeIdByItem(item); + ModelVolume* volume; if (volume_id < 0) - return; - - auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; - DynamicPrintConfig& config = get_preset_bundle()->prints.get_edited_preset().config; - auto nozzle_dmrs_cnt = config.option("nozzle_diameter")->values.size(); + volume = (*m_objects)[m_selected_object_id]->volumes[0];//return; + else + volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; + DynamicPrintConfig& config = get_preset_bundle()->printers.get_edited_preset().config; + auto nozzle_dmrs_cnt = config.option("nozzle_diameter")->values.size(); if (volume->split(nozzle_dmrs_cnt) > 1) { - // TODO update model - m_parts_changed = true; - parts_changed(m_selected_object_id); + auto model_object = (*m_objects)[m_selected_object_id]; + for (auto id = 0; id < model_object->volumes.size(); id++) + m_objects_model->AddChild(item, model_object->volumes[id]->name, m_icon_solidmesh, false); } } diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index c52448ed6..dd6655e3c 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -384,12 +384,13 @@ wxDataViewItem PrusaObjectDataViewModel::Add(wxString &name, int instances_count wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_item, const wxString &name, - const wxIcon& icon) + const wxIcon& icon, + bool create_frst_child/* = true*/) { PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID(); if (!root) return wxDataViewItem(0); - if (root->GetChildren().Count() == 0) + if (root->GetChildren().Count() == 0 && create_frst_child) { auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, 0); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 12bb156cb..257b5e47c 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -350,7 +350,8 @@ public: wxDataViewItem Add(wxString &name, int instances_count, int scale); wxDataViewItem AddChild(const wxDataViewItem &parent_item, const wxString &name, - const wxIcon& icon); + const wxIcon& icon, + bool create_frst_child = true); wxDataViewItem Delete(const wxDataViewItem &item); void DeleteAll(); wxDataViewItem GetItemById(int obj_idx); From 128d0f77081712d92e5478e1a8ad04e29d026fe3 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 31 Jul 2018 12:04:01 +0200 Subject: [PATCH 082/119] Correct object splitting to parts (sub-objects) --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 3bfbfe736..07bc115b7 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -608,7 +608,6 @@ void add_object_to_list(const std::string &name, ModelObject* model_object) for (auto id = 0; id < model_object->volumes.size(); id++) m_objects_model->AddChild(item, model_object->volumes[id]->name, m_icon_solidmesh, false); - ModelObjectPtrs* objects = m_objects; // part_selection_changed(); #ifdef __WXMSW__ object_ctrl_selection_changed(); @@ -841,6 +840,14 @@ void get_settings_choice(wxMenu *menu, int id, bool is_part) update_settings_list(); } +bool cur_item_hase_children() +{ + wxDataViewItemArray children; + if (m_objects_model->GetChildren(m_objects_ctrl->GetSelection(), children) > 0) + return true; + return false; +} + wxMenu *create_add_part_popupmenu() { wxMenu *menu = new wxMenu; @@ -860,6 +867,7 @@ wxMenu *create_add_part_popupmenu() auto menu_item = new wxMenuItem(menu, config_id_base + 3, _(L("Split to sub-objects"))); menu_item->SetBitmap(m_bmp_split); menu->Append(menu_item); + menu_item->Enable(!cur_item_hase_children()); wxWindow* win = get_tab_panel()->GetPage(0); @@ -1111,11 +1119,15 @@ void on_btn_split() volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; DynamicPrintConfig& config = get_preset_bundle()->printers.get_edited_preset().config; auto nozzle_dmrs_cnt = config.option("nozzle_diameter")->values.size(); - if (volume->split(nozzle_dmrs_cnt) > 1) { - auto model_object = (*m_objects)[m_selected_object_id]; - for (auto id = 0; id < model_object->volumes.size(); id++) - m_objects_model->AddChild(item, model_object->volumes[id]->name, m_icon_solidmesh, false); - } + auto split_rez = volume->split(nozzle_dmrs_cnt); + if (split_rez == 1) { + wxMessageBox(_(L("The selected object couldn't be split because it contains only one part."))); + return; + } + + auto model_object = (*m_objects)[m_selected_object_id]; + for (auto id = 0; id < model_object->volumes.size(); id++) + m_objects_model->AddChild(item, model_object->volumes[id]->name, m_icon_solidmesh, false); } void on_btn_move_up(){ From 19411df0e4add66308af34e72c8232b6b4de0aaf Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 31 Jul 2018 15:31:12 +0200 Subject: [PATCH 083/119] Correct split for the parts too --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 95 ++++++++++++++++++++------- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 3 +- xs/src/slic3r/GUI/wxExtensions.cpp | 31 +++++++++ xs/src/slic3r/GUI/wxExtensions.hpp | 1 + 4 files changed, 105 insertions(+), 25 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 07bc115b7..59688606e 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -277,7 +277,7 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win) }); btn_delete ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_del(); }); - btn_split ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_split(); }); + btn_split ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_split(true); }); m_btn_move_up ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_move_up(); }); m_btn_move_down ->Bind(wxEVT_BUTTON, [](wxEvent&) { on_btn_move_down(); }); //*** @@ -721,11 +721,9 @@ void update_settings_list() m_option_sizer->Clear(true); - printf("update_settings_list\n"); - if (m_config) { - auto extra_column = [](wxWindow* parent, const Line& line) + auto extra_column = [](wxWindow* parent, const Line& line) { auto opt_key = (line.get_options())[0].opt_id; //we assume that we have one option per line @@ -848,6 +846,21 @@ bool cur_item_hase_children() return false; } +wxMenuItem* menu_item_split(wxMenu* menu, int id) { + auto menu_item = new wxMenuItem(menu, id, _(L("Split to parts"))); + menu_item->SetBitmap(m_bmp_split); + return menu_item; +} + +wxMenuItem* menu_item_settings(wxMenu* menu, int id) { + auto menu_item = new wxMenuItem(menu, id, _(L("Add settings"))); + menu_item->SetBitmap(m_bmp_cog); + + auto sub_menu = create_add_settings_popupmenu(false); + menu_item->SetSubMenu(sub_menu); + return menu_item; +} + wxMenu *create_add_part_popupmenu() { wxMenu *menu = new wxMenu; @@ -864,11 +877,14 @@ wxMenu *create_add_part_popupmenu() } menu->AppendSeparator(); - auto menu_item = new wxMenuItem(menu, config_id_base + 3, _(L("Split to sub-objects"))); - menu_item->SetBitmap(m_bmp_split); + auto menu_item = menu_item_split(menu, config_id_base + i); menu->Append(menu_item); menu_item->Enable(!cur_item_hase_children()); + menu->AppendSeparator(); + // Append settings popupmenu + menu->Append(menu_item_settings(menu, config_id_base + i + 1)); + wxWindow* win = get_tab_panel()->GetPage(0); menu->Bind(wxEVT_MENU, [config_id_base, win, menu](wxEvent &event){ @@ -883,7 +899,7 @@ wxMenu *create_add_part_popupmenu() on_btn_load(win, true, true); break; case 3: - on_btn_split(); + on_btn_split(false); break; default:{ get_settings_choice(menu, event.GetId(), false); @@ -891,19 +907,34 @@ wxMenu *create_add_part_popupmenu() } }); - menu->AppendSeparator(); - // Append settings popupmenu - menu_item = new wxMenuItem(menu, config_id_base + 4, _(L("Add settings"))); - menu_item->SetBitmap(m_bmp_cog); - - auto sub_menu = create_add_settings_popupmenu(false); - - menu_item->SetSubMenu(sub_menu); - menu->Append(menu_item); - return menu; } +wxMenu *create_part_settings_popupmenu() +{ + wxMenu *menu = new wxMenu; + wxWindowID config_id_base = wxWindow::NewControlId(2); + + menu->Append(menu_item_split(menu, config_id_base)); + + menu->AppendSeparator(); + // Append settings popupmenu + menu->Append(menu_item_settings(menu, config_id_base + 1)); + + menu->Bind(wxEVT_MENU, [config_id_base, menu](wxEvent &event){ + switch (event.GetId() - config_id_base) { + case 0: + on_btn_split(true); + break; + default:{ + get_settings_choice(menu, event.GetId(), true); + break; } + } + }); + + return menu; +} + wxMenu *create_add_settings_popupmenu(bool is_part) { wxMenu *menu = new wxMenu; @@ -915,7 +946,7 @@ wxMenu *create_add_settings_popupmenu(bool is_part) for (auto cat : settings_menu) { - auto menu_item = new wxMenuItem(menu, wxID_ANY/*config_id_base + inc*/, _(cat.first)); + auto menu_item = new wxMenuItem(menu, wxID_ANY, _(cat.first)); menu_item->SetBitmap(categories.find(cat.first) == categories.end() ? wxNullBitmap : categories.at(cat.first)); menu->Append(menu_item); @@ -947,7 +978,7 @@ void object_ctrl_context_menu() // obj_idx = m_objects_model->GetIdByItem(parent); // auto volume_id = m_objects_model->GetVolumeIdByItem(item); // if (volume_id < 0) return; - auto menu = create_add_settings_popupmenu(true); + auto menu = create_part_settings_popupmenu(); get_tab_panel()->GetPage(0)->PopupMenu(menu); } } @@ -1106,15 +1137,17 @@ void on_btn_del() // #endif //__WXMSW__ } -void on_btn_split() +void on_btn_split(const bool split_part) { auto item = m_objects_ctrl->GetSelection(); if (!item) return; auto volume_id = m_objects_model->GetVolumeIdByItem(item); ModelVolume* volume; - if (volume_id < 0) - volume = (*m_objects)[m_selected_object_id]->volumes[0];//return; + if (volume_id < 0) { + if (split_part) return; + else + volume = (*m_objects)[m_selected_object_id]->volumes[0]; } else volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; DynamicPrintConfig& config = get_preset_bundle()->printers.get_edited_preset().config; @@ -1126,8 +1159,22 @@ void on_btn_split() } auto model_object = (*m_objects)[m_selected_object_id]; - for (auto id = 0; id < model_object->volumes.size(); id++) - m_objects_model->AddChild(item, model_object->volumes[id]->name, m_icon_solidmesh, false); + + if (split_part) { + auto parent = m_objects_model->GetParent(item); + m_objects_model->DeleteChildren(parent); + + for (auto id = 0; id < model_object->volumes.size(); id++) + m_objects_model->AddChild(parent, model_object->volumes[id]->name, + model_object->volumes[id]->modifier ? m_icon_modifiermesh : m_icon_solidmesh, false); + + m_objects_ctrl->Expand(parent); + } + else { + for (auto id = 0; id < model_object->volumes.size(); id++) + m_objects_model->AddChild(item, model_object->volumes[id]->name, m_icon_solidmesh, false); + m_objects_ctrl->Expand(item); + } } void on_btn_move_up(){ diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index e4484e72a..17c99f65c 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -48,6 +48,7 @@ void show_collpane_settings(bool expert_mode); wxMenu *create_add_settings_popupmenu(bool is_part); wxMenu *create_add_part_popupmenu(); +wxMenu *create_part_settings_popupmenu(); // Add object to the list //void add_object(const std::string &name); @@ -88,7 +89,7 @@ void load_lambda(wxWindow* parent, ModelObject* model_object, void on_btn_load(wxWindow* parent, bool is_modifier = false, bool is_lambda = false); void on_btn_del(); -void on_btn_split(); +void on_btn_split(const bool split_part); void on_btn_move_up(); void on_btn_move_down(); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index dd6655e3c..020ea570c 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -456,7 +456,9 @@ wxDataViewItem PrusaObjectDataViewModel::Delete(const wxDataViewItem &item) // set m_containet to FALSE if parent has no child if (node_parent && node_parent->GetChildCount() == 0){ +#ifndef __WXGTK__ node_parent->m_container = false; +#endif //__WXGTK__ ret_item = parent; } @@ -475,6 +477,35 @@ void PrusaObjectDataViewModel::DeleteAll() } } +void PrusaObjectDataViewModel::DeleteChildren(wxDataViewItem& parent) +{ + PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent.GetID(); + if (!root) // happens if item.IsOk()==false + return; + + // first remove the node from the parent's array of children; + // NOTE: MyObjectTreeModelNodePtrArray is only an array of _pointers_ + // thus removing the node from it doesn't result in freeing it + auto& children = root->GetChildren(); + for (int id = root->GetChildCount() - 1; id >= 0; --id) + { + auto node = children[id]; + auto item = wxDataViewItem(node); + children.RemoveAt(id); + + // free the node + delete node; + + // notify control + ItemDeleted(parent, item); + } + + // set m_containet to FALSE if parent has no child +#ifndef __WXGTK__ + root->m_container = false; +#endif //__WXGTK__ +} + wxDataViewItem PrusaObjectDataViewModel::GetItemById(int obj_idx) { if (obj_idx >= m_objects.size()) diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 257b5e47c..ac9fd4da0 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -354,6 +354,7 @@ public: bool create_frst_child = true); wxDataViewItem Delete(const wxDataViewItem &item); void DeleteAll(); + void DeleteChildren(wxDataViewItem& parent); wxDataViewItem GetItemById(int obj_idx); int GetIdByItem(wxDataViewItem& item); int GetVolumeIdByItem(wxDataViewItem& item); From ed5f5239aa10d32fd48668ae2b0d8cc01d044eef Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 1 Aug 2018 12:49:39 +0200 Subject: [PATCH 084/119] Added tooltips for objects list Updated icons with transparency --- resources/icons/add_object.png | Bin 591 -> 829 bytes resources/icons/exclamation_mark_.png | Bin 327 -> 1052 bytes resources/icons/lambda.png | Bin 0 -> 913 bytes resources/icons/object.png | Bin 618 -> 1017 bytes resources/icons/split.png | Bin 0 -> 1021 bytes xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 31 +++++++++++++++++++++----- xs/src/slic3r/GUI/wxExtensions.cpp | 6 +++++ xs/src/slic3r/GUI/wxExtensions.hpp | 1 + 8 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 resources/icons/lambda.png create mode 100644 resources/icons/split.png diff --git a/resources/icons/add_object.png b/resources/icons/add_object.png index 40059f5ac0de3b5c5db4ab492b4de5952fe6f25d..ffc958edc4fca5a58a8600c0495eba3941038262 100644 GIT binary patch delta 807 zcmV+?1K9k}1ic23BYy#cX+uL$b5ch_AW20-HZeIiHZ3wPF#rH4k#&*JE5l(N$6p(3 znrXzr!C?ufO-zZ4vL%$XX3B8czWb%N`S$&OrRAzzSCqK;b>J`Hs+^S~QgU!|CNAjf z^WD@W`#e3L=k>gw&*#(gd>*hzb4p&X?}L27&?4hO?_6x&>wkQr0UIt_aKsf|9Sw)4 zsA=!F5-WD?w`$dn`_~$iDO~|ugYbx=YKHKH@YJfITD&FPrexzu;S*t>CKnXGvGhcR zpDoT*_|sx78VP~DS=gKT#fe|6WVO7oyqvClZbkXIkM$CFsxUhvYp2W(bRvus#LFaO zgczisVey0b34hQlJ8I-Bk`WaZ^;yAp4)qAs{jB1 z32;bRa{vGf6951U69E94oEQKA0bxl*K~y-6b<;m<6;Tic@Zaux@eh(HmKMgu5J|p( z5Nv{2ilh+i?X(H_0n%xyfuMaLRf<4JBYp@43&B<^g(o6uG|98rvzwdsxp29A&&-^; zb7n477=L8d*&pCL{@@L!3fnFGz-+M2P-88DC)mVFNM097mN3R#Nl*s9#MOd$8W)58 z!eIywbM_&Dui{jeQWu$rx%O%ZR&X6g0lwhoe}YSFIsP|-8DSm!IKuXX;6;2&g7dhB zbFBs=JkAyG;27VqkorFcdz*8O``OPBwAp5`8-HDn@EP+-P?j)@dZ_uTfK}9e6mdtm z8(V9y64SL%VQl{;`|nVwwe}MOR z=d`8I@H1ttITf{YxPraZzEco9)QtHUPjJcE8R`1jj_d8*=2-KP#(0j)CQN7BmQuJ1 l7a*_^?1kph^aZXk{tE!YT?uli7wrH5002ovPDHLkV1n)!jl=)| delta 567 zcmV-70?7Tn2G0bLBYyw^b5ch_0Itp)=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGm zbN~PnbOGLGA9w%&0pv+UK~y+TRg+JvaZwb;_qpT_82B?J1BT2bLng{V$`_!ND4Cd; z%D`NF4&T6gm4pnGWMV=LUdg~r`Lo{hJg<%WtJPlnS!+GEbAR?x_xoLLw;MxqIQ*4( zJT6Kpna}6cbbYy8N+1wmj#>3NxY=wZ91e3Z7K=%>T4mmBHlH0Li^YPPh8YG!p%4o& z*lxEhg4Jpzr_)Jhvl;7lyPd1s?G}f_Au63tQ%EEdvfJ&RWB-r*c{6 zem|J`Hs+^S~QgU!|CNAjf z^WD@W`#e3L=k>gw&*#(gd>*hzb4p&X?}L27&?4hO?_6x&>wkQr0UIt_aKsf|9Sw)4 zsA=!F5-WD?w`$dn`_~$iDO~|ugYbx=YKHKH@YJfITD&FPrexzu;S*t>CKnXGvGhcR zpDoT*_|sx78VP~DS=gKT#fe|6WVO7oyqvClZbkXIkM$CFsxUhvYp2W(bRvus#LFaO zgczisVey0b34hQlJ8IBL_t(IjeSu~XcJ)&o%y~^*mRT4+HA8iX{i;9y-3f3_nwL<6czDcwH5K`p~Z_R zUi6^e(#`U_MO?*J;BNhJaR z$d~{?Dwusi2E4O>jvszq4&vm}e{%y6U$Id4?)_5K$H~^sR+0Dd=~Z&HX}`2BvJv+u z+qZh+=UtRC&v4*DjYrex0DXsSBi3|+q){%ad&Tc^vN3tKM;BDR$b`F38CmxVCs;E+NcukSOfs@r@Bn<$I>Mf?s?^;X!^`w_lF1DTFHsdkgdmC zIlpKo$yT3uS(XmUWc}`$^mfW=cPMW*GLbW>1leld%QCA~k3l9>Ff&rnIFoW2kf8)f iArD_xhL_*BYX1NYIOVS08S7sF0000Px#1ZP1_K>z@;j|==^1(UA<7k>cUNkl*h^V{@S(0;*kBA_5t1YYIG}kA|Q=Cz2rGVdwCR z;H$t)55W7TBt|w;uL!xXK67ASk{kFuvzw410rC^rcAS74=S6++TJilEXi6>McX0lJ z7|iU1P7q7rew1NEzC`jUDDYq(Z-(ne^@!?3Qtc^-u*E7FMv{aja9GIE?RK6WMzX0$ gq8eg&J`Hs+^S~QgU!|CNAjf^WD@W`#e3L=k>gw&*#(gd>*hzb4p&X z?}L27&?4hO?_6x&>wKaC8!lRK#1&l~4Tq)Ez@Q9*n zhVX>&)T*Icyd~VGWaCNU6Jehw7Zkp+^hAZ9EzVT<(_$?e34y&?*qiyqiC?T_wY;#r zoUVLsMftgp^%8fgFgqh_r_2s?B8(Hn%Oqoj7^I(J@q_pY&?`G?jH+;o@=my*6o`UqSAGS-p% z{eBL71)czznPmy~G4L61tRj2w4cGzRt{_M3Ye^4C$wg6EQ4|Ik@Cw+G5a_i(gZDnL zjA`o;+md$Mu`TZGoEuB}4)j~c4-$W_w3A*2*amh}a$?wh-~hM_9ByoMy1-4~7x2)` zvb4cEx32;pfWJTkd;zXSti|2TjIt~hLSQzV#Xa%f?{~Z1JHSt16S!e!dl73bF03I3 zfTn3;N&gAqSl$Bb$n*J}^QJU21JF6-(@2$LIDinsC6?C~02Yfy2qBy*1G%J?D+;K9 nr<@JNX34t&9>u!%K1kvpr}3V-p+x%d00000NkvXXu0mjf8P=-p literal 0 HcmV?d00001 diff --git a/resources/icons/object.png b/resources/icons/object.png index ff4974a532b083cd7e8f741b1a2c81d2d1184045..c85cbaf2fa5905e4738034d7bdb069b9abc4f10f 100644 GIT binary patch delta 996 zcmVlP4z`63!j` z_SQ@fhN@p^oq?uj+kWo>&mnwm+xF+NZGV-)Exugs*6WMAF#Ia|PF)Kefo}`WFY8+J z1TJ=<<55o-iHhWwqUvR?_< zwf0jG1UmrUNJ>cFA$dvCx^r$JNs?B%T>f!{z!5m=Nyg`WWMju)oQiDQ^1FoYPH&6sZ^Q+kOBP=B`uL$ zDwoSof*@GSvTQYuPx#1ZP1_K>z@;j|==^1poj532;bRa{vGm zbN~PnbOGLGA9w%&0sl!vK~y+TjZ?qNfl(Ab@9ReOv6_rTgp_1pmrdb*_c^@fGkkqdz1{2F=Q;PBdmhT;@qZ8!1SpC^s;crH*zfmr zzu(F0^}ZuS&*zg@Xu#(LpQ7b*Nxfc=`u#o=OePauuUE?F^HeMrDHsgCnM6{{nZ#UO&&v)Rm~&sG44zk#;&dOcYz7Fw^@q~exT zDn&>XkH@(JSt7p$lH$Xy-ENm}j7Fn`iW7;%>w<7NEM~JA+F^`FBT+7wh12O2kw`?u zVlm-xI7F#b62sx}%@VAER*$l7w;Puy9x-n*TA>HIW;5GqpB!1xXLdi zxhgx^GDXSWj?1RP3TQxXYDuC(MQ%=Bu~mhw64+cTAR8pCucQE0Qj%?}6yY17;GAES zs$i;Ts%M~N$E9FXl#*r@k>g7FXt#Bv$C=6)S^`fSBQuTAW;zSx}OhpQivaGchT@w8U0PKeRZts8~NOGbJ@A zIk6yLAE++7B)>qvxF9F9M6Vz(T}dD041K6OfF9C^`v}N^he>K4Fd&M6K7M>HO$!*1 z?U~Nb0mVV?P70o`&Sr*|W@frZdWH-P8WT$=?)E+$AkuChz4R!%?3)JBqc2)E#7CU`^WX`8*k-r53J;43=cit|Wpi%+maNvLtnSmVc6v_Xc&y=Le3B)R zO=6<0&x8pUCJOid#>%g{az1cMRA|{;UY=_wCLCQ9eq~b0^(S-1VkfJsOA4Kn{qyab z4}aUL_>8%Y%hGSxy=OeHSd)AE+w+aN^-~Y(?u&VQ?REEVgFjlo{9?If8uPi&>A#Np z#G+TW;Blb8L}%BNX-~bDKYS~4>(PZe=Cj(N_p_c)d7oG)oVGskKf^AS``dr<$}y(9 zW}fjm1x&!41s;*b3=DinK$vl=HlH+5@Uo|iV~9m>@8p+U%?1K3`(=W>7jo48->wt# zdg8x=B|&4Ky_w1DV5OL^kaU32_5!1^K!dBF;~Yn;bk+`~^9Ld(Fd2CAO*~yx zB*haQnY)Vl$DtXU`470J{% literal 0 HcmV?d00001 diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 59688606e..c1829dada 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -101,12 +101,15 @@ void get_options_menu(settings_menu_hierarchy& settings_menu, bool is_part) { auto options = get_options(is_part); + auto extruders_cnt = get_preset_bundle()->printers.get_edited_preset().config.option("nozzle_diameter")->values.size(); + DynamicPrintConfig config; for (auto& option : options) { auto const opt = config.def()->get(option); auto category = opt->category; - if (category.empty()) continue; + if (category.empty() || + (category == "Extruders" && extruders_cnt == 1)) continue; std::pair option_label(option, opt->label); std::vector< std::pair > new_category; @@ -135,7 +138,7 @@ void set_objects_from_model(Model &model) { } void init_mesh_icons(){ - m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("lambda_.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); + m_icon_modifiermesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); m_icon_solidmesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); // init icon for manifold warning @@ -195,7 +198,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->AppendColumn(column3); // column 4 of the view control: - m_objects_ctrl->AppendBitmapColumn("", 4, wxDATAVIEW_CELL_INERT, 25, + m_objects_ctrl->AppendBitmapColumn(" ", 4, wxDATAVIEW_CELL_INERT, 25, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) @@ -248,6 +251,19 @@ wxBoxSizer* content_objects_list(wxWindow *win) }); #endif //__WXMSW__ + m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { + wxPoint pt = event.GetPosition(); + wxDataViewItem item; + wxDataViewColumn* col; + m_objects_ctrl->HitTest(pt, item, col); + if (col->GetTitle() == " " && item) + m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("For object settings changing click a right button on icon"))); + else + m_objects_ctrl->GetMainWindow()->SetToolTip(""); +// if (m_objects_model->GetIcon(item) == m_icon_manifold_warning) +// m_objects_ctrl->GetMainWindow()->SetToolTip("Tru-lala"); + }); + return objects_sz; } @@ -604,9 +620,11 @@ void add_object_to_list(const std::string &name, ModelObject* model_object) m_objects_model->SetValue(variant, item, 0); } - if (model_object->volumes.size() > 1) + if (model_object->volumes.size() > 1) { for (auto id = 0; id < model_object->volumes.size(); id++) m_objects_model->AddChild(item, model_object->volumes[id]->name, m_icon_solidmesh, false); + m_objects_ctrl->Expand(item); + } // part_selection_changed(); #ifdef __WXMSW__ @@ -741,9 +759,12 @@ void update_settings_list() if (opt_keys.size() == 1 && opt_keys[0] == "extruder") return; + auto extruders_cnt = get_preset_bundle()->printers.get_edited_preset().config.option("nozzle_diameter")->values.size(); + for (auto& opt_key : opt_keys) { auto category = (*m_config)->def()->get(opt_key)->category; - if (category.empty()) continue; + if (category.empty() || + (category == "Extruders" && extruders_cnt==1)) continue; std::vector< std::string > new_category; diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 020ea570c..e7bb27b92 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -566,6 +566,12 @@ wxString PrusaObjectDataViewModel::GetScale(const wxDataViewItem &item) const return node->m_scale; } +wxIcon PrusaObjectDataViewModel::GetIcon(const wxDataViewItem &item) const +{ + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + return node->m_icon; +} + void PrusaObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem &item, unsigned int col) const { wxASSERT(item.IsOk()); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index ac9fd4da0..fbe8129fe 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -365,6 +365,7 @@ public: wxString GetName(const wxDataViewItem &item) const; wxString GetCopy(const wxDataViewItem &item) const; wxString GetScale(const wxDataViewItem &item) const; + wxIcon GetIcon(const wxDataViewItem &item) const; // helper methods to change the model From 6fb4ced41012096519c24907365887c1b92a629f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 1 Aug 2018 15:54:56 +0200 Subject: [PATCH 085/119] Fix for previous commit --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 43 ++++++++++++++++++++------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index c1829dada..a0dee4117 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -204,16 +204,35 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { object_ctrl_selection_changed(); -#ifdef __WXOSX__ - update_extruder_in_config(g_selected_extruder); -#endif //__WXOSX__ +// #ifdef __WXOSX__ +// update_extruder_in_config(g_selected_extruder); +// #endif //__WXOSX__ }); - m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxEvent& event) - { +// m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxDataViewEvent& event) + m_objects_ctrl->GetMainWindow()->Bind(wxEVT_LEFT_DOWN, [](wxMouseEvent& event) { + wxPoint pt = event.GetPosition(); + wxDataViewItem item; + wxDataViewColumn* col; + m_objects_ctrl->HitTest(pt, item, col); + wxString title = col->GetTitle(); + if (item && (title==" " || title == _("Name"))) { + if (item != m_objects_ctrl->GetSelection()) { + m_objects_ctrl->Select(item); + object_ctrl_selection_changed(); + g_prevent_list_events = false; + } + + if (title == " ") + object_ctrl_context_menu(); + else if (title == _("Name") && pt.x >15 && + m_objects_model->GetParent(item) == wxDataViewItem(0)) + { +// auto menu = create_add_settings_popupmenu(true);// create_correction_stl_menu !!! +// get_tab_panel()->GetPage(0)->PopupMenu(menu); + } + } event.Skip(); - object_ctrl_context_menu(); - }); m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) @@ -257,11 +276,11 @@ wxBoxSizer* content_objects_list(wxWindow *win) wxDataViewColumn* col; m_objects_ctrl->HitTest(pt, item, col); if (col->GetTitle() == " " && item) - m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("For object settings changing click a right button on icon"))); + m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("For object settings changing click on icon"))); +// else if (col->GetTitle() == _("Name") && item && m_objects_model->GetIcon(item) == m_icon_manifold_warning ) +// m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("Information about auto-repaired errors\n To fix errors, click on the icon"))); else m_objects_ctrl->GetMainWindow()->SetToolTip(""); -// if (m_objects_model->GetIcon(item) == m_icon_manifold_warning) -// m_objects_ctrl->GetMainWindow()->SetToolTip("Tru-lala"); }); return objects_sz; @@ -717,6 +736,10 @@ void object_ctrl_selection_changed() event.SetId(m_selected_object_id); get_main_frame()->ProcessWindowEvent(event); } + +#ifdef __WXOSX__ + update_extruder_in_config(g_selected_extruder); +#endif //__WXOSX__ } //update_optgroup From dc8cdcc2ba27fc31f2d3d08a4b46e1ae255ccc00 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 9 Aug 2018 12:02:09 +0200 Subject: [PATCH 086/119] Added tooltips with manifold_warning information --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 43 +++++++++++++++++++++++---- xs/src/slic3r/GUI/wxExtensions.cpp | 2 +- xs/src/slic3r/GUI/wxExtensions.hpp | 5 ++-- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index a0dee4117..fcccede41 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -228,6 +228,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) else if (title == _("Name") && pt.x >15 && m_objects_model->GetParent(item) == wxDataViewItem(0)) { + // ys_FIXME // auto menu = create_add_settings_popupmenu(true);// create_correction_stl_menu !!! // get_tab_panel()->GetPage(0)->PopupMenu(menu); } @@ -275,12 +276,44 @@ wxBoxSizer* content_objects_list(wxWindow *win) wxDataViewItem item; wxDataViewColumn* col; m_objects_ctrl->HitTest(pt, item, col); - if (col->GetTitle() == " " && item) - m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("For object settings changing click on icon"))); -// else if (col->GetTitle() == _("Name") && item && m_objects_model->GetIcon(item) == m_icon_manifold_warning ) -// m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("Information about auto-repaired errors\n To fix errors, click on the icon"))); + if (!item) return; + + if ( col->GetTitle() == " " ) + m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("Click the icon to change the object settings"))); + else if ( col->GetTitle() == _("Name") && + m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) { + int obj_idx = m_objects_model->GetIdByItem(item); + auto& stats = (*m_objects)[obj_idx]->volumes[0]->mesh.stl.stats; + int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + + stats.facets_added + stats.facets_reversed + stats.backwards_edges; + + wxString tooltip = wxString::Format(_(L("Auto-repaired (%d errors):\n")), errors); + + std::map error_msg; + error_msg[L("degenerate facets")] = stats.degenerate_facets; + error_msg[L("edges fixed")] = stats.edges_fixed; + error_msg[L("facets removed")] = stats.facets_removed; + error_msg[L("facets added")] = stats.facets_added; + error_msg[L("facets reversed")] = stats.facets_reversed; + error_msg[L("backwards edges")] = stats.backwards_edges; + + for (auto error: error_msg) + { + if (error.second > 0) + tooltip += wxString::Format(_("\t%d %s\n"), error.second, error.first); + } +// OR +// tooltip += wxString::Format(_(L("%d degenerate facets, %d edges fixed, %d facets removed, " +// "%d facets added, %d facets reversed, %d backwards edges")), +// stats.degenerate_facets, stats.edges_fixed, stats.facets_removed, +// stats.facets_added, stats.facets_reversed, stats.backwards_edges); + + // ysFIXME uncomment this when fix_error function will be exist +// tooltip += _(L("Click the icon to fix errors")); + m_objects_ctrl->GetMainWindow()->SetToolTip(tooltip); + } else - m_objects_ctrl->GetMainWindow()->SetToolTip(""); + m_objects_ctrl->GetMainWindow()->SetToolTip(""); // hide tooltip }); return objects_sz; diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index e7bb27b92..71f49a970 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -566,7 +566,7 @@ wxString PrusaObjectDataViewModel::GetScale(const wxDataViewItem &item) const return node->m_scale; } -wxIcon PrusaObjectDataViewModel::GetIcon(const wxDataViewItem &item) const +wxIcon& PrusaObjectDataViewModel::GetIcon(const wxDataViewItem &item) const { PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); return node->m_icon; diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index fbe8129fe..daff37a60 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -155,6 +155,7 @@ class PrusaObjectDataViewModelNode { PrusaObjectDataViewModelNode* m_parent; MyObjectTreeModelNodePtrArray m_children; + wxIcon m_empty_icon; public: PrusaObjectDataViewModelNode(const wxString &name, int instances_count=1, int scale=100) { m_parent = NULL; @@ -198,7 +199,7 @@ public: } wxString m_name; - wxIcon m_icon; + wxIcon& m_icon = m_empty_icon; wxString m_copy; wxString m_scale; std::string m_type; @@ -365,7 +366,7 @@ public: wxString GetName(const wxDataViewItem &item) const; wxString GetCopy(const wxDataViewItem &item) const; wxString GetScale(const wxDataViewItem &item) const; - wxIcon GetIcon(const wxDataViewItem &item) const; + wxIcon& GetIcon(const wxDataViewItem &item) const; // helper methods to change the model From fede9e95ff38f01f194d34f0e72e4b12cf5a1828 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 9 Aug 2018 15:55:08 +0200 Subject: [PATCH 087/119] Experiments with wxEVT_LEFT_DOWN/wxEVT_MOTION on OSX --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index fcccede41..3b5ae37b9 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -12,6 +12,7 @@ #include #include #include "Geometry.hpp" +#include "slic3r/Utils/FixModelByWin10.hpp" namespace Slic3r { @@ -203,6 +204,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { + auto msg_box = wxMessageBox("wxEVT_DATAVIEW_SELECTION_CHANGED"); object_ctrl_selection_changed(); // #ifdef __WXOSX__ // update_extruder_in_config(g_selected_extruder); @@ -212,6 +214,8 @@ wxBoxSizer* content_objects_list(wxWindow *win) // m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxDataViewEvent& event) m_objects_ctrl->GetMainWindow()->Bind(wxEVT_LEFT_DOWN, [](wxMouseEvent& event) { wxPoint pt = event.GetPosition(); + wxString msg = wxString::Format("wxEVT_LEFT_DOWN\n Position: x - %d, y - %d", pt.x, pt.y); + auto msg_box = wxMessageBox(msg); wxDataViewItem item; wxDataViewColumn* col; m_objects_ctrl->HitTest(pt, item, col); @@ -226,11 +230,11 @@ wxBoxSizer* content_objects_list(wxWindow *win) if (title == " ") object_ctrl_context_menu(); else if (title == _("Name") && pt.x >15 && - m_objects_model->GetParent(item) == wxDataViewItem(0)) + m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) { // ys_FIXME -// auto menu = create_add_settings_popupmenu(true);// create_correction_stl_menu !!! -// get_tab_panel()->GetPage(0)->PopupMenu(menu); +// if (is_windows10()) +// fix_through_netfabb(); } } event.Skip(); @@ -273,6 +277,8 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { wxPoint pt = event.GetPosition(); + wxString msg = wxString::Format("wxEVT_MOTION\n Position: x - %d, y - %d", pt.x, pt.y); + auto msg_box = wxMessageBox(msg); wxDataViewItem item; wxDataViewColumn* col; m_objects_ctrl->HitTest(pt, item, col); @@ -308,8 +314,9 @@ wxBoxSizer* content_objects_list(wxWindow *win) // stats.degenerate_facets, stats.edges_fixed, stats.facets_removed, // stats.facets_added, stats.facets_reversed, stats.backwards_edges); - // ysFIXME uncomment this when fix_error function will be exist -// tooltip += _(L("Click the icon to fix errors")); + if (is_windows10()) + tooltip += _(L("Click the icon to fix STL through Netfabb")); + m_objects_ctrl->GetMainWindow()->SetToolTip(tooltip); } else From 72c77a3592b60c85f79aa814bb81a1d82e42da94 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 9 Aug 2018 17:33:44 +0200 Subject: [PATCH 088/119] Next experiment --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 40 ++++++++++++++------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 3b5ae37b9..ea0f0a300 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -215,28 +215,30 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->GetMainWindow()->Bind(wxEVT_LEFT_DOWN, [](wxMouseEvent& event) { wxPoint pt = event.GetPosition(); wxString msg = wxString::Format("wxEVT_LEFT_DOWN\n Position: x - %d, y - %d", pt.x, pt.y); - auto msg_box = wxMessageBox(msg); + wxMessageBox(msg); wxDataViewItem item; wxDataViewColumn* col; m_objects_ctrl->HitTest(pt, item, col); wxString title = col->GetTitle(); - if (item && (title==" " || title == _("Name"))) { - if (item != m_objects_ctrl->GetSelection()) { - m_objects_ctrl->Select(item); - object_ctrl_selection_changed(); - g_prevent_list_events = false; - } - - if (title == " ") - object_ctrl_context_menu(); - else if (title == _("Name") && pt.x >15 && - m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) - { - // ys_FIXME -// if (is_windows10()) -// fix_through_netfabb(); - } + if (!item) { + event.Skip(); + return; } + if (item != m_objects_ctrl->GetSelection()) { + m_objects_ctrl->Select(item); + object_ctrl_selection_changed(); + g_prevent_list_events = false; + } + + if (title == " ") + object_ctrl_context_menu(); + // ys_FIXME +// else if (title == _("Name") && pt.x >15 && +// m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) +// { +// if (is_windows10()) +// fix_through_netfabb(); +// } event.Skip(); }); @@ -277,8 +279,8 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { wxPoint pt = event.GetPosition(); - wxString msg = wxString::Format("wxEVT_MOTION\n Position: x - %d, y - %d", pt.x, pt.y); - auto msg_box = wxMessageBox(msg); + wxString msg = wxString::Format("wxEVT_MOTION\n Position: x = %d, y = %d", pt.x, pt.y); + wxMessageBox(msg, wxEmptyString, 4, nullptr, pt.x, pt.y); wxDataViewItem item; wxDataViewColumn* col; m_objects_ctrl->HitTest(pt, item, col); From 1029a4c0e031e7f4ca2ccf2a3971f3aefc024472 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 9 Aug 2018 17:53:34 +0200 Subject: [PATCH 089/119] Experiments with tooltips --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index ea0f0a300..bdd0e4640 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -204,8 +204,9 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { - auto msg_box = wxMessageBox("wxEVT_DATAVIEW_SELECTION_CHANGED"); + m_objects_ctrl->SetToolTip("wxEVT_DATAVIEW_SELECTION_CHANGED"); object_ctrl_selection_changed(); + m_objects_ctrl->GetMainWindow()->SetToolTip("wxEVT_DATAVIEW_SELECTION_CHANGED from MainWindow"); // #ifdef __WXOSX__ // update_extruder_in_config(g_selected_extruder); // #endif //__WXOSX__ From a7c29b98bd69275abf61d747df49aed51d835cc8 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 10 Aug 2018 08:26:15 +0200 Subject: [PATCH 090/119] Try to understand wxEVT_MOTION on OSX --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index bdd0e4640..977f6fffb 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -204,9 +204,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { - m_objects_ctrl->SetToolTip("wxEVT_DATAVIEW_SELECTION_CHANGED"); object_ctrl_selection_changed(); - m_objects_ctrl->GetMainWindow()->SetToolTip("wxEVT_DATAVIEW_SELECTION_CHANGED from MainWindow"); // #ifdef __WXOSX__ // update_extruder_in_config(g_selected_extruder); // #endif //__WXOSX__ @@ -279,7 +277,8 @@ wxBoxSizer* content_objects_list(wxWindow *win) #endif //__WXMSW__ m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { - wxPoint pt = event.GetPosition(); + m_objects_ctrl->GetMainWindow()->SetToolTip("wxEVT_MOTION"); +/* wxPoint pt = event.GetPosition(); wxString msg = wxString::Format("wxEVT_MOTION\n Position: x = %d, y = %d", pt.x, pt.y); wxMessageBox(msg, wxEmptyString, 4, nullptr, pt.x, pt.y); wxDataViewItem item; @@ -324,7 +323,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) } else m_objects_ctrl->GetMainWindow()->SetToolTip(""); // hide tooltip - }); +*/ }); return objects_sz; } From 0477d4d8028bf8eccdbf16b66f13c2483c15027a Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 10 Aug 2018 12:19:35 +0200 Subject: [PATCH 091/119] Fixed tooltip showing on Linux and OSX(maybe) --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 133 +++++++++++++------------- 1 file changed, 64 insertions(+), 69 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 977f6fffb..d07187485 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -157,6 +157,59 @@ bool is_part_settings_changed(){ return m_part_settings_changed; } static wxString dots("…", wxConvUTF8); +void set_tooltip_for_item(const wxPoint& pt) +{ + wxDataViewItem item; + wxDataViewColumn* col; + m_objects_ctrl->HitTest(pt, item, col); + if (!item) return; + + if (col->GetTitle() == " ") + m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings"))); + else if (col->GetTitle() == _("Name") && + m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) { + int obj_idx = m_objects_model->GetIdByItem(item); + auto& stats = (*m_objects)[obj_idx]->volumes[0]->mesh.stl.stats; + int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + + stats.facets_added + stats.facets_reversed + stats.backwards_edges; + + wxString tooltip = wxString::Format(_(L("Auto-repaired (%d errors):\n")), errors); + + std::map error_msg; + error_msg[L("degenerate facets")] = stats.degenerate_facets; + error_msg[L("edges fixed")] = stats.edges_fixed; + error_msg[L("facets removed")] = stats.facets_removed; + error_msg[L("facets added")] = stats.facets_added; + error_msg[L("facets reversed")] = stats.facets_reversed; + error_msg[L("backwards edges")] = stats.backwards_edges; + + for (auto error : error_msg) + { + if (error.second > 0) + tooltip += wxString::Format(_("\t%d %s\n"), error.second, error.first); + } +// OR +// tooltip += wxString::Format(_(L("%d degenerate facets, %d edges fixed, %d facets removed, " +// "%d facets added, %d facets reversed, %d backwards edges")), +// stats.degenerate_facets, stats.edges_fixed, stats.facets_removed, +// stats.facets_added, stats.facets_reversed, stats.backwards_edges); + + if (is_windows10()) + tooltip += _(L("Right button click the icon to fix STL through Netfabb")); + + m_objects_ctrl->GetMainWindow()->SetToolTip(tooltip); + } + else + m_objects_ctrl->GetMainWindow()->SetToolTip(""); // hide tooltip +} + +wxPoint get_mouse_position_in_control() { + const wxPoint& pt = wxGetMousePosition(); + wxWindow* win = m_objects_ctrl->GetMainWindow(); + return wxPoint(pt.x - win->GetScreenPosition().x, + pt.y - win->GetScreenPosition().y); +} + // ****** from GUI.cpp wxBoxSizer* content_objects_list(wxWindow *win) { @@ -205,29 +258,17 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { object_ctrl_selection_changed(); -// #ifdef __WXOSX__ -// update_extruder_in_config(g_selected_extruder); -// #endif //__WXOSX__ +#ifndef __WXMSW__ + set_tooltip_for_item(get_mouse_position_in_control()); +#endif //__WXMSW__ }); -// m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxDataViewEvent& event) - m_objects_ctrl->GetMainWindow()->Bind(wxEVT_LEFT_DOWN, [](wxMouseEvent& event) { - wxPoint pt = event.GetPosition(); - wxString msg = wxString::Format("wxEVT_LEFT_DOWN\n Position: x - %d, y - %d", pt.x, pt.y); - wxMessageBox(msg); + m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxDataViewEvent& event) { wxDataViewItem item; wxDataViewColumn* col; - m_objects_ctrl->HitTest(pt, item, col); + m_objects_ctrl->HitTest(get_mouse_position_in_control(), item, col); wxString title = col->GetTitle(); - if (!item) { - event.Skip(); - return; - } - if (item != m_objects_ctrl->GetSelection()) { - m_objects_ctrl->Select(item); - object_ctrl_selection_changed(); - g_prevent_list_events = false; - } + if (!item) return; if (title == " ") object_ctrl_context_menu(); @@ -256,10 +297,13 @@ wxBoxSizer* content_objects_list(wxWindow *win) }); #ifdef __WXMSW__ - m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) - { + m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { update_extruder_in_config(event.GetString()); }); + + m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { + set_tooltip_for_item(event.GetPosition()); + }); #else m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) { @@ -276,55 +320,6 @@ wxBoxSizer* content_objects_list(wxWindow *win) }); #endif //__WXMSW__ - m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { - m_objects_ctrl->GetMainWindow()->SetToolTip("wxEVT_MOTION"); -/* wxPoint pt = event.GetPosition(); - wxString msg = wxString::Format("wxEVT_MOTION\n Position: x = %d, y = %d", pt.x, pt.y); - wxMessageBox(msg, wxEmptyString, 4, nullptr, pt.x, pt.y); - wxDataViewItem item; - wxDataViewColumn* col; - m_objects_ctrl->HitTest(pt, item, col); - if (!item) return; - - if ( col->GetTitle() == " " ) - m_objects_ctrl->GetMainWindow()->SetToolTip(_(L("Click the icon to change the object settings"))); - else if ( col->GetTitle() == _("Name") && - m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) { - int obj_idx = m_objects_model->GetIdByItem(item); - auto& stats = (*m_objects)[obj_idx]->volumes[0]->mesh.stl.stats; - int errors = stats.degenerate_facets + stats.edges_fixed + stats.facets_removed + - stats.facets_added + stats.facets_reversed + stats.backwards_edges; - - wxString tooltip = wxString::Format(_(L("Auto-repaired (%d errors):\n")), errors); - - std::map error_msg; - error_msg[L("degenerate facets")] = stats.degenerate_facets; - error_msg[L("edges fixed")] = stats.edges_fixed; - error_msg[L("facets removed")] = stats.facets_removed; - error_msg[L("facets added")] = stats.facets_added; - error_msg[L("facets reversed")] = stats.facets_reversed; - error_msg[L("backwards edges")] = stats.backwards_edges; - - for (auto error: error_msg) - { - if (error.second > 0) - tooltip += wxString::Format(_("\t%d %s\n"), error.second, error.first); - } -// OR -// tooltip += wxString::Format(_(L("%d degenerate facets, %d edges fixed, %d facets removed, " -// "%d facets added, %d facets reversed, %d backwards edges")), -// stats.degenerate_facets, stats.edges_fixed, stats.facets_removed, -// stats.facets_added, stats.facets_reversed, stats.backwards_edges); - - if (is_windows10()) - tooltip += _(L("Click the icon to fix STL through Netfabb")); - - m_objects_ctrl->GetMainWindow()->SetToolTip(tooltip); - } - else - m_objects_ctrl->GetMainWindow()->SetToolTip(""); // hide tooltip -*/ }); - return objects_sz; } From 4b8d7bd7fa9ea1d49512c056b8e74bfa651ed3db Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 10 Aug 2018 14:02:47 +0200 Subject: [PATCH 092/119] Fry to fix OSX-crashing on UnselectAll --- lib/Slic3r/GUI/Plater.pm | 2 ++ xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 6d6e0591f..e3f473fca 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -2222,6 +2222,8 @@ sub selection_changed { } $self->Layout; } + + print "selection_changed -> have_sel = $have_sel\n"; # prepagate the event to the frame (a custom Wx event would be cleaner) $self->GetFrame->on_plater_selection_changed($have_sel); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index d07187485..f10d22379 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -279,6 +279,9 @@ wxBoxSizer* content_objects_list(wxWindow *win) // if (is_windows10()) // fix_through_netfabb(); // } +#ifndef __WXMSW__ + m_objects_ctrl->GetMainWindow()->SetToolTip(""); // hide tooltip +#endif //__WXMSW__ event.Skip(); }); @@ -721,8 +724,10 @@ void set_object_scale(int idx, int scale) void unselect_objects() { printf("UNSELECT OBJECTS\n"); + g_prevent_list_events = true; m_objects_ctrl->UnselectAll(); part_selection_changed(); + g_prevent_list_events = false; get_optgroup(ogFrequentlyObjectSettings)->disable(); } @@ -1310,9 +1315,7 @@ void parts_changed(int obj_idx) void update_settings_value() { - printf("update_settings_value\n"); auto og = get_optgroup(ogFrequentlyObjectSettings); - printf("selected_object_id = %d\n", m_selected_object_id); if (m_selected_object_id < 0 || m_objects->size() <= m_selected_object_id) { og->set_value("scale_x", 0); og->set_value("scale_y", 0); @@ -1327,7 +1330,6 @@ void update_settings_value() void part_selection_changed() { - printf("part_selection_changed\n"); auto item = m_objects_ctrl->GetSelection(); int obj_idx = -1; auto og = get_optgroup(ogFrequentlyObjectSettings); From 9df680483571d93356f7dfd6fecb900cf1af1e9e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 10 Aug 2018 14:55:34 +0200 Subject: [PATCH 093/119] next try --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index f10d22379..bcd1846fb 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -726,7 +726,7 @@ void unselect_objects() printf("UNSELECT OBJECTS\n"); g_prevent_list_events = true; m_objects_ctrl->UnselectAll(); - part_selection_changed(); +// part_selection_changed(); g_prevent_list_events = false; get_optgroup(ogFrequentlyObjectSettings)->disable(); From 73ba96381e3c7fbaf45dec9ed624733ca1bf4c6e Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 13 Aug 2018 10:30:36 +0200 Subject: [PATCH 094/119] Drag&Drop test on Linux and OSX --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 59 +++++++++++++++++++++++++++ xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 5 +++ 2 files changed, 64 insertions(+) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index bcd1846fb..90fc61565 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -323,6 +323,9 @@ wxBoxSizer* content_objects_list(wxWindow *win) }); #endif //__WXMSW__ + m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, [](wxDataViewEvent& e) {on_begin_drag(e);}); + m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, [](wxDataViewEvent& e) {on_drop_possible(e); }); + m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_DROP, [](wxDataViewEvent& e) {on_drop(e);}); return objects_sz; } @@ -1528,5 +1531,61 @@ void update_rotation_value(const double angle, const std::string& axis) og->set_value("rotation_"+axis, deg); } +void on_begin_drag(wxDataViewEvent &event) +{ + wxDataViewItem item(event.GetItem()); + + // only allow drags for item, not containers + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) + { + event.Veto(); + return; + } + + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + wxTextDataObject *obj = new wxTextDataObject; + obj->SetText(node->m_name); + event.SetDataObject(obj); + event.SetDragFlags(wxDrag_AllowMove); // allows both copy and move; +} + +void on_drop_possible(wxDataViewEvent &event) +{ + wxDataViewItem item(event.GetItem()); + + // only allow drags for item or background, not containers + if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0)) + event.Veto(); + + if (event.GetDataFormat() != wxDF_UNICODETEXT) + event.Veto(); +} + +void on_drop(wxDataViewEvent &event) +{ + wxDataViewItem item(event.GetItem()); + + // only allow drops for item, not containers + if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0)) + { + event.Veto(); + return; + } + + if (event.GetDataFormat() != wxDF_UNICODETEXT) + { + event.Veto(); + return; + } + + wxTextDataObject obj; + obj.SetData(wxDF_UNICODETEXT, event.GetDataSize(), event.GetDataBuffer()); + + if (item.IsOk()) + wxMessageBox(wxString::Format("Text dropped on item %s: %s", m_objects_model->GetName(item), obj.GetText())); + else + wxMessageBox(wxString::Format("Text dropped on background: %s", obj.GetText())); +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 17c99f65c..8c35bea35 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -7,6 +7,7 @@ class wxBoxSizer; class wxString; class wxArrayString; class wxMenu; +class wxDataViewEvent; namespace Slic3r { class ModelObject; @@ -109,6 +110,10 @@ void update_rotation_values(); // update rotation value after "gizmos" void update_rotation_value(const double angle, const std::string& axis); +void on_begin_drag(wxDataViewEvent &event); +void on_drop_possible(wxDataViewEvent &event); +void on_drop(wxDataViewEvent &event); + } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file From 13388f1caa1ccdf2a7d3b87121920a979dfa1227 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 13 Aug 2018 14:15:43 +0200 Subject: [PATCH 095/119] Drag & Drop for sub-objects (parts of the object) --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 42 +++++++++++++-------------- xs/src/slic3r/GUI/wxExtensions.cpp | 26 +++++++++++++++++ xs/src/slic3r/GUI/wxExtensions.hpp | 5 ++++ 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 90fc61565..a5174fff3 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -306,6 +306,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { set_tooltip_for_item(event.GetPosition()); + event.Skip(); }); #else m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) @@ -1536,17 +1537,15 @@ void on_begin_drag(wxDataViewEvent &event) wxDataViewItem item(event.GetItem()); // only allow drags for item, not containers - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) - { + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { event.Veto(); return; } - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); wxTextDataObject *obj = new wxTextDataObject; - obj->SetText(node->m_name); + obj->SetText(wxString::Format("%d", m_objects_model->GetVolumeIdByItem(item))); event.SetDataObject(obj); - event.SetDragFlags(wxDrag_AllowMove); // allows both copy and move; + event.SetDragFlags(/*wxDrag_AllowMove*/wxDrag_DefaultMove); // allows both copy and move; } void on_drop_possible(wxDataViewEvent &event) @@ -1554,10 +1553,8 @@ void on_drop_possible(wxDataViewEvent &event) wxDataViewItem item(event.GetItem()); // only allow drags for item or background, not containers - if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0)) - event.Veto(); - - if (event.GetDataFormat() != wxDF_UNICODETEXT) + if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0) || + event.GetDataFormat() != wxDF_UNICODETEXT) event.Veto(); } @@ -1566,25 +1563,26 @@ void on_drop(wxDataViewEvent &event) wxDataViewItem item(event.GetItem()); // only allow drops for item, not containers - if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0)) - { + if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0) || + event.GetDataFormat() != wxDF_UNICODETEXT) { event.Veto(); return; - } - - if (event.GetDataFormat() != wxDF_UNICODETEXT) - { - event.Veto(); - return; - } + } wxTextDataObject obj; obj.SetData(wxDF_UNICODETEXT, event.GetDataSize(), event.GetDataBuffer()); - if (item.IsOk()) - wxMessageBox(wxString::Format("Text dropped on item %s: %s", m_objects_model->GetName(item), obj.GetText())); - else - wxMessageBox(wxString::Format("Text dropped on background: %s", obj.GetText())); + int from_volume_id = std::stoi(obj.GetText().ToStdString()); + int to_volume_id = m_objects_model->GetVolumeIdByItem(item); + + m_objects_ctrl->Select(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id, + m_objects_model->GetParent(item))); + + auto& volumes = (*m_objects)[m_selected_object_id]->volumes; + auto delta = to_volume_id < from_volume_id ? -1 : 1; + int cnt = 0; + for (int id = from_volume_id; cnt < abs(from_volume_id - to_volume_id); id+=delta, cnt++) + std::swap(volumes[id], volumes[id +delta]); } } //namespace GUI diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 71f49a970..6c330a3d6 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -664,6 +664,32 @@ wxDataViewItem PrusaObjectDataViewModel::MoveChildDown(const wxDataViewItem &ite return ret_item; } +wxDataViewItem PrusaObjectDataViewModel::ReorganizeChildren(int current_volume_id, int new_volume_id, const wxDataViewItem &parent) +{ + auto ret_item = wxDataViewItem(0); + if (current_volume_id == new_volume_id) + return ret_item; + wxASSERT(parent.IsOk()); + PrusaObjectDataViewModelNode *node_parent = (PrusaObjectDataViewModelNode*)parent.GetID(); + if (!node_parent) // happens if item.IsOk()==false + return ret_item; + + PrusaObjectDataViewModelNode *deleted_node = node_parent->GetNthChild(current_volume_id); + node_parent->GetChildren().Remove(deleted_node); + ItemDeleted(parent, wxDataViewItem(deleted_node)); + node_parent->Insert(deleted_node, new_volume_id); + ItemAdded(parent, wxDataViewItem(deleted_node)); + + //update volume_id value for child-nodes + auto children = node_parent->GetChildren(); + int id_frst = current_volume_id < new_volume_id ? current_volume_id : new_volume_id; + int id_last = current_volume_id > new_volume_id ? current_volume_id : new_volume_id; + for (int id = id_frst; id <= id_last; ++id) + children[id]->SetVolumeId(id); + + return wxDataViewItem(node_parent->GetNthChild(new_volume_id)); +} + // bool MyObjectTreeModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const // { // diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index daff37a60..b536232b8 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -381,6 +381,11 @@ public: wxDataViewItem MoveChildUp(const wxDataViewItem &item); wxDataViewItem MoveChildDown(const wxDataViewItem &item); + // For parent move child from cur_volume_id place to new_volume_id + // Remaining items will moved up/down accordingly + wxDataViewItem ReorganizeChildren(int cur_volume_id, + int new_volume_id, + const wxDataViewItem &parent); // virtual bool IsEnabled(const wxDataViewItem &item, // unsigned int col) const override; From acac6b0b44da4ed330670a66d19d28de10407c54 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 14 Aug 2018 13:04:11 +0200 Subject: [PATCH 096/119] Fixed DnD down-moving on GTK --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index a5174fff3..aba007a8d 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -690,7 +690,7 @@ void add_object_to_list(const std::string &name, ModelObject* model_object) } // part_selection_changed(); -#ifdef __WXMSW__ +#ifndef __WXOSX__ //#ifdef __WXMSW__ object_ctrl_selection_changed(); #endif //__WXMSW__ } @@ -1230,7 +1230,7 @@ void on_btn_del() void on_btn_split(const bool split_part) { auto item = m_objects_ctrl->GetSelection(); - if (!item) + if (!item || m_selected_object_id<0) return; auto volume_id = m_objects_model->GetVolumeIdByItem(item); ModelVolume* volume; @@ -1542,6 +1542,13 @@ void on_begin_drag(wxDataViewEvent &event) return; } + /* Under MSW or OSX, DnD moves an item to the place of another selected item + * But under GTK, DnD moves an item between another two items. + * And as a result - call EVT_CHANGE_SELECTION to unselect all items. + * To prevent such behavior use g_prevent_list_events + **/ + g_prevent_list_events = true;//it's needed for GTK + wxTextDataObject *obj = new wxTextDataObject; obj->SetText(wxString::Format("%d", m_objects_model->GetVolumeIdByItem(item))); event.SetDataObject(obj); @@ -1575,6 +1582,14 @@ void on_drop(wxDataViewEvent &event) int from_volume_id = std::stoi(obj.GetText().ToStdString()); int to_volume_id = m_objects_model->GetVolumeIdByItem(item); +#ifdef __WXGTK__ + /* Under GTK, DnD moves an item between another two items. + * And event.GetItem() return item, which is under "insertion line" + * So, if we move item down we should to decrease the to_volume_id value + **/ + if (to_volume_id > from_volume_id) to_volume_id--; +#endif // __WXGTK__ + m_objects_ctrl->Select(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id, m_objects_model->GetParent(item))); @@ -1583,6 +1598,8 @@ void on_drop(wxDataViewEvent &event) int cnt = 0; for (int id = from_volume_id; cnt < abs(from_volume_id - to_volume_id); id+=delta, cnt++) std::swap(volumes[id], volumes[id +delta]); + + g_prevent_list_events = false; } } //namespace GUI From a2eff85fa8d73b461a55f443c764f62610599187 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 14 Aug 2018 14:13:07 +0200 Subject: [PATCH 097/119] Try to fix OSX crashing on UnselectAll --- lib/Slic3r/GUI/Plater.pm | 2 +- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index e3f473fca..062746e79 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -2223,7 +2223,7 @@ sub selection_changed { $self->Layout; } - print "selection_changed -> have_sel = $have_sel\n"; + #print "selection_changed -> have_sel = $have_sel\n"; # prepagate the event to the frame (a custom Wx event would be cleaner) $self->GetFrame->on_plater_selection_changed($have_sel); diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index aba007a8d..c11aa4636 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -287,14 +287,16 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) { + printf("wxEVT_CHAR : "); if (event.GetKeyCode() == WXK_TAB) m_objects_ctrl->Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward); else if (event.GetKeyCode() == WXK_DELETE #ifdef __WXOSX__ || event.GetKeyCode() == WXK_BACK #endif //__WXOSX__ - ) - remove(); + ){ + printf("WXK_BACK\n"); + remove();} else event.Skip(); }); @@ -729,8 +731,10 @@ void unselect_objects() { printf("UNSELECT OBJECTS\n"); g_prevent_list_events = true; - m_objects_ctrl->UnselectAll(); -// part_selection_changed(); + if (m_objects_ctrl->GetSelection()) + m_objects_ctrl->UnselectAll(); + else + printf("all items are UNSELECTED\n"); g_prevent_list_events = false; get_optgroup(ogFrequentlyObjectSettings)->disable(); @@ -774,11 +778,9 @@ void object_ctrl_selection_changed() part_selection_changed(); -// if (m_selected_object_id < 0) return; - if (m_event_object_selection_changed > 0) { wxCommandEvent event(m_event_object_selection_changed); - event.SetInt(int(m_objects_model->GetParent(/*item*/ m_objects_ctrl->GetSelection()) != wxDataViewItem(0))); + event.SetInt(int(m_objects_model->GetParent(m_objects_ctrl->GetSelection()) != wxDataViewItem(0))); event.SetId(m_selected_object_id); get_main_frame()->ProcessWindowEvent(event); } From 79f2801d2a34f8dc698bd46d45f5d16234b4a8ec Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 14 Aug 2018 14:34:04 +0200 Subject: [PATCH 098/119] One more try to understand OSX crashing on UnselectAll --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index c11aa4636..3260b4d27 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -731,13 +731,13 @@ void unselect_objects() { printf("UNSELECT OBJECTS\n"); g_prevent_list_events = true; - if (m_objects_ctrl->GetSelection()) + if (m_objects_ctrl->GetSelection()) { m_objects_ctrl->UnselectAll(); + get_optgroup(ogFrequentlyObjectSettings)->disable(); + } else printf("all items are UNSELECTED\n"); g_prevent_list_events = false; - - get_optgroup(ogFrequentlyObjectSettings)->disable(); } void select_current_object(int idx) From 817fb5adb39dc6b1d74b0c767abaf7786bf5e287 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 14 Aug 2018 15:35:54 +0200 Subject: [PATCH 099/119] Test of item_changed_selection(obj_idx) --- lib/Slic3r/GUI/Plater.pm | 2 ++ xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 062746e79..3632bb07c 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1986,6 +1986,7 @@ sub on_config_change { sub item_changed_selection{ my ($self, $obj_idx) = @_; + printf "BEGIN item_changed_selection : obj_idx = $obj_idx\n"; $self->{canvas}->Refresh; if ($self->{canvas3D}) { @@ -1996,6 +1997,7 @@ sub item_changed_selection{ } Slic3r::GUI::_3DScene::render($self->{canvas3D}); } + printf "END item_changed_selection"; } sub collect_selections { diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 3260b4d27..47be0b832 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -733,7 +733,7 @@ void unselect_objects() g_prevent_list_events = true; if (m_objects_ctrl->GetSelection()) { m_objects_ctrl->UnselectAll(); - get_optgroup(ogFrequentlyObjectSettings)->disable(); + part_selection_changed(); } else printf("all items are UNSELECTED\n"); @@ -751,8 +751,6 @@ void select_current_object(int idx) m_objects_ctrl->Select(m_objects_model->GetItemById(idx)); part_selection_changed(); g_prevent_list_events = false; - - get_optgroup(ogFrequentlyObjectSettings)->enable(); } void remove() @@ -1359,11 +1357,13 @@ void part_selection_changed() auto config = m_config; og->set_value("object_name", m_objects_model->GetName(item)); + og->enable(); m_default_config = std::make_shared(*DynamicPrintConfig::new_from_defaults_keys(get_options(is_part))); } else { wxString empty_str = wxEmptyString; og->set_value("object_name", empty_str); + og->disable(); m_config = nullptr; } From 92b578779ed0669a242a40349059cbe81a4fef40 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 14 Aug 2018 16:10:58 +0200 Subject: [PATCH 100/119] Test of update_extruder_in_config() --- lib/Slic3r/GUI/Plater.pm | 2 -- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 3632bb07c..062746e79 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1986,7 +1986,6 @@ sub on_config_change { sub item_changed_selection{ my ($self, $obj_idx) = @_; - printf "BEGIN item_changed_selection : obj_idx = $obj_idx\n"; $self->{canvas}->Refresh; if ($self->{canvas3D}) { @@ -1997,7 +1996,6 @@ sub item_changed_selection{ } Slic3r::GUI::_3DScene::render($self->{canvas3D}); } - printf "END item_changed_selection"; } sub collect_selections { diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 47be0b832..93d649abf 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -1325,11 +1325,13 @@ void update_settings_value() og->set_value("scale_y", 0); og->set_value("scale_z", 0); printf("return because of unselect\n"); + og->disable(); return; } g_is_percent_scale = boost::any_cast(og->get_value("scale_unit")) == _("%"); update_scale_values(); update_rotation_values(); + og->enable(); } void part_selection_changed() @@ -1357,13 +1359,11 @@ void part_selection_changed() auto config = m_config; og->set_value("object_name", m_objects_model->GetName(item)); - og->enable(); m_default_config = std::make_shared(*DynamicPrintConfig::new_from_defaults_keys(get_options(is_part))); } else { wxString empty_str = wxEmptyString; og->set_value("object_name", empty_str); - og->disable(); m_config = nullptr; } @@ -1475,6 +1475,7 @@ void set_extruder_column_hidden(bool hide) void update_extruder_in_config(const wxString& selection) { + printf("BEGIN OF update_extruder_in_config\n"); if (!*m_config || selection.empty()) return; @@ -1485,6 +1486,7 @@ void update_extruder_in_config(const wxString& selection) wxCommandEvent e(m_event_update_scene); get_main_frame()->ProcessWindowEvent(e); } + printf("END OF update_extruder_in_config\n"); } void update_scale_values() From 3c3b8ed76f23e048e16ca4897ab2651b0d9ac465 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 14 Aug 2018 16:16:26 +0200 Subject: [PATCH 101/119] fixed typo in update_extruder_in_config --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 93d649abf..aae583ea9 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -1476,7 +1476,7 @@ void set_extruder_column_hidden(bool hide) void update_extruder_in_config(const wxString& selection) { printf("BEGIN OF update_extruder_in_config\n"); - if (!*m_config || selection.empty()) + if (!m_config || selection.empty()) return; int extruder = selection.size() > 1 ? 0 : atoi(selection.c_str()); From f0095d19be57b5fd77f766608a1d790bb531f7cc Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 15 Aug 2018 10:09:05 +0200 Subject: [PATCH 102/119] Some code refactoring --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 166 +++++++++++++------------- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 4 + 2 files changed, 88 insertions(+), 82 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index aae583ea9..8f74158e9 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -210,13 +210,12 @@ wxPoint get_mouse_position_in_control() { pt.y - win->GetScreenPosition().y); } -// ****** from GUI.cpp -wxBoxSizer* content_objects_list(wxWindow *win) +void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz) { m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); m_objects_ctrl->SetInitialSize(wxSize(-1, 150)); // TODO - Set correct height according to the opened/closed objects - auto objects_sz = new wxBoxSizer(wxVERTICAL); + objects_sz = new wxBoxSizer(wxVERTICAL); objects_sz->Add(m_objects_ctrl, 1, wxGROW | wxLEFT, 20); m_objects_model = new PrusaObjectDataViewModel; @@ -228,7 +227,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) // column 0(Icon+Text) of the view control: m_objects_ctrl->AppendIconTextColumn(_(L("Name")), 0, wxDATAVIEW_CELL_INERT, 120, - wxALIGN_LEFT, /*wxDATAVIEW_COL_SORTABLE | */wxDATAVIEW_COL_RESIZABLE); + wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE); // column 1 of the view control: m_objects_ctrl->AppendTextColumn(_(L("Copy")), 1, wxDATAVIEW_CELL_INERT, 45, @@ -254,9 +253,15 @@ wxBoxSizer* content_objects_list(wxWindow *win) // column 4 of the view control: m_objects_ctrl->AppendBitmapColumn(" ", 4, wxDATAVIEW_CELL_INERT, 25, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); +} - m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) - { +// ****** from GUI.cpp +wxBoxSizer* create_objects_list(wxWindow *win) +{ + wxBoxSizer* objects_sz; + create_objects_ctrl(win, objects_sz); + + m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { object_ctrl_selection_changed(); #ifndef __WXMSW__ set_tooltip_for_item(get_mouse_position_in_control()); @@ -264,66 +269,21 @@ wxBoxSizer* content_objects_list(wxWindow *win) }); m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_CONTEXT_MENU, [](wxDataViewEvent& event) { - wxDataViewItem item; - wxDataViewColumn* col; - m_objects_ctrl->HitTest(get_mouse_position_in_control(), item, col); - wxString title = col->GetTitle(); - if (!item) return; - - if (title == " ") - object_ctrl_context_menu(); - // ys_FIXME -// else if (title == _("Name") && pt.x >15 && -// m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) -// { -// if (is_windows10()) -// fix_through_netfabb(); -// } -#ifndef __WXMSW__ - m_objects_ctrl->GetMainWindow()->SetToolTip(""); // hide tooltip -#endif //__WXMSW__ + object_ctrl_context_menu(); event.Skip(); }); - m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) - { - printf("wxEVT_CHAR : "); - if (event.GetKeyCode() == WXK_TAB) - m_objects_ctrl->Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward); - else if (event.GetKeyCode() == WXK_DELETE -#ifdef __WXOSX__ - || event.GetKeyCode() == WXK_BACK -#endif //__WXOSX__ - ){ - printf("WXK_BACK\n"); - remove();} - else - event.Skip(); - }); + m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) { object_ctrl_key_event(event); }); #ifdef __WXMSW__ - m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { - update_extruder_in_config(event.GetString()); - }); + m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { update_extruder_in_config(event.GetString()); }); m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { set_tooltip_for_item(event.GetPosition()); event.Skip(); }); #else - m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) - { - if (event.GetColumn() == 3) - { - wxVariant variant; - m_objects_model->GetValue(variant, event.GetItem(), 3); -#ifdef __WXOSX__ - g_selected_extruder = variant.GetString(); -#else // --> for Linux - update_extruder_in_config(variant.GetString()); -#endif //__WXOSX__ - } - }); + m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) { object_ctrl_item_value_change(event); }); #endif //__WXMSW__ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, [](wxDataViewEvent& e) {on_begin_drag(e);}); @@ -332,7 +292,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) return objects_sz; } -wxBoxSizer* content_edit_object_buttons(wxWindow* win) +wxBoxSizer* create_edit_object_buttons(wxWindow* win) { auto sizer = new wxBoxSizer(wxVERTICAL); @@ -493,7 +453,7 @@ wxBoxSizer* content_settings(wxWindow *win) get_optgroups().push_back(optgroup); // ogObjectSettings auto sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(content_edit_object_buttons(win), 0, wxEXPAND, 0); // *** Edit Object Buttons*** + sizer->Add(create_edit_object_buttons(win), 0, wxEXPAND, 0); // *** Edit Object Buttons*** sizer->Add(optgroup->sizer, 1, wxEXPAND | wxLEFT, 20); @@ -509,7 +469,7 @@ wxBoxSizer* content_settings(wxWindow *win) void add_objects_list(wxWindow* parent, wxBoxSizer* sizer) { - const auto ol_sizer = content_objects_list(parent); + const auto ol_sizer = create_objects_list(parent); sizer->Add(ol_sizer, 1, wxEXPAND | wxTOP, 20); set_objects_list_sizer(ol_sizer); } @@ -646,7 +606,7 @@ wxCollapsiblePane* add_collapsible_pane(wxWindow* parent, wxBoxSizer* sizer_pare void add_collapsible_panes(wxWindow* parent, wxBoxSizer* sizer) { // *** Objects List *** - auto collpane = add_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); + auto collpane = add_collapsible_pane(parent, sizer, "Objects List:", create_objects_list); collpane->Bind(wxEVT_COLLAPSIBLEPANE_CHANGED, ([collpane](wxCommandEvent& e){ // wxWindowUpdateLocker noUpdates(g_right_panel); if (collpane->IsCollapsed()) { @@ -788,6 +748,58 @@ void object_ctrl_selection_changed() #endif //__WXOSX__ } +void object_ctrl_context_menu() +{ + wxDataViewItem item; + wxDataViewColumn* col; + m_objects_ctrl->HitTest(get_mouse_position_in_control(), item, col); + wxString title = col->GetTitle(); + if (!item) return; + + if (title == " ") + show_context_menu(); +// ys_FIXME +// else if (title == _("Name") && pt.x >15 && +// m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) +// { +// if (is_windows10()) +// fix_through_netfabb(); +// } +#ifndef __WXMSW__ + m_objects_ctrl->GetMainWindow()->SetToolTip(""); // hide tooltip +#endif //__WXMSW__ +} + +void object_ctrl_key_event(wxKeyEvent& event) +{ + if (event.GetKeyCode() == WXK_TAB) + m_objects_ctrl->Navigate(event.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward); + else if (event.GetKeyCode() == WXK_DELETE +#ifdef __WXOSX__ + || event.GetKeyCode() == WXK_BACK +#endif //__WXOSX__ + ){ + printf("WXK_BACK\n"); + remove(); + } + else + event.Skip(); +} + +void object_ctrl_item_value_change(wxDataViewEvent& event) +{ + if (event.GetColumn() == 3) + { + wxVariant variant; + m_objects_model->GetValue(variant, event.GetItem(), 3); +#ifdef __WXOSX__ + g_selected_extruder = variant.GetString(); +#else // --> for Linux + update_extruder_in_config(variant.GetString()); +#endif //__WXOSX__ + } +} + //update_optgroup void update_settings_list() { @@ -1049,30 +1061,20 @@ wxMenu *create_add_settings_popupmenu(bool is_part) return menu; } -void object_ctrl_context_menu() +void show_context_menu() { -// auto cur_column = m_objects_ctrl->GetCurrentColumn(); -// auto action_column = m_objects_ctrl->GetColumn(4); -// if (cur_column == action_column) - { - auto item = m_objects_ctrl->GetSelection(); - if (item) - { - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { - auto menu = create_add_part_popupmenu(); - get_tab_panel()->GetPage(0)->PopupMenu(menu); - } - else { -// auto parent = m_objects_model->GetParent(item); -// // Take ID of the parent object to "inform" perl-side which object have to be selected on the scene -// obj_idx = m_objects_model->GetIdByItem(parent); -// auto volume_id = m_objects_model->GetVolumeIdByItem(item); -// if (volume_id < 0) return; - auto menu = create_part_settings_popupmenu(); - get_tab_panel()->GetPage(0)->PopupMenu(menu); - } - } - } + auto item = m_objects_ctrl->GetSelection(); + if (item) + { + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { + auto menu = create_add_part_popupmenu(); + get_tab_panel()->GetPage(0)->PopupMenu(menu); + } + else { + auto menu = create_part_settings_popupmenu(); + get_tab_panel()->GetPage(0)->PopupMenu(menu); + } + } } // ****** diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index 8c35bea35..f9fffb58b 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -8,6 +8,7 @@ class wxString; class wxArrayString; class wxMenu; class wxDataViewEvent; +class wxKeyEvent; namespace Slic3r { class ModelObject; @@ -71,6 +72,9 @@ void remove(); void object_ctrl_selection_changed(); void object_ctrl_context_menu(); +void object_ctrl_key_event(wxKeyEvent& event); +void object_ctrl_item_value_change(wxDataViewEvent& event); +void show_context_menu(); void init_mesh_icons(); void set_event_object_selection_changed(const int& event); From 3e549c153d508ba2cd5cea41ee8bd35b53b87596 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 15 Aug 2018 11:18:20 +0200 Subject: [PATCH 103/119] Improvement of extruder selection for the object/part according to the actually extruders count --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 35 ++++++++++++++++++--------- xs/src/slic3r/GUI/GUI_ObjectParts.hpp | 3 +++ xs/src/slic3r/GUI/Tab.cpp | 2 +- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 8f74158e9..616f0dc57 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -8,7 +8,6 @@ #include "../../libslic3r/Utils.hpp" #include -#include #include #include #include "Geometry.hpp" @@ -210,6 +209,18 @@ wxPoint get_mouse_position_in_control() { pt.y - win->GetScreenPosition().y); } +wxDataViewColumn* object_ctrl_create_extruder_column(int extruders_count) +{ + wxArrayString choices; + choices.Add("default"); + for (int i = 1; i <= extruders_count; ++i) + choices.Add(wxString::Format("%d", i)); + wxDataViewChoiceRenderer *c = + new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_CENTER_HORIZONTAL); + wxDataViewColumn* column = new wxDataViewColumn(_(L("Extruder")), c, 3, 60, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); + return column; +} + void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz) { m_objects_ctrl = new wxDataViewCtrl(win, wxID_ANY, wxDefaultPosition, wxDefaultSize); @@ -238,17 +249,7 @@ void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz) wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); // column 3 of the view control: - wxArrayString choices; - choices.Add("default"); - choices.Add("1"); - choices.Add("2"); - choices.Add("3"); - choices.Add("4"); - wxDataViewChoiceRenderer *c = - new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_CENTER_HORIZONTAL); - wxDataViewColumn *column3 = - new wxDataViewColumn(_(L("Extruder")), c, 3, 60, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); - m_objects_ctrl->AppendColumn(column3); + m_objects_ctrl->AppendColumn(object_ctrl_create_extruder_column(4)); // column 4 of the view control: m_objects_ctrl->AppendBitmapColumn(" ", 4, wxDATAVIEW_CELL_INERT, 25, @@ -1608,5 +1609,15 @@ void on_drop(wxDataViewEvent &event) g_prevent_list_events = false; } +void update_objects_list_extruder_column(const int extruders_count) +{ + // delete old 3rd column + m_objects_ctrl->DeleteColumn(m_objects_ctrl->GetColumnAt(3)); + // insert new created 3rd column + m_objects_ctrl->InsertColumn(3, object_ctrl_create_extruder_column(extruders_count)); + // set show/hide for this column + set_extruder_column_hidden(extruders_count <= 1); +} + } //namespace GUI } //namespace Slic3r \ No newline at end of file diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp index f9fffb58b..15be90bbf 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.hpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.hpp @@ -118,6 +118,9 @@ void on_begin_drag(wxDataViewEvent &event); void on_drop_possible(wxDataViewEvent &event); void on_drop(wxDataViewEvent &event); +// update extruder column for objects_ctrl according to extruders count +void update_objects_list_extruder_column(const int extruders_count); + } //namespace GUI } //namespace Slic3r #endif //slic3r_GUI_ObjectParts_hpp_ \ No newline at end of file diff --git a/xs/src/slic3r/GUI/Tab.cpp b/xs/src/slic3r/GUI/Tab.cpp index 8fbedb121..c4736a2dd 100644 --- a/xs/src/slic3r/GUI/Tab.cpp +++ b/xs/src/slic3r/GUI/Tab.cpp @@ -1698,6 +1698,7 @@ void TabPrinter::extruders_count_changed(size_t extruders_count){ build_extruder_pages(); reload_config(); on_value_change("extruders_count", extruders_count); + update_objects_list_extruder_column(extruders_count); } void TabPrinter::append_option_line(ConfigOptionsGroupShp optgroup, const std::string opt_key) @@ -2010,7 +2011,6 @@ void Tab::load_current_preset() const Preset* parent_preset = m_presets->get_selected_preset_parent(); static_cast(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 : static_cast(parent_preset->config.option("nozzle_diameter"))->values.size(); - set_extruder_column_hidden(static_cast(this)->m_sys_extruders_count <= 1); } m_opt_status_value = (m_presets->get_selected_preset_parent() ? osSystemValue : 0) | osInitValue; init_options_list(); From 76249e56258a3e5df086175be3811d4a738d1339 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 15 Aug 2018 12:47:46 +0200 Subject: [PATCH 104/119] Fixed typo in LambdaObjectDialog. It was a reason of the wrong cube size updating for generic modifier "Cube". + some code cleaning --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 17 ++++++----------- xs/src/slic3r/GUI/LambdaObjectDialog.cpp | 6 +++--- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 616f0dc57..8c2997676 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -690,14 +690,12 @@ void set_object_scale(int idx, int scale) void unselect_objects() { - printf("UNSELECT OBJECTS\n"); + if (!m_objects_ctrl->GetSelection()) + return; + g_prevent_list_events = true; - if (m_objects_ctrl->GetSelection()) { - m_objects_ctrl->UnselectAll(); - part_selection_changed(); - } - else - printf("all items are UNSELECTED\n"); + m_objects_ctrl->UnselectAll(); + part_selection_changed(); g_prevent_list_events = false; } @@ -1327,7 +1325,6 @@ void update_settings_value() og->set_value("scale_x", 0); og->set_value("scale_y", 0); og->set_value("scale_z", 0); - printf("return because of unselect\n"); og->disable(); return; } @@ -1478,7 +1475,6 @@ void set_extruder_column_hidden(bool hide) void update_extruder_in_config(const wxString& selection) { - printf("BEGIN OF update_extruder_in_config\n"); if (!m_config || selection.empty()) return; @@ -1489,7 +1485,6 @@ void update_extruder_in_config(const wxString& selection) wxCommandEvent e(m_event_update_scene); get_main_frame()->ProcessWindowEvent(e); } - printf("END OF update_extruder_in_config\n"); } void update_scale_values() @@ -1612,7 +1607,7 @@ void on_drop(wxDataViewEvent &event) void update_objects_list_extruder_column(const int extruders_count) { // delete old 3rd column - m_objects_ctrl->DeleteColumn(m_objects_ctrl->GetColumnAt(3)); + m_objects_ctrl->DeleteColumn(m_objects_ctrl->GetColumn(3)); // insert new created 3rd column m_objects_ctrl->InsertColumn(3, object_ctrl_create_extruder_column(extruders_count)); // set show/hide for this column diff --git a/xs/src/slic3r/GUI/LambdaObjectDialog.cpp b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp index b5479fb12..7543821c0 100644 --- a/xs/src/slic3r/GUI/LambdaObjectDialog.cpp +++ b/xs/src/slic3r/GUI/LambdaObjectDialog.cpp @@ -30,9 +30,9 @@ LambdaObjectDialog::LambdaObjectDialog(wxWindow* parent) auto optgroup = init_modificator_options_page(_(L("Box"))); optgroup->m_on_change = [this](t_config_option_key opt_key, boost::any value){ - int opt_id = opt_key == "L" ? 0 : - opt_key == "W" ? 1 : - opt_key == "L" ? 2 : -1; + int opt_id = opt_key == "l" ? 0 : + opt_key == "w" ? 1 : + opt_key == "h" ? 2 : -1; if (opt_id < 0) return; object_parameters.dim[opt_id] = boost::any_cast(value); }; From 8c7cc73da66608ecd3cfa8ecd10e2851006d42bd Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 15 Aug 2018 13:59:33 +0200 Subject: [PATCH 105/119] Update extruder value for the object from the beginning --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 22 +++++++++++++++------- xs/src/slic3r/GUI/wxExtensions.cpp | 9 ++++++--- xs/src/slic3r/GUI/wxExtensions.hpp | 7 +++++-- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 8c2997676..7838bb10e 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -648,12 +648,15 @@ void add_object_to_list(const std::string &name, ModelObject* model_object) if (model_object->volumes.size() > 1) { for (auto id = 0; id < model_object->volumes.size(); id++) - m_objects_model->AddChild(item, model_object->volumes[id]->name, m_icon_solidmesh, false); + m_objects_model->AddChild(item, + model_object->volumes[id]->name, + m_icon_solidmesh, + model_object->volumes[id]->config.option("extruder")->value, + false); m_objects_ctrl->Expand(item); } -// part_selection_changed(); -#ifndef __WXOSX__ //#ifdef __WXMSW__ +#ifndef __WXOSX__ object_ctrl_selection_changed(); #endif //__WXMSW__ } @@ -1257,13 +1260,18 @@ void on_btn_split(const bool split_part) for (auto id = 0; id < model_object->volumes.size(); id++) m_objects_model->AddChild(parent, model_object->volumes[id]->name, - model_object->volumes[id]->modifier ? m_icon_modifiermesh : m_icon_solidmesh, false); + model_object->volumes[id]->modifier ? m_icon_modifiermesh : m_icon_solidmesh, + model_object->volumes[id]->config.option("extruder")->value, + false); m_objects_ctrl->Expand(parent); } else { for (auto id = 0; id < model_object->volumes.size(); id++) - m_objects_model->AddChild(item, model_object->volumes[id]->name, m_icon_solidmesh, false); + m_objects_model->AddChild(item, model_object->volumes[id]->name, + m_icon_solidmesh, + model_object->volumes[id]->config.option("extruder")->value, + false); m_objects_ctrl->Expand(item); } } @@ -1519,7 +1527,7 @@ void update_rotation_values() auto rotation_z = (*m_objects)[m_selected_object_id]->instances[0]->rotation; auto deg = int(Geometry::rad2deg(rotation_z)); - if (deg > 180) deg -= 360; +// if (deg > 180) deg -= 360; og->set_value("rotation_z", deg); } @@ -1529,7 +1537,7 @@ void update_rotation_value(const double angle, const std::string& axis) auto og = get_optgroup(ogFrequentlyObjectSettings); int deg = int(Geometry::rad2deg(angle)); - if (deg>180) deg -= 360; +// if (deg>180) deg -= 360; og->set_value("rotation_"+axis, deg); } diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 6c330a3d6..294eea454 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -385,15 +385,18 @@ wxDataViewItem PrusaObjectDataViewModel::Add(wxString &name, int instances_count wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_item, const wxString &name, const wxIcon& icon, - bool create_frst_child/* = true*/) + const int extruder/* = 0*/, + const bool create_frst_child/* = true*/) { PrusaObjectDataViewModelNode *root = (PrusaObjectDataViewModelNode*)parent_item.GetID(); if (!root) return wxDataViewItem(0); + wxString extruder_str = extruder == 0 ? "default" : wxString::Format("%d", extruder); + if (root->GetChildren().Count() == 0 && create_frst_child) { auto icon_solid_mesh = wxIcon(Slic3r::GUI::from_u8(Slic3r::var("object.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("package.png")), wxBITMAP_TYPE_PNG); - auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, 0); + auto node = new PrusaObjectDataViewModelNode(root, root->m_name, icon_solid_mesh, extruder_str, 0); root->Append(node); // notify control wxDataViewItem child((void*)node); @@ -401,7 +404,7 @@ wxDataViewItem PrusaObjectDataViewModel::AddChild( const wxDataViewItem &parent_ } auto volume_id = root->GetChildCount(); - auto node = new PrusaObjectDataViewModelNode(root, name, icon, volume_id); + auto node = new PrusaObjectDataViewModelNode(root, name, icon, extruder_str, volume_id); root->Append(node); // notify control wxDataViewItem child((void*)node); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index b536232b8..32ae0a4f9 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -176,7 +176,8 @@ public: PrusaObjectDataViewModelNode( PrusaObjectDataViewModelNode* parent, const wxString& sub_obj_name, const wxIcon& icon, - int volume_id=-1) { + const wxString& extruder, + const int volume_id=-1) { m_parent = parent; m_name = sub_obj_name; m_copy = wxEmptyString; @@ -184,6 +185,7 @@ public: m_icon = icon; m_type = "volume"; m_volume_id = volume_id; + m_extruder = extruder; set_part_action_icon(); } @@ -352,7 +354,8 @@ public: wxDataViewItem AddChild(const wxDataViewItem &parent_item, const wxString &name, const wxIcon& icon, - bool create_frst_child = true); + const int = 0, + const bool create_frst_child = true); wxDataViewItem Delete(const wxDataViewItem &item); void DeleteAll(); void DeleteChildren(wxDataViewItem& parent); From 3391ea050dcbc5b397f1cca9d69f0e2d6a6627d8 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 16 Aug 2018 09:12:24 +0200 Subject: [PATCH 106/119] Try to handle wxEVT_CHAR_HOOK on OSX --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 7838bb10e..1ab4a84ad 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -274,7 +274,13 @@ wxBoxSizer* create_objects_list(wxWindow *win) event.Skip(); }); - m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) { object_ctrl_key_event(event); }); + m_objects_ctrl->Bind( +#ifdef __WXOSX__ + wxEVT_CHAR_HOOK, +#else + wxEVT_CHAR, +#endif //__WXOSX__ + [](wxKeyEvent& event) { object_ctrl_key_event(event); }); #ifdef __WXMSW__ m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { update_extruder_in_config(event.GetString()); }); From 5de933b77e7a9d841385af358ca78110db637dfa Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 16 Aug 2018 09:35:21 +0200 Subject: [PATCH 107/119] Try to fix evt_motion on OSX & GTK --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 1ab4a84ad..3fc42bd4d 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -209,6 +209,15 @@ wxPoint get_mouse_position_in_control() { pt.y - win->GetScreenPosition().y); } +bool is_mouse_position_in_control(wxPoint& pt) { + pt = get_mouse_position_in_control(); + const wxSize& cz = m_objects_ctrl->GetSize(); + if (pt.x > 0 && pt.x < cz.x && + pt.y > 0 && pt.y < cz.y) + return true; + return false; +} + wxDataViewColumn* object_ctrl_create_extruder_column(int extruders_count) { wxArrayString choices; @@ -260,8 +269,10 @@ void create_objects_ctrl(wxWindow* win, wxBoxSizer*& objects_sz) wxBoxSizer* create_objects_list(wxWindow *win) { wxBoxSizer* objects_sz; + // create control create_objects_ctrl(win, objects_sz); + // describe control behavior m_objects_ctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [](wxEvent& event) { object_ctrl_selection_changed(); #ifndef __WXMSW__ @@ -283,6 +294,7 @@ wxBoxSizer* create_objects_list(wxWindow *win) [](wxKeyEvent& event) { object_ctrl_key_event(event); }); #ifdef __WXMSW__ + // Extruder value changed m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { update_extruder_in_config(event.GetString()); }); m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { @@ -290,7 +302,15 @@ wxBoxSizer* create_objects_list(wxWindow *win) event.Skip(); }); #else + // equivalent to wxEVT_CHOICE on __WXMSW__ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) { object_ctrl_item_value_change(event); }); + + get_right_panel()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { + event.Skip(); + wxPoint pt; + if (is_mouse_position_in_control(pt)) + set_tooltip_for_item(pt); + }); #endif //__WXMSW__ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, [](wxDataViewEvent& e) {on_begin_drag(e);}); From e6fce6e1f63fd988515fb39f978107ccd902518b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 16 Aug 2018 09:46:34 +0200 Subject: [PATCH 108/119] Try to handle wxEVT_KEY_DOWN on OSX --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 3fc42bd4d..5715fdeef 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -287,7 +287,7 @@ wxBoxSizer* create_objects_list(wxWindow *win) m_objects_ctrl->Bind( #ifdef __WXOSX__ - wxEVT_CHAR_HOOK, + wxEVT_KEY_DOWN, #else wxEVT_CHAR, #endif //__WXOSX__ From eae7752d300227386ad0927defa377db8b5f7209 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 16 Aug 2018 10:43:56 +0200 Subject: [PATCH 109/119] Corrections for the last commit --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 38 +++++++++++++++++++-------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 5715fdeef..3e4fe906e 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -293,24 +293,40 @@ wxBoxSizer* create_objects_list(wxWindow *win) #endif //__WXOSX__ [](wxKeyEvent& event) { object_ctrl_key_event(event); }); + m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { +#ifdef __WXMSW__ + set_tooltip_for_item(event.GetPosition()); +#else + printf("wxEVT_MOTION from GetMainWindow\n"); + wxPoint pt; + if (is_mouse_position_in_control(pt)) + set_tooltip_for_item(pt); +#endif + event.Skip(); + }); + +#ifndef __WXMSW__ + win->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { + printf("wxEVT_MOTION from win\n"); + wxPoint pt; + if (is_mouse_position_in_control(pt)) + set_tooltip_for_item(pt); + event.Skip(); + }); +#endif + #ifdef __WXMSW__ // Extruder value changed m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { update_extruder_in_config(event.GetString()); }); - m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { - set_tooltip_for_item(event.GetPosition()); - event.Skip(); - }); +// m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { +// set_tooltip_for_item(event.GetPosition()); +// event.Skip(); +// }); + #else // equivalent to wxEVT_CHOICE on __WXMSW__ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) { object_ctrl_item_value_change(event); }); - - get_right_panel()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { - event.Skip(); - wxPoint pt; - if (is_mouse_position_in_control(pt)) - set_tooltip_for_item(pt); - }); #endif //__WXMSW__ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, [](wxDataViewEvent& e) {on_begin_drag(e);}); From d10cdeb25f5f1ac0ff7924efa142ff98c39aecd6 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 16 Aug 2018 16:43:16 +0200 Subject: [PATCH 110/119] Delete previous experiments --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 39 ++++----------------------- 1 file changed, 5 insertions(+), 34 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 3e4fe906e..e9d08ede5 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -285,45 +285,16 @@ wxBoxSizer* create_objects_list(wxWindow *win) event.Skip(); }); - m_objects_ctrl->Bind( -#ifdef __WXOSX__ - wxEVT_KEY_DOWN, -#else - wxEVT_CHAR, -#endif //__WXOSX__ - [](wxKeyEvent& event) { object_ctrl_key_event(event); }); - - m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { -#ifdef __WXMSW__ - set_tooltip_for_item(event.GetPosition()); -#else - printf("wxEVT_MOTION from GetMainWindow\n"); - wxPoint pt; - if (is_mouse_position_in_control(pt)) - set_tooltip_for_item(pt); -#endif - event.Skip(); - }); - -#ifndef __WXMSW__ - win->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { - printf("wxEVT_MOTION from win\n"); - wxPoint pt; - if (is_mouse_position_in_control(pt)) - set_tooltip_for_item(pt); - event.Skip(); - }); -#endif + m_objects_ctrl->Bind(wxEVT_CHAR, [](wxKeyEvent& event) { object_ctrl_key_event(event); }); // doesn't work on OSX #ifdef __WXMSW__ // Extruder value changed m_objects_ctrl->Bind(wxEVT_CHOICE, [](wxCommandEvent& event) { update_extruder_in_config(event.GetString()); }); -// m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { -// set_tooltip_for_item(event.GetPosition()); -// event.Skip(); -// }); - + m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { + set_tooltip_for_item(event.GetPosition()); + event.Skip(); + }); #else // equivalent to wxEVT_CHOICE on __WXMSW__ m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) { object_ctrl_item_value_change(event); }); From 1b26cd414d41a89c3c68e0e2590257666a28c1cb Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 21 Aug 2018 02:03:10 +0200 Subject: [PATCH 111/119] DoubleSlider prototype --- xs/src/slic3r/GUI/GUI.cpp | 10 + xs/src/slic3r/GUI/wxExtensions.cpp | 320 ++++++++++++++++++++++++++++- xs/src/slic3r/GUI/wxExtensions.hpp | 80 +++++++- 3 files changed, 408 insertions(+), 2 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 088cbf80b..e50c7220a 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1052,6 +1052,16 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl // Object List add_objects_list(parent, sizer); + // experiment with slider + PrusaDoubleSlider* slider_h = new PrusaDoubleSlider(parent, wxID_ANY, 50, 70, 0, 200, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL); + sizer->AddSpacer(5); + sizer->Add(slider_h, 0, wxEXPAND | wxLEFT, 20); + sizer->AddSpacer(5); + PrusaDoubleSlider* slider_v = new PrusaDoubleSlider(parent, wxID_ANY, 50, 70, 0, 100, wxDefaultPosition, wxSize(wxDefaultSize.x ,150), wxSL_VERTICAL); + sizer->AddSpacer(5); + sizer->Add(slider_v, 0, wxLEFT, 20); + sizer->AddSpacer(5); + // Frequently Object Settings add_object_settings(parent, sizer); } diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 294eea454..710d91b49 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -5,6 +5,7 @@ #include #include +#include const unsigned int wxCheckListBoxComboPopup::DefaultWidth = 200; const unsigned int wxCheckListBoxComboPopup::DefaultHeight = 200; @@ -747,6 +748,323 @@ unsigned int PrusaObjectDataViewModel::GetChildren(const wxDataViewItem &parent, return count; } -// ************************************** EXPERIMENTS *************************************** +// ************************************** EXPERIMENTS *************************************** +PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, + wxWindowID id, + int lowerValue, + int higherValue, + int minValue, + int maxValue, + const wxPoint& pos, + const wxSize& size, + long style, + const wxValidator& val, + const wxString& name) : + wxControl(parent, id, pos, size, wxBORDER_NONE), + m_lower_value(lowerValue), m_higher_value (higherValue), + m_min_value(minValue), m_max_value(maxValue), + m_style(style) +{ + SetDoubleBuffered(true); + + if (m_style != wxSL_HORIZONTAL && m_style != wxSL_VERTICAL) + m_style = wxSL_HORIZONTAL; + + m_thumb_higher = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("right_half_circle.png")) : + Slic3r::GUI::from_u8(Slic3r::var("up_half_circle.png")), wxBITMAP_TYPE_PNG); + m_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("left_half_circle.png")) : + Slic3r::GUI::from_u8(Slic3r::var("down_half_circle.png")), wxBITMAP_TYPE_PNG); + + + m_selection = ssUndef; + + // slider events + Bind(wxEVT_PAINT, &PrusaDoubleSlider::OnPaint, this); + Bind(wxEVT_LEFT_DOWN, &PrusaDoubleSlider::OnLeftDown, this); + Bind(wxEVT_MOTION, &PrusaDoubleSlider::OnMotion, this); + Bind(wxEVT_LEFT_UP, &PrusaDoubleSlider::OnLeftUp, this); + Bind(wxEVT_LEAVE_WINDOW,&PrusaDoubleSlider::OnLeftUp, this); + Bind(wxEVT_MOUSEWHEEL, &PrusaDoubleSlider::OnWheel, this); + + // control's view variables + SLIDER_MARGIN = 2 + (style == wxSL_HORIZONTAL ? m_thumb_higher.GetWidth() : m_thumb_higher.GetHeight()); + + DARK_ORANGE_PEN = wxPen(wxColour(253, 84, 2)); + ORANGE_PEN = wxPen(wxColour(253, 126, 66)); + LIGHT_ORANGE_PEN = wxPen(wxColour(254, 177, 139)); + + DARK_GREY_PEN = wxPen(wxColour(128, 128, 128)); + GREY_PEN = wxPen(wxColour(164, 164, 164)); + LIGHT_GREY_PEN = wxPen(wxColour(204, 204, 204)); + + line_pens = { &DARK_GREY_PEN, &GREY_PEN, &LIGHT_GREY_PEN }; + segm_pens = { &DARK_ORANGE_PEN, &ORANGE_PEN, &LIGHT_ORANGE_PEN }; +} + +void PrusaDoubleSlider::SetLowerValue(const int lower_val) +{ + m_lower_value = lower_val; + Refresh(); + Update(); +} + +void PrusaDoubleSlider::SetHigherValue(const int higher_val) +{ + m_higher_value = higher_val; + Refresh(); + Update(); +} + +void PrusaDoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos) +{ + int width; + int height; + GetSize(&width, &height); + + wxCoord line_beg_x = is_horizontal() ? SLIDER_MARGIN : width*0.5 - 1; + wxCoord line_beg_y = is_horizontal() ? height*0.5 - 1 : SLIDER_MARGIN; + wxCoord line_end_x = is_horizontal() ? width - SLIDER_MARGIN + 1 : width*0.5 - 1; + wxCoord line_end_y = is_horizontal() ? height*0.5 - 1 : height - SLIDER_MARGIN + 1; + + wxCoord segm_beg_x = is_horizontal() ? lower_pos : width*0.5 - 1; + wxCoord segm_beg_y = is_horizontal() ? height*0.5 - 1 : lower_pos-1; + wxCoord segm_end_x = is_horizontal() ? higher_pos : width*0.5 - 1; + wxCoord segm_end_y = is_horizontal() ? height*0.5 - 1 : higher_pos-1; + + for (int id = 0; id < line_pens.size(); id++) + { + dc.SetPen(*line_pens[id]); + dc.DrawLine(line_beg_x, line_beg_y, line_end_x, line_end_y); + dc.SetPen(*segm_pens[id]); + dc.DrawLine(segm_beg_x, segm_beg_y, segm_end_x, segm_end_y); + if (is_horizontal()) + line_beg_y = line_end_y = segm_beg_y = segm_end_y += 1; + else + line_beg_x = line_end_x = segm_beg_x = segm_end_x += 1; + } +} + +double PrusaDoubleSlider::get_scroll_step() +{ + const wxSize sz = GetSize(); + const int& slider_len = m_style == wxSL_HORIZONTAL ? sz.x : sz.y; + return double(slider_len - SLIDER_MARGIN * 2) / (m_max_value - m_min_value); +} + +void PrusaDoubleSlider::get_lower_and_higher_position(int& lower_pos, int& higher_pos) +{ + const double step = get_scroll_step(); + if (is_horizontal()) { + lower_pos = SLIDER_MARGIN + int(m_lower_value*step + 0.5); + higher_pos = SLIDER_MARGIN + int(m_higher_value*step + 0.5); + } + else { + lower_pos = SLIDER_MARGIN + int((m_max_value - m_lower_value)*step + 0.5); + higher_pos = SLIDER_MARGIN + int((m_max_value - m_higher_value)*step + 0.5); + } +} + +void PrusaDoubleSlider::OnPaint(wxPaintEvent& event) +{ + SetBackgroundColour(GetParent()->GetBackgroundColour()); + + wxPaintDC dc(this); + int width, height; + GetSize(&width, &height); + + int lower_pos, higher_pos; + get_lower_and_higher_position(lower_pos, higher_pos); + + // draw line + draw_scroll_line(dc, lower_pos, higher_pos); + + //lower slider: + wxPoint pos = is_horizontal() ? wxPoint(lower_pos, height*0.5) : wxPoint(0.5*width, lower_pos); + draw_lower_thumb(dc, pos); + + //higher slider: + pos = is_horizontal() ? wxPoint(higher_pos, height*0.5) : wxPoint(0.5*width, higher_pos); + draw_higher_thumb(dc, pos); +} + +void PrusaDoubleSlider::draw_lower_thumb(wxDC& dc, const wxPoint& pos) +{ + // Draw thumb + wxCoord x_draw, y_draw; + const wxSize thumb_size = m_thumb_lower.GetSize(); + if (is_horizontal()) { + x_draw = pos.x - thumb_size.x; + y_draw = pos.y - int(0.5*thumb_size.y); + } + else { + x_draw = pos.x - int(0.5*thumb_size.x); + y_draw = pos.y; + } + dc.DrawBitmap(m_thumb_lower, x_draw, y_draw); + + // Draw thumb text + wxCoord text_width, text_height; + dc.GetTextExtent(wxString::Format("%d", m_lower_value), &text_width, &text_height); + wxPoint text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + thumb_size.x) : + wxPoint(pos.x + thumb_size.y, pos.y - 1 - text_height); + dc.DrawText(wxString::Format("%d", m_lower_value), text_pos); + + // Update thumb rect + m_rect_lower_thumb = wxRect(x_draw, y_draw, thumb_size.x, thumb_size.y); +} + + +void PrusaDoubleSlider::draw_higher_thumb(wxDC& dc, const wxPoint& pos) +{ + wxCoord x_draw, y_draw; + const wxSize thumb_size = m_thumb_higher.GetSize(); + if (is_horizontal()) { + x_draw = pos.x; + y_draw = pos.y - int(0.5*thumb_size.y); + } + else { + x_draw = pos.x - int(0.5*thumb_size.x); + y_draw = pos.y - thumb_size.y; + } + dc.DrawBitmap(m_thumb_higher, x_draw, y_draw); + + // Draw thumb text + wxCoord text_width, text_height; + dc.GetTextExtent(wxString::Format("%d", m_higher_value), &text_width, &text_height); + wxPoint text_pos = is_horizontal() ? wxPoint(pos.x - text_width-1, pos.y - thumb_size.x - text_height) : + wxPoint(pos.x - text_width-1 - thumb_size.y, pos.y + 1); + dc.DrawText(wxString::Format("%d", m_higher_value), text_pos); + + // Update thumb rect + m_rect_higher_thumb = wxRect(x_draw, y_draw, thumb_size.x, thumb_size.y); +} + +int PrusaDoubleSlider::position_to_value(wxDC& dc, const wxCoord x, const wxCoord y) +{ + int width, height; + dc.GetSize(&width, &height); + const double step = get_scroll_step(); + + if (is_horizontal()) + return int(double(x - SLIDER_MARGIN) / step + 0.5); + else + return int(m_min_value + double(height - SLIDER_MARGIN - y) / step + 0.5); +} + +void PrusaDoubleSlider::detect_selected_slider(const wxPoint& pt, const bool is_mouse_wheel /*= false*/) +{ + if (is_mouse_wheel) + { + if (is_horizontal()) { + m_selection = pt.x <= m_rect_lower_thumb.GetRight() ? ssLower : + pt.x >= m_rect_higher_thumb.GetLeft() ? ssHigher : ssUndef; + } + else { + m_selection = pt.y >= m_rect_lower_thumb.GetTop() ? ssLower : + pt.y <= m_rect_higher_thumb.GetBottom() ? ssHigher : ssUndef; + } + return; + } + + m_selection = is_point_in_rect(pt, m_rect_lower_thumb) ? ssLower : + is_point_in_rect(pt, m_rect_higher_thumb) ? ssHigher : ssUndef; +} + +bool PrusaDoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect) +{ + if (rect.GetLeft() <= pt.x && pt.x <= rect.GetRight() && + rect.GetTop() <= pt.y && pt.y <= rect.GetBottom()) + return true; + return false; +} + +void PrusaDoubleSlider::OnLeftDown(wxMouseEvent& event) +{ + m_is_left_down = true; + wxClientDC dc(this); + wxPoint pos = event.GetLogicalPosition(dc); + detect_selected_slider(pos); + event.Skip(); +} + +void PrusaDoubleSlider::correct_lower_value() +{ + if (m_lower_value < m_min_value) + m_lower_value = m_min_value; + else if (m_lower_value >= m_higher_value && m_lower_value <= m_max_value) + m_higher_value = m_lower_value; + else if (m_lower_value > m_max_value) + m_lower_value = m_max_value; +} + +void PrusaDoubleSlider::correct_higher_value() +{ + if (m_higher_value > m_max_value) + m_higher_value = m_max_value; + else if (m_higher_value <= m_lower_value && m_higher_value >= m_min_value) + m_lower_value = m_higher_value; + else if (m_higher_value < m_min_value) + m_higher_value = m_min_value; +} + +void PrusaDoubleSlider::OnMotion(wxMouseEvent& event) +{ + if (!m_is_left_down || m_selection == ssUndef) + return; + + wxClientDC dc(this); + wxPoint pos = event.GetLogicalPosition(dc); + + if (m_selection == ssLower) { + m_lower_value = position_to_value(dc, pos.x, pos.y); + correct_lower_value(); + } + else if (m_selection == ssHigher) { + m_higher_value = position_to_value(dc, pos.x, pos.y); + correct_higher_value(); + } + + Refresh(); + Update(); + event.Skip(); +} + +void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event) +{ + m_is_left_down = false; + event.Skip(); + + wxCommandEvent e(wxEVT_SCROLL_CHANGED); + e.SetEventObject(this); + ProcessWindowEvent(e); +} + +void PrusaDoubleSlider::OnWheel(wxMouseEvent& event) +{ + wxClientDC dc(this); + wxPoint pos = event.GetLogicalPosition(dc); + detect_selected_slider(pos, true); + + if (m_selection == ssUndef) + return; + + int delta = event.GetWheelRotation() > 0 ? -1 : 1; + if (is_horizontal()) + delta *= -1; + if (m_selection == ssLower) { + m_lower_value -= delta; + correct_lower_value(); + } + else if (m_selection == ssHigher) { + m_higher_value -= delta; + correct_higher_value(); + } + Refresh(); + Update(); + + wxCommandEvent e(wxEVT_SCROLL_CHANGED); + e.SetEventObject(this); + ProcessWindowEvent(e); +} // ***************************************************************************** diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 32ae0a4f9..584882d96 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include @@ -496,7 +496,85 @@ private: wxString m_value; }; // ******************************* EXPERIMENTS ********************************************** +enum SelectedSlider { + ssUndef, + ssLower, + ssHigher +}; +class PrusaDoubleSlider : public wxControl +{ +public: + PrusaDoubleSlider( + wxWindow *parent, + wxWindowID id, + int lowerValue, + int higherValue, + int minValue, + int maxValue, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxSL_HORIZONTAL, + const wxValidator& val = wxDefaultValidator, + const wxString& name = wxEmptyString); + int GetLowerValue() { + return m_lower_value; + } + int GetHigherValue() { + return m_higher_value; + } + void SetLowerValue(int lower_val); + void SetHigherValue(int higher_val); + + wxSize DoGetBestSize(){ return wxDefaultSize; } + + void OnPaint(wxPaintEvent& event); + void OnLeftDown(wxMouseEvent& event); + void OnMotion(wxMouseEvent& event); + void OnLeftUp(wxMouseEvent& event); + void OnWheel(wxMouseEvent& event); + +protected: + void correct_lower_value(); + void correct_higher_value(); + void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos); + double get_scroll_step(); + void get_lower_and_higher_position(int& lower_pos, int& higher_pos); + void draw_lower_thumb (wxDC& dc, const wxPoint& pos); + void draw_higher_thumb(wxDC& dc, const wxPoint& pos); + int position_to_value(wxDC& dc, const wxCoord x, const wxCoord y); + void detect_selected_slider(const wxPoint& pt, const bool is_mouse_wheel = false); + bool is_point_in_rect(const wxPoint& pt, const wxRect& rect); + bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } + +private: + int m_min_value; + int m_max_value; + int m_lower_value; + int m_higher_value; + wxBitmap m_thumb_higher; + wxBitmap m_thumb_lower; + SelectedSlider m_selection; + bool m_is_left_down = false; + + wxRect m_rect_lower_thumb; + wxRect m_rect_higher_thumb; + long m_style; + +// control's view variables + wxCoord SLIDER_MARGIN; // margin around slider + + wxPen DARK_ORANGE_PEN; + wxPen ORANGE_PEN; + wxPen LIGHT_ORANGE_PEN; + + wxPen DARK_GREY_PEN; + wxPen GREY_PEN; + wxPen LIGHT_GREY_PEN; + + std::vector line_pens; + std::vector segm_pens; +}; // ****************************************************************************************** From bc64154f2111465b13b84c38f378d9a1138516b2 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 21 Aug 2018 17:47:05 +0200 Subject: [PATCH 112/119] PrusaDoubleSlider improvement + OnKeyDown + marked selected thumb + marked selected control ... --- resources/icons/down_half_circle.png | Bin 0 -> 506 bytes resources/icons/left_half_circle.png | Bin 0 -> 518 bytes resources/icons/right_half_circle.png | Bin 0 -> 521 bytes resources/icons/up_half_circle.png | Bin 0 -> 517 bytes xs/src/slic3r/GUI/GUI.cpp | 3 +- xs/src/slic3r/GUI/wxExtensions.cpp | 119 ++++++++++++++++++++++---- xs/src/slic3r/GUI/wxExtensions.hpp | 16 +++- 7 files changed, 118 insertions(+), 20 deletions(-) create mode 100644 resources/icons/down_half_circle.png create mode 100644 resources/icons/left_half_circle.png create mode 100644 resources/icons/right_half_circle.png create mode 100644 resources/icons/up_half_circle.png diff --git a/resources/icons/down_half_circle.png b/resources/icons/down_half_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..84aba5c3cdd7b54590874c1999593bb3da8b50fd GIT binary patch literal 506 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!3HEhl+{lMQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0V%N?Oj+ueoXKL{?^yL>W8Sy_Q&I?yN`F#c^( zlnE46Epd$~Nl7e8wMs5Z1yT$~28Kqu29~-;#vz6lR)z*v2Bx|O=2iv<8LQ0dQ8eV{ zr(~v8;?^Mfz3(tkgCxj?;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1U#L5e~$ zOL9^f+;j4aiz^lUixTtFQx%*ui;{Cv6+Dyk^N!!=nE+I}&C|s(L?d|WguR?hjv_7l zZFin=VX+Qq(RMr-A+V8++u-UEhc^e9)*NDM*~}um*3pNDrT&`v_C-x6-?B6RPP>2L zjn#e++kR<_M<14Xc{wRJr+-)!aBLIjTfvCNj42z}d}b4V9dEq&jd95ToT$odg*M|I zBFl?1!X=eW1YYaCDG!($ZSg-N_~9Dn$9pz7F)J>%=e@da*=|pH)t5T{<+m!^k8VGx re_K_?tiY;m=e?F|3{{^E>KnvU@0-4U)LZln=mQ2%S3j3^P6Cc6VX;4}uH!E}sliR#xDc4m3&!jDK4c zWda3NOI#yLQW8s2t&)pUffR$0fuWJEfu*jIafqRXm7#%^fvK*6xs`!I#wxRV6b-rg zDVb@NxHU+A?>h|CAPKS|I6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDWD>GkfM;x zlAKfq_niFV;z|YoqQt!PR0ZeEqU4-Z1<&OCyyN$ICIFQl@^o#Zf-s&7JG2Zu@#nxR&$u?=W7l;>ts@a<(-Op0Jm6KWLe2 zHd*5h)0L=#&bcD>cBLNayjR)YxW+Gi7bNue<6Sxbi5DF|wF&+`2J{Vsr>mdKI;Vst E09RGD!TCc6VX;4}uH!E}sliR#xDc4m3&!jDK4c zWda3NOI#yLQW8s2t&)pUffR$0fuWJEfu*jIafqRXm7#%^fvK*6xs`!I#wxRV6b-rg zDVb@NxHU+A?>h|CAPKS|I6tkVJh3R1p}f3YFEcN@I61K(RWH9NefB#WDWD>GkfM;x zlAKfq_niFV;z|YoqQt!PR0ZeEqU4-Z1<&OCyyN$ICIFQl^>lFz(Fjid6Mz20e8+&! zM#rPgjRzObYix|}VU#rZx1L$+2Ybq2#z*=NInsv?2yBy5VQ2H<>2a7O*>STmf}_KK zePY541`|Q984FBU8bpejKVJUL!y`TUfYS=Dga+=8?`PPfelxc-&G2l$RiMGZD5kJ) zvur=pgfqLXD?}U^^H>*b5DYrFm_ejKYo3M3ANEJ<9dg23oe!ETlzFoJYGL+e^jW?| ziMjc|%?1JCh!6S#|5+ZDJLGWntZAxtU}F*J$YWz;csx%>XqWDSRX`6hc)I$ztaD0e F0sxp@rON;S literal 0 HcmV?d00001 diff --git a/resources/icons/up_half_circle.png b/resources/icons/up_half_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..9eea07fda7f4e2b7aa63a2370c2899b44106791a GIT binary patch literal 517 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~c!3HEhl+{lMQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0V%N?Oj+ueoXKL{?^yL>W8Sy_Q&I?yN`F#c^( zlnE46Epd$~Nl7e8wMs5Z1yT$~28Kqu29~-;#vz6lR)z*v2Bx|O=2iv<8LQ0dQ8eV{ zr(~v8;?^Mfz3(tkgCxj?;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1U#L5e~$ zOL9^f+;j4aiz^lUixTtFQx%*ui;{Cv6+Dyk^N!!=nE+IJ(9^{+L?d|WgpGWRjv}u7 z7X?I*icQ(q9H;%K!)@`xi$4TbFTeMrx3{b5NSKrIwcW;(RF&R%<{1?~ziV#1euC7V zB1=b;)(Y0;H>$siZP|4}(s}8-z3T6I4>9IU3)otEGNeTBj<5OUn^)dB+fR9YLh8)y zf*a0}>x%6HpI#L)N!U?5ZGZB`&kwuS?r&{97qU1iHD&2@=TjODv&zo>?v0x?Bh9_K zk!_j%e`&E*p=z@tnk(M2PZLkoiB`FpcKKYh(aCA-KHBD=R?CNp06oLt>FVdQ&MBb@ E0N(4k1^@s6 literal 0 HcmV?d00001 diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index e50c7220a..67be47987 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1057,7 +1057,8 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl sizer->AddSpacer(5); sizer->Add(slider_h, 0, wxEXPAND | wxLEFT, 20); sizer->AddSpacer(5); - PrusaDoubleSlider* slider_v = new PrusaDoubleSlider(parent, wxID_ANY, 50, 70, 0, 100, wxDefaultPosition, wxSize(wxDefaultSize.x ,150), wxSL_VERTICAL); + PrusaDoubleSlider* slider_v = new PrusaDoubleSlider(parent, wxID_ANY, 5, 7, 0, 10, wxDefaultPosition, wxSize(wxDefaultSize.x ,150), wxSL_VERTICAL); + slider_v->SetKoefForLabels(0.15); sizer->AddSpacer(5); sizer->Add(slider_v, 0, wxLEFT, 20); sizer->AddSpacer(5); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 710d91b49..3ba0d3886 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -6,6 +6,7 @@ #include #include #include +#include const unsigned int wxCheckListBoxComboPopup::DefaultWidth = 200; const unsigned int wxCheckListBoxComboPopup::DefaultHeight = 200; @@ -761,7 +762,7 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, long style, const wxValidator& val, const wxString& name) : - wxControl(parent, id, pos, size, wxBORDER_NONE), + wxControl(parent, id, pos, size, wxWANTS_CHARS | wxBORDER_NONE), m_lower_value(lowerValue), m_higher_value (higherValue), m_min_value(minValue), m_max_value(maxValue), m_style(style) @@ -784,8 +785,10 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, Bind(wxEVT_LEFT_DOWN, &PrusaDoubleSlider::OnLeftDown, this); Bind(wxEVT_MOTION, &PrusaDoubleSlider::OnMotion, this); Bind(wxEVT_LEFT_UP, &PrusaDoubleSlider::OnLeftUp, this); - Bind(wxEVT_LEAVE_WINDOW,&PrusaDoubleSlider::OnLeftUp, this); Bind(wxEVT_MOUSEWHEEL, &PrusaDoubleSlider::OnWheel, this); + Bind(wxEVT_ENTER_WINDOW,&PrusaDoubleSlider::OnEnterWin, this); + Bind(wxEVT_LEAVE_WINDOW,&PrusaDoubleSlider::OnLeaveWin, this); + Bind(wxEVT_KEY_DOWN, &PrusaDoubleSlider::OnKeyDown, this); // control's view variables SLIDER_MARGIN = 2 + (style == wxSL_HORIZONTAL ? m_thumb_higher.GetWidth() : m_thumb_higher.GetHeight()); @@ -865,9 +868,22 @@ void PrusaDoubleSlider::get_lower_and_higher_position(int& lower_pos, int& highe } } -void PrusaDoubleSlider::OnPaint(wxPaintEvent& event) +void PrusaDoubleSlider::draw_focus_rect() +{ + if (!m_is_focused) + return; + const wxSize sz = GetSize(); + wxPaintDC dc(this); + const wxPen pen = wxPen(wxColour(128, 128, 10), 1, wxPENSTYLE_DOT); + dc.SetPen(pen); + dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxBRUSHSTYLE_TRANSPARENT)); + dc.DrawRectangle(2, 2, sz.x - 4, sz.y - 4); +} + +void PrusaDoubleSlider::render() { SetBackgroundColour(GetParent()->GetBackgroundColour()); + draw_focus_rect(); wxPaintDC dc(this); int width, height; @@ -888,6 +904,21 @@ void PrusaDoubleSlider::OnPaint(wxPaintEvent& event) draw_higher_thumb(dc, pos); } +void PrusaDoubleSlider::draw_info_line(wxDC& dc, const wxPoint& pos, const wxSize& thumb_size, const SelectedSlider selection) +{ + if (m_selection == selection) { + dc.SetPen(DARK_ORANGE_PEN); + is_horizontal() ? dc.DrawLine(pos.x, pos.y - thumb_size.y, pos.x, pos.y + thumb_size.y): + dc.DrawLine(pos.x - thumb_size.x, pos.y-1, pos.x + thumb_size.x, pos.y-1); + } +} + +wxString PrusaDoubleSlider::get_label(const int value) +{ + return m_label_koef == 1.0 ? wxString::Format("%d", value) : + wxNumberFormatter::ToString(m_label_koef*value, 2, wxNumberFormatter::Style_None); +} + void PrusaDoubleSlider::draw_lower_thumb(wxDC& dc, const wxPoint& pos) { // Draw thumb @@ -902,13 +933,16 @@ void PrusaDoubleSlider::draw_lower_thumb(wxDC& dc, const wxPoint& pos) y_draw = pos.y; } dc.DrawBitmap(m_thumb_lower, x_draw, y_draw); + // Draw info_line + draw_info_line(dc, pos, thumb_size, ssLower); // Draw thumb text wxCoord text_width, text_height; - dc.GetTextExtent(wxString::Format("%d", m_lower_value), &text_width, &text_height); + wxString label = get_label(m_lower_value); + dc.GetTextExtent(label, &text_width, &text_height); wxPoint text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + thumb_size.x) : - wxPoint(pos.x + thumb_size.y, pos.y - 1 - text_height); - dc.DrawText(wxString::Format("%d", m_lower_value), text_pos); + wxPoint(pos.x + thumb_size.x+1, pos.y - 0.5*text_height - 1); + dc.DrawText(label, text_pos); // Update thumb rect m_rect_lower_thumb = wxRect(x_draw, y_draw, thumb_size.x, thumb_size.y); @@ -928,13 +962,16 @@ void PrusaDoubleSlider::draw_higher_thumb(wxDC& dc, const wxPoint& pos) y_draw = pos.y - thumb_size.y; } dc.DrawBitmap(m_thumb_higher, x_draw, y_draw); + // Draw info_line + draw_info_line(dc, pos, thumb_size, ssHigher); // Draw thumb text wxCoord text_width, text_height; - dc.GetTextExtent(wxString::Format("%d", m_higher_value), &text_width, &text_height); - wxPoint text_pos = is_horizontal() ? wxPoint(pos.x - text_width-1, pos.y - thumb_size.x - text_height) : - wxPoint(pos.x - text_width-1 - thumb_size.y, pos.y + 1); - dc.DrawText(wxString::Format("%d", m_higher_value), text_pos); + wxString label = get_label(m_higher_value); + dc.GetTextExtent(label, &text_width, &text_height); + wxPoint text_pos = is_horizontal() ? wxPoint(pos.x - text_width-1, pos.y - thumb_size.x - text_height) : + wxPoint(pos.x - text_width - 1 - thumb_size.x, pos.y - 0.5*text_height + 1); + dc.DrawText(label, text_pos); // Update thumb rect m_rect_higher_thumb = wxRect(x_draw, y_draw, thumb_size.x, thumb_size.y); @@ -1033,6 +1070,9 @@ void PrusaDoubleSlider::OnMotion(wxMouseEvent& event) void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event) { m_is_left_down = false; + m_selection = ssUndef; + Refresh(); + Update(); event.Skip(); wxCommandEvent e(wxEVT_SCROLL_CHANGED); @@ -1040,18 +1080,29 @@ void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event) ProcessWindowEvent(e); } -void PrusaDoubleSlider::OnWheel(wxMouseEvent& event) +void PrusaDoubleSlider::OnEnterWin(wxMouseEvent& event) { - wxClientDC dc(this); - wxPoint pos = event.GetLogicalPosition(dc); - detect_selected_slider(pos, true); + m_is_focused = true; + Refresh(); + Update(); + event.Skip(); +} - if (m_selection == ssUndef) - return; +void PrusaDoubleSlider::OnLeaveWin(wxMouseEvent& event) +{ + m_is_focused = false; + OnLeftUp(event); +} - int delta = event.GetWheelRotation() > 0 ? -1 : 1; +// "condition" have to be true for: +// - value increase (if wxSL_VERTICAL) +// - value decrease (if wxSL_HORIZONTAL) +void PrusaDoubleSlider::move_current_thumb(const bool condition) +{ + int delta = condition ? -1 : 1; if (is_horizontal()) delta *= -1; + if (m_selection == ssLower) { m_lower_value -= delta; correct_lower_value(); @@ -1067,4 +1118,38 @@ void PrusaDoubleSlider::OnWheel(wxMouseEvent& event) e.SetEventObject(this); ProcessWindowEvent(e); } + +void PrusaDoubleSlider::OnWheel(wxMouseEvent& event) +{ + wxClientDC dc(this); + wxPoint pos = event.GetLogicalPosition(dc); + detect_selected_slider(pos, true); + + if (m_selection == ssUndef) + return; + + move_current_thumb(event.GetWheelRotation() > 0); +} + +void PrusaDoubleSlider::OnKeyDown(wxKeyEvent &event) +{ + if (is_horizontal()) + { + if (event.GetKeyCode() == WXK_LEFT || event.GetKeyCode() == WXK_RIGHT) + move_current_thumb(event.GetKeyCode() == WXK_LEFT); + else if (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_DOWN){ + m_selection = event.GetKeyCode() == WXK_UP ? ssHigher : ssLower; + Refresh(); + } + } + else { + if (event.GetKeyCode() == WXK_LEFT || event.GetKeyCode() == WXK_RIGHT) { + m_selection = event.GetKeyCode() == WXK_LEFT ? ssHigher : ssLower; + Refresh(); + } + else if (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_DOWN) + move_current_thumb(event.GetKeyCode() == WXK_UP); + } +} + // ***************************************************************************** diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 584882d96..59d27e448 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -525,27 +525,37 @@ public: } void SetLowerValue(int lower_val); void SetHigherValue(int higher_val); + void SetKoefForLabels(float koef){ m_label_koef = koef;} wxSize DoGetBestSize(){ return wxDefaultSize; } - void OnPaint(wxPaintEvent& event); + void OnPaint(wxPaintEvent& ){ render();} void OnLeftDown(wxMouseEvent& event); void OnMotion(wxMouseEvent& event); void OnLeftUp(wxMouseEvent& event); + void OnEnterWin(wxMouseEvent& event); + void OnLeaveWin(wxMouseEvent& event); void OnWheel(wxMouseEvent& event); + void OnKeyDown(wxKeyEvent &event); protected: + + void render(); + void draw_info_line(wxDC& dc, const wxPoint& pos, const wxSize& thumb_size, SelectedSlider selection); + wxString get_label(const int value); void correct_lower_value(); void correct_higher_value(); void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos); double get_scroll_step(); void get_lower_and_higher_position(int& lower_pos, int& higher_pos); - void draw_lower_thumb (wxDC& dc, const wxPoint& pos); + void draw_focus_rect(); + void draw_lower_thumb(wxDC& dc, const wxPoint& pos); void draw_higher_thumb(wxDC& dc, const wxPoint& pos); int position_to_value(wxDC& dc, const wxCoord x, const wxCoord y); void detect_selected_slider(const wxPoint& pt, const bool is_mouse_wheel = false); bool is_point_in_rect(const wxPoint& pt, const wxRect& rect); bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } + void move_current_thumb(const bool condition); private: int m_min_value; @@ -556,10 +566,12 @@ private: wxBitmap m_thumb_lower; SelectedSlider m_selection; bool m_is_left_down = false; + bool m_is_focused = false; wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb; long m_style; + float m_label_koef = 1.0; // control's view variables wxCoord SLIDER_MARGIN; // margin around slider From 5cd4597d387264bb7739a882936f7bd150830495 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 22 Aug 2018 08:54:07 +0200 Subject: [PATCH 113/119] Fix for last commit --- xs/src/slic3r/GUI/wxExtensions.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 3ba0d3886..fe1018076 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -767,7 +767,9 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, m_min_value(minValue), m_max_value(maxValue), m_style(style) { +#ifndef __WXOSX__ // SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX SetDoubleBuffered(true); +#endif //__WXOSX__ if (m_style != wxSL_HORIZONTAL && m_style != wxSL_VERTICAL) m_style = wxSL_HORIZONTAL; From a5119a41a5a82d611d9e7f80a3edbc58fc8de193 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 22 Aug 2018 10:44:11 +0200 Subject: [PATCH 114/119] Added overriding of the DoGetBestSize() to correct control sizing on OSX and Linux/GTK --- xs/src/slic3r/GUI/wxExtensions.cpp | 16 +++++++++++----- xs/src/slic3r/GUI/wxExtensions.hpp | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index fe1018076..9e229a0b0 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -765,15 +765,12 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, wxControl(parent, id, pos, size, wxWANTS_CHARS | wxBORDER_NONE), m_lower_value(lowerValue), m_higher_value (higherValue), m_min_value(minValue), m_max_value(maxValue), - m_style(style) + m_style(style == wxSL_HORIZONTAL || style == wxSL_VERTICAL ? style: wxSL_HORIZONTAL) { #ifndef __WXOSX__ // SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX SetDoubleBuffered(true); #endif //__WXOSX__ - if (m_style != wxSL_HORIZONTAL && m_style != wxSL_VERTICAL) - m_style = wxSL_HORIZONTAL; - m_thumb_higher = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("right_half_circle.png")) : Slic3r::GUI::from_u8(Slic3r::var("up_half_circle.png")), wxBITMAP_TYPE_PNG); m_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("left_half_circle.png")) : @@ -789,7 +786,7 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, Bind(wxEVT_LEFT_UP, &PrusaDoubleSlider::OnLeftUp, this); Bind(wxEVT_MOUSEWHEEL, &PrusaDoubleSlider::OnWheel, this); Bind(wxEVT_ENTER_WINDOW,&PrusaDoubleSlider::OnEnterWin, this); - Bind(wxEVT_LEAVE_WINDOW,&PrusaDoubleSlider::OnLeaveWin, this); + Bind(wxEVT_LEAVE_WINDOW,&PrusaDoubleSlider::OnLeaveWin, this); Bind(wxEVT_KEY_DOWN, &PrusaDoubleSlider::OnKeyDown, this); // control's view variables @@ -807,6 +804,15 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, segm_pens = { &DARK_ORANGE_PEN, &ORANGE_PEN, &LIGHT_ORANGE_PEN }; } +wxSize PrusaDoubleSlider::DoGetBestSize() const +{ + wxSize size = wxControl::DoGetBestSize(); + if (size.x > 1 && size.y > 1) + return size; + const int new_size = is_horizontal() ? 80 : 120; + return wxSize(new_size, new_size); +} + void PrusaDoubleSlider::SetLowerValue(const int lower_val) { m_lower_value = lower_val; diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 59d27e448..362583547 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -527,7 +527,7 @@ public: void SetHigherValue(int higher_val); void SetKoefForLabels(float koef){ m_label_koef = koef;} - wxSize DoGetBestSize(){ return wxDefaultSize; } + wxSize DoGetBestSize() const override; void OnPaint(wxPaintEvent& ){ render();} void OnLeftDown(wxMouseEvent& event); From d2282c4bf9ff834dac7534a5f87e51cdf7a6f6a5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 22 Aug 2018 14:24:30 +0200 Subject: [PATCH 115/119] Refactored code --- xs/src/slic3r/GUI/GUI.cpp | 6 +- xs/src/slic3r/GUI/wxExtensions.cpp | 134 ++++++++++++++++------------- xs/src/slic3r/GUI/wxExtensions.hpp | 33 ++++--- 3 files changed, 97 insertions(+), 76 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 67be47987..396c16257 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1053,11 +1053,13 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl add_objects_list(parent, sizer); // experiment with slider - PrusaDoubleSlider* slider_h = new PrusaDoubleSlider(parent, wxID_ANY, 50, 70, 0, 200, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL); + PrusaDoubleSlider* slider_h = new PrusaDoubleSlider(parent, wxID_ANY, 50, 70, 0, 200, wxDefaultPosition, + wxSize(60, wxDefaultSize.y), wxSL_HORIZONTAL); sizer->AddSpacer(5); sizer->Add(slider_h, 0, wxEXPAND | wxLEFT, 20); sizer->AddSpacer(5); - PrusaDoubleSlider* slider_v = new PrusaDoubleSlider(parent, wxID_ANY, 5, 7, 0, 10, wxDefaultPosition, wxSize(wxDefaultSize.x ,150), wxSL_VERTICAL); + PrusaDoubleSlider* slider_v = new PrusaDoubleSlider(parent, wxID_ANY, 50, 70, 0, 200, wxDefaultPosition, + wxSize(wxDefaultSize.x ,250), wxSL_VERTICAL); slider_v->SetKoefForLabels(0.15); sizer->AddSpacer(5); sizer->Add(slider_v, 0, wxLEFT, 20); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 9e229a0b0..92f9e1e37 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -775,8 +775,7 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, Slic3r::GUI::from_u8(Slic3r::var("up_half_circle.png")), wxBITMAP_TYPE_PNG); m_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("left_half_circle.png")) : Slic3r::GUI::from_u8(Slic3r::var("down_half_circle.png")), wxBITMAP_TYPE_PNG); - - + m_thumb_size = m_thumb_lower.GetSize(); m_selection = ssUndef; // slider events @@ -806,7 +805,7 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, wxSize PrusaDoubleSlider::DoGetBestSize() const { - wxSize size = wxControl::DoGetBestSize(); + const wxSize size = wxControl::DoGetBestSize(); if (size.x > 1 && size.y > 1) return size; const int new_size = is_horizontal() ? 80 : 120; @@ -904,85 +903,98 @@ void PrusaDoubleSlider::render() draw_scroll_line(dc, lower_pos, higher_pos); //lower slider: - wxPoint pos = is_horizontal() ? wxPoint(lower_pos, height*0.5) : wxPoint(0.5*width, lower_pos); - draw_lower_thumb(dc, pos); + draw_thumb(dc, lower_pos, ssLower); //higher slider: - pos = is_horizontal() ? wxPoint(higher_pos, height*0.5) : wxPoint(0.5*width, higher_pos); - draw_higher_thumb(dc, pos); + draw_thumb(dc, higher_pos, ssHigher); } -void PrusaDoubleSlider::draw_info_line(wxDC& dc, const wxPoint& pos, const wxSize& thumb_size, const SelectedSlider selection) +void PrusaDoubleSlider::draw_info_line(wxDC& dc, const wxPoint& pos, const SelectedSlider selection) const { if (m_selection == selection) { dc.SetPen(DARK_ORANGE_PEN); - is_horizontal() ? dc.DrawLine(pos.x, pos.y - thumb_size.y, pos.x, pos.y + thumb_size.y): - dc.DrawLine(pos.x - thumb_size.x, pos.y-1, pos.x + thumb_size.x, pos.y-1); + is_horizontal() ? dc.DrawLine(pos.x, pos.y - m_thumb_size.y, pos.x, pos.y + m_thumb_size.y): + dc.DrawLine(pos.x - m_thumb_size.x, pos.y-1, pos.x + m_thumb_size.x, pos.y-1); } } -wxString PrusaDoubleSlider::get_label(const int value) +wxString PrusaDoubleSlider::get_label(const SelectedSlider& selection) const { + const int value = selection == ssLower ? m_lower_value : m_higher_value; return m_label_koef == 1.0 ? wxString::Format("%d", value) : wxNumberFormatter::ToString(m_label_koef*value, 2, wxNumberFormatter::Style_None); + } -void PrusaDoubleSlider::draw_lower_thumb(wxDC& dc, const wxPoint& pos) +void PrusaDoubleSlider::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const { + if (selection == ssUndef) return; + wxCoord text_width, text_height; + const wxString label = get_label(selection); + dc.GetTextExtent(label, &text_width, &text_height); + wxPoint text_pos; + if (selection ==ssLower) + text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + m_thumb_size.x) : + wxPoint(pos.x + m_thumb_size.x+1, pos.y - 0.5*text_height - 1); + else + text_pos = is_horizontal() ? wxPoint(pos.x - text_width - 1, pos.y - m_thumb_size.x - text_height) : + wxPoint(pos.x - text_width - 1 - m_thumb_size.x, pos.y - 0.5*text_height + 1); + dc.DrawText(label, text_pos); +} + +void PrusaDoubleSlider::draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) +{ + wxCoord x_draw, y_draw; + if (selection == ssLower) { + if (is_horizontal()) { + x_draw = pos.x - m_thumb_size.x; + y_draw = pos.y - int(0.5*m_thumb_size.y); + } + else { + x_draw = pos.x - int(0.5*m_thumb_size.x); + y_draw = pos.y; + } + } + else{ + if (is_horizontal()) { + x_draw = pos.x; + y_draw = pos.y - int(0.5*m_thumb_size.y); + } + else { + x_draw = pos.x - int(0.5*m_thumb_size.x); + y_draw = pos.y - m_thumb_size.y; + } + } + dc.DrawBitmap(selection == ssLower ? m_thumb_lower : m_thumb_higher, x_draw, y_draw); + + // Update thumb rect + update_thumb_rect(x_draw, y_draw, selection); +} + +void PrusaDoubleSlider::draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection) +{ + //calculate thumb position on slider line + int width, height; + GetSize(&width, &height); + const wxPoint pos = is_horizontal() ? wxPoint(pos_coord, height*0.5) : wxPoint(0.5*width, pos_coord); + // Draw thumb - wxCoord x_draw, y_draw; - const wxSize thumb_size = m_thumb_lower.GetSize(); - if (is_horizontal()) { - x_draw = pos.x - thumb_size.x; - y_draw = pos.y - int(0.5*thumb_size.y); - } - else { - x_draw = pos.x - int(0.5*thumb_size.x); - y_draw = pos.y; - } - dc.DrawBitmap(m_thumb_lower, x_draw, y_draw); + draw_thumb_item(dc, pos, selection); + // Draw info_line - draw_info_line(dc, pos, thumb_size, ssLower); + draw_info_line(dc, pos, selection); // Draw thumb text - wxCoord text_width, text_height; - wxString label = get_label(m_lower_value); - dc.GetTextExtent(label, &text_width, &text_height); - wxPoint text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + thumb_size.x) : - wxPoint(pos.x + thumb_size.x+1, pos.y - 0.5*text_height - 1); - dc.DrawText(label, text_pos); - - // Update thumb rect - m_rect_lower_thumb = wxRect(x_draw, y_draw, thumb_size.x, thumb_size.y); + draw_thumb_text(dc, pos, selection); } - -void PrusaDoubleSlider::draw_higher_thumb(wxDC& dc, const wxPoint& pos) +void PrusaDoubleSlider::update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection) { - wxCoord x_draw, y_draw; - const wxSize thumb_size = m_thumb_higher.GetSize(); - if (is_horizontal()) { - x_draw = pos.x; - y_draw = pos.y - int(0.5*thumb_size.y); - } - else { - x_draw = pos.x - int(0.5*thumb_size.x); - y_draw = pos.y - thumb_size.y; - } - dc.DrawBitmap(m_thumb_higher, x_draw, y_draw); - // Draw info_line - draw_info_line(dc, pos, thumb_size, ssHigher); - - // Draw thumb text - wxCoord text_width, text_height; - wxString label = get_label(m_higher_value); - dc.GetTextExtent(label, &text_width, &text_height); - wxPoint text_pos = is_horizontal() ? wxPoint(pos.x - text_width-1, pos.y - thumb_size.x - text_height) : - wxPoint(pos.x - text_width - 1 - thumb_size.x, pos.y - 0.5*text_height + 1); - dc.DrawText(label, text_pos); - - // Update thumb rect - m_rect_higher_thumb = wxRect(x_draw, y_draw, thumb_size.x, thumb_size.y); + const wxRect& rect = wxRect(begin_x, begin_y, m_thumb_size.x, m_thumb_size.y); + if (selection == ssLower) + m_rect_lower_thumb = rect; + else + m_rect_higher_thumb = rect; } int PrusaDoubleSlider::position_to_value(wxDC& dc, const wxCoord x, const wxCoord y) @@ -1030,6 +1042,8 @@ void PrusaDoubleSlider::OnLeftDown(wxMouseEvent& event) wxClientDC dc(this); wxPoint pos = event.GetLogicalPosition(dc); detect_selected_slider(pos); + Refresh(); + Update(); event.Skip(); } @@ -1078,7 +1092,6 @@ void PrusaDoubleSlider::OnMotion(wxMouseEvent& event) void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event) { m_is_left_down = false; - m_selection = ssUndef; Refresh(); Update(); event.Skip(); @@ -1099,6 +1112,7 @@ void PrusaDoubleSlider::OnEnterWin(wxMouseEvent& event) void PrusaDoubleSlider::OnLeaveWin(wxMouseEvent& event) { m_is_focused = false; + m_selection = ssUndef; OnLeftUp(event); } diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 362583547..6f000015b 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -523,11 +523,10 @@ public: int GetHigherValue() { return m_higher_value; } + wxSize DoGetBestSize() const override; void SetLowerValue(int lower_val); void SetHigherValue(int higher_val); - void SetKoefForLabels(float koef){ m_label_koef = koef;} - - wxSize DoGetBestSize() const override; + void SetKoefForLabels(const double koef){ m_label_koef = koef;} void OnPaint(wxPaintEvent& ){ render();} void OnLeftDown(wxMouseEvent& event); @@ -541,21 +540,26 @@ public: protected: void render(); - void draw_info_line(wxDC& dc, const wxPoint& pos, const wxSize& thumb_size, SelectedSlider selection); - wxString get_label(const int value); + void draw_focus_rect(); + void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos); + void draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection); + void draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection); + void draw_info_line(wxDC& dc, const wxPoint& pos, SelectedSlider selection) const; + void draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const; + + void update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection); + void detect_selected_slider(const wxPoint& pt, const bool is_mouse_wheel = false); void correct_lower_value(); void correct_higher_value(); - void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos); - double get_scroll_step(); - void get_lower_and_higher_position(int& lower_pos, int& higher_pos); - void draw_focus_rect(); - void draw_lower_thumb(wxDC& dc, const wxPoint& pos); - void draw_higher_thumb(wxDC& dc, const wxPoint& pos); - int position_to_value(wxDC& dc, const wxCoord x, const wxCoord y); - void detect_selected_slider(const wxPoint& pt, const bool is_mouse_wheel = false); + void move_current_thumb(const bool condition); + bool is_point_in_rect(const wxPoint& pt, const wxRect& rect); bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } - void move_current_thumb(const bool condition); + + double get_scroll_step(); + wxString get_label(const SelectedSlider& selection) const; + void get_lower_and_higher_position(int& lower_pos, int& higher_pos); + int position_to_value(wxDC& dc, const wxCoord x, const wxCoord y); private: int m_min_value; @@ -570,6 +574,7 @@ private: wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb; + wxSize m_thumb_size; long m_style; float m_label_koef = 1.0; From 8a9bdc55eed88f0216c1fc9acc005bd5e88be7a9 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 22 Aug 2018 18:00:48 +0200 Subject: [PATCH 116/119] Added functions for tick adding/deleting --- xs/src/slic3r/GUI/wxExtensions.cpp | 46 ++++++++++++++++++++++++++++-- xs/src/slic3r/GUI/wxExtensions.hpp | 4 +++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 92f9e1e37..21ca75ac9 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -787,6 +787,7 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, Bind(wxEVT_ENTER_WINDOW,&PrusaDoubleSlider::OnEnterWin, this); Bind(wxEVT_LEAVE_WINDOW,&PrusaDoubleSlider::OnLeaveWin, this); Bind(wxEVT_KEY_DOWN, &PrusaDoubleSlider::OnKeyDown, this); + Bind(wxEVT_RIGHT_DOWN, &PrusaDoubleSlider::OnRightDown,this); // control's view variables SLIDER_MARGIN = 2 + (style == wxSL_HORIZONTAL ? m_thumb_higher.GetWidth() : m_thumb_higher.GetHeight()); @@ -862,6 +863,14 @@ double PrusaDoubleSlider::get_scroll_step() return double(slider_len - SLIDER_MARGIN * 2) / (m_max_value - m_min_value); } +// get position on the slider line from entered value +wxCoord PrusaDoubleSlider::get_position_from_value(const int value) +{ + const double step = get_scroll_step(); + const int val = is_horizontal() ? value : m_max_value - value; + return wxCoord(SLIDER_MARGIN + int(val*step + 0.5)); +} + void PrusaDoubleSlider::get_lower_and_higher_position(int& lower_pos, int& higher_pos) { const double step = get_scroll_step(); @@ -896,8 +905,8 @@ void PrusaDoubleSlider::render() int width, height; GetSize(&width, &height); - int lower_pos, higher_pos; - get_lower_and_higher_position(lower_pos, higher_pos); + const wxCoord lower_pos = get_position_from_value(m_lower_value); + const wxCoord higher_pos = get_position_from_value(m_higher_value); // draw line draw_scroll_line(dc, lower_pos, higher_pos); @@ -907,6 +916,9 @@ void PrusaDoubleSlider::render() //higher slider: draw_thumb(dc, higher_pos, ssHigher); + + //draw color print ticks + draw_ticks(dc); } void PrusaDoubleSlider::draw_info_line(wxDC& dc, const wxPoint& pos, const SelectedSlider selection) const @@ -988,6 +1000,23 @@ void PrusaDoubleSlider::draw_thumb(wxDC& dc, const wxCoord& pos_coord, const Sel draw_thumb_text(dc, pos, selection); } +void PrusaDoubleSlider::draw_ticks(wxDC& dc) +{ + dc.SetPen(DARK_GREY_PEN); + int height, width; + GetSize(&width, &height); + const wxCoord mid = is_horizontal() ? 0.5*height : 0.5*width; + for (auto tick : m_ticks) + { + const wxCoord pos = get_position_from_value(tick); + + is_horizontal() ? dc.DrawLine(pos, mid-14, pos, mid-9) : + dc.DrawLine(mid - 14, pos - 1, mid - 9, pos - 1); + is_horizontal() ? dc.DrawLine(pos, mid+14, pos, mid+9) : + dc.DrawLine(mid + 14, pos - 1, mid + 9, pos - 1); + } +} + void PrusaDoubleSlider::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); @@ -1174,4 +1203,17 @@ void PrusaDoubleSlider::OnKeyDown(wxKeyEvent &event) } } +void PrusaDoubleSlider::OnRightDown(wxMouseEvent& event) +{ + if (m_selection == ssUndef) + return; + + int new_tick = m_selection == ssLower ? m_lower_value : m_higher_value; + + if (!m_ticks.insert(new_tick).second) + m_ticks.erase(new_tick); + Refresh(); + Update(); +} + // ***************************************************************************** diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 6f000015b..36892fe47 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -536,6 +536,7 @@ public: void OnLeaveWin(wxMouseEvent& event); void OnWheel(wxMouseEvent& event); void OnKeyDown(wxKeyEvent &event); + void OnRightDown(wxMouseEvent& event); protected: @@ -543,6 +544,7 @@ protected: void draw_focus_rect(); void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos); void draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection); + void draw_ticks(wxDC& dc); void draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection); void draw_info_line(wxDC& dc, const wxPoint& pos, SelectedSlider selection) const; void draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const; @@ -560,6 +562,7 @@ protected: wxString get_label(const SelectedSlider& selection) const; void get_lower_and_higher_position(int& lower_pos, int& higher_pos); int position_to_value(wxDC& dc, const wxCoord x, const wxCoord y); + wxCoord get_position_from_value(const int value); private: int m_min_value; @@ -591,6 +594,7 @@ private: std::vector line_pens; std::vector segm_pens; + std::set m_ticks; }; // ****************************************************************************************** From 2a7059edb30ee4bee1fea3f2aa834f07aa9816a4 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 23 Aug 2018 13:01:18 +0200 Subject: [PATCH 117/119] Added active icon for selected tick --- resources/icons/colorchange_add_off.png | Bin 0 -> 600 bytes resources/icons/colorchange_add_on.png | Bin 0 -> 695 bytes resources/icons/colorchange_delete_off.png | Bin 0 -> 589 bytes resources/icons/colorchange_delete_on.png | Bin 0 -> 628 bytes xs/src/slic3r/GUI/GUI.cpp | 6 +- xs/src/slic3r/GUI/wxExtensions.cpp | 132 +++++++++++++++------ xs/src/slic3r/GUI/wxExtensions.hpp | 15 ++- 7 files changed, 116 insertions(+), 37 deletions(-) create mode 100644 resources/icons/colorchange_add_off.png create mode 100644 resources/icons/colorchange_add_on.png create mode 100644 resources/icons/colorchange_delete_off.png create mode 100644 resources/icons/colorchange_delete_on.png diff --git a/resources/icons/colorchange_add_off.png b/resources/icons/colorchange_add_off.png new file mode 100644 index 0000000000000000000000000000000000000000..6ddeccbe0a2a82019c5c2efd1773c20c0833c4d4 GIT binary patch literal 600 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBC{YpM6XNqfL!5oT`ng2Uv7KO- z`>oK>c;wi#w-Y8-9OfwbtPfPmnB?v5!uX#__a2bLS>O>_%)p?h48n{ROYO^mg6t)p zzOL*KxFrR+#s37PM*)TAdb&7gOf=4WlTK;F^nd^Dc_ijpxxR1T zX#3n&TDl=r(%}>cpt3=meXk`S|u=mmKH$V*x Mp00i_>zopr04OBpdH?_b literal 0 HcmV?d00001 diff --git a/resources/icons/colorchange_add_on.png b/resources/icons/colorchange_add_on.png new file mode 100644 index 0000000000000000000000000000000000000000..cc800b81e8a6355877fa8cf58fee3731540f5dbb GIT binary patch literal 695 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S3?yCqj{O5tEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD6u8LC&cwX?ZDQK|Lu1F z3#9(1u>Ehd{lBC4e=5iS1cv`9?Ekm-{NK>{f7gWnt9$>~IQ`$*4|2u&`v2?e{dfTo%*MD>FcgxMz#tc&>wjKYvlkv2}>W3ZX<P)+_zJD`=!SuPm-m%Y^cA85^??v;%fYzs559euLSj6?CPDVv# z8OPo07q)BrukMjxdUaSr{b2Kv9pC;|`Sb4o|Mpw@uyeDVx zW$1|Bsj=8bi@Q>L-?mjR+Ky$nt-EqlSb4pc^PF5&HlSxzOI#yLQW8s2t&)pUffR$0 zfuWhMp`oskX^5ejm7%GXsj;?!p_PHb`H8EHQ8eV{r(~v8qH8d;GO~ndkeu{n5l{nz Mr>mdKI;Vst0C-YMUjP6A literal 0 HcmV?d00001 diff --git a/resources/icons/colorchange_delete_off.png b/resources/icons/colorchange_delete_off.png new file mode 100644 index 0000000000000000000000000000000000000000..c16655271a7e10d9d83047189086d4d6b509abc3 GIT binary patch literal 589 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S0wixl{&NRXEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZEE?e4>iGH4#PT$HOWYUVmw=D)W4<$2R?NV2M}KA?FdtNTmJp~!15S*|LT8;MoC zXsZ3%W24$-moh2c@9l*fmo+q>Gq62KSXA699k*xgMiDE{G|yhA4QhurtG<}@uu!C_ z<$>}m-=I62B~!k9UHS2l6URxP__|{b{!P~`Som^z%$(k+UE0pWDc5vL>wMPBh1~ac zOgPu;&>~>6W*@_Frwy&D=l0S8q@B+Qm*U`007}-kq7#>;Nm&p5M&yqHoBEQzy zY0CSzuP^(vnT8meSs9vI xnHp;w7+M(^oS(SL7)3*FeoAIqCAtPfD`O*whU@kljsZ0=c)I$ztaD0e0ssxu+3)}W literal 0 HcmV?d00001 diff --git a/resources/icons/colorchange_delete_on.png b/resources/icons/colorchange_delete_on.png new file mode 100644 index 0000000000000000000000000000000000000000..8f27ce9fe684cca59295bd787f0c564f14a56a25 GIT binary patch literal 628 zcmeAS@N?(olHy`uVBq!ia0vp^!XV7S0wixl{&NRXEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8ZEE?e4yA$Thpan!eyJ5ZE|lwT7;ffcnvE zS;w+UCtS;Nk}WE(*0icP_POSv<^KD{Mb$yQ(FI4REZ!IK`2_R)UyEa!cz3P+`04`t z{hZU%K_&mTt8UMEpM2aV&hod9dl<8x*4CJ9HxKi5&!3)Df4S#W*Q&b>yI22j=vX^V zN2n)Lr+H5h+lo`osZwf9*@ahFFK4ad3^C7@C^3O zPrjD~3a37HGZKiN!`D`B)H&;x+upMdZvr^>@ujWVCAfaBxAC{SdtoWHFMjlkyh{DG za*j&_)BC37>U<7=kI(V^<2moiw_|H`-C}#RDkiV9dRkkwNm};kgU!{O7tC!`5!kGA z^GE;ee@5|{S6i4p0)jJVZr^=>`yT6c`+I)XS|^=q?fadV_WRo97S>|Fv|GC`%Kv5L zl`d>pzF+$gFcwrxTq8h@qL4p{bRrv9^Jsm4U(e niK~oJH00)|WTsW3YcRAjHic*qn$hP0)WG2B>gTe~DWM4f)HnL< literal 0 HcmV?d00001 diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 396c16257..8701db511 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1058,9 +1058,9 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl sizer->AddSpacer(5); sizer->Add(slider_h, 0, wxEXPAND | wxLEFT, 20); sizer->AddSpacer(5); - PrusaDoubleSlider* slider_v = new PrusaDoubleSlider(parent, wxID_ANY, 50, 70, 0, 200, wxDefaultPosition, - wxSize(wxDefaultSize.x ,250), wxSL_VERTICAL); - slider_v->SetKoefForLabels(0.15); + PrusaDoubleSlider* slider_v = new PrusaDoubleSlider(parent, wxID_ANY, 50, 70, 0, 100, wxDefaultPosition, + wxSize(120 ,200), wxSL_VERTICAL); + slider_v->SetKoefForLabels(2.25); sizer->AddSpacer(5); sizer->Add(slider_v, 0, wxLEFT, 20); sizer->AddSpacer(5); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 21ca75ac9..10ba4efb5 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -776,6 +776,13 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, m_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("left_half_circle.png")) : Slic3r::GUI::from_u8(Slic3r::var("down_half_circle.png")), wxBITMAP_TYPE_PNG); m_thumb_size = m_thumb_lower.GetSize(); + + m_add_tick_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_add_on.png")), wxBITMAP_TYPE_PNG); + m_add_tick_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_add_off.png")), wxBITMAP_TYPE_PNG); + m_del_tick_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_delete_on.png")), wxBITMAP_TYPE_PNG); + m_del_tick_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_delete_off.png")), wxBITMAP_TYPE_PNG); + m_tick_icon_dim = m_add_tick_on.GetSize().x; + m_selection = ssUndef; // slider events @@ -790,7 +797,7 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, Bind(wxEVT_RIGHT_DOWN, &PrusaDoubleSlider::OnRightDown,this); // control's view variables - SLIDER_MARGIN = 2 + (style == wxSL_HORIZONTAL ? m_thumb_higher.GetWidth() : m_thumb_higher.GetHeight()); + SLIDER_MARGIN = 4 + (style == wxSL_HORIZONTAL ? m_thumb_higher.GetWidth() : m_thumb_higher.GetHeight()); DARK_ORANGE_PEN = wxPen(wxColour(253, 84, 2)); ORANGE_PEN = wxPen(wxColour(253, 126, 66)); @@ -901,9 +908,10 @@ void PrusaDoubleSlider::render() SetBackgroundColour(GetParent()->GetBackgroundColour()); draw_focus_rect(); - wxPaintDC dc(this); - int width, height; - GetSize(&width, &height); + wxPaintDC dc(this); + wxFont font = dc.GetFont(); + const wxFont smaller_font = font.Smaller(); + dc.SetFont(smaller_font); const wxCoord lower_pos = get_position_from_value(m_lower_value); const wxCoord higher_pos = get_position_from_value(m_higher_value); @@ -921,21 +929,49 @@ void PrusaDoubleSlider::render() draw_ticks(dc); } -void PrusaDoubleSlider::draw_info_line(wxDC& dc, const wxPoint& pos, const SelectedSlider selection) const +void PrusaDoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end) +{ + const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; + wxBitmap* icon = m_is_action_icon_focesed ? &m_add_tick_off :&m_add_tick_on; + if (m_ticks.find(tick) != m_ticks.end()) + icon = m_is_action_icon_focesed ? &m_del_tick_off :&m_del_tick_on; + + wxCoord x_draw, y_draw; + is_horizontal() ? x_draw = pt_beg.x - 0.5*m_tick_icon_dim : y_draw = pt_beg.y - 0.5*m_tick_icon_dim; + if (m_selection == ssLower) + is_horizontal() ? y_draw = pt_end.y + 3 : x_draw = pt_beg.x - m_tick_icon_dim-2; + else + is_horizontal() ? y_draw = pt_beg.y - m_tick_icon_dim-2 : x_draw = pt_end.x + 3; + + dc.DrawBitmap(*icon, x_draw, y_draw); + + //update rect of the tick action icon + m_rect_tick_action = wxRect(x_draw, y_draw, m_tick_icon_dim, m_tick_icon_dim); +} + +void PrusaDoubleSlider::draw_info_line_with_icon(wxDC& dc, const wxPoint& pos, const SelectedSlider selection) { if (m_selection == selection) { + //draw info line dc.SetPen(DARK_ORANGE_PEN); - is_horizontal() ? dc.DrawLine(pos.x, pos.y - m_thumb_size.y, pos.x, pos.y + m_thumb_size.y): - dc.DrawLine(pos.x - m_thumb_size.x, pos.y-1, pos.x + m_thumb_size.x, pos.y-1); + const wxPoint pt_beg = is_horizontal() ? wxPoint(pos.x, pos.y - m_thumb_size.y) : wxPoint(pos.x - m_thumb_size.x, pos.y - 1); + const wxPoint pt_end = is_horizontal() ? wxPoint(pos.x, pos.y + m_thumb_size.y) : wxPoint(pos.x + m_thumb_size.x, pos.y - 1); + dc.DrawLine(pt_beg, pt_end); + + //draw action icon + draw_action_icon(dc, pt_beg, pt_end); } } wxString PrusaDoubleSlider::get_label(const SelectedSlider& selection) const { const int value = selection == ssLower ? m_lower_value : m_higher_value; - return m_label_koef == 1.0 ? wxString::Format("%d", value) : - wxNumberFormatter::ToString(m_label_koef*value, 2, wxNumberFormatter::Style_None); + if (m_label_koef == 1.0) + return wxString::Format("%d", value); + + const wxString str = wxNumberFormatter::ToString(m_label_koef*value, 2, wxNumberFormatter::Style_None); + return wxString::Format("%s\n(%d)", str, value); } void PrusaDoubleSlider::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const @@ -943,7 +979,7 @@ void PrusaDoubleSlider::draw_thumb_text(wxDC& dc, const wxPoint& pos, const Sele if (selection == ssUndef) return; wxCoord text_width, text_height; const wxString label = get_label(selection); - dc.GetTextExtent(label, &text_width, &text_height); + dc.GetMultiLineTextExtent(label, &text_width, &text_height); wxPoint text_pos; if (selection ==ssLower) text_pos = is_horizontal() ? wxPoint(pos.x + 1, pos.y + m_thumb_size.x) : @@ -994,7 +1030,7 @@ void PrusaDoubleSlider::draw_thumb(wxDC& dc, const wxCoord& pos_coord, const Sel draw_thumb_item(dc, pos, selection); // Draw info_line - draw_info_line(dc, pos, selection); + draw_info_line_with_icon(dc, pos, selection); // Draw thumb text draw_thumb_text(dc, pos, selection); @@ -1067,9 +1103,14 @@ bool PrusaDoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect) void PrusaDoubleSlider::OnLeftDown(wxMouseEvent& event) { - m_is_left_down = true; wxClientDC dc(this); wxPoint pos = event.GetLogicalPosition(dc); + if (is_point_in_rect(pos, m_rect_tick_action)) { + OnRightDown(event); + return; + } + + m_is_left_down = true; detect_selected_slider(pos); Refresh(); Update(); @@ -1098,21 +1139,23 @@ void PrusaDoubleSlider::correct_higher_value() void PrusaDoubleSlider::OnMotion(wxMouseEvent& event) { - if (!m_is_left_down || m_selection == ssUndef) + if (m_selection == ssUndef) return; - wxClientDC dc(this); wxPoint pos = event.GetLogicalPosition(dc); - - if (m_selection == ssLower) { - m_lower_value = position_to_value(dc, pos.x, pos.y); - correct_lower_value(); + if (!m_is_left_down){ + m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); } - else if (m_selection == ssHigher) { - m_higher_value = position_to_value(dc, pos.x, pos.y); - correct_higher_value(); + else { + if (m_selection == ssLower) { + m_lower_value = position_to_value(dc, pos.x, pos.y); + correct_lower_value(); + } + else if (m_selection == ssHigher) { + m_higher_value = position_to_value(dc, pos.x, pos.y); + correct_higher_value(); + } } - Refresh(); Update(); event.Skip(); @@ -1141,7 +1184,6 @@ void PrusaDoubleSlider::OnEnterWin(wxMouseEvent& event) void PrusaDoubleSlider::OnLeaveWin(wxMouseEvent& event) { m_is_focused = false; - m_selection = ssUndef; OnLeftUp(event); } @@ -1170,6 +1212,25 @@ void PrusaDoubleSlider::move_current_thumb(const bool condition) ProcessWindowEvent(e); } +void PrusaDoubleSlider::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); + if (it == m_ticks.end() && action == taAdd) + m_ticks.insert(tick); + else if (it != m_ticks.end() && action == taDel) + m_ticks.erase(tick); + else + return; + + Refresh(); + Update(); +} + void PrusaDoubleSlider::OnWheel(wxMouseEvent& event) { wxClientDC dc(this); @@ -1184,22 +1245,27 @@ void PrusaDoubleSlider::OnWheel(wxMouseEvent& event) void PrusaDoubleSlider::OnKeyDown(wxKeyEvent &event) { - if (is_horizontal()) + const int key = event.GetKeyCode(); + if (key == '+' || key == WXK_NUMPAD_ADD) + action_tick(taAdd); + else if (key == '-' || key == 390 || key == WXK_DELETE || key == WXK_BACK) + action_tick(taDel); + else if (is_horizontal()) { - if (event.GetKeyCode() == WXK_LEFT || event.GetKeyCode() == WXK_RIGHT) - move_current_thumb(event.GetKeyCode() == WXK_LEFT); - else if (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_DOWN){ - m_selection = event.GetKeyCode() == WXK_UP ? ssHigher : ssLower; + if (key == WXK_LEFT || key == WXK_RIGHT) + move_current_thumb(key == WXK_LEFT); + else if (key == WXK_UP || key == WXK_DOWN){ + m_selection = key == WXK_UP ? ssHigher : ssLower; Refresh(); } } else { - if (event.GetKeyCode() == WXK_LEFT || event.GetKeyCode() == WXK_RIGHT) { - m_selection = event.GetKeyCode() == WXK_LEFT ? ssHigher : ssLower; + if (key == WXK_LEFT || key == WXK_RIGHT) { + m_selection = key == WXK_LEFT ? ssHigher : ssLower; Refresh(); } - else if (event.GetKeyCode() == WXK_UP || event.GetKeyCode() == WXK_DOWN) - move_current_thumb(event.GetKeyCode() == WXK_UP); + else if (key == WXK_UP || key == WXK_DOWN) + move_current_thumb(key == WXK_UP); } } @@ -1208,7 +1274,7 @@ void PrusaDoubleSlider::OnRightDown(wxMouseEvent& event) if (m_selection == ssUndef) return; - int new_tick = m_selection == ssLower ? m_lower_value : m_higher_value; + const int new_tick = m_selection == ssLower ? m_lower_value : m_higher_value; if (!m_ticks.insert(new_tick).second) m_ticks.erase(new_tick); diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 36892fe47..ed029d800 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -501,6 +501,10 @@ enum SelectedSlider { ssLower, ssHigher }; +enum TicksAction{ + taAdd, + taDel +}; class PrusaDoubleSlider : public wxControl { public: @@ -541,12 +545,13 @@ public: protected: void render(); + void draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end); void draw_focus_rect(); void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos); void draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection); void draw_ticks(wxDC& dc); void draw_thumb_item(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection); - void draw_info_line(wxDC& dc, const wxPoint& pos, SelectedSlider selection) const; + 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; void update_thumb_rect(const wxCoord& begin_x, const wxCoord& begin_y, const SelectedSlider& selection); @@ -554,6 +559,7 @@ protected: void correct_lower_value(); void correct_higher_value(); void move_current_thumb(const bool condition); + void action_tick(const TicksAction action); bool is_point_in_rect(const wxPoint& pt, const wxRect& rect); bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } @@ -571,13 +577,20 @@ private: int m_higher_value; wxBitmap m_thumb_higher; wxBitmap m_thumb_lower; + wxBitmap m_add_tick_on; + wxBitmap m_add_tick_off; + wxBitmap m_del_tick_on; + wxBitmap m_del_tick_off; SelectedSlider m_selection; bool m_is_left_down = false; bool m_is_focused = false; + bool m_is_action_icon_focesed = false; wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb; + wxRect m_rect_tick_action; wxSize m_thumb_size; + int m_tick_icon_dim; long m_style; float m_label_koef = 1.0; From 2ec045a0fb7bafad12f3e512576215483efacd6b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 23 Aug 2018 14:37:17 +0200 Subject: [PATCH 118/119] Added SetSliderValues and GetActiveValue functions --- lib/Slic3r/GUI/Plater.pm | 1 + xs/src/slic3r/GUI/wxExtensions.cpp | 20 ++++++++++++++++++-- xs/src/slic3r/GUI/wxExtensions.hpp | 16 ++++++++++++---- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 062746e79..a0a6a560d 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -1674,6 +1674,7 @@ sub print_info_box_show { $sizer->Show(1, $show); $self->Layout; + Wx::GetTopLevelParent($self)->Refresh; # temporary workaround for DoubleSlider on right panel $panel->Refresh; } diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 10ba4efb5..43628cb47 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -811,6 +811,13 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, segm_pens = { &DARK_ORANGE_PEN, &ORANGE_PEN, &LIGHT_ORANGE_PEN }; } +int PrusaDoubleSlider::GetActiveValue() const +{ + return m_selection == ssLower ? + m_lower_value : m_selection == ssHigher ? + m_higher_value : -1; +} + wxSize PrusaDoubleSlider::DoGetBestSize() const { const wxSize size = wxControl::DoGetBestSize(); @@ -834,6 +841,13 @@ void PrusaDoubleSlider::SetHigherValue(const int higher_val) Update(); } +void PrusaDoubleSlider::SetMaxValue(int max_value) +{ + m_max_value = max_value; + Refresh(); + Update(); +} + void PrusaDoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos) { int width; @@ -967,10 +981,12 @@ wxString PrusaDoubleSlider::get_label(const SelectedSlider& selection) const { const int value = selection == ssLower ? m_lower_value : m_higher_value; - if (m_label_koef == 1.0) + if (m_label_koef == 1.0 && m_values.empty()) return wxString::Format("%d", value); - const wxString str = wxNumberFormatter::ToString(m_label_koef*value, 2, wxNumberFormatter::Style_None); + const wxString str = m_values.empty() ? + wxNumberFormatter::ToString(m_label_koef*value, 2, wxNumberFormatter::Style_None) : + wxNumberFormatter::ToString(m_values[value], 2, wxNumberFormatter::Style_None); return wxString::Format("%s\n(%d)", str, value); } diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index ed029d800..1887db2b3 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -521,16 +521,23 @@ public: const wxValidator& val = wxDefaultValidator, const wxString& name = wxEmptyString); - int GetLowerValue() { + int GetLowerValue() const { return m_lower_value; } - int GetHigherValue() { + int GetHigherValue() const { return m_higher_value; } + int GetActiveValue() const; wxSize DoGetBestSize() const override; void SetLowerValue(int lower_val); void SetHigherValue(int higher_val); - void SetKoefForLabels(const double koef){ m_label_koef = koef;} + void SetMaxValue(int max_value); + void SetKoefForLabels(const double koef) { + m_label_koef = koef; + } + void SetSliderValues(const std::vector& values) { + m_values = values; + } void OnPaint(wxPaintEvent& ){ render();} void OnLeftDown(wxMouseEvent& event); @@ -545,8 +552,8 @@ public: protected: void render(); - void draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end); void draw_focus_rect(); + void draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end); void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos); void draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection); void draw_ticks(wxDC& dc); @@ -608,6 +615,7 @@ private: std::vector line_pens; std::vector segm_pens; std::set m_ticks; + std::vector m_values; }; // ****************************************************************************************** From d90f5fa591d35b930bb3668b9d86381c02ddfe82 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Fri, 24 Aug 2018 13:34:38 +0200 Subject: [PATCH 119/119] Added "one_layer" mode for PrusaDoubleSlider --- resources/icons/one_layer_lock_off.png | Bin 0 -> 577 bytes resources/icons/one_layer_lock_on.png | Bin 0 -> 528 bytes resources/icons/one_layer_unlock_off.png | Bin 0 -> 508 bytes resources/icons/one_layer_unlock_on.png | Bin 0 -> 483 bytes xs/src/slic3r/GUI/GUI.cpp | 13 -- xs/src/slic3r/GUI/wxExtensions.cpp | 232 ++++++++++++++++------- xs/src/slic3r/GUI/wxExtensions.hpp | 41 ++-- 7 files changed, 197 insertions(+), 89 deletions(-) create mode 100644 resources/icons/one_layer_lock_off.png create mode 100644 resources/icons/one_layer_lock_on.png create mode 100644 resources/icons/one_layer_unlock_off.png create mode 100644 resources/icons/one_layer_unlock_on.png diff --git a/resources/icons/one_layer_lock_off.png b/resources/icons/one_layer_lock_off.png new file mode 100644 index 0000000000000000000000000000000000000000..7dc8b06118fbf0e2e3960e458d2ccaded8dc6398 GIT binary patch literal 577 zcmV-H0>1r;P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&0oF-GK~y+TeN$N| zrC}KU<5*H|WNDJ+#-(y)kUJSAS6nOSSW<>rkPD&?Y8ofhIVmJJgsI7vL?>IBL5)ap zA(DN`KGw55-uL|9`Tk$Y(|hqh-}}7Z|8AcGJudcPx54rWW#P{ze^kVxB?~hhxIPvF z54JO+8n8&(yEg+935s@4-j0fTkyD+)q)A+{E<^A9Vd*qq1CGJaR1I2a}a z#w~EWyfM@5F!^#!O+2=ju=ER!sVEI&I?}+w<EqW25` zP(5i#;R~Fa5D0(j=`F(oqUht-17aj6T6LWO4fLDCe|h}PziG)Y7^LO zIj~z{{-|l1(iN^xa!Ty#2nXw2`tB;%M$I_g=4MDuS%d6)`{J5Jn`Vvo8Gap zAG&=bI36+E`QBdt>4D3kYIQRq(EFKe#m_W)KTe|oUq8T-fvL7vg92Uvsz+lDLmI@D P00000NkvXXu0mjfoBjT? literal 0 HcmV?d00001 diff --git a/resources/icons/one_layer_lock_on.png b/resources/icons/one_layer_lock_on.png new file mode 100644 index 0000000000000000000000000000000000000000..41b7ff173f98d36fc3ccbafcfa9ac4cf20a83726 GIT binary patch literal 528 zcmV+r0`L8aP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&0i{VqK~y+Tl~PG4 zg<%wx5|NDzSs2P%$-*298Il!iMaD8_+7R`;m*N?UEJ!viC}l_@31uuI#X?>$GDn_S z@s4}ncmMYu7IM0a@7#ON|J{4P-v$52FV8|RjH#&bN3j=bL(!FqrG6=CaPq7S!jOQW zLL6_vyp7#y9Ie8IJ|Cl7tQF&w5XY>lzG+>hy$p3ODEs1FmF!_yRjTo<&& z;CK@wl_>ILN}-SAZfipL+?u4cHqW#{6ja-rK~I)Yis~TlE#FNj`NgA;l~iX2_UABK z2VE53OwpT-g&ydlMbMt2c}lz`MUCBG;Ou}$KiT8iXc^ZgUWO7>1ZbW-S4r7nxni5; zQYb+Q3O(p()0O#3%4%gwnCs$(XN^K%A4K4|hnAyKpC3#KlRDlnEn4B_UIdPL?0d6* zG9|2!pg#vY6GGn}ML_!y4?(?;y*D-Y-Ko&`XRfv;D&{nIsSit^Zh3Vy{lhgMC?0Qc ze#lR!!O62cfaXZ);YS$au{JESZytsDZnP!yzgOUnsz4aiu-GRh4Zl2p0{8;H4zuib SoxZjJ0000hI literal 0 HcmV?d00001 diff --git a/resources/icons/one_layer_unlock_off.png b/resources/icons/one_layer_unlock_off.png new file mode 100644 index 0000000000000000000000000000000000000000..c3931f8b9d11ba5db566066820ac2afb40b87057 GIT binary patch literal 508 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&0g*{WK~y+TeUr

yC2SD3|l|&Ez;vJoVMgJM+xE&%E=Q`wI?- zL#NY8r_+Hzz-F_B!{KZ;+w1jCr;}z_P|o#w9SjB}k@_EzNMt-7OD1@5Ak=C#jemf{ z;b^s5x7$rQbhq2>`Fwu0T2XH@nP3zO1rC*A!Rd5LH?!OAd_EsX%jL3ME@O~dEEW+a zs$LNag^tIgX*3$*&*$@0DkXL-7Nf1l;}Q22)H3mST%6HpluRbM0Oc87sZ@$aqkg|1 z*X#944xp}ayWQfDK`fKW%w{w0$(=Ww4fb?8MWN&XN|-mHl}ZJb0M25uV5HcLOT!in z-PN?fxP()$*HJ|)?EQYPVd;}dB-FF;TJ^b1@rm+k@I<#MT3s~Y(X6#nj;(E9!Um%Sbi yhcb7d904-g?KayWn-&ZPS%_}8`{)0;-+urK-CfHDDVaL}0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&0eDG7K~y+Tm6FS= zK~WTk?;lSd$Ezge5D76ekrQU5L@1956VDlikpbIx?%K{l>UMvl_4@YSYpwmG{;yA_ z-|v@7rD!x72n6Esc%@Pq4u?ATl*^3A<4h*w`KEk6uZw==GRm0^3&CO;5Mw(K~vUnsf6hP$MW;2~mhtO)ZDi({9PNh<{TFo#FaUF4x zX0q8V{&YGm6be3{kK-9bqtQqvlaWXSHxvp9!=ai927~xikSmwV%jJ@H9*@WUeviFa zEa*@ec+I@_+G@3kAei-feY@ST@Atc8{eC~L&F}yTA;x7BO10ZN5Ua>Eii)7uoA@(EDYPCw;`F!SV5dbSD z^|l{TI2;!2tN44m?v)vhM(K1~m%NLHCzFY;du2quUXRT(AC?=7#aQlOFwnWDKAFFz Z)C1+OrOso1VzU4M002ovPDHLkV1i}d*xLXA literal 0 HcmV?d00001 diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 8701db511..088cbf80b 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -1052,19 +1052,6 @@ void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFl // Object List add_objects_list(parent, sizer); - // experiment with slider - PrusaDoubleSlider* slider_h = new PrusaDoubleSlider(parent, wxID_ANY, 50, 70, 0, 200, wxDefaultPosition, - wxSize(60, wxDefaultSize.y), wxSL_HORIZONTAL); - sizer->AddSpacer(5); - sizer->Add(slider_h, 0, wxEXPAND | wxLEFT, 20); - sizer->AddSpacer(5); - PrusaDoubleSlider* slider_v = new PrusaDoubleSlider(parent, wxID_ANY, 50, 70, 0, 100, wxDefaultPosition, - wxSize(120 ,200), wxSL_VERTICAL); - slider_v->SetKoefForLabels(2.25); - sizer->AddSpacer(5); - sizer->Add(slider_v, 0, wxLEFT, 20); - sizer->AddSpacer(5); - // Frequently Object Settings add_object_settings(parent, sizer); } diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 43628cb47..7fcad9e65 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -771,17 +771,23 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, SetDoubleBuffered(true); #endif //__WXOSX__ - m_thumb_higher = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("right_half_circle.png")) : - Slic3r::GUI::from_u8(Slic3r::var("up_half_circle.png")), wxBITMAP_TYPE_PNG); - m_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("left_half_circle.png")) : - Slic3r::GUI::from_u8(Slic3r::var("down_half_circle.png")), wxBITMAP_TYPE_PNG); - m_thumb_size = m_thumb_lower.GetSize(); + m_bmp_thumb_higher = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("right_half_circle.png")) : + Slic3r::GUI::from_u8(Slic3r::var("up_half_circle.png")), wxBITMAP_TYPE_PNG); + m_bmp_thumb_lower = wxBitmap(style == wxSL_HORIZONTAL ? Slic3r::GUI::from_u8(Slic3r::var("left_half_circle.png")) : + Slic3r::GUI::from_u8(Slic3r::var("down_half_circle.png")), wxBITMAP_TYPE_PNG); + m_thumb_size = m_bmp_thumb_lower.GetSize(); - m_add_tick_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_add_on.png")), wxBITMAP_TYPE_PNG); - m_add_tick_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_add_off.png")), wxBITMAP_TYPE_PNG); - m_del_tick_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_delete_on.png")), wxBITMAP_TYPE_PNG); - m_del_tick_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_delete_off.png")), wxBITMAP_TYPE_PNG); - m_tick_icon_dim = m_add_tick_on.GetSize().x; + m_bmp_add_tick_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_add_on.png")), wxBITMAP_TYPE_PNG); + m_bmp_add_tick_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_add_off.png")), wxBITMAP_TYPE_PNG); + m_bmp_del_tick_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_delete_on.png")), wxBITMAP_TYPE_PNG); + m_bmp_del_tick_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("colorchange_delete_off.png")), wxBITMAP_TYPE_PNG); + m_tick_icon_dim = m_bmp_add_tick_on.GetSize().x; + + m_bmp_one_layer_lock_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_lock_on.png")), wxBITMAP_TYPE_PNG); + m_bmp_one_layer_lock_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_lock_off.png")), wxBITMAP_TYPE_PNG); + m_bmp_one_layer_unlock_on = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_unlock_on.png")), wxBITMAP_TYPE_PNG); + m_bmp_one_layer_unlock_off = wxBitmap(Slic3r::GUI::from_u8(Slic3r::var("one_layer_unlock_off.png")), wxBITMAP_TYPE_PNG); + m_lock_icon_dim = m_bmp_one_layer_lock_on.GetSize().x; m_selection = ssUndef; @@ -794,10 +800,12 @@ PrusaDoubleSlider::PrusaDoubleSlider( wxWindow *parent, Bind(wxEVT_ENTER_WINDOW,&PrusaDoubleSlider::OnEnterWin, this); Bind(wxEVT_LEAVE_WINDOW,&PrusaDoubleSlider::OnLeaveWin, this); Bind(wxEVT_KEY_DOWN, &PrusaDoubleSlider::OnKeyDown, this); + Bind(wxEVT_KEY_UP, &PrusaDoubleSlider::OnKeyUp, this); Bind(wxEVT_RIGHT_DOWN, &PrusaDoubleSlider::OnRightDown,this); + Bind(wxEVT_RIGHT_UP, &PrusaDoubleSlider::OnRightUp, this); // control's view variables - SLIDER_MARGIN = 4 + (style == wxSL_HORIZONTAL ? m_thumb_higher.GetWidth() : m_thumb_higher.GetHeight()); + SLIDER_MARGIN = 4 + (style == wxSL_HORIZONTAL ? m_bmp_thumb_higher.GetWidth() : m_bmp_thumb_higher.GetHeight()); DARK_ORANGE_PEN = wxPen(wxColour(253, 84, 2)); ORANGE_PEN = wxPen(wxColour(253, 126, 66)); @@ -841,7 +849,7 @@ void PrusaDoubleSlider::SetHigherValue(const int higher_val) Update(); } -void PrusaDoubleSlider::SetMaxValue(int max_value) +void PrusaDoubleSlider::SetMaxValue(const int max_value) { m_max_value = max_value; Refresh(); @@ -852,7 +860,7 @@ void PrusaDoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const in { int width; int height; - GetSize(&width, &height); + get_size(&width, &height); wxCoord line_beg_x = is_horizontal() ? SLIDER_MARGIN : width*0.5 - 1; wxCoord line_beg_y = is_horizontal() ? height*0.5 - 1 : SLIDER_MARGIN; @@ -879,7 +887,7 @@ void PrusaDoubleSlider::draw_scroll_line(wxDC& dc, const int lower_pos, const in double PrusaDoubleSlider::get_scroll_step() { - const wxSize sz = GetSize(); + const wxSize sz = get_size(); const int& slider_len = m_style == wxSL_HORIZONTAL ? sz.x : sz.y; return double(slider_len - SLIDER_MARGIN * 2) / (m_max_value - m_min_value); } @@ -892,6 +900,19 @@ wxCoord PrusaDoubleSlider::get_position_from_value(const int value) return wxCoord(SLIDER_MARGIN + int(val*step + 0.5)); } +wxSize PrusaDoubleSlider::get_size() +{ + int w, h; + get_size(&w, &h); + return wxSize(w, h); +} + +void PrusaDoubleSlider::get_size(int *w, int *h) +{ + GetSize(w, h); + is_horizontal() ? *w -= m_lock_icon_dim : *h -= m_lock_icon_dim; +} + void PrusaDoubleSlider::get_lower_and_higher_position(int& lower_pos, int& higher_pos) { const double step = get_scroll_step(); @@ -914,7 +935,7 @@ void PrusaDoubleSlider::draw_focus_rect() const wxPen pen = wxPen(wxColour(128, 128, 10), 1, wxPENSTYLE_DOT); dc.SetPen(pen); dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxBRUSHSTYLE_TRANSPARENT)); - dc.DrawRectangle(2, 2, sz.x - 4, sz.y - 4); + dc.DrawRectangle(1, 1, sz.x - 2, sz.y - 2); } void PrusaDoubleSlider::render() @@ -933,22 +954,27 @@ void PrusaDoubleSlider::render() // draw line draw_scroll_line(dc, lower_pos, higher_pos); - //lower slider: - draw_thumb(dc, lower_pos, ssLower); +// //lower slider: +// draw_thumb(dc, lower_pos, ssLower); +// //higher slider: +// draw_thumb(dc, higher_pos, ssHigher); - //higher slider: - draw_thumb(dc, higher_pos, ssHigher); + // draw both sliders + draw_thumbs(dc, lower_pos, higher_pos); //draw color print ticks draw_ticks(dc); + + //draw color print ticks + draw_one_layer_icon(dc); } void PrusaDoubleSlider::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end) { const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; - wxBitmap* icon = m_is_action_icon_focesed ? &m_add_tick_off :&m_add_tick_on; + wxBitmap* icon = m_is_action_icon_focesed ? &m_bmp_add_tick_off : &m_bmp_add_tick_on; if (m_ticks.find(tick) != m_ticks.end()) - icon = m_is_action_icon_focesed ? &m_del_tick_off :&m_del_tick_on; + icon = m_is_action_icon_focesed ? &m_bmp_del_tick_off : &m_bmp_del_tick_on; wxCoord x_draw, y_draw; is_horizontal() ? x_draw = pt_beg.x - 0.5*m_tick_icon_dim : y_draw = pt_beg.y - 0.5*m_tick_icon_dim; @@ -992,7 +1018,8 @@ wxString PrusaDoubleSlider::get_label(const SelectedSlider& selection) const void PrusaDoubleSlider::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const { - if (selection == ssUndef) return; + if (m_is_one_layer && selection != m_selection || !selection) + return; wxCoord text_width, text_height; const wxString label = get_label(selection); dc.GetMultiLineTextExtent(label, &text_width, &text_height); @@ -1029,7 +1056,7 @@ void PrusaDoubleSlider::draw_thumb_item(wxDC& dc, const wxPoint& pos, const Sele y_draw = pos.y - m_thumb_size.y; } } - dc.DrawBitmap(selection == ssLower ? m_thumb_lower : m_thumb_higher, x_draw, y_draw); + dc.DrawBitmap(selection == ssLower ? m_bmp_thumb_lower : m_bmp_thumb_higher, x_draw, y_draw); // Update thumb rect update_thumb_rect(x_draw, y_draw, selection); @@ -1039,7 +1066,7 @@ void PrusaDoubleSlider::draw_thumb(wxDC& dc, const wxCoord& pos_coord, const Sel { //calculate thumb position on slider line int width, height; - GetSize(&width, &height); + get_size(&width, &height); const wxPoint pos = is_horizontal() ? wxPoint(pos_coord, height*0.5) : wxPoint(0.5*width, pos_coord); // Draw thumb @@ -1052,11 +1079,35 @@ void PrusaDoubleSlider::draw_thumb(wxDC& dc, const wxCoord& pos_coord, const Sel draw_thumb_text(dc, pos, selection); } +void PrusaDoubleSlider::draw_thumbs(wxDC& dc, const wxCoord& lower_pos, const wxCoord& higher_pos) +{ + //calculate thumb position on slider line + int width, height; + get_size(&width, &height); + const wxPoint pos_l = is_horizontal() ? wxPoint(lower_pos, height*0.5) : wxPoint(0.5*width, lower_pos); + const wxPoint pos_h = is_horizontal() ? wxPoint(higher_pos, height*0.5) : wxPoint(0.5*width, higher_pos); + + // Draw lower thumb + draw_thumb_item(dc, pos_l, ssLower); + // Draw lower info_line + draw_info_line_with_icon(dc, pos_l, ssLower); + + // Draw higher thumb + draw_thumb_item(dc, pos_h, ssHigher); + // Draw higher info_line + draw_info_line_with_icon(dc, pos_h, ssHigher); + // Draw higher thumb text + draw_thumb_text(dc, pos_h, ssHigher); + + // Draw lower thumb text + draw_thumb_text(dc, pos_l, ssLower); +} + void PrusaDoubleSlider::draw_ticks(wxDC& dc) { dc.SetPen(DARK_GREY_PEN); int height, width; - GetSize(&width, &height); + get_size(&width, &height); const wxCoord mid = is_horizontal() ? 0.5*height : 0.5*width; for (auto tick : m_ticks) { @@ -1069,6 +1120,25 @@ void PrusaDoubleSlider::draw_ticks(wxDC& dc) } } +void PrusaDoubleSlider::draw_one_layer_icon(wxDC& dc) +{ + wxBitmap* icon = m_is_one_layer ? + m_is_one_layer_icon_focesed ? &m_bmp_one_layer_lock_off : &m_bmp_one_layer_lock_on : + m_is_one_layer_icon_focesed ? &m_bmp_one_layer_unlock_off : &m_bmp_one_layer_unlock_on; + + int width, height; + get_size(&width, &height); + + wxCoord x_draw, y_draw; + is_horizontal() ? x_draw = width-2 : x_draw = 0.5*width - 0.5*m_lock_icon_dim; + is_horizontal() ? y_draw = 0.5*height - 0.5*m_lock_icon_dim : y_draw = height-2; + + dc.DrawBitmap(*icon, x_draw, y_draw); + + //update rect of the lock/unlock icon + m_rect_one_layer_icon = wxRect(x_draw, y_draw, m_lock_icon_dim, m_lock_icon_dim); +} + void PrusaDoubleSlider::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); @@ -1078,10 +1148,9 @@ void PrusaDoubleSlider::update_thumb_rect(const wxCoord& begin_x, const wxCoord& m_rect_higher_thumb = rect; } -int PrusaDoubleSlider::position_to_value(wxDC& dc, const wxCoord x, const wxCoord y) +int PrusaDoubleSlider::get_value_from_position(const wxCoord x, const wxCoord y) { - int width, height; - dc.GetSize(&width, &height); + const int height = get_size().y; const double step = get_scroll_step(); if (is_horizontal()) @@ -1119,15 +1188,23 @@ bool PrusaDoubleSlider::is_point_in_rect(const wxPoint& pt, const wxRect& rect) void PrusaDoubleSlider::OnLeftDown(wxMouseEvent& event) { + this->CaptureMouse(); wxClientDC dc(this); wxPoint pos = event.GetLogicalPosition(dc); if (is_point_in_rect(pos, m_rect_tick_action)) { - OnRightDown(event); + action_tick(taOnIcon); return; } m_is_left_down = true; - detect_selected_slider(pos); + if (is_point_in_rect(pos, m_rect_one_layer_icon)){ + m_is_one_layer = !m_is_one_layer; + m_selection == ssLower ? correct_lower_value() : correct_higher_value(); + if (!m_selection) m_selection = ssHigher; + } + else + detect_selected_slider(pos); + Refresh(); Update(); event.Skip(); @@ -1137,38 +1214,39 @@ void PrusaDoubleSlider::correct_lower_value() { if (m_lower_value < m_min_value) m_lower_value = m_min_value; - else if (m_lower_value >= m_higher_value && m_lower_value <= m_max_value) - m_higher_value = m_lower_value; else if (m_lower_value > m_max_value) m_lower_value = m_max_value; + + if (m_lower_value >= m_higher_value && m_lower_value <= m_max_value || m_is_one_layer) + m_higher_value = m_lower_value; } void PrusaDoubleSlider::correct_higher_value() { if (m_higher_value > m_max_value) m_higher_value = m_max_value; - else if (m_higher_value <= m_lower_value && m_higher_value >= m_min_value) - m_lower_value = m_higher_value; else if (m_higher_value < m_min_value) m_higher_value = m_min_value; + + if (m_higher_value <= m_lower_value && m_higher_value >= m_min_value || m_is_one_layer) + m_lower_value = m_higher_value; } void PrusaDoubleSlider::OnMotion(wxMouseEvent& event) { - if (m_selection == ssUndef) - return; - wxClientDC dc(this); - wxPoint pos = event.GetLogicalPosition(dc); - if (!m_is_left_down){ + const wxClientDC dc(this); + const wxPoint pos = event.GetLogicalPosition(dc); + m_is_one_layer_icon_focesed = is_point_in_rect(pos, m_rect_one_layer_icon); + if (!m_is_left_down && !m_is_one_layer){ m_is_action_icon_focesed = is_point_in_rect(pos, m_rect_tick_action); } - else { + else if (m_is_left_down || m_is_right_down){ if (m_selection == ssLower) { - m_lower_value = position_to_value(dc, pos.x, pos.y); + m_lower_value = get_value_from_position(pos.x, pos.y); correct_lower_value(); } else if (m_selection == ssHigher) { - m_higher_value = position_to_value(dc, pos.x, pos.y); + m_higher_value = get_value_from_position(pos.x, pos.y); correct_higher_value(); } } @@ -1179,6 +1257,7 @@ void PrusaDoubleSlider::OnMotion(wxMouseEvent& event) void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event) { + this->ReleaseMouse(); m_is_left_down = false; Refresh(); Update(); @@ -1189,25 +1268,20 @@ void PrusaDoubleSlider::OnLeftUp(wxMouseEvent& event) ProcessWindowEvent(e); } -void PrusaDoubleSlider::OnEnterWin(wxMouseEvent& event) +void PrusaDoubleSlider::enter_window(wxMouseEvent& event, const bool enter) { - m_is_focused = true; + m_is_focused = enter; Refresh(); Update(); event.Skip(); } -void PrusaDoubleSlider::OnLeaveWin(wxMouseEvent& event) -{ - m_is_focused = false; - OnLeftUp(event); -} - // "condition" have to be true for: // - value increase (if wxSL_VERTICAL) // - value decrease (if wxSL_HORIZONTAL) void PrusaDoubleSlider::move_current_thumb(const bool condition) { + m_is_one_layer = wxGetKeyState(WXK_CONTROL); int delta = condition ? -1 : 1; if (is_horizontal()) delta *= -1; @@ -1235,13 +1309,17 @@ void PrusaDoubleSlider::action_tick(const TicksAction action) const int tick = m_selection == ssLower ? m_lower_value : m_higher_value; - 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) + if (action == taOnIcon && !m_ticks.insert(tick).second) m_ticks.erase(tick); - else - return; + 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); + else + return; + } Refresh(); Update(); @@ -1285,17 +1363,43 @@ void PrusaDoubleSlider::OnKeyDown(wxKeyEvent &event) } } -void PrusaDoubleSlider::OnRightDown(wxMouseEvent& event) +void PrusaDoubleSlider::OnKeyUp(wxKeyEvent &event) { - if (m_selection == ssUndef) - return; - - const int new_tick = m_selection == ssLower ? m_lower_value : m_higher_value; - - if (!m_ticks.insert(new_tick).second) - m_ticks.erase(new_tick); + if (event.GetKeyCode() == WXK_CONTROL) + m_is_one_layer = false; Refresh(); Update(); + event.Skip(); +} + +void PrusaDoubleSlider::OnRightDown(wxMouseEvent& event) +{ + this->CaptureMouse(); + const wxClientDC dc(this); + detect_selected_slider(event.GetLogicalPosition(dc)); + if (!m_selection) + return; + + if (m_selection == ssLower) + m_higher_value = m_lower_value; + else + m_lower_value = m_higher_value; + + m_is_right_down = m_is_one_layer = true; + + Refresh(); + Update(); + event.Skip(); +} + +void PrusaDoubleSlider::OnRightUp(wxMouseEvent& event) +{ + this->ReleaseMouse(); + m_is_right_down = m_is_one_layer = false; + + Refresh(); + Update(); + event.Skip(); } // ***************************************************************************** diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 1887db2b3..064ce1038 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -502,6 +502,7 @@ enum SelectedSlider { ssHigher }; enum TicksAction{ + taOnIcon, taAdd, taDel }; @@ -529,9 +530,9 @@ public: } int GetActiveValue() const; wxSize DoGetBestSize() const override; - void SetLowerValue(int lower_val); - void SetHigherValue(int higher_val); - void SetMaxValue(int max_value); + void SetLowerValue(const int lower_val); + void SetHigherValue(const int higher_val); + void SetMaxValue(const int max_value); void SetKoefForLabels(const double koef) { m_label_koef = koef; } @@ -543,11 +544,13 @@ public: void OnLeftDown(wxMouseEvent& event); void OnMotion(wxMouseEvent& event); void OnLeftUp(wxMouseEvent& event); - void OnEnterWin(wxMouseEvent& event); - void OnLeaveWin(wxMouseEvent& event); + void OnEnterWin(wxMouseEvent& event){ enter_window(event, true); } + void OnLeaveWin(wxMouseEvent& event){ enter_window(event, false); } void OnWheel(wxMouseEvent& event); void OnKeyDown(wxKeyEvent &event); + void OnKeyUp(wxKeyEvent &event); void OnRightDown(wxMouseEvent& event); + void OnRightUp(wxMouseEvent& event); protected: @@ -556,7 +559,9 @@ protected: void draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end); void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos); void draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection); + void draw_thumbs(wxDC& dc, const wxCoord& lower_pos, const wxCoord& higher_pos); void draw_ticks(wxDC& dc); + void draw_one_layer_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; @@ -567,6 +572,7 @@ protected: void correct_higher_value(); void move_current_thumb(const bool condition); void action_tick(const TicksAction action); + void enter_window(wxMouseEvent& event, const bool enter); bool is_point_in_rect(const wxPoint& pt, const wxRect& rect); bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; } @@ -574,30 +580,41 @@ protected: double get_scroll_step(); wxString get_label(const SelectedSlider& selection) const; void get_lower_and_higher_position(int& lower_pos, int& higher_pos); - int position_to_value(wxDC& dc, const wxCoord x, const wxCoord y); + int get_value_from_position(const wxCoord x, const wxCoord y); wxCoord get_position_from_value(const int value); + wxSize get_size(); + void get_size(int *w, int *h); private: int m_min_value; int m_max_value; int m_lower_value; int m_higher_value; - wxBitmap m_thumb_higher; - wxBitmap m_thumb_lower; - wxBitmap m_add_tick_on; - wxBitmap m_add_tick_off; - wxBitmap m_del_tick_on; - wxBitmap m_del_tick_off; + wxBitmap m_bmp_thumb_higher; + wxBitmap m_bmp_thumb_lower; + wxBitmap m_bmp_add_tick_on; + wxBitmap m_bmp_add_tick_off; + wxBitmap m_bmp_del_tick_on; + wxBitmap m_bmp_del_tick_off; + wxBitmap m_bmp_one_layer_lock_on; + wxBitmap m_bmp_one_layer_lock_off; + wxBitmap m_bmp_one_layer_unlock_on; + wxBitmap m_bmp_one_layer_unlock_off; SelectedSlider m_selection; bool m_is_left_down = false; + bool m_is_right_down = false; + bool m_is_one_layer = false; bool m_is_focused = false; bool m_is_action_icon_focesed = false; + bool m_is_one_layer_icon_focesed = false; wxRect m_rect_lower_thumb; wxRect m_rect_higher_thumb; wxRect m_rect_tick_action; + wxRect m_rect_one_layer_icon; wxSize m_thumb_size; int m_tick_icon_dim; + int m_lock_icon_dim = 16; long m_style; float m_label_koef = 1.0;