Fixed non-consistency of the selection
This commit is contained in:
parent
d806e8e5e1
commit
09054a0bc9
@ -89,7 +89,24 @@ ObjectList::ObjectList(wxWindow* parent) :
|
|||||||
// manipulator cache with the following call to selection_changed()
|
// manipulator cache with the following call to selection_changed()
|
||||||
wxGetApp().obj_manipul()->emulate_kill_focus();
|
wxGetApp().obj_manipul()->emulate_kill_focus();
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
/* For multiple selection with pressed SHIFT,
|
||||||
|
* event.GetItem() returns value of a first item in selection list
|
||||||
|
* instead of real last clicked item.
|
||||||
|
* So, let check last selected item in such strange way
|
||||||
|
*/
|
||||||
|
if (wxGetKeyState(WXK_SHIFT))
|
||||||
|
{
|
||||||
|
wxDataViewItemArray sels;
|
||||||
|
GetSelections(sels);
|
||||||
|
if (sels.front() == m_last_selected_item)
|
||||||
|
m_last_selected_item = sels.back();
|
||||||
|
else
|
||||||
m_last_selected_item = event.GetItem();
|
m_last_selected_item = event.GetItem();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_last_selected_item = event.GetItem();
|
||||||
|
|
||||||
selection_changed();
|
selection_changed();
|
||||||
#ifndef __WXMSW__
|
#ifndef __WXMSW__
|
||||||
set_tooltip_for_item(get_mouse_position_in_control());
|
set_tooltip_for_item(get_mouse_position_in_control());
|
||||||
@ -511,7 +528,7 @@ void ObjectList::key_event(wxKeyEvent& event)
|
|||||||
printf("WXK_BACK\n");
|
printf("WXK_BACK\n");
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_SHIFT))
|
else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL/*WXK_SHIFT*/))
|
||||||
select_item_all_children();
|
select_item_all_children();
|
||||||
else
|
else
|
||||||
event.Skip();
|
event.Skip();
|
||||||
@ -2183,11 +2200,10 @@ void ObjectList::select_item_all_children()
|
|||||||
// update selection mode for non-multiple selection
|
// update selection mode for non-multiple selection
|
||||||
void ObjectList::update_selection_mode()
|
void ObjectList::update_selection_mode()
|
||||||
{
|
{
|
||||||
m_last_selected_item = wxDataViewItem(0);
|
|
||||||
|
|
||||||
// All items are unselected
|
// All items are unselected
|
||||||
if (!GetSelection())
|
if (!GetSelection())
|
||||||
{
|
{
|
||||||
|
m_last_selected_item = wxDataViewItem(0);
|
||||||
m_selection_mode = smUndef;
|
m_selection_mode = smUndef;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2198,33 +2214,55 @@ void ObjectList::update_selection_mode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check last selected item. If is it possible to select it
|
// check last selected item. If is it possible to select it
|
||||||
bool ObjectList::check_last_selection()
|
bool ObjectList::check_last_selection(wxString& msg_str)
|
||||||
{
|
{
|
||||||
if (!m_last_selected_item)
|
if (!m_last_selected_item)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
const bool is_shift_pressed = wxGetKeyState(WXK_SHIFT);
|
||||||
|
|
||||||
/* We can't mix Parts and Objects/Instances.
|
/* We can't mix Parts and Objects/Instances.
|
||||||
* So, unselect last selected item and show information about it
|
* So, show information about it
|
||||||
*/
|
*/
|
||||||
const ItemType type = m_objects_model->GetItemType(m_last_selected_item);
|
const ItemType type = m_objects_model->GetItemType(m_last_selected_item);
|
||||||
if (type & itSettings ||
|
|
||||||
|
// check a case of a selection of the Parts from different Objects
|
||||||
|
bool impossible_multipart_selection = false;
|
||||||
|
if (type & itVolume && m_selection_mode == smVolume)
|
||||||
|
{
|
||||||
|
wxDataViewItemArray sels;
|
||||||
|
GetSelections(sels);
|
||||||
|
for (const auto& sel: sels)
|
||||||
|
if (sel != m_last_selected_item &&
|
||||||
|
m_objects_model->GetParent(sel) != m_objects_model->GetParent(m_last_selected_item))
|
||||||
|
{
|
||||||
|
impossible_multipart_selection = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (impossible_multipart_selection ||
|
||||||
|
type & itSettings ||
|
||||||
type & itVolume && m_selection_mode == smInstance ||
|
type & itVolume && m_selection_mode == smInstance ||
|
||||||
!(type & itVolume) && m_selection_mode == smVolume)
|
!(type & itVolume) && m_selection_mode == smVolume)
|
||||||
{
|
{
|
||||||
Unselect(m_last_selected_item);
|
|
||||||
|
|
||||||
// Inform user why selection isn't complited
|
// Inform user why selection isn't complited
|
||||||
const wxString item_type = m_selection_mode == smInstance ? _(L("Object or Instance")) : _(L("Part"));
|
const wxString item_type = m_selection_mode == smInstance ? _(L("Object or Instance")) : _(L("Part"));
|
||||||
|
|
||||||
const wxString msg_str = wxString::Format(_(L("You started your selection with %s Item.")) + "\n" +
|
msg_str = wxString::Format( _(L("Unsupported selection")) + "\n\n" +
|
||||||
_(L("In this mode you can select only another %s Items%s")), item_type, item_type,
|
_(L("You started your selection with %s Item.")) + "\n" +
|
||||||
m_selection_mode == smInstance ? "." : " " + _(L("of a current Object")));
|
_(L("In this mode you can select only other %s Items%s")),
|
||||||
|
item_type, item_type,
|
||||||
|
m_selection_mode == smInstance ? "." :
|
||||||
|
" " + _(L("of a current Object")));
|
||||||
|
|
||||||
wxMessageDialog dialog(this, _(L("Unsupported selection")) + "\n\n" + msg_str,
|
// Unselect last selected item, if selection is without SHIFT
|
||||||
_(L("Info")), wxICON_INFORMATION);
|
if (!is_shift_pressed) {
|
||||||
dialog.ShowModal();
|
Unselect(m_last_selected_item);
|
||||||
|
show_info(this, msg_str, _(L("Info")));
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return is_shift_pressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -2237,7 +2275,8 @@ void ObjectList::fix_multiselection_conflicts()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!check_last_selection())
|
wxString msg_string;
|
||||||
|
if (!check_last_selection(msg_string))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_prevent_list_events = true;
|
m_prevent_list_events = true;
|
||||||
@ -2245,9 +2284,27 @@ void ObjectList::fix_multiselection_conflicts()
|
|||||||
wxDataViewItemArray sels;
|
wxDataViewItemArray sels;
|
||||||
GetSelections(sels);
|
GetSelections(sels);
|
||||||
|
|
||||||
m_selection_mode = smInstance;
|
if (m_selection_mode == smVolume)
|
||||||
|
{
|
||||||
|
// identify correct parent of the initial selected item
|
||||||
|
const wxDataViewItem& parent = m_objects_model->GetParent(m_last_selected_item == sels.front() ? sels.back() : sels.front());
|
||||||
|
|
||||||
for (const auto item : sels) {
|
sels.clear();
|
||||||
|
wxDataViewItemArray children; // selected volumes from current parent
|
||||||
|
m_objects_model->GetChildren(parent, children);
|
||||||
|
|
||||||
|
for (const auto child : children)
|
||||||
|
if (IsSelected(child) && m_objects_model->GetItemType(child)&itVolume)
|
||||||
|
sels.Add(child);
|
||||||
|
|
||||||
|
// If some part is selected, unselect all items except of selected parts of the current object
|
||||||
|
UnselectAll();
|
||||||
|
SetSelections(sels);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const auto item : sels)
|
||||||
|
{
|
||||||
if (!IsSelected(item)) // if this item is unselected now (from previous actions)
|
if (!IsSelected(item)) // if this item is unselected now (from previous actions)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -2267,27 +2324,19 @@ void ObjectList::fix_multiselection_conflicts()
|
|||||||
Unselect(unsel_item);
|
Unselect(unsel_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_objects_model->GetItemType(item) == itVolume)
|
if (m_objects_model->GetItemType(item) & itVolume)
|
||||||
{
|
Unselect(item);
|
||||||
// If some part is selected, unselect all items except of selected parts of the current object
|
|
||||||
sels.clear();
|
|
||||||
|
|
||||||
wxDataViewItemArray children; // selected volumes from current parent
|
m_selection_mode = smInstance;
|
||||||
m_objects_model->GetChildren(parent, children);
|
|
||||||
for (const auto child : children)
|
|
||||||
{
|
|
||||||
if (IsSelected(child) && m_objects_model->GetItemType(child)&itVolume)
|
|
||||||
sels.Add(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
UnselectAll();
|
|
||||||
SetSelections(sels);
|
|
||||||
|
|
||||||
m_selection_mode = smVolume;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!msg_string.IsEmpty())
|
||||||
|
show_info(this, msg_string, _(L("Info")));
|
||||||
|
|
||||||
|
if (!IsSelected(m_last_selected_item))
|
||||||
|
m_last_selected_item = wxDataViewItem(0);
|
||||||
|
|
||||||
m_prevent_list_events = false;
|
m_prevent_list_events = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ public:
|
|||||||
void select_all();
|
void select_all();
|
||||||
void select_item_all_children();
|
void select_item_all_children();
|
||||||
void update_selection_mode();
|
void update_selection_mode();
|
||||||
bool check_last_selection();
|
bool check_last_selection(wxString& msg_str);
|
||||||
// correct current selections to avoid of the possible conflicts
|
// correct current selections to avoid of the possible conflicts
|
||||||
void fix_multiselection_conflicts();
|
void fix_multiselection_conflicts();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user