Fixed wrong context menu selection for instance(s). Related to #3275
This commit is contained in:
parent
bced486db3
commit
d66761e030
3 changed files with 101 additions and 42 deletions
|
@ -59,6 +59,11 @@ static PrinterTechnology 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
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -1400,17 +1408,23 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu)
|
|||
|
||||
const ConfigOptionMode mode = wxGetApp().get_mode();
|
||||
|
||||
wxWindow* parent = wxGetApp().plater();
|
||||
|
||||
if (mode == comAdvanced) {
|
||||
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) {
|
||||
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); },
|
||||
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), "",
|
||||
[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;
|
||||
}
|
||||
|
@ -1420,7 +1434,8 @@ void ObjectList::append_menu_items_add_volume(wxMenu* menu)
|
|||
auto& item = ADD_VOLUME_MENU_ITEMS[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());
|
||||
}
|
||||
|
||||
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")), "",
|
||||
[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_)
|
||||
|
@ -1475,6 +1497,12 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
|
|||
#endif
|
||||
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();
|
||||
if (sel_vol && sel_vol->type() >= ModelVolumeType::SUPPORT_ENFORCER)
|
||||
return nullptr;
|
||||
|
@ -1490,7 +1518,8 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_)
|
|||
menu->SetFirstSeparator();
|
||||
|
||||
// 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);
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
/* 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*/)
|
||||
{
|
||||
return append_menu_check_item(menu, wxID_ANY, _(L("Printable")), "", [](wxCommandEvent&) {
|
||||
wxGetApp().plater()->canvas3D()->get_selection().toggle_instance_printable_state();
|
||||
}, menu);
|
||||
return append_menu_check_item(menu, wxID_ANY, _(L("Printable")), "", [this](wxCommandEvent&) {
|
||||
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
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)
|
||||
|
@ -1620,7 +1669,7 @@ void ObjectList::create_object_popupmenu(wxMenu *menu)
|
|||
menu->AppendSeparator();
|
||||
|
||||
// Layers Editing for object
|
||||
append_menu_item_layers_editing(menu);
|
||||
append_menu_item_layers_editing(menu, wxGetApp().plater());
|
||||
menu->AppendSeparator();
|
||||
|
||||
// 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)
|
||||
{
|
||||
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)
|
||||
|
@ -1688,7 +1726,7 @@ wxMenu* ObjectList::create_settings_popupmenu(wxMenu *parent_menu)
|
|||
wxMenu *menu = new wxMenu;
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
const Selection& selection = scene_selection();
|
||||
assert(obj_idx == selection.get_object_idx());
|
||||
|
||||
/** 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()
|
||||
{
|
||||
const auto item = GetSelection();
|
||||
const int obj_idx = get_selected_obj_idx();
|
||||
if (!item || obj_idx < 0)
|
||||
const Selection& selection = scene_selection();
|
||||
const int obj_idx = selection.get_object_idx();
|
||||
wxDataViewItem item = obj_idx >= 0 && GetSelectedItemsCount() > 1 && selection.is_single_full_object() ?
|
||||
m_objects_model->GetItemById(obj_idx) :
|
||||
GetSelection();
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
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()
|
||||
{
|
||||
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
const Selection& selection = scene_selection();
|
||||
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"));
|
||||
|
||||
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
|
||||
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()
|
||||
{
|
||||
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
const Selection& selection = scene_selection();
|
||||
wxDataViewItemArray sels;
|
||||
|
||||
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()
|
||||
{
|
||||
const Selection& selection = wxGetApp().plater()->canvas3D()->get_selection();
|
||||
const Selection& selection = scene_selection();
|
||||
const int obj_idx = selection.get_object_idx();
|
||||
if (obj_idx == -1)
|
||||
return;
|
||||
|
|
|
@ -226,11 +226,12 @@ public:
|
|||
void get_settings_choice(const wxString& category_name);
|
||||
void get_freq_settings_choice(const wxString& bundle_name);
|
||||
void show_settings(const wxDataViewItem settings_item);
|
||||
bool is_instance_or_object_selected();
|
||||
|
||||
wxMenu* append_submenu_add_generic(wxMenu* menu, const ModelVolumeType type);
|
||||
void append_menu_items_add_volume(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_change_type(wxMenu* menu);
|
||||
wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu, wxWindow* parent);
|
||||
|
|
|
@ -3602,17 +3602,29 @@ void Plater::priv::on_right_click(RBtnEvent& evt)
|
|||
|
||||
wxMenu* menu = nullptr;
|
||||
|
||||
if (obj_idx == -1)
|
||||
menu = &default_menu;
|
||||
if (obj_idx == -1) // no one or several object are selected
|
||||
{
|
||||
if (evt.data.second) // right button was clicked on empty space
|
||||
menu = &default_menu;
|
||||
else
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If in 3DScene is(are) selected volume(s), but right button was clicked on empty space
|
||||
if (evt.data.second)
|
||||
return;
|
||||
|
||||
menu = printer_technology == ptSLA ? &sla_object_menu :
|
||||
get_selection().is_single_full_instance() ? // show "Object menu" for each FullInstance instead of FullObject
|
||||
&object_menu : &part_menu;
|
||||
if (printer_technology == ptSLA)
|
||||
menu = &sla_object_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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
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();
|
||||
|
||||
q->Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) {
|
||||
const Selection& selection = get_selection();
|
||||
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)
|
||||
{
|
||||
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();
|
||||
|
||||
// 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();
|
||||
|
||||
// "Add (volumes)" popupmenu will be added later in append_menu_items_add_volume()
|
||||
|
|
Loading…
Reference in a new issue