Pressing Ctrl key while drawing a box forces it into a square

This commit is contained in:
Matthias Koefferlein 2026-01-11 23:46:11 +01:00
parent c6faa3e628
commit 160cceb7b5
5 changed files with 60 additions and 11 deletions

View File

@ -108,7 +108,10 @@ BoxService::do_mouse_move_inactive (const db::DPoint &p)
void
BoxService::do_mouse_move (const db::DPoint &p)
{
lay::PointSnapToObjectResult snap_details = snap2_details (p);
// snap to square if Ctrl button is pressed
bool snap_square = alt_ac () == lay::AC_Diagonal;
lay::PointSnapToObjectResult snap_details = snap2_details (p, m_p1, snap_square ? lay::AC_DiagonalOnly : lay::AC_Any);
db::DPoint ps = snap_details.snapped_point;
if (snap_details.object_snap == lay::PointSnapToObjectResult::NoObject) {
@ -122,12 +125,22 @@ BoxService::do_mouse_move (const db::DPoint &p)
lay::PointSnapToObjectResult snap_details_y = snap2_details (py);
if (snap_details_x.object_snap != lay::PointSnapToObjectResult::NoObject) {
ps = db::DPoint (snap_details_x.snapped_point.x (), ps.y ());
if (snap_square) {
double dx = fabs (snap_details_x.snapped_point.x () - m_p1.x ());
ps = db::DPoint (snap_details_x.snapped_point.x (), m_p1.y () + (ps.y () < m_p1.y () ? -dx : dx));
} else {
ps = db::DPoint (snap_details_x.snapped_point.x (), ps.y ());
}
mouse_cursor_from_snap_details (snap_details_x, true /*add*/);
}
if (snap_details_y.object_snap != lay::PointSnapToObjectResult::NoObject) {
ps = db::DPoint (ps.x (), snap_details_y.snapped_point.y ());
if (snap_square) {
double dy = fabs (snap_details_y.snapped_point.x () - m_p1.y ());
ps = db::DPoint (m_p1.x () + (ps.x () < m_p1.x () ? -dy : dy), snap_details_y.snapped_point.y ());
} else {
ps = db::DPoint (ps.x (), snap_details_y.snapped_point.y ());
}
mouse_cursor_from_snap_details (snap_details_y, true /*add*/);
}

View File

@ -103,14 +103,21 @@ Service::~Service ()
clear_transient_selection ();
}
lay::angle_constraint_type
lay::angle_constraint_type
Service::alt_ac () const
{
// fetch m_alt_ac (which is set from mouse buttons)
return m_alt_ac;
}
lay::angle_constraint_type
Service::connect_ac () const
{
// m_alt_ac (which is set from mouse buttons) can override the specified connect angle constraint
return m_alt_ac != lay::AC_Global ? m_alt_ac : m_connect_ac;
}
lay::angle_constraint_type
lay::angle_constraint_type
Service::move_ac () const
{
// m_alt_ac (which is set from mouse buttons) can override the specified move angle constraint
@ -290,11 +297,23 @@ Service::snap2 (const db::DPoint &p) const
return snap2_details (p).snapped_point;
}
lay::PointSnapToObjectResult
Service::snap2_details (const db::DPoint &p, const db::DPoint &plast, lay::angle_constraint_type ac) const
{
double snap_range = ui ()->mouse_event_trans ().inverted ().ctrans (lay::snap_range_pixels ());
return lay::obj_snap (m_snap_to_objects ? view () : 0, plast, p, m_edit_grid == db::DVector () ? m_global_grid : m_edit_grid, ac, snap_range);
}
lay::PointSnapToObjectResult
Service::snap2_details (const db::DPoint &p, const db::DPoint &plast, bool connect) const
{
return snap2_details (p, plast, connect ? connect_ac () : move_ac ());
}
db::DPoint
Service::snap2 (const db::DPoint &p, const db::DPoint &plast, bool connect) const
{
double snap_range = ui ()->mouse_event_trans ().inverted ().ctrans (lay::snap_range_pixels ());
return lay::obj_snap (m_snap_to_objects ? view () : 0, plast, p, m_edit_grid == db::DVector () ? m_global_grid : m_edit_grid, connect ? connect_ac () : move_ac (), snap_range).snapped_point;
return snap2_details (p, plast, connect ? connect_ac () : move_ac ()).snapped_point;
}
void

View File

@ -611,6 +611,7 @@ protected:
db::DPoint snap2 (const db::DPoint &p, const db::DPoint &plast, bool connect = true) const;
protected:
lay::angle_constraint_type alt_ac () const;
lay::angle_constraint_type connect_ac () const;
lay::angle_constraint_type move_ac () const;
@ -654,6 +655,16 @@ protected:
*/
lay::PointSnapToObjectResult snap2_details (const db::DPoint &p) const;
/**
* @brief Point snapping with detailed return value
*/
lay::PointSnapToObjectResult snap2_details (const db::DPoint &p, const db::DPoint &plast, bool connect) const;
/**
* @brief Point snapping with detailed return value and specific angle constraint
*/
lay::PointSnapToObjectResult snap2_details (const db::DPoint &p, const db::DPoint &plast, lay::angle_constraint_type ac) const;
private:
friend class EditableSelectionIterator;

View File

@ -188,9 +188,11 @@ snap_angle (const db::DVector &in, lay::angle_constraint_type ac, db::DVector *s
std::vector <db::DVector> ref_dir;
if (ac != lay::AC_Any) {
ref_dir.reserve (4);
ref_dir.push_back (db::DVector (1.0, 0));
ref_dir.push_back (db::DVector (0, 1.0));
if (ac == lay::AC_Diagonal) {
if (ac != lay::AC_DiagonalOnly) {
ref_dir.push_back (db::DVector (1.0, 0));
ref_dir.push_back (db::DVector (0, 1.0));
}
if (ac == lay::AC_Diagonal || ac == lay::AC_DiagonalOnly) {
ref_dir.push_back (db::DVector (-1.0, 1.0));
ref_dir.push_back (db::DVector (1.0, 1.0));
}
@ -963,6 +965,10 @@ make_cutlines (lay::angle_constraint_type snap_mode, const db::DPoint &p1, std::
cutlines.push_back (db::DEdge (p1, p1 + db::DVector (1.0, 0.0)));
cutlines.push_back (db::DEdge (p1, p1 + db::DVector (1.0, 1.0)));
cutlines.push_back (db::DEdge (p1, p1 + db::DVector (1.0, -1.0)));
} else if (snap_mode == lay::AC_DiagonalOnly) {
cutlines.reserve (2);
cutlines.push_back (db::DEdge (p1, p1 + db::DVector (1.0, 1.0)));
cutlines.push_back (db::DEdge (p1, p1 + db::DVector (1.0, -1.0)));
}
}

View File

@ -53,7 +53,7 @@ namespace lay
* Vertical: vertical only
* Global: use global setting (templates and ruler specific setting only)
*/
enum angle_constraint_type { AC_Any = 0, AC_Diagonal, AC_Ortho, AC_Horizontal, AC_Vertical, AC_Global, AC_NumModes };
enum angle_constraint_type { AC_Any = 0, AC_Diagonal, AC_DiagonalOnly, AC_Ortho, AC_Horizontal, AC_Vertical, AC_Global, AC_NumModes };
/**
* @brief snap a coordinate value to a unit grid