From ee622fc10402bbfa5434281af156609fb59e4d01 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 13 Jan 2026 12:54:10 +0100 Subject: [PATCH] WIP --- src/ant/ant/antService.cc | 7 ++++- src/edt/edt/edtPartialService.cc | 2 ++ src/edt/edt/edtService.cc | 23 ++++++++------ src/img/img/imgService.cc | 1 + src/laybasic/laybasic/layEditable.cc | 40 +++++++++++++++++++++-- src/laybasic/laybasic/layEditable.h | 47 +++++++++++++++++++++++++++- src/laybasic/laybasic/layMove.cc | 38 +++++++++++++++++++++- 7 files changed, 144 insertions(+), 14 deletions(-) diff --git a/src/ant/ant/antService.cc b/src/ant/ant/antService.cc index 6f6c0e556..b7ead8384 100644 --- a/src/ant/ant/antService.cc +++ b/src/ant/ant/antService.cc @@ -1598,6 +1598,8 @@ Service::move (const db::DPoint &p, lay::angle_constraint_type ac) auto ac_eff = ac == lay::AC_Global ? m_snap_mode : ac; clear_mouse_cursors (); + bool indicate_ruler_as_message = true; + if (m_move_mode == MoveP1) { m_current.seg_p1 (m_seg_index, snap2_visual (m_p1, p, &m_current, ac)); @@ -1653,6 +1655,9 @@ Service::move (const db::DPoint &p, lay::angle_constraint_type ac) m_trans = db::DTrans (dp + (m_p1 - db::DPoint ()) - m_trans.disp ()) * m_trans * db::DTrans (db::DPoint () - m_p1); + propose_move_transformation (m_trans, 1); + indicate_ruler_as_message = false; + snap_rulers (ac_eff); for (std::vector::iterator r = m_rulers.begin (); r != m_rulers.end (); ++r) { @@ -1661,7 +1666,7 @@ Service::move (const db::DPoint &p, lay::angle_constraint_type ac) } - if (m_move_mode != MoveSelected) { + if (indicate_ruler_as_message) { show_message (); } } diff --git a/src/edt/edt/edtPartialService.cc b/src/edt/edt/edtPartialService.cc index d8e5d59cb..d80a08bcd 100644 --- a/src/edt/edt/edtPartialService.cc +++ b/src/edt/edt/edtPartialService.cc @@ -2481,6 +2481,8 @@ PartialService::move (const db::DPoint &p, lay::angle_constraint_type ac) } + propose_move_transformation (db::DTrans (m_current - m_start), 0); + selection_to_view (); m_alt_ac = lay::AC_Global; diff --git a/src/edt/edt/edtService.cc b/src/edt/edt/edtService.cc index ededabe19..a044dd441 100644 --- a/src/edt/edt/edtService.cc +++ b/src/edt/edt/edtService.cc @@ -563,15 +563,20 @@ void Service::move (const db::DPoint &pu, lay::angle_constraint_type ac) { m_alt_ac = ac; + if (view ()->is_editable () && m_moving) { + db::DPoint ref = snap (m_move_start); bool snapped = false; db::DPoint p = ref + snap_marker_to_grid (pu - m_move_start, snapped); if (! snapped) { p = ref + snap (pu - m_move_start, false /*move*/); } + move_markers (db::DTrans (p - db::DPoint ()) * db::DTrans (m_move_trans.fp_trans ()) * db::DTrans (db::DPoint () - ref)); + } + m_alt_ac = lay::AC_Global; } @@ -579,15 +584,20 @@ void Service::move_transform (const db::DPoint &pu, db::DFTrans tr, lay::angle_constraint_type ac) { m_alt_ac = ac; + if (view ()->is_editable () && m_moving) { + db::DPoint ref = snap (m_move_start); bool snapped = false; db::DPoint p = ref + snap_marker_to_grid (pu - m_move_start, snapped); if (! snapped) { p = ref + snap (pu - m_move_start, false /*move*/); } + move_markers (db::DTrans (p - db::DPoint ()) * db::DTrans (tr * m_move_trans.fp_trans ()) * db::DTrans (db::DPoint () - ref)); + } + m_alt_ac = lay::AC_Global; } @@ -1701,16 +1711,11 @@ Service::select (const lay::ObjectInstPath &obj, lay::Editable::SelectionMode mo void Service::move_markers (const db::DTrans &t) { - if (m_move_trans != t) { + if (has_selection ()) { + propose_move_transformation (t, 0); + } - // display current move vector - if (has_selection ()) { - std::string pos = std::string ("dx: ") + tl::micron_to_string (t.disp ().x ()) + " dy: " + tl::micron_to_string (t.disp ().y ()); - if (t.rot () != 0) { - pos += std::string (" ") + ((const db::DFTrans &) t).to_string (); - } - view ()->message (pos); - } + if (m_move_trans != t) { for (auto r = m_markers.begin (); r != m_markers.end (); ++r) { diff --git a/src/img/img/imgService.cc b/src/img/img/imgService.cc index 9e27d9449..ce0b06961 100644 --- a/src/img/img/imgService.cc +++ b/src/img/img/imgService.cc @@ -740,6 +740,7 @@ Service::move (const db::DPoint &p, lay::angle_constraint_type ac) m_p1 = p; m_trans = db::DTrans (dp) * m_trans; + propose_move_transformation (m_trans, 2); for (std::vector::iterator r = m_selected_image_views.begin (); r != m_selected_image_views.end (); ++r) { (*r)->transform_by (db::DCplxTrans (m_trans)); diff --git a/src/laybasic/laybasic/layEditable.cc b/src/laybasic/laybasic/layEditable.cc index 60fd18a19..49060757a 100644 --- a/src/laybasic/laybasic/layEditable.cc +++ b/src/laybasic/laybasic/layEditable.cc @@ -47,7 +47,7 @@ struct first_of_pair_cmp_f // Editable implementation Editable::Editable (lay::Editables *editables) - : mp_editables (editables) + : mp_editables (editables), m_move_transformation_priority (-1) { if (editables) { editables->m_editables.push_back (this); @@ -75,6 +75,20 @@ Editable::~Editable () } } +void +Editable::reset_proposed_move_transformation () +{ + m_move_transformation = db::DTrans (); + m_move_transformation_priority = -1; +} + +void +Editable::propose_move_transformation (const db::DTrans &t, unsigned int priority) +{ + m_move_transformation = t; + m_move_transformation_priority = priority; +} + // ---------------------------------------------------------------- // Editables implementation @@ -490,6 +504,9 @@ Editables::begin_move (const db::DPoint &p, lay::angle_constraint_type ac) cancel_edits (); clear_previous_selection (); + m_move_start = p; + m_move_transform = db::DFTrans (); + m_move_selection = false; m_any_move_operation = false; @@ -567,19 +584,38 @@ Editables::begin_move (const db::DPoint &p, lay::angle_constraint_type ac) } } -void +std::pair Editables::move (const db::DPoint &p, lay::angle_constraint_type ac) { + int move_transformation_priority = -1; + db::DTrans move_transformation (p - m_move_start); + move_transformation *= db::DTrans (m_move_transform); + m_any_move_operation = true; + for (iterator e = begin (); e != end (); ++e) { + + e->reset_proposed_move_transformation (); + e->move (p, ac); + + auto pmv = e->proposed_move_transformation (); + if (move_transformation_priority < 0 || (pmv.first >= 0 && pmv.first <= move_transformation_priority)) { + move_transformation_priority = pmv.first; + move_transformation = pmv.second; + } + } + + return std::make_pair (move_transformation_priority, move_transformation); } void Editables::move_transform (const db::DPoint &p, db::DFTrans t, lay::angle_constraint_type ac) { m_any_move_operation = true; + m_move_transform *= t; + for (iterator e = begin (); e != end (); ++e) { e->move_transform (p, t, ac); } diff --git a/src/laybasic/laybasic/layEditable.h b/src/laybasic/laybasic/layEditable.h index cb696600c..9722e2ff3 100644 --- a/src/laybasic/laybasic/layEditable.h +++ b/src/laybasic/laybasic/layEditable.h @@ -405,13 +405,48 @@ public: } protected: + friend class lay::Editables; + Editables *editables () { return mp_editables; } + /** + * @brief Resets the proposed move transformation + * + * You should not need to call this method from an Editable implementation. + */ + void reset_proposed_move_transformation (); + + /** + * @brief Proposes a move transformation + * + * On "move", the Editable can propose an actual move transformation that + * may differ from the actual move distance due to implementation-specific + * snapping. + * + * This method proposes a move transformation with a given priority. The + * Editable with the lowest priority value wins. + */ + void propose_move_transformation (const db::DTrans &mv, unsigned int priority); + + /** + * @brief Gets the proposed move transformation and priority + * + * @return A pair with (priority, transformation) + * + * The returned priority is negative if not priority was set. + */ + std::pair proposed_move_transformation () const + { + return std::make_pair (m_move_transformation_priority, m_move_transformation); + } + private: Editables *mp_editables; + int m_move_transformation_priority; + db::DTrans m_move_transformation; }; /** @@ -551,8 +586,16 @@ public: /** * @brief Continue "move" operation + * + * The return value is the "proposed move transformation", i.e. a representative + * one used for the actual move. As every interface may decide about the + * actual move transformation (due to specific snapping to objects etc.), the + * return value many be ambiguous and should be used for information purposes + * only. + * + * @return A pair (priority, transformation) where priority is negative if no vector was proposed */ - void move (const db::DPoint &p, lay::angle_constraint_type ac); + std::pair move (const db::DPoint &p, lay::angle_constraint_type ac); /** * @brief Transform during a move operation @@ -678,6 +721,8 @@ private: tl::shared_collection m_editables; std::set m_enabled; + db::DPoint m_move_start; + db::DFTrans m_move_transform; bool m_move_selection; bool m_any_move_operation; db::DBox m_last_selected_point; diff --git a/src/laybasic/laybasic/layMove.cc b/src/laybasic/laybasic/layMove.cc index ae677b3ff..08310c798 100644 --- a/src/laybasic/laybasic/layMove.cc +++ b/src/laybasic/laybasic/layMove.cc @@ -180,7 +180,26 @@ MoveService::mouse_move_event (const db::DPoint &p, unsigned int buttons, bool p if (m_dragging) { set_cursor (lay::Cursor::size_all); - mp_editables->move (p, ac_from_buttons (buttons)); + auto pmv = mp_editables->move (p, ac_from_buttons (buttons)); + + // display the proposed move transformation + if (pmv.first >= 0) { + + std::string pos = std::string ("dx: ") + tl::micron_to_string (pmv.second.disp ().x ()) + " dy: " + tl::micron_to_string (pmv.second.disp ().y ()); + if (pmv.second.rot () != 0) { + pos += std::string (" ") + ((const db::DFTrans &) pmv.second).to_string (); + } + mp_view->message (pos); + + lay::EditorOptionsPage *toolbox_widget = 0; + if (mp_view->editor_options_pages ()) { + toolbox_widget = mp_view->editor_options_pages ()->page_with_name (move_editor_options_name); + } + if (toolbox_widget) { + toolbox_widget->configure (move_distance_setter_name, pmv.second.disp ().to_string ()); + } + + } } else if (prio) { @@ -477,6 +496,23 @@ public: } } + virtual void configure (const std::string &name, const std::string &value) + { + if (name == move_distance_setter_name && ! mp_x_le->hasFocus () && ! mp_y_le->hasFocus ()) { + + try { + + db::DVector mv; + tl::from_string (value, mv); + + mp_x_le->setText (tl::to_qstring (tl::to_string (mv.x ()))); + mp_y_le->setText (tl::to_qstring (tl::to_string (mv.y ()))); + + } catch (...) { + } + } + } + virtual void cancel () { tl::info << "@@@ Escape!";