From e53d432117c66090a844bfc7e5955aa854f3873d Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 29 Jul 2023 01:01:50 +0200 Subject: [PATCH] Better support for point-like handles PCells have been featuring point-like handles but they suffered some issues because they have been mapped to degenerated boxes: - hardly visible - could be destroyed using partial editing Now, the database offers points, hence it is possible to store points explicitly, so no tricks need to be played to make them visible. Editing has been implemented to some extent, so it is possible for example to configure handles in the properties dialogs. --- src/edt/edt/edtPartialService.cc | 42 +++++++++++++++++++++++++++++- src/edt/edt/edtService.cc | 25 ++++++++++++++++-- src/laybasic/laybasic/layFinder.cc | 2 +- src/laybasic/laybasic/laySnap.cc | 8 +++++- 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/src/edt/edt/edtPartialService.cc b/src/edt/edt/edtPartialService.cc index 669bfe2f5..0d9fd63b7 100644 --- a/src/edt/edt/edtPartialService.cc +++ b/src/edt/edt/edtPartialService.cc @@ -849,6 +849,14 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co } + } else if (shape->is_point ()) { + + db::Point tp (shape->point ()); + + if (hit_box.contains (tp)) { + edges.push_back (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0)); + } + } else if (shape->is_text ()) { db::Point tp (shape->text_trans () * db::Point ()); @@ -1000,6 +1008,17 @@ PartialShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, co } + } else if (shape->is_point ()) { + + db::Point tp (shape->point ()); + + if (hit_box.contains (tp)) { + d = tp.distance (hit_box.center ()); + edge_sel.clear (); + edge_sel.push_back (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0)); + match = true; + } + } else if (shape->is_text ()) { db::Point tp (shape->text_trans () * db::Point ()); @@ -1258,6 +1277,11 @@ PartialService::timeout () db::Point tp (r->first.shape ().text_trans () * db::Point ()); enter_edge (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0), n_marker, r, new_points, new_edges, gt, *tv_list, true); + } else if (r->first.shape ().is_point ()) { + + db::Point tp (r->first.shape ().point ()); + enter_edge (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0), n_marker, r, new_points, new_edges, gt, *tv_list, true); + } } @@ -1479,6 +1503,17 @@ PartialService::transform_selection (const db::DTrans &move_trans) shape = shapes.replace (shape, t); } + } else if (shape.is_point ()) { + + db::Point p; + shape.point (p); + + std::map ::const_iterator np = new_points.find (PointWithIndex (p, 0, 0)); + + if (np != new_points.end ()) { + shape = shapes.replace (shape, np->second); + } + } // transform the selection @@ -2204,7 +2239,7 @@ PartialService::del () shapes_to_delete_by_cell.insert (std::make_pair (std::make_pair (r->first.cell_index (), std::make_pair (r->first.cv_index (), r->first.layer ())), std::vector ())).first->second.push_back (r); } - } else if (shape.is_text ()) { + } else if (shape.is_text () || shape.is_point ()) { shapes_to_delete_by_cell.insert (std::make_pair (std::make_pair (r->first.cell_index (), std::make_pair (r->first.cv_index (), r->first.layer ())), std::vector ())).first->second.push_back (r); @@ -2684,6 +2719,11 @@ PartialService::do_selection_to_view () db::Point tp (r->first.shape ().text_trans () * db::Point ()); enter_edge (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0), n_marker, r, new_points, new_edges, gt, *tv_list, false); + } else if (r->first.shape ().is_point ()) { + + db::Point tp (r->first.shape ().point ()); + enter_edge (EdgeWithIndex (db::Edge (tp, tp), 0, 0, 0), n_marker, r, new_points, new_edges, gt, *tv_list, false); + } } diff --git a/src/edt/edt/edtService.cc b/src/edt/edt/edtService.cc index aefcf86dd..8afdf95e3 100644 --- a/src/edt/edt/edtService.cc +++ b/src/edt/edt/edtService.cc @@ -1108,7 +1108,20 @@ Service::transient_select (const db::DPoint &pos) lay::ShapeMarker *marker = new lay::ShapeMarker (view (), r->cv_index ()); marker->set (r->shape (), gt, mp_view->cv_transform_variants (r->cv_index (), r->layer ())); - marker->set_vertex_size (0); + + bool is_point = false; + if (r->shape ().is_edge () || r->shape ().is_box ()) { + is_point = r->shape ().bbox ().is_point (); + } else if (r->shape ().is_point ()) { + is_point = true; + } + + if (is_point) { + marker->set_vertex_shape (lay::ViewOp::Cross); + marker->set_vertex_size (9 /*cross vertex size*/); + } else { + marker->set_vertex_size (0); + } marker->set_line_width (1); marker->set_halo (0); @@ -1602,7 +1615,15 @@ Service::do_selection_to_view () } marker->set (r->shape (), gt, *tv_list); - if (r->shape ().is_text ()) { + + bool is_point = false; + if (r->shape ().is_text () || r->shape ().is_point ()) { + is_point = true; + } else if (r->shape ().is_edge () || r->shape ().is_box ()) { + is_point = r->shape ().bbox ().is_point (); + } + + if (is_point) { // show the origins as crosses for texts marker->set_vertex_shape (lay::ViewOp::Cross); marker->set_vertex_size (9 /*cross vertex size*/); diff --git a/src/laybasic/laybasic/layFinder.cc b/src/laybasic/laybasic/layFinder.cc index df2cdcc36..d227d7ae6 100644 --- a/src/laybasic/laybasic/layFinder.cc +++ b/src/laybasic/laybasic/layFinder.cc @@ -606,7 +606,7 @@ ShapeFinder::visit_cell (const db::Cell &cell, const db::Box &hit_box, const db: match = true; } - } else if (shape->is_box () || shape->is_text ()) { + } else if (shape->is_box () || shape->is_point () || shape->is_text ()) { db::Box box = shape->bbox (); if (text_info () && shape->is_text ()) { diff --git a/src/laybasic/laybasic/laySnap.cc b/src/laybasic/laybasic/laySnap.cc index 4606eb868..b6d268b32 100644 --- a/src/laybasic/laybasic/laySnap.cc +++ b/src/laybasic/laybasic/laySnap.cc @@ -598,7 +598,7 @@ private: const db::Shapes &shapes = cell.shapes (l); - db::ShapeIterator shape = shapes.begin_touching (touch_box, db::ShapeIterator::Polygons | db::ShapeIterator::Paths | db::ShapeIterator::Boxes, mp_prop_sel, m_inv_prop_sel); + db::ShapeIterator shape = shapes.begin_touching (touch_box, db::ShapeIterator::Polygons | db::ShapeIterator::Paths | db::ShapeIterator::Boxes | db::ShapeIterator::Points, mp_prop_sel, m_inv_prop_sel); while (! shape.at_end () && m_tests > 0) { --m_tests; @@ -653,6 +653,12 @@ private: test_edge (t * db::Edge (box.p2 (), db::Point (box.right (), box.bottom ()))); test_edge (t * db::Edge (db::Point (box.right (), box.bottom ()), box.p1 ())); + } else if (shape->is_point ()) { + + const db::Point &p = shape->point (); + + test_edge (t * db::Edge (p, p)); + } ++shape;