This commit is contained in:
Matthias Koefferlein
2026-01-13 12:54:10 +01:00
parent cabcde3bf5
commit ee622fc104
7 changed files with 144 additions and 14 deletions
+38 -2
View File
@@ -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<int, db::DTrans>
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);
}
+46 -1
View File
@@ -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<int, db::DTrans> 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<int, db::DTrans> move (const db::DPoint &p, lay::angle_constraint_type ac);
/**
* @brief Transform during a move operation
@@ -678,6 +721,8 @@ private:
tl::shared_collection<lay::Editable> m_editables;
std::set<lay::Editable *> 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;
+37 -1
View File
@@ -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!";