Skip to content

Commit

Permalink
Trying to improve "grab" behavior of partial selection
Browse files Browse the repository at this point in the history
Problem was: with a partial selection, clicking
in the vicinity of a non-selected edge could
make this edge the selected one. So it was
not possible to drag the selection in some
cases.

With "move mode" it was. The difference was in
the detection logic that decides where a click
is on the selection or outside.

Now, the logic is aligned, and partial mode
clicks will check whether the mouse pointer
is inside the selection bbox (plus some
margin). In that case, the click applies to
the current selection.
  • Loading branch information
Matthias Koefferlein committed Jul 27, 2024
1 parent b253eaa commit fb83b9f
Showing 1 changed file with 31 additions and 38 deletions.
69 changes: 31 additions & 38 deletions src/edt/edt/edtPartialService.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1182,6 +1182,19 @@ PartialService::timeout ()
mp_view->clear_transient_selection ();
clear_mouse_cursors ();

double le = catch_distance () * 3.0; // see Editables::selection_catch_bbox()
db::DBox sel_catch_box = selection_bbox ().enlarged (db::DVector (le, le));
if (has_selection () && sel_catch_box.contains (m_hover_point)) {

// no transient selection if inside current selection - if we click there, we catch the
// currently selected objects
resize_markers (0, true);
resize_inst_markers (0, true);

return;

}

// compute search box
double l = catch_distance ();
db::DBox search_box = db::DBox (m_hover_point, m_hover_point).enlarged (db::DVector (l, l));
Expand Down Expand Up @@ -2035,45 +2048,13 @@ PartialService::mouse_click_event (const db::DPoint &p, unsigned int buttons, bo
// select is allowed to throw an exception
try {

// compute search box
double l = catch_distance ();
db::DBox search_box = db::DBox (p, p).enlarged (db::DVector (l, l));

// check, if there is a selected shape under the mouse - in this case, we do not do a new selection
PartialShapeFinder finder (true /*point mode*/, m_top_level_sel, db::ShapeIterator::All);
finder.find (view (), search_box);

// check, if there is a selected shape under the mouse - in this case, we do not do a new selection
lay::InstFinder inst_finder (true /*point mode*/, m_top_level_sel, true /*full arrays*/, true /*enclose*/, 0 /*no excludes*/, true /*visible layers*/);
inst_finder.find (view (), search_box);

// collect the founds from the finder
// consider a new selection if new objects are selected or the current selection is shape-only
// (this may happen if points have been inserted)
bool new_selection = ((finder.begin () == finder.end () && inst_finder.begin () == inst_finder.end ())
|| mode != lay::Editable::Replace);

for (PartialShapeFinder::iterator f = finder.begin (); f != finder.end () && ! new_selection; ++f) {
partial_objects::const_iterator sel = m_selection.find (f->first);
new_selection = true;
if (sel != m_selection.end ()) {
for (std::vector<edt::EdgeWithIndex>::const_iterator e = f->second.begin (); e != f->second.end () && new_selection; ++e) {
if (sel->second.find (*e) != sel->second.end ()) {
new_selection = false;
}
}
}
}

if (finder.begin () == finder.end ()) {

for (lay::InstFinder::iterator f = inst_finder.begin (); f != inst_finder.end () && ! new_selection; ++f) {
partial_objects::const_iterator sel = m_selection.find (*f);
if (sel == m_selection.end ()) {
new_selection = true;
}
}
bool new_selection = true;

double le = catch_distance () * 3.0; // see Editables::selection_catch_bbox()
db::DBox sel_catch_box = selection_bbox ().enlarged (db::DVector (le, le));
if (mode == lay::Editable::Replace && has_selection () && sel_catch_box.contains (p)) {
// drag current selection
new_selection = false;
}

if (new_selection) {
Expand All @@ -2082,6 +2063,18 @@ PartialService::mouse_click_event (const db::DPoint &p, unsigned int buttons, bo
m_selection.clear ();
}

// compute search box
double l = catch_distance ();
db::DBox search_box = db::DBox (p, p).enlarged (db::DVector (l, l));

// identify the edges under the mouse
PartialShapeFinder finder (true /*point mode*/, m_top_level_sel, db::ShapeIterator::All);
finder.find (view (), search_box);

// identify the instances under the mouse
lay::InstFinder inst_finder (true /*point mode*/, m_top_level_sel, true /*full arrays*/, true /*enclose*/, 0 /*no excludes*/, true /*visible layers*/);
inst_finder.find (view (), search_box);

// clear the selection if we now select a guiding shape or if it was consisting of a guiding shape before
// (that way we ensure there is only a guiding shape selected)
PartialShapeFinder::iterator f0 = finder.begin ();
Expand Down

0 comments on commit fb83b9f

Please sign in to comment.