mirror of https://github.com/KLayout/klayout.git
Merge pull request #2202 from KLayout/bugfix/issue-2201
Fixed issue #2201 (trace path)
This commit is contained in:
commit
3a069427cd
|
|
@ -1327,6 +1327,13 @@ static std::string path_to_string (const db::Layout &layout, const lay::ObjectIn
|
||||||
void
|
void
|
||||||
Service::display_status (bool transient)
|
Service::display_status (bool transient)
|
||||||
{
|
{
|
||||||
|
if (transient && view ()->canvas ()->begin_mouse_receivers () != view ()->canvas ()->end_mouse_receivers ()
|
||||||
|
&& (*view ()->canvas ()->begin_mouse_receivers ())->claims_message_bar ()) {
|
||||||
|
// do not display transient if there is a plugin active that has captured the mouse and claims the message bar -
|
||||||
|
// this way we can use messages in active plugins and still get visual feedback by the transient selection.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
EditableSelectionIterator r = transient ? begin_transient_selection () : begin_selection ();
|
EditableSelectionIterator r = transient ? begin_transient_selection () : begin_selection ();
|
||||||
EditableSelectionIterator rr = r;
|
EditableSelectionIterator rr = r;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ static int inst_point_sel_tests = 10000;
|
||||||
|
|
||||||
Finder::Finder (bool point_mode, bool top_level_sel)
|
Finder::Finder (bool point_mode, bool top_level_sel)
|
||||||
: m_min_level (0), m_max_level (0),
|
: 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 ();
|
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 ();
|
checkpoint ();
|
||||||
|
|
||||||
// Viewport in current cell coordinate space (DBU)
|
// 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 ()) {
|
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;
|
bool any_valid_edge = m_capture_all_shapes;
|
||||||
for (db::Shape::polygon_edge_iterator e = shape->begin_edge (); ! e.at_end (); ++e) {
|
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;
|
any_valid_edge = true;
|
||||||
test_edge (t, *e, d, match);
|
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;
|
++pt;
|
||||||
for (; pt != shape->end_point (); ++pt) {
|
for (; pt != shape->end_point (); ++pt) {
|
||||||
db::Edge e (p, *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;
|
any_valid_edge = true;
|
||||||
test_edge (t, e, d, match);
|
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;
|
db::Polygon poly;
|
||||||
shape->polygon (poly);
|
shape->polygon (poly);
|
||||||
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
|
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;
|
any_valid_edge = true;
|
||||||
test_edge (t, *e, d, match);
|
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
|
// convert to polygon and test those edges
|
||||||
db::Polygon poly (box);
|
db::Polygon poly (box);
|
||||||
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
|
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;
|
any_valid_edge = true;
|
||||||
test_edge (t, *e, d, match);
|
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 ();
|
checkpoint ();
|
||||||
|
|
||||||
// Viewport in current cell coordinate space (DBU)
|
// 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 ()) {
|
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;
|
bool any_valid_edge = false;
|
||||||
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
|
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
|
||||||
// only consider edges that cut through the viewport
|
// 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;
|
any_valid_edge = true;
|
||||||
test_edge (t, *e, d, match);
|
test_edge (t, *e, d, match);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,25 @@ public:
|
||||||
m_catch_all = f;
|
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)
|
* @brief Destructor (just provided to please the compiler)
|
||||||
*/
|
*/
|
||||||
|
|
@ -217,6 +236,7 @@ private:
|
||||||
double m_distance;
|
double m_distance;
|
||||||
bool m_point_mode;
|
bool m_point_mode;
|
||||||
bool m_catch_all;
|
bool m_catch_all;
|
||||||
|
bool m_consider_viewport;
|
||||||
bool m_top_level_sel;
|
bool m_top_level_sel;
|
||||||
db::box_convert <db::CellInst, false> m_box_convert;
|
db::box_convert <db::CellInst, false> m_box_convert;
|
||||||
db::box_convert <db::Cell, false> m_cell_box_convert;
|
db::box_convert <db::Cell, false> m_cell_box_convert;
|
||||||
|
|
|
||||||
|
|
@ -621,7 +621,10 @@ END_PROTECTED
|
||||||
void
|
void
|
||||||
ViewObjectUI::set_cursor (lay::Cursor::cursor_shape cursor)
|
ViewObjectUI::set_cursor (lay::Cursor::cursor_shape cursor)
|
||||||
{
|
{
|
||||||
|
if (m_cursor != cursor) {
|
||||||
m_cursor = cursor;
|
m_cursor = cursor;
|
||||||
|
realize_cursor ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -629,15 +632,7 @@ ViewObjectUI::set_default_cursor (lay::Cursor::cursor_shape cursor)
|
||||||
{
|
{
|
||||||
if (cursor != m_default_cursor) {
|
if (cursor != m_default_cursor) {
|
||||||
m_default_cursor = cursor;
|
m_default_cursor = cursor;
|
||||||
#if defined(HAVE_QT)
|
realize_cursor ();
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -652,11 +647,17 @@ ViewObjectUI::ensure_entered ()
|
||||||
void
|
void
|
||||||
ViewObjectUI::begin_mouse_event (lay::Cursor::cursor_shape cursor)
|
ViewObjectUI::begin_mouse_event (lay::Cursor::cursor_shape cursor)
|
||||||
{
|
{
|
||||||
m_cursor = cursor;
|
set_cursor (cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ViewObjectUI::end_mouse_event ()
|
ViewObjectUI::end_mouse_event ()
|
||||||
|
{
|
||||||
|
realize_cursor ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ViewObjectUI::realize_cursor ()
|
||||||
{
|
{
|
||||||
#if defined(HAVE_QT)
|
#if defined(HAVE_QT)
|
||||||
if (mp_widget) {
|
if (mp_widget) {
|
||||||
|
|
|
||||||
|
|
@ -285,6 +285,14 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void drag_cancel () { }
|
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
|
* @brief Gets a value indicating whether a cursor position it set
|
||||||
*/
|
*/
|
||||||
|
|
@ -1121,6 +1129,7 @@ private:
|
||||||
void objects_changed ();
|
void objects_changed ();
|
||||||
int widget_height () const;
|
int widget_height () const;
|
||||||
int widget_width () const;
|
int widget_width () const;
|
||||||
|
void realize_cursor ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Register a service
|
* @brief Register a service
|
||||||
|
|
|
||||||
|
|
@ -202,13 +202,32 @@ NetTracerDialog::item_double_clicked (QListWidgetItem *item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetTracerDialog::drag_cancel ()
|
||||||
|
{
|
||||||
|
if (m_mouse_state > 0) {
|
||||||
|
|
||||||
|
view ()->message ();
|
||||||
|
ui ()->ungrab_mouse (this);
|
||||||
|
set_cursor (lay::Cursor::none);
|
||||||
|
|
||||||
|
m_mouse_state = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
NetTracerDialog::claims_message_bar () const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
NetTracerDialog::mouse_move_event (const db::DPoint & /*p*/, unsigned int /*buttons*/, bool prio)
|
NetTracerDialog::mouse_move_event (const db::DPoint & /*p*/, unsigned int /*buttons*/, bool prio)
|
||||||
{
|
{
|
||||||
if (prio && m_mouse_state != 0) {
|
if (prio && m_mouse_state != 0) {
|
||||||
set_cursor (lay::Cursor::cross);
|
set_cursor (lay::Cursor::cross);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -397,11 +416,13 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
||||||
{
|
{
|
||||||
unsigned int start_layer = 0;
|
unsigned int start_layer = 0;
|
||||||
db::Point start_point;
|
db::Point start_point;
|
||||||
|
db::Shape start_shape;
|
||||||
|
|
||||||
// locate the seed
|
// locate the seed
|
||||||
{
|
{
|
||||||
|
|
||||||
lay::ShapeFinder finder (true /*point mode*/, false /*all levels*/, db::ShapeIterator::All);
|
lay::ShapeFinder finder (true /*point mode*/, false /*all levels*/, db::ShapeIterator::All);
|
||||||
|
finder.set_consider_viewport (false);
|
||||||
|
|
||||||
// go through all visible layers of all cellviews and find a seed shape
|
// go through all visible layers of all cellviews and find a seed shape
|
||||||
for (lay::LayerPropertiesConstIterator lprop = view ()->begin_layers (); ! lprop.at_end (); ++lprop) {
|
for (lay::LayerPropertiesConstIterator lprop = view ()->begin_layers (); ! lprop.at_end (); ++lprop) {
|
||||||
|
|
@ -417,7 +438,7 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cv_index = r->cv_index ();
|
m_cv_index = r->cv_index ();
|
||||||
|
start_shape = r->shape ();
|
||||||
start_layer = r->layer ();
|
start_layer = r->layer ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -440,6 +461,12 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
||||||
|
|
||||||
start_point = tt.inverted ().trans (start_search_box.center ());
|
start_point = tt.inverted ().trans (start_search_box.center ());
|
||||||
|
|
||||||
|
// stop if the center start point is not inside the start polygon
|
||||||
|
db::Polygon poly;
|
||||||
|
if (start_shape.polygon (poly) && db::inside_poly (poly.begin_edge (), start_point) < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the net tracer environment
|
// Set up the net tracer environment
|
||||||
|
|
@ -455,6 +482,7 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
||||||
if (trace_path) {
|
if (trace_path) {
|
||||||
|
|
||||||
lay::ShapeFinder finder (true /*point mode*/, false /*all levels*/, db::ShapeIterator::All);
|
lay::ShapeFinder finder (true /*point mode*/, false /*all levels*/, db::ShapeIterator::All);
|
||||||
|
finder.set_consider_viewport (false);
|
||||||
|
|
||||||
// go through all visible layers of all cellviews and find a seed shape
|
// go through all visible layers of all cellviews and find a seed shape
|
||||||
for (lay::LayerPropertiesConstIterator lprop = view ()->begin_layers (); ! lprop.at_end (); ++lprop) {
|
for (lay::LayerPropertiesConstIterator lprop = view ()->begin_layers (); ! lprop.at_end (); ++lprop) {
|
||||||
|
|
@ -483,6 +511,12 @@ NetTracerDialog::do_trace (const db::DBox &start_search_box, const db::DBox &sto
|
||||||
stop_point = tt.inverted ().trans (stop_search_box.center ());
|
stop_point = tt.inverted ().trans (stop_search_box.center ());
|
||||||
stop_layer = r->layer ();
|
stop_layer = r->layer ();
|
||||||
|
|
||||||
|
// stop if the center stop point is not inside the stop polygon
|
||||||
|
db::Polygon poly;
|
||||||
|
if (r->shape ().polygon (poly) && db::inside_poly (poly.begin_edge (), stop_point) < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
db::NetTracer net_tracer;
|
db::NetTracer net_tracer;
|
||||||
|
|
@ -1261,6 +1295,7 @@ NetTracerDialog::release_mouse ()
|
||||||
m_mouse_state = 0;
|
m_mouse_state = 0;
|
||||||
view ()->message ();
|
view ()->message ();
|
||||||
ui ()->ungrab_mouse (this);
|
ui ()->ungrab_mouse (this);
|
||||||
|
set_cursor (lay::Cursor::none);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ public:
|
||||||
NetTracerDialog (lay::Dispatcher *root, lay::LayoutViewBase *view);
|
NetTracerDialog (lay::Dispatcher *root, lay::LayoutViewBase *view);
|
||||||
virtual ~NetTracerDialog ();
|
virtual ~NetTracerDialog ();
|
||||||
|
|
||||||
|
virtual void drag_cancel ();
|
||||||
|
virtual bool claims_message_bar () const;
|
||||||
virtual bool mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
virtual bool mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||||
virtual bool mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
virtual bool mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||||
virtual void menu_activated (const std::string &symbol);
|
virtual void menu_activated (const std::string &symbol);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue