mirror of
https://github.com/KLayout/klayout.git
synced 2026-09-06 01:07:36 +02:00
Enhance the selection behavior of partial edit mode: allow selection of edge ends if edges overlap, graphical indicator for selected partial
This commit is contained in:
@@ -210,6 +210,7 @@ EditorServiceBase::EditorServiceBase (LayoutViewBase *view)
|
||||
: lay::ViewService (view->canvas ()),
|
||||
lay::Editable (view),
|
||||
lay::Plugin (view),
|
||||
mp_view (view),
|
||||
m_cursor_enabled (true),
|
||||
m_has_tracking_position (false)
|
||||
{
|
||||
@@ -229,12 +230,30 @@ EditorServiceBase::add_mouse_cursor (const db::DPoint &pt, bool emphasize)
|
||||
m_mouse_cursor_markers.push_back (new MouseCursorViewObject (this, ui (), pt, emphasize));
|
||||
}
|
||||
|
||||
void
|
||||
EditorServiceBase::add_mouse_cursor (const db::Point &pt, unsigned int cv_index, const db::ICplxTrans >, const std::vector<db::DCplxTrans> &tv, bool emphasize)
|
||||
{
|
||||
double dbu = mp_view->cellview (cv_index)->layout ().dbu ();
|
||||
for (auto t = tv.begin (); t != tv.end (); ++t) {
|
||||
add_mouse_cursor (*t * db::CplxTrans (dbu) * gt * pt, emphasize);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EditorServiceBase::add_edge_marker (const db::DEdge &e, bool emphasize)
|
||||
{
|
||||
m_mouse_cursor_markers.push_back (new EdgeMarkerViewObject (this, ui (), e, emphasize));
|
||||
}
|
||||
|
||||
void
|
||||
EditorServiceBase::add_edge_marker (const db::Edge &e, unsigned int cv_index, const db::ICplxTrans >, const std::vector<db::DCplxTrans> &tv, bool emphasize)
|
||||
{
|
||||
double dbu = mp_view->cellview (cv_index)->layout ().dbu ();
|
||||
for (auto t = tv.begin (); t != tv.end (); ++t) {
|
||||
add_edge_marker (*t * db::CplxTrans (dbu) * gt * e, emphasize);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EditorServiceBase::clear_mouse_cursors ()
|
||||
{
|
||||
|
||||
@@ -74,10 +74,20 @@ public:
|
||||
*/
|
||||
void add_mouse_cursor (const db::DPoint &pt, bool emphasize = false);
|
||||
|
||||
/**
|
||||
* @brief Adds a mouse cursor to the given point in layout space
|
||||
*/
|
||||
void add_mouse_cursor (const db::Point &pt, unsigned int cv_index, const db::ICplxTrans >, const std::vector<db::DCplxTrans> &tv, bool emphasize = false);
|
||||
|
||||
/**
|
||||
* @brief Adds an edge marker for the given edge
|
||||
*/
|
||||
void add_edge_marker (const db::DEdge &e, bool emphasize);
|
||||
void add_edge_marker (const db::DEdge &e, bool emphasize = false);
|
||||
|
||||
/**
|
||||
* @brief Adds an edge marker for the given edge in layout space
|
||||
*/
|
||||
void add_edge_marker (const db::Edge &e, unsigned int cv_index, const db::ICplxTrans >, const std::vector<db::DCplxTrans> &tv, bool emphasize = false);
|
||||
|
||||
/**
|
||||
* @brief Resets the mouse cursor
|
||||
@@ -132,6 +142,7 @@ protected:
|
||||
|
||||
private:
|
||||
// The marker representing the mouse cursor
|
||||
lay::LayoutViewBase *mp_view;
|
||||
std::vector<lay::ViewObject *> m_mouse_cursor_markers;
|
||||
tl::Color m_cursor_color;
|
||||
bool m_cursor_enabled;
|
||||
|
||||
@@ -123,47 +123,74 @@ Finder::start (lay::LayoutViewBase *view, unsigned int cv_index, const std::vect
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Finder::test_edge (const db::ICplxTrans &trans, const db::Edge &edge, double &distance, bool &match)
|
||||
{
|
||||
if (test_edge (trans, edge, true, distance, match) == 0) {
|
||||
test_edge (trans, edge, false, distance, match);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int
|
||||
Finder::test_edge (const db::ICplxTrans &trans, const db::Edge &edg, double &distance, bool &match)
|
||||
Finder::test_edge (const db::ICplxTrans &trans, const db::Edge &edg, bool points, double &distance, bool &match)
|
||||
{
|
||||
db::Point p1 = trans * edg.p1 ();
|
||||
db::Point p2 = trans * edg.p2 ();
|
||||
|
||||
unsigned int ret = 0;
|
||||
|
||||
// we hit the region with the edge end points - take the closest vertex
|
||||
if (m_region.contains (p1) || m_region.contains (p2)) {
|
||||
if (points) {
|
||||
|
||||
double d1 = p1.double_distance (m_region.center ());
|
||||
double d2 = p2.double_distance (m_region.center ());
|
||||
// we hit the region with the edge end points - take the closest vertex
|
||||
if (m_region.contains (p1) || m_region.contains (p2)) {
|
||||
|
||||
double d1 = p1.double_distance (m_region.center ());
|
||||
double d2 = p2.double_distance (m_region.center ());
|
||||
if (d1 < d2) {
|
||||
ret = 1;
|
||||
} else {
|
||||
ret = 2;
|
||||
}
|
||||
|
||||
double d = std::min (d1, d2);
|
||||
// add a penalty of 1 DBU for being on the wrong
|
||||
// side of the edge - this favors the right edge
|
||||
// in case of butting corners
|
||||
if (ret == 1) {
|
||||
if (db::sprod_sign (m_region.center () - p1, p2 - p1) < 0) {
|
||||
d += trans.ctrans (1);
|
||||
}
|
||||
} else {
|
||||
if (db::sprod_sign (m_region.center () - p2, p1 - p2) < 0) {
|
||||
d += trans.ctrans (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (! match || d < distance) {
|
||||
distance = d;
|
||||
}
|
||||
|
||||
match = true;
|
||||
|
||||
double d = std::min (d1, d2);
|
||||
if (! match || d < distance) {
|
||||
distance = d;
|
||||
}
|
||||
|
||||
if (d1 < d2) {
|
||||
ret = 1;
|
||||
} else {
|
||||
ret = 2;
|
||||
}
|
||||
|
||||
match = true;
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
// if the edge cuts through the active region: test the
|
||||
// edge as a whole
|
||||
if (ret == 0) {
|
||||
// if the edge cuts through the active region: test the
|
||||
// edge as a whole
|
||||
db::Edge edg_trans (p1, p2);
|
||||
if (edg_trans.clipped (m_region).first) {
|
||||
|
||||
double d = edg_trans.distance_abs (m_region.center ());
|
||||
if (! match || d < distance) {
|
||||
distance = d;
|
||||
ret = 3;
|
||||
}
|
||||
|
||||
ret = 3;
|
||||
match = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -176,11 +176,18 @@ protected:
|
||||
*
|
||||
* "trans" is the transformation to be applied to the edge before the test.
|
||||
*
|
||||
* If "points" is true, only points are tested, otherwise edges are tested.
|
||||
*
|
||||
* This method returns a mask indicating which point of the edge was matching.
|
||||
* Bit 0 of this mask indicates the first point is matching, bit 1 indicates the
|
||||
* second point is matching.
|
||||
*/
|
||||
unsigned int test_edge (const db::ICplxTrans &trans, const db::Edge &edge, double &distance, bool &match);
|
||||
unsigned int test_edge (const db::ICplxTrans &trans, const db::Edge &edge, bool points, double &distance, bool &match);
|
||||
|
||||
/**
|
||||
* @brief Tests an edge in point mode and edge mode (later)
|
||||
*/
|
||||
void test_edge (const db::ICplxTrans &trans, const db::Edge &edge, double &distance, bool &match);
|
||||
|
||||
private:
|
||||
void do_find (const db::Cell &cell, int level, const db::DCplxTrans &vp, const db::ICplxTrans &t);
|
||||
|
||||
Reference in New Issue
Block a user