From 340c1ef6e9e08ec0669c181efbf80524a5af1777 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 30 Aug 2025 18:39:41 +0200 Subject: [PATCH] Some refactoring, editor options are shown more consistently now Specifically, in move mode, now the editor options are shown too. This makes sense as some of these options there are also effective in move mode. --- src/lay/lay/layMainWindow.cc | 49 ++++++++++-------- src/lay/lay/layMainWindow.h | 1 + .../laybasic/layEditorOptionsPages.cc | 18 +++++-- src/laybasic/laybasic/layEditorOptionsPages.h | 1 + src/laybasic/laybasic/layLayoutViewBase.cc | 51 ++++++++----------- src/laybasic/laybasic/layMouseTracker.cc | 30 ++++++++++- src/laybasic/laybasic/layMouseTracker.h | 3 +- src/laybasic/laybasic/layMove.cc | 22 +++++++- src/laybasic/laybasic/layMove.h | 5 +- src/laybasic/laybasic/layPlugin.cc | 6 +++ src/laybasic/laybasic/layPlugin.h | 17 +++++++ src/laybasic/laybasic/laySelector.cc | 26 ++++++++++ src/laybasic/laybasic/laySelector.h | 4 +- src/laybasic/laybasic/layZoomBox.cc | 27 +++++++++- src/laybasic/laybasic/layZoomBox.h | 3 +- src/layview/layview/layGridNet.cc | 2 +- src/layview/layview/layLayoutView_qt.cc | 13 +---- src/layview/unit_tests/layLayoutViewTests.cc | 36 +++++++++++++ 18 files changed, 238 insertions(+), 76 deletions(-) diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index 11f9d9f55..72430e410 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -1664,32 +1664,38 @@ MainWindow::select_mode (int m) } } - // if the current mode supports editing, show the editor options panel + update_editor_options_dock (); - const lay::PluginDeclaration *pd_sel = 0; - for (tl::Registrar::iterator cls = tl::Registrar::begin (); cls != tl::Registrar::end (); ++cls) { - const lay::PluginDeclaration *pd = cls.operator-> (); - if (pd->id () == m_mode) { - pd_sel = pd; - } - } + } +} - bool eo_visible = false; - if (mp_eo_stack && pd_sel) { - eo_visible = pd_sel->editable_enabled (); - } - if (current_view () && eo_visible) { - lay::EditorOptionsPages *eo_pages = current_view ()->editor_options_pages (); - if (! eo_pages || ! eo_pages->has_content ()) { - eo_visible = false; - } - } +void +MainWindow::update_editor_options_dock () +{ + // if the current mode supports editing, show the editor options panel - if (eo_visible != m_eo_visible) { - m_eo_visible = eo_visible; - show_dock_widget (mp_eo_dock_widget, m_eo_visible); + const lay::PluginDeclaration *pd_sel = 0; + for (tl::Registrar::iterator cls = tl::Registrar::begin (); cls != tl::Registrar::end (); ++cls) { + const lay::PluginDeclaration *pd = cls.operator-> (); + if (pd->id () == m_mode) { + pd_sel = pd; } + } + bool eo_visible = false; + if (mp_eo_stack && pd_sel) { + eo_visible = pd_sel->editable_enabled (); + } + if (current_view () && eo_visible) { + lay::EditorOptionsPages *eo_pages = current_view ()->editor_options_pages (); + if (! eo_pages || ! eo_pages->has_content ()) { + eo_visible = false; + } + } + + if (eo_visible != m_eo_visible) { + m_eo_visible = eo_visible; + show_dock_widget (mp_eo_dock_widget, m_eo_visible); } } @@ -2439,6 +2445,7 @@ MainWindow::select_view (int index) current_view_changed (); + update_editor_options_dock (); clear_current_pos (); edits_enabled_changed (); clear_message (); diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h index 1f6fc2f69..56c3dd597 100644 --- a/src/lay/lay/layMainWindow.h +++ b/src/lay/lay/layMainWindow.h @@ -857,6 +857,7 @@ private: void interactive_close_view (int from, int to, bool invert_range, bool all_cellviews); void call_on_current_view (void (lay::LayoutView::*func) (), const std::string &op_desc); void current_view_changed (); + void update_editor_options_dock (); void update_window_title (); void update_tab_title (int i); void add_view (LayoutViewWidget *view); diff --git a/src/laybasic/laybasic/layEditorOptionsPages.cc b/src/laybasic/laybasic/layEditorOptionsPages.cc index 9daad1b5a..eefe25ee9 100644 --- a/src/laybasic/laybasic/layEditorOptionsPages.cc +++ b/src/laybasic/laybasic/layEditorOptionsPages.cc @@ -81,20 +81,32 @@ EditorOptionsPages::focusInEvent (QFocusEvent * /*event*/) // Sends the focus to the current page's last focus owner if (mp_pages->currentWidget () && mp_pages->currentWidget ()->focusWidget ()) { mp_pages->currentWidget ()->focusWidget ()->setFocus (); - } + } } bool EditorOptionsPages::has_content () const { for (std::vector ::const_iterator p = m_pages.begin (); p != m_pages.end (); ++p) { - // NOTE: we ignore unspecific pages because they are always visible and don't contribute specific content - if ((*p)->active () && (*p)->plugin_declaration () != 0) { + if ((*p)->active ()) { return true; } } return false; } +void EditorOptionsPages::activate (const lay::Plugin *plugin) +{ + for (auto op = m_pages.begin (); op != m_pages.end (); ++op) { + bool is_active = false; + if ((*op)->plugin_declaration () == 0) { + is_active = (plugin && plugin->plugin_declaration ()->enable_catchall_editor_options_pages ()); + } else if (plugin && plugin->plugin_declaration () == (*op)->plugin_declaration ()) { + is_active = true; + } + (*op)->activate (is_active); + } +} + void EditorOptionsPages::unregister_page (lay::EditorOptionsPage *page) { diff --git a/src/laybasic/laybasic/layEditorOptionsPages.h b/src/laybasic/laybasic/layEditorOptionsPages.h index 1cd66753c..dd4e1b15c 100644 --- a/src/laybasic/laybasic/layEditorOptionsPages.h +++ b/src/laybasic/laybasic/layEditorOptionsPages.h @@ -58,6 +58,7 @@ public: void unregister_page (lay::EditorOptionsPage *page); void activate_page (lay::EditorOptionsPage *page); + void activate (const lay::Plugin *plugin); void focusInEvent (QFocusEvent *event); const std::vector &pages () const diff --git a/src/laybasic/laybasic/layLayoutViewBase.cc b/src/laybasic/laybasic/layLayoutViewBase.cc index 960e1df97..7320fae7e 100644 --- a/src/laybasic/laybasic/layLayoutViewBase.cc +++ b/src/laybasic/laybasic/layLayoutViewBase.cc @@ -398,21 +398,6 @@ LayoutViewBase::init (db::Manager *mgr) mp_canvas = new lay::LayoutCanvas (this); - // occupy services and editables: - // these services get deleted by the canvas destructor automatically: - if ((m_options & LV_NoTracker) == 0) { - mp_tracker = new lay::MouseTracker (this); - } - if ((m_options & LV_NoZoom) == 0) { - mp_zoom_service = new lay::ZoomService (this); - } - if ((m_options & LV_NoSelection) == 0) { - mp_selection_service = new lay::SelectionService (this); - } - if ((m_options & LV_NoMove) == 0) { - mp_move_service = new lay::MoveService (this); - } - create_plugins (); } @@ -615,10 +600,26 @@ void LayoutViewBase::create_plugins (const lay::PluginDeclaration *except_this) if (current_name == "ant::Plugin" || current_name == "img::Plugin") { // ant and img are created always create_plugin (current); + } else if (current_name == "laybasic::MouseTrackerPlugin") { + if ((m_options & LV_NoTracker) == 0) { + mp_tracker = dynamic_cast (create_plugin (current)); + } + } else if (current_name == "laybasic::MoveServicePlugin") { + if ((m_options & LV_NoMove) == 0) { + mp_move_service = dynamic_cast (create_plugin (current)); + } + } else if (current_name == "laybasic::SelectionServicePlugin") { + if ((m_options & LV_NoSelection) == 0) { + mp_selection_service = dynamic_cast (create_plugin (current)); + } + } else if (current_name == "laybasic::ZoomServicePlugin") { + if ((m_options & LV_NoZoom) == 0) { + mp_zoom_service = dynamic_cast (create_plugin (current)); + } } else if ((options () & LV_NoPlugins) == 0) { // others: only create unless LV_NoPlugins is set create_plugin (current); - } else if ((options () & LV_NoGrid) == 0 && current_name == "GridNetPlugin") { + } else if ((options () & LV_NoGrid) == 0 && current_name == "lay::GridNetPlugin") { // except grid net plugin which is created on request create_plugin (current); } @@ -5790,20 +5791,12 @@ LayoutViewBase::mode (int m) m_mode = m; mp_active_plugin = 0; - if (m > 0) { - - for (std::vector::iterator p = mp_plugins.begin (); p != mp_plugins.end (); ++p) { - if ((*p)->plugin_declaration ()->id () == m) { - mp_active_plugin = *p; - mp_canvas->activate ((*p)->view_service_interface ()); - break; - } + for (std::vector::iterator p = mp_plugins.begin (); p != mp_plugins.end (); ++p) { + if ((*p)->plugin_declaration ()->id () == m) { + mp_active_plugin = *p; + mp_canvas->activate ((*p)->view_service_interface ()); + break; } - - } else if (m == 0 && mp_selection_service) { - mp_canvas->activate (mp_selection_service); - } else if (m == -1 && mp_move_service) { - mp_canvas->activate (mp_move_service); } } diff --git a/src/laybasic/laybasic/layMouseTracker.cc b/src/laybasic/laybasic/layMouseTracker.cc index 981c72c62..11c128299 100644 --- a/src/laybasic/laybasic/layMouseTracker.cc +++ b/src/laybasic/laybasic/layMouseTracker.cc @@ -31,7 +31,7 @@ namespace lay { MouseTracker::MouseTracker (lay::LayoutViewBase *view) - : lay::ViewService (view->canvas ()), mp_view (view), + : lay::ViewService (view->canvas ()), lay::Plugin (view), mp_view (view), m_cursor_color (tl::Color ()), m_cursor_line_style (0), m_cursor_enabled (false) { ui ()->grab_mouse (this, false); @@ -129,5 +129,31 @@ MouseTracker::mouse_move_event (const db::DPoint &p, unsigned int /*buttons*/, b return false; } -} // namespace lay +// ---------------------------------------------------------------------------- +// NOTE: configuration currently is not declared here. +// Same for the configuration pages. + +class MouseTrackerDeclaration + : public lay::PluginDeclaration +{ +public: + MouseTrackerDeclaration () + { + // .. nothing yet .. + } + + virtual lay::Plugin *create_plugin (db::Manager * /*manager*/, lay::Dispatcher * /*dispatcher*/, lay::LayoutViewBase *view) const + { + return new MouseTracker (view); + } + + virtual bool enable_catchall_editor_options_pages () const + { + return false; + } +}; + +static tl::RegisteredClass tracker_decl (new MouseTrackerDeclaration (), -1000, "laybasic::MouseTrackerPlugin"); + +} // namespace lay diff --git a/src/laybasic/laybasic/layMouseTracker.h b/src/laybasic/laybasic/layMouseTracker.h index 554da9be6..7be70a9aa 100644 --- a/src/laybasic/laybasic/layMouseTracker.h +++ b/src/laybasic/laybasic/layMouseTracker.h @@ -26,6 +26,7 @@ #include "layViewObject.h" #include "layMarker.h" +#include "layPlugin.h" #include "tlObject.h" class QMouseEvent; @@ -36,7 +37,7 @@ class LayoutCanvas; class LayoutViewBase; class MouseTracker - : public lay::ViewService + : public lay::ViewService, public lay::Plugin { public: MouseTracker (lay::LayoutViewBase *view); diff --git a/src/laybasic/laybasic/layMove.cc b/src/laybasic/laybasic/layMove.cc index 7675b95c4..35c86188c 100644 --- a/src/laybasic/laybasic/layMove.cc +++ b/src/laybasic/laybasic/layMove.cc @@ -36,6 +36,7 @@ namespace lay MoveService::MoveService (lay::LayoutViewBase *view) : lay::ViewService (view->canvas ()), + lay::Plugin (view), m_dragging (false), m_dragging_transient (false), mp_editables (view), @@ -366,5 +367,24 @@ MoveService::finish () } } -} +// ---------------------------------------------------------------------------- +class MoveServiceDeclaration + : public lay::PluginDeclaration +{ +public: + MoveServiceDeclaration () + : lay::PluginDeclaration (-1) + { + // .. nothing yet .. + } + + virtual lay::Plugin *create_plugin (db::Manager * /*manager*/, lay::Dispatcher * /*dispatcher*/, lay::LayoutViewBase *view) const + { + return new MoveService (view); + } +}; + +static tl::RegisteredClass move_service_decl (new MoveServiceDeclaration (), -970, "laybasic::MoveServicePlugin"); + +} diff --git a/src/laybasic/laybasic/layMove.h b/src/laybasic/laybasic/layMove.h index 589cea374..485bbc199 100644 --- a/src/laybasic/laybasic/layMove.h +++ b/src/laybasic/laybasic/layMove.h @@ -24,8 +24,9 @@ #define HDR_layMove #include "laybasicCommon.h" -#include "dbManager.h" #include "layViewObject.h" +#include "layPlugin.h" +#include "dbManager.h" #include @@ -35,7 +36,7 @@ class Editables; class LayoutViewBase; class LAYBASIC_PUBLIC MoveService : - public lay::ViewService + public lay::ViewService, public lay::Plugin { public: MoveService (lay::LayoutViewBase *view); diff --git a/src/laybasic/laybasic/layPlugin.cc b/src/laybasic/laybasic/layPlugin.cc index f8c995c10..842351536 100644 --- a/src/laybasic/laybasic/layPlugin.cc +++ b/src/laybasic/laybasic/layPlugin.cc @@ -55,6 +55,12 @@ PluginDeclaration::PluginDeclaration () // .. nothing yet .. } +PluginDeclaration::PluginDeclaration (int id) + : m_id (id), m_editable_enabled (true) +{ + // .. nothing yet .. +} + PluginDeclaration::~PluginDeclaration () { if (Dispatcher::instance ()) { diff --git a/src/laybasic/laybasic/layPlugin.h b/src/laybasic/laybasic/layPlugin.h index f334252cd..2d5ee32d4 100644 --- a/src/laybasic/laybasic/layPlugin.h +++ b/src/laybasic/laybasic/layPlugin.h @@ -160,6 +160,11 @@ public: */ PluginDeclaration (); + /** + * @brief Constructor with a fixed ID + */ + PluginDeclaration (int id); + /** * @brief Destructor */ @@ -331,6 +336,18 @@ public: { // .. no pages in the default implementation .. } + + /** + * @brief Gets a value indicating whether "catchall" editor options pages shall be included + * + * "catchall" editor options pages are ones that are unspecific and render a null "plugin_declaration". + * A plugin can choose to include these pages if it listens to global configuration events. + * Otherwise it should return false here to suppress these pages. + */ + virtual bool enable_catchall_editor_options_pages () const + { + return true; + } #endif /** diff --git a/src/laybasic/laybasic/laySelector.cc b/src/laybasic/laybasic/laySelector.cc index c3c292d99..8a86a6048 100644 --- a/src/laybasic/laybasic/laySelector.cc +++ b/src/laybasic/laybasic/laySelector.cc @@ -43,6 +43,7 @@ SelectionService::SelectionService (lay::LayoutViewBase *view) : QObject (), #endif lay::ViewService (view->canvas ()), + lay::Plugin (view), mp_view (view), mp_box (0), m_color (0), @@ -317,4 +318,29 @@ SelectionService::begin (const db::DPoint &pos) ui ()->grab_mouse (this, true); } +// ---------------------------------------------------------------------------- + +class SelectionServiceDeclaration + : public lay::PluginDeclaration +{ +public: + SelectionServiceDeclaration () + : lay::PluginDeclaration (0) + { + // .. nothing yet .. + } + + virtual lay::Plugin *create_plugin (db::Manager * /*manager*/, lay::Dispatcher * /*dispatcher*/, lay::LayoutViewBase *view) const + { + return new SelectionService (view); + } + + virtual bool enable_catchall_editor_options_pages () const + { + return false; + } +}; + +static tl::RegisteredClass selection_service_decl (new SelectionServiceDeclaration (), -980, "laybasic::SelectionServicePlugin"); + } diff --git a/src/laybasic/laybasic/laySelector.h b/src/laybasic/laybasic/laySelector.h index b15fe0400..7fd2036f4 100644 --- a/src/laybasic/laybasic/laySelector.h +++ b/src/laybasic/laybasic/laySelector.h @@ -29,6 +29,7 @@ #include "layViewObject.h" #include "layEditable.h" +#include "layPlugin.h" #if defined (HAVE_QT) # include @@ -45,7 +46,8 @@ class LAYBASIC_PUBLIC SelectionService : #if defined (HAVE_QT) public QObject, #endif - public lay::ViewService + public lay::ViewService, + public lay::Plugin { #if defined (HAVE_QT) Q_OBJECT diff --git a/src/laybasic/laybasic/layZoomBox.cc b/src/laybasic/laybasic/layZoomBox.cc index 221849169..064209ee2 100644 --- a/src/laybasic/laybasic/layZoomBox.cc +++ b/src/laybasic/laybasic/layZoomBox.cc @@ -32,7 +32,7 @@ namespace lay // ZoomService implementation ZoomService::ZoomService (lay::LayoutViewBase *view) - : lay::ViewService (view->canvas ()), + : lay::ViewService (view->canvas ()), lay::Plugin (view), mp_view (view), mp_box (0), m_color (0) @@ -282,5 +282,28 @@ ZoomService::begin (const db::DPoint &pos) ui ()->grab_mouse (this, true); } -} +// ---------------------------------------------------------------------------- +class ZoomServiceDeclaration + : public lay::PluginDeclaration +{ +public: + ZoomServiceDeclaration () + { + // .. nothing yet .. + } + + virtual lay::Plugin *create_plugin (db::Manager * /*manager*/, lay::Dispatcher * /*dispatcher*/, lay::LayoutViewBase *view) const + { + return new ZoomService (view); + } + + virtual bool enable_catchall_editor_options_pages () const + { + return false; + } +}; + +static tl::RegisteredClass zoom_service_decl (new ZoomServiceDeclaration (), -990, "laybasic::ZoomServicePlugin"); + +} diff --git a/src/laybasic/laybasic/layZoomBox.h b/src/laybasic/laybasic/layZoomBox.h index 2530eec98..ff2c5e866 100644 --- a/src/laybasic/laybasic/layZoomBox.h +++ b/src/laybasic/laybasic/layZoomBox.h @@ -26,6 +26,7 @@ #define HDR_layZoomBox #include "layViewObject.h" +#include "layPlugin.h" namespace lay { @@ -35,7 +36,7 @@ class LayoutCanvas; class RubberBox; class LAYBASIC_PUBLIC ZoomService - : public lay::ViewService + : public lay::ViewService, public lay::Plugin { public: ZoomService (lay::LayoutViewBase *view); diff --git a/src/layview/layview/layGridNet.cc b/src/layview/layview/layGridNet.cc index 92fc3b6ab..c6ecb634c 100644 --- a/src/layview/layview/layGridNet.cc +++ b/src/layview/layview/layGridNet.cc @@ -129,7 +129,7 @@ GridNetPluginDeclaration::create_plugin (db::Manager *, Dispatcher *, lay::Layou return new lay::GridNet (view); } -static tl::RegisteredClass config_decl (new GridNetPluginDeclaration (), 2010, "GridNetPlugin"); +static tl::RegisteredClass config_decl (new GridNetPluginDeclaration (), 2010, "lay::GridNetPlugin"); // ------------------------------------------------------------ // Implementation of the GridNet object diff --git a/src/layview/layview/layLayoutView_qt.cc b/src/layview/layview/layLayoutView_qt.cc index d361b4601..692ca8e2b 100644 --- a/src/layview/layview/layLayoutView_qt.cc +++ b/src/layview/layview/layLayoutView_qt.cc @@ -1591,18 +1591,7 @@ LayoutView::activate_editor_option_pages () { lay::EditorOptionsPages *eo_pages = editor_options_pages (); if (eo_pages) { - - // TODO: this is very inefficient as each "activate" will regenerate the tabs - for (std::vector::const_iterator op = eo_pages->pages ().begin (); op != eo_pages->pages ().end (); ++op) { - bool is_active = false; - if ((*op)->plugin_declaration () == 0) { - is_active = true; - } else if (active_plugin () && active_plugin ()->plugin_declaration () == (*op)->plugin_declaration ()) { - is_active = true; - } - (*op)->activate (is_active); - } - + eo_pages->activate (active_plugin ()); } } diff --git a/src/layview/unit_tests/layLayoutViewTests.cc b/src/layview/unit_tests/layLayoutViewTests.cc index 4cdf3b498..64b7b0cc0 100644 --- a/src/layview/unit_tests/layLayoutViewTests.cc +++ b/src/layview/unit_tests/layLayoutViewTests.cc @@ -173,6 +173,42 @@ TEST(4) EXPECT_EQ ((int) img.height (), 217); } +// options +TEST(5) +{ + std::unique_ptr lv; + + lv.reset (new lay::LayoutView (0, false, 0)); + EXPECT_EQ (lv->mouse_tracker () == 0, false); + EXPECT_EQ (lv->zoom_service () == 0, false); + EXPECT_EQ (lv->move_service () == 0, false); + EXPECT_EQ (lv->selection_service () == 0, false); + + lv.reset (new lay::LayoutView (0, false, 0, lay::LayoutView::LV_NoMove)); + EXPECT_EQ (lv->mouse_tracker () == 0, false); + EXPECT_EQ (lv->zoom_service () == 0, false); + EXPECT_EQ (lv->move_service () == 0, true); + EXPECT_EQ (lv->selection_service () == 0, false); + + lv.reset (new lay::LayoutView (0, false, 0, lay::LayoutView::LV_NoTracker)); + EXPECT_EQ (lv->mouse_tracker () == 0, true); + EXPECT_EQ (lv->zoom_service () == 0, false); + EXPECT_EQ (lv->move_service () == 0, false); + EXPECT_EQ (lv->selection_service () == 0, false); + + lv.reset (new lay::LayoutView (0, false, 0, lay::LayoutView::LV_NoZoom)); + EXPECT_EQ (lv->mouse_tracker () == 0, false); + EXPECT_EQ (lv->zoom_service () == 0, true); + EXPECT_EQ (lv->move_service () == 0, false); + EXPECT_EQ (lv->selection_service () == 0, false); + + lv.reset (new lay::LayoutView (0, false, 0, lay::LayoutView::LV_NoSelection)); + EXPECT_EQ (lv->mouse_tracker () == 0, false); + EXPECT_EQ (lv->zoom_service () == 0, false); + EXPECT_EQ (lv->move_service () == 0, false); + EXPECT_EQ (lv->selection_service () == 0, true); +} + #if defined(HAVE_PNG) TEST(11) {