Refactoring, displaying move vector also in partial mode

This commit is contained in:
Matthias Koefferlein 2026-01-15 13:34:52 +01:00
parent 9fe22869ed
commit 900ac4bc0f
15 changed files with 85 additions and 129 deletions

View File

@ -26,6 +26,7 @@
#include "laySnap.h"
#include "layFinder.h"
#include "layConverters.h"
#include "layMove.h"
#include "tlProgress.h"
#include "edtPartialService.h"
#include "edtService.h"
@ -1096,7 +1097,7 @@ PartialService::PartialService (db::Manager *manager, lay::LayoutViewBase *view,
db::Object (manager),
mp_view (view),
mp_root (root),
m_dragging (false),
m_moving (false),
m_keep_selection (true),
mp_box (0),
m_color (0),
@ -1760,7 +1761,7 @@ void
PartialService::edit_cancel ()
{
// stop dragging, clear selection
m_dragging = false;
m_moving = false;
if (mp_box) {
delete mp_box;
@ -1853,24 +1854,13 @@ PartialService::move_impl (const db::DPoint &p)
selection_to_view ();
}
bool
bool
PartialService::mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio)
{
clear_mouse_cursors ();
if (m_moving) {
if (m_dragging) {
set_cursor (lay::Cursor::size_all);
m_alt_ac = lay::ac_from_buttons (buttons);
move_impl (p);
call_editor_hooks (m_editor_hooks, &edt::EditorHooks::begin_edits);
issue_editor_hook_calls (m_editor_hooks);
call_editor_hooks (m_editor_hooks, &edt::EditorHooks::end_edits);
m_alt_ac = lay::AC_Global;
// event is handled by the move service
return false;
} else if (prio) {
@ -1929,9 +1919,9 @@ PartialService::mouse_press_event (const db::DPoint &p, unsigned int buttons, bo
return false;
}
if (m_dragging) {
if (m_moving) {
// eat events if already dragging
// eat events if moving -> handled by move service
return true;
} else if (! mp_box) {
@ -1977,25 +1967,8 @@ PartialService::mouse_press_event (const db::DPoint &p, unsigned int buttons, bo
} else {
// something was selected: start dragging this ..
m_dragging = true;
m_keep_selection = true;
if (is_single_point_selection ()) {
// for a single selected point we use the original point as the start location which
// allows bringing it to grid
m_current = m_start = single_selected_point ();
} else if (is_single_edge_selection ()) {
// for an edge selection use the point projected to edge as the start location which
// allows bringing it to grid
m_current = m_start = projected_to_edge (single_selected_edge (), p);
} else {
m_current = m_start = p;
}
ui ()->grab_mouse (this, true);
open_editor_hooks ();
// delegate further actions to move service, which will start a move operation
mp_view->move_service ()->start_move ();
}
@ -2027,41 +2000,9 @@ PartialService::mouse_click_event (const db::DPoint &p, unsigned int buttons, bo
return false;
}
if (m_dragging) {
if (m_moving) {
m_alt_ac = lay::ac_from_buttons (buttons);
if (m_current != m_start) {
// stop dragging
ui ()->ungrab_mouse (this);
if (manager ()) {
manager ()->transaction (tl::to_string (tr ("Partial move")));
}
db::DTrans move_trans = db::DTrans (m_current - m_start);
transform_selection (move_trans);
if (manager ()) {
manager ()->commit ();
}
}
if (! m_keep_selection) {
m_selection.clear ();
}
m_dragging = false;
selection_to_view ();
close_editor_hooks (true);
m_alt_ac = lay::AC_Global;
return true;
return false;
} else if (ui ()->mouse_event_viewport ().contains (p)) {
@ -2154,26 +2095,16 @@ PartialService::mouse_click_event (const db::DPoint &p, unsigned int buttons, bo
}
// start dragging with that single selection
// start dragging with the selection
if (mode == lay::Editable::Replace && ! m_selection.empty ()) {
m_dragging = true;
// delegate further actions to move service, which will start a move operation
mp_view->move_service ()->start_move ();
// modify the decision to keep the selection (needs to come after the
// move service called begin_move)
m_keep_selection = ! new_selection;
if (is_single_point_selection ()) {
// for a single selected point we use the original point as the start location which
// allows bringing it to grid
m_current = m_start = single_selected_point ();
} else if (is_single_edge_selection ()) {
// for an edge selection use the point projected to edge as the start location which
// allows bringing it to grid
m_current = m_start = projected_to_edge (single_selected_edge (), p);
} else {
m_current = m_start = p;
}
open_editor_hooks ();
}
selection_to_view ();
@ -2208,10 +2139,6 @@ PartialService::mouse_double_click_event (const db::DPoint &p, unsigned int butt
close_editor_hooks (false);
// stop dragging
ui ()->ungrab_mouse (this);
m_dragging = false;
partial_select (db::DBox (p, p), lay::Editable::Replace);
if (! m_selection.empty ()) {
@ -2363,7 +2290,7 @@ PartialService::begin_move (MoveMode mode, const db::DPoint &p, lay::angle_const
m_alt_ac = ac;
m_dragging = true;
m_moving = true;
m_keep_selection = true;
if (is_single_point_selection ()) {
@ -2463,7 +2390,7 @@ PartialService::snap_move (const db::DVector &v) const
void
PartialService::move (const db::DPoint &p, lay::angle_constraint_type ac)
{
if (! m_dragging) {
if (! m_moving) {
return;
}
@ -2489,15 +2416,12 @@ PartialService::end_move (const db::DVector &v)
void
PartialService::end_move (const db::DPoint & /*p*/, lay::angle_constraint_type /*ac*/)
{
if (! m_dragging) {
if (! m_moving) {
return;
}
if (m_current != m_start) {
// stop dragging
ui ()->ungrab_mouse (this);
if (manager ()) {
manager ()->transaction (tl::to_string (tr ("Partial move")));
}
@ -2516,7 +2440,7 @@ PartialService::end_move (const db::DPoint & /*p*/, lay::angle_constraint_type /
m_selection.clear ();
}
m_dragging = false;
m_moving = false;
selection_to_view ();
clear_mouse_cursors ();
@ -2602,9 +2526,6 @@ PartialService::del ()
{
std::set<db::Layout *> needs_cleanup;
// stop dragging
ui ()->ungrab_mouse (this);
std::map <std::pair <db::cell_index_type, std::pair <unsigned int, unsigned int> >, std::vector <partial_objects::const_iterator> > shapes_to_delete_by_cell;
for (partial_objects::iterator r = m_selection.begin (); r != m_selection.end (); ++r) {
@ -2697,7 +2618,6 @@ PartialService::del ()
handle_guiding_shape_changes ();
m_selection.clear ();
m_dragging = false;
selection_to_view ();
close_editor_hooks (false);
@ -3002,15 +2922,8 @@ PartialService::do_selection_to_view ()
{
// if dragging, establish the current displacement
db::DTrans move_trans;
if (m_dragging) {
if (m_moving) {
move_trans = db::DTrans (m_current - m_start);
// display vector
view ()->message (std::string ("dx: ") + tl::micron_to_string (move_trans.disp ().x ()) +
std::string (" dy: ") + tl::micron_to_string (move_trans.disp ().y ()) +
std::string (" d: ") + tl::micron_to_string (move_trans.disp ().length ()));
}
size_t n_marker = 0;
@ -3052,7 +2965,7 @@ PartialService::do_selection_to_view ()
std::map <EdgeWithIndex, db::Edge> new_edges;
std::map <PointWithIndex, db::Point> new_points;
if (m_dragging) {
if (m_moving) {
create_shift_sets (r->first.shape (), r->second, new_points, new_edges, move_vector);
}

View File

@ -340,7 +340,7 @@ private:
// The layout view that this service is attached to
lay::LayoutViewBase *mp_view;
lay::Dispatcher *mp_root;
bool m_dragging;
bool m_moving;
bool m_keep_selection;
db::DPoint m_start, m_current;
db::DPoint m_p1, m_p2;

View File

@ -72,11 +72,11 @@ EditorOptionsPage::show ()
return -1;
} else if (m_toolbox_widget) {
set_focus ();
return -1;
return 1;
} else if (mp_owner) {
if (! is_modal_page ()) {
mp_owner->make_page_current (this);
return -1;
return 1;
} else {
return mp_owner->exec_modal (this) ? 1 : 0;
}

View File

@ -372,8 +372,7 @@ bool
EditorServiceBase::key_event (unsigned int key, unsigned int /*buttons*/)
{
if (is_active () && (key == lay::KeyTab || key == lay::KeyBacktab)) {
focus_page_open ();
return true;
return focus_page_open () >= 0;
} else {
return false;
}
@ -393,7 +392,7 @@ int
EditorServiceBase::focus_page_open ()
{
auto fp = focus_page ();
return fp ? fp->show () : 0;
return fp ? fp->show () : -1;
}
void

View File

@ -33,6 +33,7 @@
#include "layLayoutCanvas.h"
#include "layRedrawThread.h"
#include "layLayoutViewBase.h"
#include "layEditorOptionsPage.h"
#include "layMarker.h"
#if defined(HAVE_QT)
# include "gtf.h"
@ -238,7 +239,12 @@ LayoutCanvas::init_ui (QWidget *parent)
void
LayoutCanvas::key_event (unsigned int key, unsigned int buttons)
{
if (! (buttons & lay::ShiftButton)) {
if (int (key) == lay::KeyTab || int (key) == lay::KeyBacktab) {
auto page = first_toolbox_widget ();
if (page) {
page->set_focus ();
}
} else if (! (buttons & lay::ShiftButton)) {
if (int (key) == lay::KeyDown) {
down_arrow_key_pressed ();
} else if (int (key) == lay::KeyUp) {
@ -261,6 +267,33 @@ LayoutCanvas::key_event (unsigned int key, unsigned int buttons)
}
}
bool
LayoutCanvas::shortcut_override_event (unsigned int key, unsigned int /*buttons*/)
{
if (int (key) == lay::KeyTab || int (key) == lay::KeyBacktab) {
return first_toolbox_widget () != 0;
} else {
return false;
}
}
lay::EditorOptionsPage *
LayoutCanvas::first_toolbox_widget ()
{
auto pages = mp_view->editor_options_pages ();
if (! pages) {
return 0;
}
auto pv = pages->editor_options_pages ();
for (auto p = pv.begin (); p != pv.end (); ++p) {
if ((*p)->is_toolbox_widget () && (*p)->is_visible ()) {
return *p;
}
}
return 0;
}
void
LayoutCanvas::set_image_cache_size (size_t sz)
{

View File

@ -50,6 +50,7 @@ namespace lay
class LayoutViewBase;
class RedrawThread;
class EditorOptionsPage;
/**
* @brief A class representing one entry in the image cache
@ -459,7 +460,10 @@ private:
tl::Mutex m_mutex;
virtual void key_event (unsigned int key, unsigned int buttons);
virtual bool shortcut_override_event (unsigned int key, unsigned int buttons);
virtual void resize_event (unsigned int width, unsigned int height);
lay::EditorOptionsPage *first_toolbox_widget ();
#if defined(HAVE_QT)
virtual void gtf_probe ();
virtual void paint_event ();

View File

@ -4169,7 +4169,7 @@ LayoutViewBase::cancel_edits ()
// the move service takes a special role here as it manages the
// transaction for the collective move operation.
if (mp_move_service) {
mp_move_service->cancel ();
mp_move_service->cancel_transaction ();
}
// cancel all drag and pending edit operations such as move operations.
@ -4186,7 +4186,7 @@ LayoutViewBase::finish_edits ()
// the move service takes a special role here as it manages the
// transaction for the collective move operation.
if (mp_move_service) {
mp_move_service->finish ();
mp_move_service->finish_transaction ();
}
// cancel all drag operations

View File

@ -425,7 +425,7 @@ MoveService::drag_cancel ()
}
void
MoveService::cancel ()
MoveService::cancel_transaction ()
{
if (m_dragging) {
if (mp_transaction.get ()) {
@ -436,7 +436,7 @@ MoveService::cancel ()
}
void
MoveService::finish ()
MoveService::finish_transaction ()
{
if (m_dragging) {
mp_transaction.reset (0);

View File

@ -48,8 +48,8 @@ public:
bool configure (const std::string &name, const std::string &value);
void function (const std::string &name, const std::string &value);
void finish ();
void cancel ();
void finish_transaction ();
void cancel_transaction ();
private:
virtual bool mouse_press_event (const db::DPoint &p, unsigned int buttons, bool prio);

View File

@ -711,7 +711,7 @@ ViewObjectUI::send_shortcut_override_event(unsigned int key, unsigned int button
}
if (! done) {
key_event (key, buttons);
done = shortcut_override_event (key, buttons);
}
return done;

View File

@ -852,6 +852,14 @@ public:
*/
virtual void key_event (unsigned int /*key*/, unsigned int /*buttons*/) { }
/**
* @brief Handler for remaining shortcut override events
*
* This event handler is called if no ViewObject requested handling
* of this event.
*/
virtual bool shortcut_override_event (unsigned int /*key*/, unsigned int /*buttons*/) { return false; }
#if defined(HAVE_QT)
/**
* @brief The drag enter event

View File

@ -91,7 +91,6 @@ SOURCES += \
layUtils.cc \
HEADERS += \
gsiDeclLayPlugin.h \
layEditorOptionsPage.h \
layEditorUtils.h \
layMargin.h \

View File

@ -47,7 +47,6 @@ MoveEditorOptionsPage::MoveEditorOptionsPage (lay::LayoutViewBase *view, lay::Di
hide ();
set_focus_page (true);
set_toolbox_widget (true);
set_transparent (true);
}
@ -112,6 +111,6 @@ MoveEditorOptionsPage::configure (const std::string &name, const std::string &va
}
// registers the factory for the move editor options page
static tl::RegisteredClass<lay::EditorOptionsPageFactoryBase> s_factory (new lay::EditorOptionsPageFactory<MoveEditorOptionsPage> ("laybasic::MoveServicePlugin"), 0);
static tl::RegisteredClass<lay::EditorOptionsPageFactoryBase> s_factory (new lay::EditorOptionsPageFactory<MoveEditorOptionsPage> (), 0);
}

View File

@ -16,6 +16,7 @@ SOURCES = \
layviewForceLink.cc \
HEADERS = \
gsiDeclLayPlugin.h \
layGridNet.h \
layLayoutView.h \
layviewForceLink.h \