Fixed issue #2201 (trace path)

* you can zoom in now to select the end point. Problem was
  actually that zooming in was a problem when the start point
  went out of the viewport

In addition:
* Messages are sticky now ("Click on second point")
* "Esc" will cancel path trace mode
* The cursor switches back to normal after tracing
This commit is contained in:
Matthias Koefferlein
2025-10-25 23:12:22 +02:00
parent 564111af77
commit b454d2ae42
7 changed files with 101 additions and 21 deletions
+14 -8
View File
@@ -63,7 +63,7 @@ static int inst_point_sel_tests = 10000;
Finder::Finder (bool point_mode, bool top_level_sel)
: m_min_level (0), m_max_level (0),
mp_layout (0), mp_view (0), m_cv_index (0), m_point_mode (point_mode), m_catch_all (false), m_top_level_sel (top_level_sel)
mp_layout (0), mp_view (0), m_cv_index (0), m_point_mode (point_mode), m_catch_all (false), m_consider_viewport (true), m_top_level_sel (top_level_sel)
{
m_distance = std::numeric_limits<double>::max ();
}
@@ -482,7 +482,10 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
checkpoint ();
// Viewport in current cell coordinate space (DBU)
db::Box viewport_box = (vp * db::CplxTrans (layout ().dbu ()) * t).inverted () * db::DBox (0, 0, view ()->viewport ().width (), view ()->viewport ().height ());
db::Box viewport_box;
if (consider_viewport ()) {
viewport_box = (vp * db::CplxTrans (layout ().dbu ()) * t).inverted () * db::DBox (0, 0, view ()->viewport ().width (), view ()->viewport ().height ());
}
if (! m_context_layers.empty ()) {
@@ -583,7 +586,7 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
bool any_valid_edge = m_capture_all_shapes;
for (db::Shape::polygon_edge_iterator e = shape->begin_edge (); ! e.at_end (); ++e) {
if ((*e).clipped (viewport_box).first) {
if (viewport_box.empty () || (*e).clipped (viewport_box).first) {
any_valid_edge = true;
test_edge (t, *e, d, match);
}
@@ -606,7 +609,7 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
++pt;
for (; pt != shape->end_point (); ++pt) {
db::Edge e (p, *pt);
if (e.clipped (viewport_box).first) {
if (viewport_box.empty () || e.clipped (viewport_box).first) {
any_valid_edge = true;
test_edge (t, e, d, match);
}
@@ -618,7 +621,7 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
db::Polygon poly;
shape->polygon (poly);
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
if ((*e).clipped (viewport_box).first) {
if (viewport_box.empty () || (*e).clipped (viewport_box).first) {
any_valid_edge = true;
test_edge (t, *e, d, match);
}
@@ -651,7 +654,7 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db:
// convert to polygon and test those edges
db::Polygon poly (box);
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
if ((*e).clipped (viewport_box).first) {
if (viewport_box.empty () || (*e).clipped (viewport_box).first) {
any_valid_edge = true;
test_edge (t, *e, d, match);
}
@@ -819,7 +822,10 @@ InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const d
checkpoint ();
// Viewport in current cell coordinate space (DBU)
db::Box viewport_box = (vp * db::CplxTrans (layout ().dbu ()) * t).inverted () * db::DBox (0, 0, view ()->viewport ().width (), view ()->viewport ().height ());
db::Box viewport_box;
if (consider_viewport ()) {
viewport_box = (vp * db::CplxTrans (layout ().dbu ()) * t).inverted () * db::DBox (0, 0, view ()->viewport ().width (), view ()->viewport ().height ());
}
if (! point_mode ()) {
@@ -952,7 +958,7 @@ InstFinder::visit_cell (const db::Cell &cell, const db::Box &search_box, const d
bool any_valid_edge = false;
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
// only consider edges that cut through the viewport
if ((*e).clipped (viewport_box).first) {
if (viewport_box.empty () || (*e).clipped (viewport_box).first) {
any_valid_edge = true;
test_edge (t, *e, d, match);
}
+20
View File
@@ -96,6 +96,25 @@ public:
m_catch_all = f;
}
/**
* @brief Gets a flag indicating that the viewport will be considered
*/
bool consider_viewport () const
{
return m_consider_viewport;
}
/**
* @brief Sets a flag indicating that the viewport will be considered
* If this flag is true (the default), only shapes and instances will be considered
* if edges (or polygons) or boundary edges (for instances) are visible in the
* viewport. If this flag is false, shapes or instances are considered always.
*/
void set_consider_viewport (bool f)
{
m_consider_viewport = f;
}
/**
* @brief Destructor (just provided to please the compiler)
*/
@@ -217,6 +236,7 @@ private:
double m_distance;
bool m_point_mode;
bool m_catch_all;
bool m_consider_viewport;
bool m_top_level_sel;
db::box_convert <db::CellInst, false> m_box_convert;
db::box_convert <db::Cell, false> m_cell_box_convert;
+12 -11
View File
@@ -621,7 +621,10 @@ END_PROTECTED
void
ViewObjectUI::set_cursor (lay::Cursor::cursor_shape cursor)
{
m_cursor = cursor;
if (m_cursor != cursor) {
m_cursor = cursor;
realize_cursor ();
}
}
void
@@ -629,15 +632,7 @@ ViewObjectUI::set_default_cursor (lay::Cursor::cursor_shape cursor)
{
if (cursor != m_default_cursor) {
m_default_cursor = cursor;
#if defined(HAVE_QT)
if (m_cursor == lay::Cursor::none && mp_widget) {
if (m_default_cursor == lay::Cursor::none) {
mp_widget->unsetCursor ();
} else {
mp_widget->setCursor (lay::Cursor::qcursor (m_default_cursor));
}
}
#endif
realize_cursor ();
}
}
@@ -652,11 +647,17 @@ ViewObjectUI::ensure_entered ()
void
ViewObjectUI::begin_mouse_event (lay::Cursor::cursor_shape cursor)
{
m_cursor = cursor;
set_cursor (cursor);
}
void
ViewObjectUI::end_mouse_event ()
{
realize_cursor ();
}
void
ViewObjectUI::realize_cursor ()
{
#if defined(HAVE_QT)
if (mp_widget) {
+9
View File
@@ -285,6 +285,14 @@ public:
*/
virtual void drag_cancel () { }
/**
* @brief Gets a value indicating whether the mouse receiver claims the view message bar
*
* If this method returns true, other services are not supposed to emit transient
* messages.
*/
virtual bool claims_message_bar () const { return false; }
/**
* @brief Gets a value indicating whether a cursor position it set
*/
@@ -1121,6 +1129,7 @@ private:
void objects_changed ();
int widget_height () const;
int widget_width () const;
void realize_cursor ();
/**
* @brief Register a service