mirror of https://github.com/KLayout/klayout.git
Improving ruler snapping (after move_transform, snap to objects, visual snap details hint ...)
This commit is contained in:
parent
53c173d01e
commit
43454962d4
|
|
@ -1431,7 +1431,7 @@ Service::begin_move (lay::Editable::MoveMode mode, const db::DPoint &p, lay::ang
|
|||
const ant::Object *robj = dynamic_cast <const ant::Object *> ((*ri).ptr ());
|
||||
if (robj && (! robj_min || robj == robj_min)) {
|
||||
|
||||
if (dragging_what (robj, search_dbox, m_move_mode, m_p1, m_seg_index) && m_move_mode != MoveRuler) {
|
||||
if (dragging_what (robj, search_dbox, m_move_mode, m_p1, m_seg_index)) {
|
||||
|
||||
// found anything: make the moved ruler the selection
|
||||
clear_selection ();
|
||||
|
|
@ -1516,28 +1516,70 @@ Service::begin_move (lay::Editable::MoveMode mode, const db::DPoint &p, lay::ang
|
|||
}
|
||||
|
||||
void
|
||||
Service::move_transform (const db::DPoint &p, db::DFTrans tr, lay::angle_constraint_type /*ac*/)
|
||||
Service::snap_rulers (lay::angle_constraint_type ac)
|
||||
{
|
||||
if (m_rulers.empty ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
lay::PointSnapToObjectResult min_snp;
|
||||
double min_dist = -1.0;
|
||||
db::DVector min_delta;
|
||||
|
||||
for (auto r = m_rulers.begin (); r != m_rulers.end (); ++r) {
|
||||
|
||||
const ant::Object *ruler = (*r)->ruler ();
|
||||
|
||||
db::DPoint p1 = m_trans * ruler->p1 ();
|
||||
db::DPoint p2 = m_trans * ruler->p2 ();
|
||||
|
||||
auto tr = db::DTrans ((m_p1 - db::DPoint ()) - m_trans.disp ()) * m_trans * db::DTrans (db::DPoint () - m_p1);
|
||||
db::DPoint org1 = tr * ruler->p1 ();
|
||||
db::DPoint org2 = tr * ruler->p2 ();
|
||||
|
||||
auto snp = snap2_details (org1, p1, ruler, ac);
|
||||
double dist = p1.distance (snp.snapped_point);
|
||||
|
||||
if (min_dist < 0 || dist < min_dist) {
|
||||
min_snp = snp;
|
||||
min_dist = dist;
|
||||
min_delta = snp.snapped_point - p1;
|
||||
}
|
||||
|
||||
snp = snap2_details (org2, p2, ruler, ac);
|
||||
dist = p2.distance (snp.snapped_point);
|
||||
|
||||
if (min_dist < 0 || dist < min_dist) {
|
||||
min_snp = snp;
|
||||
min_dist = dist;
|
||||
min_delta = snp.snapped_point - p2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (min_snp.object_snap != lay::PointSnapToObjectResult::NoObject) {
|
||||
mouse_cursor_from_snap_details (min_snp);
|
||||
}
|
||||
|
||||
m_trans = db::DTrans (min_delta) * m_trans;
|
||||
}
|
||||
|
||||
void
|
||||
Service::move_transform (const db::DPoint & /*p*/, db::DFTrans tr, lay::angle_constraint_type ac)
|
||||
{
|
||||
if (m_rulers.empty () || m_selected.empty ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_move_mode == MoveRuler) {
|
||||
auto ac_eff = ac == lay::AC_Global ? m_snap_mode : ac;
|
||||
clear_mouse_cursors ();
|
||||
|
||||
db::DVector dp = p - db::DPoint ();
|
||||
|
||||
m_original.transform (db::DTrans (m_p1 - db::DPoint ()) * db::DTrans (tr) * db::DTrans (db::DPoint () - m_p1));
|
||||
m_current.transform (db::DTrans (dp) * db::DTrans (tr) * db::DTrans (-dp));
|
||||
|
||||
// display current rulers' parameters
|
||||
show_message ();
|
||||
|
||||
m_rulers [0]->redraw ();
|
||||
|
||||
} else if (m_move_mode == MoveSelected) {
|
||||
if (m_move_mode == MoveSelected) {
|
||||
|
||||
m_trans *= db::DTrans (m_p1 - db::DPoint ()) * db::DTrans (tr) * db::DTrans (db::DPoint () - m_p1);
|
||||
|
||||
snap_rulers (ac_eff);
|
||||
|
||||
for (std::vector<ant::View *>::iterator r = m_rulers.begin (); r != m_rulers.end (); ++r) {
|
||||
(*r)->transform_by (db::DCplxTrans (m_trans));
|
||||
}
|
||||
|
|
@ -1553,90 +1595,66 @@ Service::move (const db::DPoint &p, lay::angle_constraint_type ac)
|
|||
return;
|
||||
}
|
||||
|
||||
auto ac_eff = ac == lay::AC_Global ? m_snap_mode : ac;
|
||||
clear_mouse_cursors ();
|
||||
|
||||
if (m_move_mode == MoveP1) {
|
||||
|
||||
m_current.seg_p1 (m_seg_index, snap2 (m_p1, p, &m_current, ac).second);
|
||||
m_current.seg_p1 (m_seg_index, snap2_visual (m_p1, p, &m_current, ac));
|
||||
m_rulers [0]->redraw ();
|
||||
|
||||
} else if (m_move_mode == MoveP2) {
|
||||
|
||||
m_current.seg_p2 (m_seg_index, snap2 (m_p1, p, &m_current, ac).second);
|
||||
m_current.seg_p2 (m_seg_index, snap2_visual (m_p1, p, &m_current, ac));
|
||||
m_rulers [0]->redraw ();
|
||||
|
||||
} else if (m_move_mode == MoveP12) {
|
||||
|
||||
db::DPoint p12 = snap2 (m_p1, p, &m_current, ac).second;
|
||||
db::DPoint p12 = snap2_visual (m_p1, p, &m_current, ac);
|
||||
m_current.seg_p1 (m_seg_index, db::DPoint (m_current.seg_p1 (m_seg_index).x(), p12.y ()));
|
||||
m_current.seg_p2 (m_seg_index, db::DPoint (p12.x (), m_current.seg_p2 (m_seg_index).y ()));
|
||||
m_rulers [0]->redraw ();
|
||||
|
||||
} else if (m_move_mode == MoveP21) {
|
||||
|
||||
db::DPoint p21 = snap2 (m_p1, p, &m_current, ac).second;
|
||||
db::DPoint p21 = snap2_visual (m_p1, p, &m_current, ac);
|
||||
m_current.seg_p1 (m_seg_index, db::DPoint (p21.x (), m_current.seg_p1 (m_seg_index).y ()));
|
||||
m_current.seg_p2 (m_seg_index, db::DPoint (m_current.seg_p2 (m_seg_index).x(), p21.y ()));
|
||||
m_rulers [0]->redraw ();
|
||||
|
||||
} else if (m_move_mode == MoveP1X) {
|
||||
|
||||
db::DPoint pc = snap2 (m_p1, p, &m_current, ac).second;
|
||||
db::DPoint pc = snap2_visual (m_p1, p, &m_current, ac);
|
||||
m_current.seg_p1 (m_seg_index, db::DPoint (pc.x (), m_current.seg_p1 (m_seg_index).y ()));
|
||||
m_rulers [0]->redraw ();
|
||||
|
||||
} else if (m_move_mode == MoveP2X) {
|
||||
|
||||
db::DPoint pc = snap2 (m_p1, p, &m_current, ac).second;
|
||||
db::DPoint pc = snap2_visual (m_p1, p, &m_current, ac);
|
||||
m_current.seg_p2 (m_seg_index, db::DPoint (pc.x (), m_current.seg_p2 (m_seg_index).y ()));
|
||||
m_rulers [0]->redraw ();
|
||||
|
||||
} else if (m_move_mode == MoveP1Y) {
|
||||
|
||||
db::DPoint pc = snap2 (m_p1, p, &m_current, ac).second;
|
||||
db::DPoint pc = snap2_visual (m_p1, p, &m_current, ac);
|
||||
m_current.seg_p1 (m_seg_index, db::DPoint (m_current.seg_p1 (m_seg_index).x (), pc.y ()));
|
||||
m_rulers [0]->redraw ();
|
||||
|
||||
} else if (m_move_mode == MoveP2Y) {
|
||||
|
||||
db::DPoint pc = snap2 (m_p1, p, &m_current, ac).second;
|
||||
db::DPoint pc = snap2_visual (m_p1, p, &m_current, ac);
|
||||
m_current.seg_p2 (m_seg_index, db::DPoint (m_current.seg_p2 (m_seg_index).x (), pc.y ()));
|
||||
m_rulers [0]->redraw ();
|
||||
|
||||
} else if (m_move_mode == MoveRuler) {
|
||||
|
||||
// try two ways of snapping
|
||||
db::DVector dp = lay::snap_angle (p - m_p1, ac == lay::AC_Global ? m_snap_mode : ac);
|
||||
|
||||
db::DPoint p1 = m_original.p1 () + dp;
|
||||
db::DPoint p2 = m_original.p2 () + dp;
|
||||
|
||||
std::pair<bool, db::DPoint> r1 = snap1 (p1, m_obj_snap && m_original.snap ());
|
||||
db::DPoint q1 = r1.second;
|
||||
std::pair<bool, db::DPoint> r2 = snap1 (p2, m_obj_snap && m_original.snap ());
|
||||
db::DPoint q2 = r2.second;
|
||||
|
||||
if ((!r2.first && r1.first) || ((r1.first || (!r1.first && !r2.first)) && q1.distance (p1) < q2.distance (p2))) {
|
||||
q2 = q1 + (m_original.p2 () - m_original.p1 ());
|
||||
} else {
|
||||
q1 = q2 + (m_original.p1 () - m_original.p2 ());
|
||||
}
|
||||
|
||||
m_current.p1 (q1);
|
||||
m_current.p2 (q2);
|
||||
|
||||
m_rulers [0]->redraw ();
|
||||
|
||||
} else if (m_move_mode == MoveSelected) {
|
||||
|
||||
db::DVector dp = p - m_p1;
|
||||
// round the drag distance to grid if required: this is the least we can do in this case
|
||||
if (m_grid_snap) {
|
||||
dp = db::DVector (lay::snap (dp.x (), m_grid), lay::snap (dp.y (), m_grid));
|
||||
}
|
||||
|
||||
dp = lay::snap_angle (dp, ac == lay::AC_Global ? m_snap_mode : ac);
|
||||
dp = lay::snap_angle (dp, ac_eff);
|
||||
|
||||
m_trans = db::DTrans (dp + (m_p1 - db::DPoint ()) - m_trans.disp ()) * m_trans * db::DTrans (db::DPoint () - m_p1);
|
||||
|
||||
snap_rulers (ac_eff);
|
||||
|
||||
for (std::vector<ant::View *>::iterator r = m_rulers.begin (); r != m_rulers.end (); ++r) {
|
||||
(*r)->transform_by (db::DCplxTrans (m_trans));
|
||||
}
|
||||
|
|
@ -1646,7 +1664,6 @@ Service::move (const db::DPoint &p, lay::angle_constraint_type ac)
|
|||
if (m_move_mode != MoveSelected) {
|
||||
show_message ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1703,6 +1720,7 @@ Service::end_move (const db::DPoint &, lay::angle_constraint_type)
|
|||
// termine the operation
|
||||
m_move_mode = MoveNone;
|
||||
|
||||
clear_mouse_cursors ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2040,7 +2058,7 @@ Service::mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
|||
// otherwise we risk manipulating p1 too.
|
||||
ant::Object::point_list pts = m_current.points ();
|
||||
if (! pts.empty ()) {
|
||||
pts.back () = snap2 (m_p1, p, mp_active_ruler->ruler (), ac_from_buttons (buttons)).second;
|
||||
pts.back () = snap_details.snapped_point;
|
||||
}
|
||||
m_current.set_points_exact (pts);
|
||||
|
||||
|
|
@ -2095,11 +2113,16 @@ Service::snap2_details (const db::DPoint &p1, const db::DPoint &p2, const ant::O
|
|||
return lay::obj_snap (m_obj_snap && obj->snap () ? mp_view : 0, p1, p2, g, snap_mode, snap_range);
|
||||
}
|
||||
|
||||
std::pair <bool, db::DPoint>
|
||||
Service::snap2 (const db::DPoint &p1, const db::DPoint &p2, const ant::Object *obj, lay::angle_constraint_type ac)
|
||||
db::DPoint
|
||||
Service::snap2_visual (const db::DPoint &p1, const db::DPoint &p2, const ant::Object *obj, lay::angle_constraint_type ac)
|
||||
{
|
||||
lay::PointSnapToObjectResult res = snap2_details (p1, p2, obj, ac);
|
||||
return std::make_pair (res.object_snap != lay::PointSnapToObjectResult::NoObject, res.snapped_point);
|
||||
|
||||
if (res.object_snap != lay::PointSnapToObjectResult::NoObject) {
|
||||
mouse_cursor_from_snap_details (res);
|
||||
}
|
||||
|
||||
return res.snapped_point;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -208,10 +208,9 @@ public:
|
|||
* MoveP2X - dragging P2.x (if box-like)
|
||||
* MoveP1Y - dragging P1.y (if box-like)
|
||||
* MoveP2Y - dragging P2.y (if box-like)
|
||||
* MoveRuler - dragging a whole ruler (one)
|
||||
* MoveSelection - dragging a whole ruler (many)
|
||||
*/
|
||||
enum MoveMode { MoveNone, MoveP1, MoveP2, MoveP12, MoveP21, MoveP1X, MoveP2X, MoveP1Y, MoveP2Y, MoveRuler, MoveSelected };
|
||||
enum MoveMode { MoveNone, MoveP1, MoveP2, MoveP12, MoveP21, MoveP1X, MoveP2X, MoveP1Y, MoveP2Y, MoveSelected };
|
||||
|
||||
Service (db::Manager *manager, lay::LayoutViewBase *view);
|
||||
|
||||
|
|
@ -601,7 +600,7 @@ private:
|
|||
|
||||
std::pair<bool, db::DPoint> snap1 (const db::DPoint &p, bool obj_snap);
|
||||
lay::PointSnapToObjectResult snap1_details (const db::DPoint &p, bool obj_snap);
|
||||
std::pair<bool, db::DPoint> snap2 (const db::DPoint &p1, const db::DPoint &p2, const ant::Object *obj, lay::angle_constraint_type ac);
|
||||
db::DPoint snap2_visual (const db::DPoint &p1, const db::DPoint &p2, const ant::Object *obj, lay::angle_constraint_type ac);
|
||||
lay::PointSnapToObjectResult snap2_details (const db::DPoint &p1, const db::DPoint &p2, const ant::Object *obj, lay::angle_constraint_type ac);
|
||||
lay::TwoPointSnapToObjectResult auto_measure (const db::DPoint &p, lay::angle_constraint_type ac, const ant::Template &tpl);
|
||||
|
||||
|
|
@ -620,6 +619,8 @@ private:
|
|||
virtual bool mouse_double_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||
virtual void deactivated ();
|
||||
|
||||
void snap_rulers (lay::angle_constraint_type ac);
|
||||
|
||||
/**
|
||||
* @brief Select a certain ruler
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1584,8 +1584,8 @@ Class<gsi::PluginBase> decl_Plugin ("lay", "Plugin",
|
|||
"angle constraint. Only grid constraints and snapping to objects is supported.\n"
|
||||
"\n"
|
||||
"If \"visualize\" is true, the function will generate calls to \\add_mouse_cursor or \\add_edge_marker to "
|
||||
"provide a visualization of the edges or vertexes that the point is snapping to. If you use this feature, "
|
||||
"make sure you call \\clear_mouse_cursors before to remove existing cursors.\n"
|
||||
"provide a visualization of the edges or vertexes that the point is snapping to. \\clear_mouse_cursors will "
|
||||
"be called before.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.30.4."
|
||||
) +
|
||||
|
|
@ -1609,8 +1609,8 @@ Class<gsi::PluginBase> decl_Plugin ("lay", "Plugin",
|
|||
"will snap to another object. The behavior is given by the respective configuration.\n"
|
||||
"\n"
|
||||
"If \"visualize\" is true, the function will generate calls to \\add_mouse_cursor or \\add_edge_marker to "
|
||||
"provide a visualization of the edges or vertexes that the point is snapping to. If you use this feature, "
|
||||
"make sure you call \\clear_mouse_cursors before to remove existing cursors.\n"
|
||||
"provide a visualization of the edges or vertexes that the point is snapping to. \\clear_mouse_cursors will "
|
||||
"be called before.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.30.4."
|
||||
) +
|
||||
|
|
|
|||
Loading…
Reference in New Issue