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) {