Fixed wrong context menu selection for instance(s). Related to

This commit is contained in:
YuSanka 2019-12-11 16:07:00 +01:00
parent bced486db3
commit d66761e030
3 changed files with 101 additions and 42 deletions

View file

@ -59,6 +59,11 @@ static PrinterTechnology printer_technology()
return wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology(); return wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology();
} }
static const Selection& scene_selection()
{
return wxGetApp().plater()->canvas3D()->get_selection();
}
// Config from current edited printer preset // Config from current edited printer preset
static DynamicPrintConfig& printer_config() static DynamicPrintConfig& printer_config()
{ {
@ -1312,7 +1317,10 @@ void ObjectList::get_settings_choice(const wxString& category_name)
void ObjectList::get_freq_settings_choice(const wxString& bundle_name) void ObjectList::get_freq_settings_choice(const wxString& bundle_name)
{ {
std::vector<std::string> options = get_options_for_bundle(bundle_name); std::vector<std::string> options = get_options_for_bundle(bundle_name);
wxDataViewItem item = GetSelection(); const Selection& selection = scene_selection();
wxDataViewItem item = GetSelectedItemsCount() > 1 && selection.is_single_full_object() ?
m_objects_model->GetItemById(selection.get_object_idx()) :
GetSelection();
ItemType item_type = m_objects_model->GetItemType(item); ItemType item_type = m_objects_model->GetItemType(item);
@ -1400,17 +1408,23 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu)
const ConfigOptionMode mode = wxGetApp().get_mode(); const ConfigOptionMode mode = wxGetApp().get_mode();
wxWindow* parent = wxGetApp().plater();
if (mode == comAdvanced) { if (mode == comAdvanced) {
append_menu_item(menu, wxID_ANY, _(ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::MODEL_PART)].first), "", append_menu_item(menu, wxID_ANY, _(ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::MODEL_PART)].first), "",
[this](wxCommandEvent&) { load_subobject(ModelVolumeType::MODEL_PART); }, ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::MODEL_PART)].second); [this](wxCommandEvent&) { load_subobject(ModelVolumeType::MODEL_PART); },
ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::MODEL_PART)].second, nullptr,
[this]() { return is_instance_or_object_selected(); }, parent);
} }
if (mode == comSimple) { if (mode == comSimple) {
append_menu_item(menu, wxID_ANY, _(ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_ENFORCER)].first), "", append_menu_item(menu, wxID_ANY, _(ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_ENFORCER)].first), "",
[this](wxCommandEvent&) { load_generic_subobject(L("Box"), ModelVolumeType::SUPPORT_ENFORCER); }, [this](wxCommandEvent&) { load_generic_subobject(L("Box"), ModelVolumeType::SUPPORT_ENFORCER); },
ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_ENFORCER)].second); ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_ENFORCER)].second, nullptr,
[this]() { return is_instance_or_object_selected(); }, parent);
append_menu_item(menu, wxID_ANY, _(ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_BLOCKER)].first), "", append_menu_item(menu, wxID_ANY, _(ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_BLOCKER)].first), "",
[this](wxCommandEvent&) { load_generic_subobject(L("Box"), ModelVolumeType::SUPPORT_BLOCKER); }, [this](wxCommandEvent&) { load_generic_subobject(L("Box"), ModelVolumeType::SUPPORT_BLOCKER); },
ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_BLOCKER)].second); ADD_VOLUME_MENU_ITEMS[int(ModelVolumeType::SUPPORT_BLOCKER)].second, nullptr,
[this]() { return is_instance_or_object_selected(); }, parent);
return; return;
} }
@ -1420,7 +1434,8 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu)
auto& item = ADD_VOLUME_MENU_ITEMS[type]; auto& item = ADD_VOLUME_MENU_ITEMS[type];
wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType(type)); wxMenu* sub_menu = append_submenu_add_generic(menu, ModelVolumeType(type));
append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second); append_submenu(menu, sub_menu, wxID_ANY, _(item.first), "", item.second,
[this]() { return is_instance_or_object_selected(); }, parent);
} }
} }
@ -1431,10 +1446,17 @@ wxMenuItem* ObjectList::append_menu_item_split(wxMenu* menu)
[this]() { return is_splittable(); }, wxGetApp().plater()); [this]() { return is_splittable(); }, wxGetApp().plater());
} }
wxMenuItem* ObjectList::append_menu_item_layers_editing(wxMenu* menu) bool ObjectList::is_instance_or_object_selected()
{
const Selection& selection = scene_selection();
return selection.is_single_full_instance() || selection.is_single_full_object();
}
wxMenuItem* ObjectList::append_menu_item_layers_editing(wxMenu* menu, wxWindow* parent)
{ {
return append_menu_item(menu, wxID_ANY, _(L("Height range Modifier")), "", return append_menu_item(menu, wxID_ANY, _(L("Height range Modifier")), "",
[this](wxCommandEvent&) { layers_editing(); }, "edit_layers_all", menu); [this](wxCommandEvent&) { layers_editing(); }, "edit_layers_all", menu,
[this]() { return is_instance_or_object_selected(); }, parent);
} }
wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_) wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
@ -1475,6 +1497,12 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
#endif #endif
menu->DestroySeparators(); // delete old separators menu->DestroySeparators(); // delete old separators
// If there are selected more then one instance but not all of them
// don't add settings menu items
const Selection& selection = scene_selection();
if (selection.is_multiple_full_instance() && !selection.is_single_full_object())
return nullptr;
const auto sel_vol = get_selected_model_volume(); const auto sel_vol = get_selected_model_volume();
if (sel_vol && sel_vol->type() >= ModelVolumeType::SUPPORT_ENFORCER) if (sel_vol && sel_vol->type() >= ModelVolumeType::SUPPORT_ENFORCER)
return nullptr; return nullptr;
@ -1490,7 +1518,8 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
menu->SetFirstSeparator(); menu->SetFirstSeparator();
// Add frequently settings // Add frequently settings
const bool is_object_settings = m_objects_model->GetItemType(GetSelection()) == itObject; const ItemType item_type = m_objects_model->GetItemType(GetSelection());
const bool is_object_settings = item_type & itObject || item_type & itInstance || selection.is_single_full_object();
create_freq_settings_popupmenu(menu, is_object_settings); create_freq_settings_popupmenu(menu, is_object_settings);
if (mode == comAdvanced) if (mode == comAdvanced)
@ -1516,15 +1545,35 @@ wxMenuItem* ObjectList::append_menu_item_change_type(wxMenu* menu)
wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu, wxWindow* parent) wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu, wxWindow* parent)
{ {
return append_menu_item(menu, wxID_ANY, _(L("Set as a Separated Object")), "", wxMenuItem* menu_item = append_menu_item(menu, wxID_ANY, _(L("Set as a Separated Object")), "",
[this](wxCommandEvent&) { split_instances(); }, "", menu, [](){return wxGetApp().plater()->can_set_instance_to_object(); }, parent); [this](wxCommandEvent&) { split_instances(); }, "", menu, [](){return wxGetApp().plater()->can_set_instance_to_object(); }, parent);
/* New behavior logic:
* 1. Split Object to several separated object, if ALL instances are selected
* 2. Separate selected instances from the initial object to the separated object,
* if some (not all) instances are selected
*/
parent->Bind(wxEVT_UPDATE_UI, [](wxUpdateUIEvent& evt) {
evt.SetText(wxGetApp().plater()->canvas3D()->get_selection().is_single_full_object() ?
_(L("Set as a Separated Objects")) : _(L("Set as a Separated Object")));
}, menu_item->GetId());
return menu_item;
} }
wxMenuItem* ObjectList::append_menu_item_printable(wxMenu* menu, wxWindow* /*parent*/) wxMenuItem* ObjectList::append_menu_item_printable(wxMenu* menu, wxWindow* /*parent*/)
{ {
return append_menu_check_item(menu, wxID_ANY, _(L("Printable")), "", [](wxCommandEvent&) { return append_menu_check_item(menu, wxID_ANY, _(L("Printable")), "", [this](wxCommandEvent&) {
wxGetApp().plater()->canvas3D()->get_selection().toggle_instance_printable_state(); const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
}, menu); wxDataViewItem item;
if (GetSelectedItemsCount() > 1 && selection.is_single_full_object())
item = m_objects_model->GetItemById(selection.get_object_idx());
else
item = GetSelection();
if (item)
toggle_printable_state(item);
}, menu);
} }
void ObjectList::append_menu_items_osx(wxMenu* menu) void ObjectList::append_menu_items_osx(wxMenu* menu)
@ -1620,7 +1669,7 @@ void ObjectList::create_object_popupmenu(wxMenu *menu)
menu->AppendSeparator(); menu->AppendSeparator();
// Layers Editing for object // Layers Editing for object
append_menu_item_layers_editing(menu); append_menu_item_layers_editing(menu, wxGetApp().plater());
menu->AppendSeparator(); menu->AppendSeparator();
// rest of a object_menu will be added later in: // rest of a object_menu will be added later in:
@ -1664,17 +1713,6 @@ void ObjectList::create_part_popupmenu(wxMenu *menu)
void ObjectList::create_instance_popupmenu(wxMenu*menu) void ObjectList::create_instance_popupmenu(wxMenu*menu)
{ {
m_menu_item_split_instances = append_menu_item_instance_to_object(menu, wxGetApp().plater()); m_menu_item_split_instances = append_menu_item_instance_to_object(menu, wxGetApp().plater());
/* New behavior logic:
* 1. Split Object to several separated object, if ALL instances are selected
* 2. Separate selected instances from the initial object to the separated object,
* if some (not all) instances are selected
*/
wxGetApp().plater()->Bind(wxEVT_UPDATE_UI, [](wxUpdateUIEvent& evt) {
// evt.Enable(can_split_instances()); }, m_menu_item_split_instances->GetId());
evt.SetText(wxGetApp().plater()->canvas3D()->get_selection().is_single_full_object() ?
_(L("Set as a Separated Objects")) : _(L("Set as a Separated Object")));
}, m_menu_item_split_instances->GetId());
} }
void ObjectList::create_default_popupmenu(wxMenu*menu) void ObjectList::create_default_popupmenu(wxMenu*menu)
@ -1688,7 +1726,7 @@ wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu)
wxMenu *menu = new wxMenu; wxMenu *menu = new wxMenu;
settings_menu_hierarchy settings_menu; settings_menu_hierarchy settings_menu;
const bool is_part = m_objects_model->GetParent(GetSelection()) != wxDataViewItem(nullptr); const bool is_part = !(m_objects_model->GetItemType(GetSelection()) == itObject || scene_selection().is_single_full_object());
get_options_menu(settings_menu, is_part); get_options_menu(settings_menu, is_part);
for (auto cat : settings_menu) { for (auto cat : settings_menu) {
@ -1857,7 +1895,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode
if (obj_idx < 0) if (obj_idx < 0)
return; return;
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); const Selection& selection = scene_selection();
assert(obj_idx == selection.get_object_idx()); assert(obj_idx == selection.get_object_idx());
/** Any changes of the Object's composition is duplicated for all Object's Instances /** Any changes of the Object's composition is duplicated for all Object's Instances
@ -2182,9 +2220,13 @@ void ObjectList::split()
void ObjectList::layers_editing() void ObjectList::layers_editing()
{ {
const auto item = GetSelection(); const Selection& selection = scene_selection();
const int obj_idx = get_selected_obj_idx(); const int obj_idx = selection.get_object_idx();
if (!item || obj_idx < 0) wxDataViewItem item = obj_idx >= 0 && GetSelectedItemsCount() > 1 && selection.is_single_full_object() ?
m_objects_model->GetItemById(obj_idx) :
GetSelection();
if (!item)
return; return;
const wxDataViewItem obj_item = m_objects_model->GetTopParent(item); const wxDataViewItem obj_item = m_objects_model->GetTopParent(item);
@ -2297,7 +2339,7 @@ bool ObjectList::selected_instances_of_same_object()
bool ObjectList::can_split_instances() bool ObjectList::can_split_instances()
{ {
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); const Selection& selection = scene_selection();
return selection.is_multiple_full_instance() || selection.is_single_full_instance(); return selection.is_multiple_full_instance() || selection.is_single_full_instance();
} }
@ -2325,7 +2367,7 @@ void ObjectList::part_selection_changed()
{ {
og_name = _(L("Group manipulation")); og_name = _(L("Group manipulation"));
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); const Selection& selection = scene_selection();
// don't show manipulation panel for case of all Object's parts selection // don't show manipulation panel for case of all Object's parts selection
update_and_show_manipulations = !selection.is_single_full_instance(); update_and_show_manipulations = !selection.is_single_full_instance();
} }
@ -2933,7 +2975,7 @@ int ObjectList::get_selected_layers_range_idx() const
void ObjectList::update_selections() void ObjectList::update_selections()
{ {
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); const Selection& selection = scene_selection();
wxDataViewItemArray sels; wxDataViewItemArray sels;
if ( ( m_selection_mode & (smSettings|smLayer|smLayerRoot) ) == 0) if ( ( m_selection_mode & (smSettings|smLayer|smLayerRoot) ) == 0)
@ -3640,7 +3682,7 @@ void ObjectList::instances_to_separated_objects(const int obj_idx)
void ObjectList::split_instances() void ObjectList::split_instances()
{ {
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); const Selection& selection = scene_selection();
const int obj_idx = selection.get_object_idx(); const int obj_idx = selection.get_object_idx();
if (obj_idx == -1) if (obj_idx == -1)
return; return;

View file

@ -226,11 +226,12 @@ public:
void get_settings_choice(const wxString& category_name); void get_settings_choice(const wxString& category_name);
void get_freq_settings_choice(const wxString& bundle_name); void get_freq_settings_choice(const wxString& bundle_name);
void show_settings(const wxDataViewItem settings_item); void show_settings(const wxDataViewItem settings_item);
bool is_instance_or_object_selected();
wxMenu* append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type); wxMenu* append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type);
void append_menu_items_add_volume(wxMenu* menu); void append_menu_items_add_volume(wxMenu* menu);
wxMenuItem* append_menu_item_split(wxMenu* menu); wxMenuItem* append_menu_item_split(wxMenu* menu);
wxMenuItem* append_menu_item_layers_editing(wxMenu* menu); wxMenuItem* append_menu_item_layers_editing(wxMenu* menu, wxWindow* parent);
wxMenuItem* append_menu_item_settings(wxMenu* menu); wxMenuItem* append_menu_item_settings(wxMenu* menu);
wxMenuItem* append_menu_item_change_type(wxMenu* menu); wxMenuItem* append_menu_item_change_type(wxMenu* menu);
wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu, wxWindow* parent); wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu, wxWindow* parent);

View file

@ -3602,17 +3602,29 @@ void Plater::priv::on_right_click(RBtnEvent& evt)
wxMenu* menu = nullptr; wxMenu* menu = nullptr;
if (obj_idx == -1) if (obj_idx == -1) // no one or several object are selected
menu = &default_menu; {
if (evt.data.second) // right button was clicked on empty space
menu = &default_menu;
else
return;
}
else else
{ {
// If in 3DScene is(are) selected volume(s), but right button was clicked on empty space // If in 3DScene is(are) selected volume(s), but right button was clicked on empty space
if (evt.data.second) if (evt.data.second)
return; return;
menu = printer_technology == ptSLA ? &sla_object_menu : if (printer_technology == ptSLA)
get_selection().is_single_full_instance() ? // show "Object menu" for each FullInstance instead of FullObject menu = &sla_object_menu;
&object_menu : &part_menu; else
{
// show "Object menu" for each one or several FullInstance instead of FullObject
const bool is_some_full_instances = get_selection().is_single_full_instance() ||
get_selection().is_single_full_object() ||
get_selection().is_multiple_full_instance();
menu = is_some_full_instances ? &object_menu : &part_menu;
}
sidebar->obj_list()->append_menu_item_settings(menu); sidebar->obj_list()->append_menu_item_settings(menu);
@ -3805,14 +3817,18 @@ bool Plater::priv::init_common_menu(wxMenu* menu, const bool is_part/* = false*/
[this](wxCommandEvent&) { reload_from_disk(); }, "", nullptr, [this]() { return can_reload_from_disk(); }, q); [this](wxCommandEvent&) { reload_from_disk(); }, "", nullptr, [this]() { return can_reload_from_disk(); }, q);
append_menu_item(menu, wxID_ANY, _(L("Export as STL")) + dots, _(L("Export the selected object as STL file")), append_menu_item(menu, wxID_ANY, _(L("Export as STL")) + dots, _(L("Export the selected object as STL file")),
[this](wxCommandEvent&) { q->export_stl(false, true); }); [this](wxCommandEvent&) { q->export_stl(false, true); }, "", nullptr,
[this]() {
const Selection& selection = get_selection();
return selection.is_single_full_instance() || selection.is_single_full_object();
}, q);
menu->AppendSeparator(); menu->AppendSeparator();
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) {
const Selection& selection = get_selection(); const Selection& selection = get_selection();
int instance_idx = selection.get_instance_idx(); int instance_idx = selection.get_instance_idx();
evt.Enable(instance_idx != -1); evt.Enable(selection.is_single_full_instance() || selection.is_single_full_object());
if (instance_idx != -1) if (instance_idx != -1)
{ {
evt.Check(model.objects[selection.get_object_idx()]->instances[instance_idx]->printable); evt.Check(model.objects[selection.get_object_idx()]->instances[instance_idx]->printable);
@ -3858,7 +3874,7 @@ bool Plater::priv::complit_init_object_menu()
object_menu.AppendSeparator(); object_menu.AppendSeparator();
// Layers Editing for object // Layers Editing for object
sidebar->obj_list()->append_menu_item_layers_editing(&object_menu); sidebar->obj_list()->append_menu_item_layers_editing(&object_menu, q);
object_menu.AppendSeparator(); object_menu.AppendSeparator();
// "Add (volumes)" popupmenu will be added later in append_menu_items_add_volume() // "Add (volumes)" popupmenu will be added later in append_menu_items_add_volume()