Leaner solution: provide snap and swap

"Swap points": will swap P1 and P2
"Snap both": will take P2 into account (before it was only P1)
This commit is contained in:
Matthias Koefferlein 2019-09-01 23:14:21 +02:00
parent 9fa5277e41
commit 2e695bd048
5 changed files with 629 additions and 731 deletions

File diff suppressed because it is too large Load Diff

View File

@ -39,20 +39,13 @@ PropertiesPage::PropertiesPage (ant::Service *rulers, db::Manager *manager, QWid
setupUi (this);
connect (p1x_to_p2x, SIGNAL (clicked ()), this, SLOT (xfer_coord_clicked ()));
connect (p2x_to_p1x, SIGNAL (clicked ()), this, SLOT (xfer_coord_clicked ()));
connect (p1y_to_p2y, SIGNAL (clicked ()), this, SLOT (xfer_coord_clicked ()));
connect (p2y_to_p1y, SIGNAL (clicked ()), this, SLOT (xfer_coord_clicked ()));
connect (swap_points, SIGNAL (clicked ()), this, SLOT (swap_points_clicked ()));
connect (p1_to_layout, SIGNAL (clicked ()), this, SLOT (snap_to_layout_clicked ()));
connect (p2_to_layout, SIGNAL (clicked ()), this, SLOT (snap_to_layout_clicked ()));
connect (both_to_layout, SIGNAL (clicked ()), this, SLOT (snap_to_layout_clicked ()));
p1x_to_p2x->setEnabled (! readonly());
p2x_to_p1x->setEnabled (! readonly());
p1y_to_p2y->setEnabled (! readonly());
p2y_to_p1y->setEnabled (! readonly());
swap_points->setEnabled (! readonly());
p1_to_layout->setEnabled (! readonly());
p2_to_layout->setEnabled (! readonly());
both_to_layout->setEnabled (! readonly());
@ -80,23 +73,24 @@ PropertiesPage::front ()
}
void
PropertiesPage::xfer_coord_clicked ()
PropertiesPage::swap_points_clicked ()
{
if (readonly ()) {
return;
}
if (sender () == p1x_to_p2x) {
x2->setText (x1->text ());
} else if (sender () == p2x_to_p1x) {
x1->setText (x2->text ());
} else if (sender () == p1y_to_p2y) {
y2->setText (y1->text ());
} else if (sender () == p2y_to_p1y) {
y1->setText (y2->text ());
}
QString tx1 = x1->text (), tx2 = x2->text ();
QString ty1 = y1->text (), ty2 = y2->text ();
db::Transaction t (manager (), tl::to_string (QObject::tr ("Copy ruler coordinates")));
std::swap (tx1, tx2);
std::swap (ty1, ty2);
x1->setText (tx1);
x2->setText (tx2);
y1->setText (ty1);
y2->setText (ty2);
db::Transaction t (manager (), tl::to_string (QObject::tr ("Swap ruler points")));
apply ();
}
@ -136,12 +130,14 @@ PropertiesPage::snap_to_layout_clicked ()
if (sender () == p1_to_layout || sender () == p2_to_layout) {
bool snap_p1 = sender () == p1_to_layout;
double snap_range = service->widget ()->mouse_event_trans ().inverted ().ctrans (service->snap_range ());
double max_range = 1000 * snap_range;
while (snap_range < max_range) {
std::pair<bool, db::DPoint> pp = lay::obj_snap (service->view (), p1, p1, g, ac, snap_range);
std::pair<bool, db::DPoint> pp = lay::obj_snap (service->view (), snap_p1 ? p2 : p1, snap_p1 ? p1 : p2, g, ac, snap_range);
if (pp.first) {
QString xs = tl::to_qstring (tl::micron_to_string (pp.second.x ()));
@ -155,7 +151,7 @@ PropertiesPage::snap_to_layout_clicked ()
y2->setText (ys);
}
db::Transaction t (manager (), tl::to_string (sender () == p1_to_layout ? QObject::tr ("Snap first ruler point") : QObject::tr ("Snap second ruler point")));
db::Transaction t (manager (), tl::to_string (snap_p1 ? QObject::tr ("Snap first ruler point") : QObject::tr ("Snap second ruler point")));
apply ();
break;
@ -172,7 +168,7 @@ PropertiesPage::snap_to_layout_clicked ()
double snap_range = service->widget ()->mouse_event_trans ().inverted ().ctrans (service->snap_range ());
snap_range *= 0.5;
std::pair<bool, db::DEdge> ee = lay::obj_snap2 (service->view (), p1, g, ac, snap_range, snap_range * 1000.0);
std::pair<bool, db::DEdge> ee = lay::obj_snap2 (service->view (), p1, p2, g, ac, snap_range, snap_range * 1000.0);
if (ee.first) {
x1->setText (tl::to_qstring (tl::micron_to_string (ee.second.p1 ().x ())));

View File

@ -54,7 +54,7 @@ public:
virtual void apply ();
private slots:
void xfer_coord_clicked ();
void swap_points_clicked ();
void snap_to_layout_clicked ();
private:

View File

@ -441,7 +441,7 @@ private:
if (m_directed) {
for (std::vector<db::DEdge>::const_iterator cl = m_cutlines.begin (); cl != m_cutlines.end (); ++cl) {
if (db::sprod_sign (p - cl->p1 (), cl->d ()) <= 0) {
if (db::sprod_sign (p - m_original, cl->d ()) <= 0) {
return;
}
}
@ -462,7 +462,7 @@ private:
if (m_directed) {
for (std::vector<db::DEdge>::const_iterator cl = m_cutlines.begin (); cl != m_cutlines.end (); ++cl) {
if (db::sprod_sign (p - cl->p1 (), cl->d ()) < 0) {
if (db::sprod_sign (p - m_original, cl->d ()) < 0) {
return;
}
}
@ -765,10 +765,12 @@ do_obj_snap (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &gri
}
std::pair <bool, db::DEdge>
do_obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, double min_search_range, double max_search_range, const std::vector <db::DEdge> &cutlines)
do_obj_snap2 (lay::LayoutView *view, const db::DPoint &pt1, const db::DPoint &pt2, const db::DVector &grid, double min_search_range, double max_search_range, const std::vector <db::DEdge> &cutlines)
{
db::DPoint dp (pt);
ContourFinder finder (dp, grid, cutlines, false /*no vertex snap*/);
db::DPoint dp1 (pt1);
db::DPoint dp2 (pt2);
ContourFinder finder (dp1, grid, cutlines, false /*no vertex snap*/);
double sr = min_search_range;
while (sr < max_search_range + 1e-6) {
@ -788,9 +790,9 @@ do_obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &gr
for (std::vector<db::DEdge>::const_iterator i = cutlines.begin (); i != cutlines.end (); ++i) {
db::DVector n = i->d ();
db::DVector d = dp - p1;
db::DVector d = dp2 - p1;
if (fabs (db::vprod (n, d)) < 1e-6 * n.length () * d.length ()) {
if (db::sprod (n, d) < 0.0) {
if (db::sprod_sign (n, d) < 0) {
n = -n;
}
cl.push_back (db::DEdge (p1, p1 + n));
@ -801,14 +803,14 @@ do_obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &gr
} else if (finder.has_found_edge ()) {
n = finder.get_found_edge ().d ().transformed (db::DTrans (db::DTrans::r90));
if (db::sprod (n, dp - p1) < 0.0) {
if (db::sprod_sign (n, dp2 - p1) < 0) {
n = -n;
}
cl.push_back (db::DEdge (p1, p1 + n));
}
ContourFinder finder2 (dp, grid, cl, false /*no vertex snap*/, true /*directional cutlines*/);
ContourFinder finder2 (dp2, grid, cl, false /*no vertex snap*/, true /*directional cutlines*/);
double sr2 = min_search_range;
while (sr2 < max_search_range + 1e-6) {
@ -872,17 +874,33 @@ obj_snap (lay::LayoutView *view, const db::DPoint &p1, const db::DPoint &p2, con
std::pair <bool, db::DEdge>
obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, double min_search_range, double max_search_range)
{
return do_obj_snap2 (view, lay::snap_xy (pt, grid), db::DVector (), min_search_range, max_search_range, std::vector<db::DEdge> ());
return obj_snap2 (view, pt, pt, grid, min_search_range, max_search_range);
}
std::pair <bool, db::DEdge>
obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, lay::angle_constraint_type snap_mode, double min_search_range, double max_search_range)
obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, lay::angle_constraint_type ac, double min_search_range, double max_search_range)
{
db::DPoint dp = lay::snap_xy (pt, grid);
return obj_snap2 (view, pt, pt, grid, ac, min_search_range, max_search_range);
}
std::pair <bool, db::DEdge>
obj_snap2 (lay::LayoutView *view, const db::DPoint &pt1, const db::DPoint &pt2, const db::DVector &grid, double min_search_range, double max_search_range)
{
db::DPoint dp1 = lay::snap_xy (pt1, grid);
db::DPoint dp2 = lay::snap_xy (pt2, grid);
return do_obj_snap2 (view, dp1, dp2, db::DVector (), min_search_range, max_search_range, std::vector<db::DEdge> ());
}
std::pair <bool, db::DEdge>
obj_snap2 (lay::LayoutView *view, const db::DPoint &pt1, const db::DPoint &pt2, const db::DVector &grid, lay::angle_constraint_type snap_mode, double min_search_range, double max_search_range)
{
db::DPoint dp1 = lay::snap_xy (pt1, grid);
db::DPoint dp2 = lay::snap_xy (pt2, grid);
std::vector <db::DEdge> cutlines;
make_cutlines (snap_mode, dp, cutlines);
return do_obj_snap2 (view, dp, db::DVector (), min_search_range, max_search_range, cutlines);
make_cutlines (snap_mode, dp1, cutlines);
return do_obj_snap2 (view, dp1, dp2, db::DVector (), min_search_range, max_search_range, cutlines);
}
}

View File

@ -143,6 +143,16 @@ namespace lay
*/
LAYBASIC_PUBLIC std::pair <bool, db::DEdge> obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, double min_search_range, double max_search_range);
/**
* @brief Same than obj_snap, but delivers two points on two opposite sides of the initial points
*
* This method basically implements "auto measure". The first value of the returned pair
* is true if such an edge could be found. Otherwise it's false.
*
* This version accepts two points defining different search regions for first and second edge.
*/
LAYBASIC_PUBLIC std::pair <bool, db::DEdge> obj_snap2 (lay::LayoutView *view, const db::DPoint &pt1, const db::DPoint &pt2, const db::DVector &grid, double min_search_range, double max_search_range);
/**
* @brief Same than the previous obj_snap2, but allows specification of an angle constraint
*
@ -150,6 +160,15 @@ namespace lay
*/
LAYBASIC_PUBLIC std::pair <bool, db::DEdge> obj_snap2 (lay::LayoutView *view, const db::DPoint &pt, const db::DVector &grid, lay::angle_constraint_type ac, double min_search_range, double max_search_range);
/**
* @brief Same than the previous obj_snap2, but allows specification of an angle constraint
*
* Measurements will be confined to the direction specified.
*
* This version accepts two points defining different search regions for first and second edge.
*/
LAYBASIC_PUBLIC std::pair <bool, db::DEdge> obj_snap2 (lay::LayoutView *view, const db::DPoint &pt1, const db::DPoint &pt2, const db::DVector &grid, lay::angle_constraint_type ac, double min_search_range, double max_search_range);
/**
* @brief Reduce a given vector according to the angle constraint
*/