From 6a23769387ee77723b3bb18867549b7c13c48305 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 26 Jan 2021 07:56:49 +0100 Subject: [PATCH] Different integration of Dispatcher interface with MainWindow In 0.27 the main window got it's own configuration API as now it's possible to instantiate a main window explicitly and not application backs up configuration. Because GSI allows as single base class only, we cannot derive from Dispatcher. A delegate is used instead. --- src/gsi/gsi/gsiCallback.h | 50 ++++++--- src/gsi/gsi/gsiCallbackVar.h | 17 ++-- src/lay/lay/gsiDeclLayMainWindow.cc | 82 ++++++++++++++- src/lay/lay/layApplication.cc | 8 +- src/lay/lay/layMainWindow.cc | 27 ++--- src/lay/lay/layMainWindow.h | 21 +++- src/lay/lay/layNavigator.cc | 4 +- src/laybasic/laybasic/gsiDeclLayPlugin.cc | 60 ++++++++--- src/laybasic/laybasic/layDispatcher.cc | 31 +++++- src/laybasic/laybasic/layDispatcher.h | 118 ++++++++++++++++++++-- src/laybasic/laybasic/layLayoutView.cc | 6 +- src/laybasic/laybasic/layLayoutView.h | 3 - 12 files changed, 348 insertions(+), 79 deletions(-) diff --git a/src/gsi/gsi/gsiCallback.h b/src/gsi/gsi/gsiCallback.h index 7cfc693ef..42536c4c8 100644 --- a/src/gsi/gsi/gsiCallback.h +++ b/src/gsi/gsi/gsiCallback.h @@ -80,6 +80,7 @@ struct Callback #define _TMPLARGPART #define _FUNCARGLIST +#define _COMMA #define _CALLARGLIST #define _CALLARGS #define _SETVALUE @@ -87,6 +88,7 @@ struct Callback #include "gsiCallbackVar.h" #undef _SETVALUE +#undef _COMMA #undef _CALLARGLIST #undef _CALLARGS #undef _FUNCARGLIST @@ -94,15 +96,17 @@ struct Callback // 1 argument -#define _TMPLARGPART , class A1 +#define _TMPLARGPART class A1 #define _FUNCARGLIST A1 -#define _CALLARGLIST , A1 a1 +#define _COMMA , +#define _CALLARGLIST A1 a1 #define _CALLARGS a1 #define _SETVALUE args.write (a1); \ #include "gsiCallbackVar.h" #undef _SETVALUE +#undef _COMMA #undef _CALLARGS #undef _CALLARGLIST #undef _FUNCARGLIST @@ -110,9 +114,10 @@ struct Callback // 2 arguments -#define _TMPLARGPART , class A1, class A2 +#define _TMPLARGPART class A1, class A2 #define _FUNCARGLIST A1, A2 -#define _CALLARGLIST , A1 a1, A2 a2 +#define _COMMA , +#define _CALLARGLIST A1 a1, A2 a2 #define _CALLARGS a1, a2 #define _SETVALUE args.write (a1); \ args.write (a2); \ @@ -120,6 +125,7 @@ struct Callback #include "gsiCallbackVar.h" #undef _SETVALUE +#undef _COMMA #undef _CALLARGS #undef _CALLARGLIST #undef _FUNCARGLIST @@ -127,9 +133,10 @@ struct Callback // 3 arguments -#define _TMPLARGPART , class A1, class A2, class A3 +#define _TMPLARGPART class A1, class A2, class A3 #define _FUNCARGLIST A1, A2, A3 -#define _CALLARGLIST , A1 a1, A2 a2, A3 a3 +#define _COMMA , +#define _CALLARGLIST A1 a1, A2 a2, A3 a3 #define _CALLARGS a1, a2, a3 #define _SETVALUE args.write (a1); \ args.write (a2); \ @@ -138,6 +145,7 @@ struct Callback #include "gsiCallbackVar.h" #undef _SETVALUE +#undef _COMMA #undef _CALLARGS #undef _CALLARGLIST #undef _FUNCARGLIST @@ -145,9 +153,10 @@ struct Callback // 4 arguments -#define _TMPLARGPART , class A1, class A2, class A3, class A4 +#define _TMPLARGPART class A1, class A2, class A3, class A4 #define _FUNCARGLIST A1, A2, A3, A4 -#define _CALLARGLIST , A1 a1, A2 a2, A3 a3, A4 a4 +#define _COMMA , +#define _CALLARGLIST A1 a1, A2 a2, A3 a3, A4 a4 #define _CALLARGS a1, a2, a3, a4 #define _SETVALUE args.write (a1); \ args.write (a2); \ @@ -157,6 +166,7 @@ struct Callback #include "gsiCallbackVar.h" #undef _SETVALUE +#undef _COMMA #undef _CALLARGS #undef _CALLARGLIST #undef _FUNCARGLIST @@ -164,9 +174,10 @@ struct Callback // 5 arguments -#define _TMPLARGPART , class A1, class A2, class A3, class A4, class A5 +#define _TMPLARGPART class A1, class A2, class A3, class A4, class A5 #define _FUNCARGLIST A1, A2, A3, A4, A5 -#define _CALLARGLIST , A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 +#define _COMMA , +#define _CALLARGLIST A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 #define _CALLARGS a1, a2, a3, a4, a5 #define _SETVALUE args.write (a1); \ args.write (a2); \ @@ -177,6 +188,7 @@ struct Callback #include "gsiCallbackVar.h" #undef _SETVALUE +#undef _COMMA #undef _CALLARGS #undef _CALLARGLIST #undef _FUNCARGLIST @@ -184,9 +196,10 @@ struct Callback // 6 arguments -#define _TMPLARGPART , class A1, class A2, class A3, class A4, class A5, class A6 +#define _TMPLARGPART class A1, class A2, class A3, class A4, class A5, class A6 #define _FUNCARGLIST A1, A2, A3, A4, A5, A6 -#define _CALLARGLIST , A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 +#define _COMMA , +#define _CALLARGLIST A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 #define _CALLARGS a1, a2, a3, a4, a5, a6 #define _SETVALUE args.write (a1); \ args.write (a2); \ @@ -198,6 +211,7 @@ struct Callback #include "gsiCallbackVar.h" #undef _SETVALUE +#undef _COMMA #undef _CALLARGS #undef _CALLARGLIST #undef _FUNCARGLIST @@ -205,9 +219,10 @@ struct Callback // 7 arguments -#define _TMPLARGPART , class A1, class A2, class A3, class A4, class A5, class A6, class A7 +#define _TMPLARGPART class A1, class A2, class A3, class A4, class A5, class A6, class A7 #define _FUNCARGLIST A1, A2, A3, A4, A5, A6, A7 -#define _CALLARGLIST , A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 +#define _COMMA , +#define _CALLARGLIST A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 #define _CALLARGS a1, a2, a3, a4, a5, a6, a7 #define _SETVALUE args.write (a1); \ args.write (a2); \ @@ -220,6 +235,7 @@ struct Callback #include "gsiCallbackVar.h" #undef _SETVALUE +#undef _COMMA #undef _CALLARGS #undef _CALLARGLIST #undef _FUNCARGLIST @@ -227,9 +243,10 @@ struct Callback // 8 arguments -#define _TMPLARGPART , class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 +#define _TMPLARGPART class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 #define _FUNCARGLIST A1, A2, A3, A4, A5, A6, A7, A8 -#define _CALLARGLIST , A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 +#define _COMMA , +#define _CALLARGLIST A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 #define _CALLARGS a1, a2, a3, a4, a5, a6, a7, a8 #define _SETVALUE args.write (a1); \ args.write (a2); \ @@ -243,6 +260,7 @@ struct Callback #include "gsiCallbackVar.h" #undef _SETVALUE +#undef _COMMA #undef _CALLARGS #undef _CALLARGLIST #undef _FUNCARGLIST diff --git a/src/gsi/gsi/gsiCallbackVar.h b/src/gsi/gsi/gsiCallbackVar.h index 62556fe16..876f5dc9a 100644 --- a/src/gsi/gsi/gsiCallbackVar.h +++ b/src/gsi/gsi/gsiCallbackVar.h @@ -30,24 +30,24 @@ // _CALLARGLIST ", A1 a1" // _SETVALUE "args.template write (a1);" -template -void issue (void (X::*) (_FUNCARGLIST) _CALLARGLIST) const +template +void issue (void (X::*) (_FUNCARGLIST) _COMMA _CALLARGLIST) const { SerialArgs args (argsize), ret (retsize); _SETVALUE call_int (args, ret); } -template -void issue (void (X::*) (_FUNCARGLIST) const _CALLARGLIST) const +template +void issue (void (X::*) (_FUNCARGLIST) const _COMMA _CALLARGLIST) const { SerialArgs args (argsize), ret (retsize); _SETVALUE call_int (args, ret); } -template -R issue (R (X::*) (_FUNCARGLIST) _CALLARGLIST) const +template +R issue (R (X::*) (_FUNCARGLIST) _COMMA _CALLARGLIST) const { tl::Heap heap; SerialArgs args (argsize), ret (retsize); @@ -56,8 +56,8 @@ R issue (R (X::*) (_FUNCARGLIST) _CALLARGLIST) const return ret.template read (heap); } -template -R issue (R (X::*) (_FUNCARGLIST) const _CALLARGLIST) const +template +R issue (R (X::*) (_FUNCARGLIST) const _COMMA _CALLARGLIST) const { tl::Heap heap; SerialArgs args (argsize), ret (retsize); @@ -66,4 +66,3 @@ R issue (R (X::*) (_FUNCARGLIST) const _CALLARGLIST) const return ret.template read (heap); } - diff --git a/src/lay/lay/gsiDeclLayMainWindow.cc b/src/lay/lay/gsiDeclLayMainWindow.cc index 02b512ad8..fc330863b 100644 --- a/src/lay/lay/gsiDeclLayMainWindow.cc +++ b/src/lay/lay/gsiDeclLayMainWindow.cc @@ -189,11 +189,89 @@ gsi::Methods cm_method_decl () // is not the first base class. static lay::AbstractMenu *menu (lay::MainWindow *mw) { - return mw->menu (); + return mw->dispatcher ()->menu (); +} + +static void clear_config (lay::MainWindow *mw) +{ + mw->dispatcher ()->clear_config (); +} + +static bool write_config (lay::MainWindow *mw, const std::string &config_file) +{ + return mw->dispatcher ()->write_config (config_file); +} + +static bool read_config (lay::MainWindow *mw, const std::string &config_file) +{ + return mw->dispatcher ()->read_config (config_file); +} + +static tl::Variant get_config (lay::MainWindow *mw, const std::string &name) +{ + std::string value; + if (mw->dispatcher ()->config_get (name, value)) { + return tl::Variant (value); + } else { + return tl::Variant (); + } +} + +static void set_config (lay::MainWindow *mw, const std::string &name, const std::string &value) +{ + mw->dispatcher ()->config_set (name, value); +} + +static std::vector +get_config_names (lay::MainWindow *mw) +{ + std::vector names; + mw->dispatcher ()->get_config_names (names); + return names; +} + +void +config_end (lay::MainWindow *mw) +{ + mw->dispatcher ()->config_end (); } Class decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "lay", "MainWindow", + // Dispatcher interface and convenience functions + method ("dispatcher", &lay::MainWindow::dispatcher, + "@brief Gets the dispatcher interface (the plugin root configuration space)\n" + "This method has been introduced in version 0.27." + ) + + method_ext ("clear_config", &clear_config, + "@brief Clears the configuration parameters\n" + "Since version 0.27 this is a convenience method which is equivalent to 'dispatcher().clear_config()'. See \\Dispatcher#clear_config for details." + ) + + method_ext ("write_config", &write_config, gsi::arg ("file_name"), + "@brief Writes configuration to a file\n" + "Since version 0.27 this is a convenience method which is equivalent to 'dispatcher().write_config(...)'. See \\Dispatcher#write_config for details." + ) + + method_ext ("read_config", &read_config, gsi::arg ("file_name"), + "@brief Reads the configuration from a file\n" + "Since version 0.27 this is a convenience method which is equivalent to 'dispatcher().read_config(...)'. See \\Dispatcher#read_config for details." + ) + + method_ext ("get_config", &get_config, gsi::arg ("name"), + "@brief Gets the value of a local configuration parameter\n" + "Since version 0.27 this is a convenience method which is equivalent to 'dispatcher().get_config(...)'. See \\Dispatcher#get_config for details." + ) + + method_ext ("set_config", &set_config, gsi::arg ("name"), gsi::arg ("value"), + "@brief Set a local configuration parameter with the given name to the given value\n" + "Since version 0.27 this is a convenience method which is equivalent to 'dispatcher().set_config(...)'. See \\Dispatcher#set_config for details." + ) + + method_ext ("get_config_names", &get_config_names, + "@brief Gets the configuration parameter names\n" + "Since version 0.27 this is a convenience method which is equivalent to 'dispatcher().get_config_names(...)'. See \\Dispatcher#get_config_names for details." + ) + + method_ext ("commit_config", &config_end, + "@brief Commits the configuration settings\n" + "Since version 0.27 this is a convenience method which is equivalent to 'dispatcher().config_end(...)'. See \\Dispatcher#config_end for details." + ) + + // QMainWindow interface gsi::method_ext ("menu", &menu, "@brief Returns a reference to the abstract menu\n" @@ -510,7 +588,7 @@ Class decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "lay", "M "\n" "This method has been introduced in version 0.26.\n" ) + - gsi::method ("call_menu", &lay::MainWindow::menu_activated, + gsi::method ("call_menu", &lay::MainWindow::menu_activated, gsi::arg ("symbol"), "@brief Calls the menu item with the provided symbol.\n" "To obtain all symbols, use menu_symbols.\n" "\n" diff --git a/src/lay/lay/layApplication.cc b/src/lay/lay/layApplication.cc index 5fa542a75..f52ac9bd3 100644 --- a/src/lay/lay/layApplication.cc +++ b/src/lay/lay/layApplication.cc @@ -605,7 +605,7 @@ ApplicationBase::init_app () bool editable_from_config = false; { - lay::Dispatcher cfg (0); + lay::Dispatcher cfg; for (std::vector ::const_iterator c = m_config_files.begin (); c != m_config_files.end (); ++c) { try { @@ -1474,7 +1474,7 @@ GuiApplication::start_recording () lay::Dispatcher * GuiApplication::dispatcher () const { - return mp_mw; + return mp_mw->dispatcher (); } void @@ -1482,7 +1482,7 @@ GuiApplication::setup () { tl_assert (mp_mw == 0); - mp_mw = new lay::MainWindow (this, 0, "main_window", is_undo_enabled ()); + mp_mw = new lay::MainWindow (this, "main_window", is_undo_enabled ()); QObject::connect (mp_mw, SIGNAL (closed ()), this, SLOT (quit ())); @@ -1579,7 +1579,7 @@ NonGuiApplication::setup () mp_pr = new lay::ProgressReporter (); mp_pb = new TextProgress (10 /*verbosity level*/); mp_pr->set_progress_bar (mp_pb); - mp_dispatcher = new lay::Dispatcher (0); + mp_dispatcher = new lay::Dispatcher (); } } diff --git a/src/lay/lay/layMainWindow.cc b/src/lay/lay/layMainWindow.cc index abd6a321e..51047d932 100644 --- a/src/lay/lay/layMainWindow.cc +++ b/src/lay/lay/layMainWindow.cc @@ -154,9 +154,11 @@ show_dock_widget (QDockWidget *dock_widget, bool visible) // ------------------------------------------------------------- -MainWindow::MainWindow (QApplication *app, lay::Plugin *plugin_parent, const char *name, bool undo_enabled) +MainWindow::MainWindow (QApplication *app, const char *name, bool undo_enabled) : QMainWindow (0), - lay::Dispatcher (plugin_parent, false), + tl::Object (), + lay::DispatcherDelegate (), + m_dispatcher (this), m_text_progress (this, 10 /*verbosity threshold*/), m_mode (std::numeric_limits::max ()), mp_setup_form (0), @@ -175,6 +177,9 @@ MainWindow::MainWindow (QApplication *app, lay::Plugin *plugin_parent, const cha mp_app (app), m_manager (undo_enabled) { + // install us as menu widget parent + m_dispatcher.set_menu_parent_widget (this); + // ensures the deferred method scheduler is present tl::DeferredMethodScheduler::instance (); @@ -699,7 +704,7 @@ MainWindow::about_to_exec () bool f; f = false; - config_get (cfg_full_hier_new_cell, f); + dispatcher ()->config_get (cfg_full_hier_new_cell, f); if (!f) { TipDialog td (this, tl::to_string (QObject::tr ("" @@ -737,7 +742,7 @@ MainWindow::about_to_exec () } f = false; - config_get (cfg_no_stipple, f); + dispatcher ()->config_get (cfg_no_stipple, f); if (f) { TipDialog td (this, tl::to_string (QObject::tr ("Layers are shown without fill because fill has been intentionally turned off. This can be confusing since selecting a stipple does not have an effect in this case.\n\nTo turn this feature off, uncheck \"Show Layers Without Fill\" in the \"View\" menu.")), @@ -749,7 +754,7 @@ MainWindow::about_to_exec () } f = false; - config_get (cfg_markers_visible, f); + dispatcher ()->config_get (cfg_markers_visible, f); if (! f) { TipDialog td (this, tl::to_string (QObject::tr ("Markers are not visible because they have been turned off.\nYou may not see markers when using the marker browser feature.\n\nTo turn markers on, check \"Show Markers\" in the \"View\" menu.")), @@ -761,7 +766,7 @@ MainWindow::about_to_exec () } f = false; - config_get (cfg_hide_empty_layers, f); + dispatcher ()->config_get (cfg_hide_empty_layers, f); if (f) { TipDialog td (this, tl::to_string (QObject::tr ("The \"Hide Empty Layers\" feature is enabled. This can be confusing, in particular in edit mode, because layers are not shown although they are actually present.\n\nTo disable this feature, uncheck \"Hide Empty Layers\" in the layer panel's context menu.")), @@ -916,8 +921,6 @@ MainWindow::config_finalize () bool MainWindow::configure (const std::string &name, const std::string &value) { - lay::Dispatcher::configure (name, value); - if (name == cfg_grid) { double g = 0.0; @@ -3337,7 +3340,7 @@ MainWindow::do_create_view () view->set_synchronous (synchronous ()); int tl = 0; - config_get (cfg_initial_hier_depth, tl); + dispatcher ()->config_get (cfg_initial_hier_depth, tl); view->set_hier_levels (std::make_pair (0, tl)); // select the current mode and select the enabled editables @@ -3399,7 +3402,7 @@ MainWindow::create_or_load_layout (const std::string *filename, const db::LoadLa if (mode == 0) { // reset the hierarchy depth in the "replace" case int tl = 0; - config_get (cfg_initial_hier_depth, tl); + dispatcher ()->config_get (cfg_initial_hier_depth, tl); vw->set_hier_levels (std::make_pair (0, tl)); vw->clear_states (); vw->store_state (); @@ -3552,7 +3555,7 @@ MainWindow::get_hier_levels () const return current_view ()->get_hier_levels (); } else { int tl = 0; - config_get (cfg_initial_hier_depth, tl); + dispatcher ()->config_get (cfg_initial_hier_depth, tl); return std::make_pair (0, tl); } } @@ -4136,7 +4139,7 @@ MainWindow::plugin_registered (lay::PluginDeclaration *cls) void MainWindow::plugin_removed (lay::PluginDeclaration *cls) { - cls->remove_menu_items (this); + cls->remove_menu_items (dispatcher ()); // recreate all plugins except the one that got removed for (std::vector ::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) { diff --git a/src/lay/lay/layMainWindow.h b/src/lay/lay/layMainWindow.h index 43398ebda..0286e4f97 100644 --- a/src/lay/lay/layMainWindow.h +++ b/src/lay/lay/layMainWindow.h @@ -94,7 +94,8 @@ class ProgressWidget; */ class LAY_PUBLIC MainWindow : public QMainWindow, - public lay::Dispatcher + public tl::Object, + public lay::DispatcherDelegate { Q_OBJECT public: @@ -107,7 +108,7 @@ public: /** * @brief Constructor */ - MainWindow (QApplication *app = 0, lay::Plugin *parent_plugin = 0, const char *name = "main_window", bool undo_enabled = true); + MainWindow (QApplication *app = 0, const char *name = "main_window", bool undo_enabled = true); /** * @brief Destructor @@ -115,11 +116,11 @@ public: ~MainWindow (); /** - * @brief Implementation of the Dispatcher interface + * @brief Gets the dispatcher interface */ - QWidget *menu_parent_widget () + lay::Dispatcher *dispatcher () const { - return this; + return const_cast (&m_dispatcher); } /** @@ -498,6 +499,14 @@ public: */ void show_macro_editor (const std::string &cat = std::string (), bool add = false); + /** + * @brief Gets the main window's menu + */ + AbstractMenu *menu () + { + return m_dispatcher.menu (); + } + /** * @brief Handles a generic menu request */ @@ -658,6 +667,8 @@ protected: void do_update_mru_menus (); private: + lay::Dispatcher m_dispatcher; + TextProgressDelegate m_text_progress; // Main menu diff --git a/src/lay/lay/layNavigator.cc b/src/lay/lay/layNavigator.cc index dbcf8c4a0..aeaf936af 100644 --- a/src/lay/lay/layNavigator.cc +++ b/src/lay/lay/layNavigator.cc @@ -572,8 +572,8 @@ Navigator::showEvent (QShowEvent *) void Navigator::closeEvent (QCloseEvent *) { - mp_main_window->config_set (cfg_show_navigator, "false"); - mp_main_window->config_end (); + mp_main_window->dispatcher ()->config_set (cfg_show_navigator, "false"); + mp_main_window->dispatcher ()->config_end (); } void diff --git a/src/laybasic/laybasic/gsiDeclLayPlugin.cc b/src/laybasic/laybasic/gsiDeclLayPlugin.cc index e3f5208c6..15d8cc180 100644 --- a/src/laybasic/laybasic/gsiDeclLayPlugin.cc +++ b/src/laybasic/laybasic/gsiDeclLayPlugin.cc @@ -127,30 +127,48 @@ public: virtual bool mouse_press_event (const db::DPoint &p, unsigned int buttons, bool prio) { if (f_mouse_press_event.can_issue ()) { - return f_mouse_press_event.issue (&lay::ViewService::mouse_press_event, p, buttons, prio); + return f_mouse_press_event.issue (&PluginBase::mouse_press_event_noref, p, buttons, prio); } else { return lay::ViewService::mouse_press_event (p, buttons, prio); } } + // NOTE: this version doesn't take a point reference which allows up to store the point + bool mouse_press_event_noref (db::DPoint p, unsigned int buttons, bool prio) + { + return mouse_press_event (p, buttons, prio); + } + virtual bool mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio) { if (f_mouse_click_event.can_issue ()) { - return f_mouse_click_event.issue (&lay::ViewService::mouse_click_event, p, buttons, prio); + return f_mouse_click_event.issue (&PluginBase::mouse_click_event_noref, p, buttons, prio); } else { return lay::ViewService::mouse_click_event (p, buttons, prio); } } + // NOTE: this version doesn't take a point reference which allows up to store the point + bool mouse_click_event_noref (db::DPoint p, unsigned int buttons, bool prio) + { + return mouse_click_event (p, buttons, prio); + } + virtual bool mouse_double_click_event (const db::DPoint &p, unsigned int buttons, bool prio) { if (f_mouse_double_click_event.can_issue ()) { - return f_mouse_double_click_event.issue (&lay::ViewService::mouse_double_click_event, p, buttons, prio); + return f_mouse_double_click_event.issue (&PluginBase::mouse_double_click_event_noref, p, buttons, prio); } else { return lay::ViewService::mouse_double_click_event (p, buttons, prio); } } + // NOTE: this version doesn't take a point reference which allows up to store the point + bool mouse_double_click_event_noref (db::DPoint p, unsigned int buttons, bool prio) + { + return mouse_double_click_event (p, buttons, prio); + } + virtual bool leave_event (bool prio) { if (f_leave_event.can_issue ()) { @@ -172,30 +190,48 @@ public: virtual bool mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio) { if (f_mouse_move_event.can_issue ()) { - return f_mouse_move_event.issue (&lay::ViewService::mouse_move_event, p, buttons, prio); + return f_mouse_move_event.issue (&PluginBase::mouse_move_event_noref, p, buttons, prio); } else { return lay::ViewService::mouse_move_event (p, buttons, prio); } } + // NOTE: this version doesn't take a point reference which allows up to store the point + bool mouse_move_event_noref (db::DPoint p, unsigned int buttons, bool prio) + { + return mouse_move_event (p, buttons, prio); + } + virtual bool mouse_release_event (const db::DPoint &p, unsigned int buttons, bool prio) { if (f_mouse_release_event.can_issue ()) { - return f_mouse_release_event.issue (&lay::ViewService::mouse_release_event, p, buttons, prio); + return f_mouse_release_event.issue (&PluginBase::mouse_release_event_noref, p, buttons, prio); } else { return lay::ViewService::mouse_release_event (p, buttons, prio); } } + // NOTE: this version doesn't take a point reference which allows up to store the point + bool mouse_release_event_noref (db::DPoint p, unsigned int buttons, bool prio) + { + return mouse_release_event (p, buttons, prio); + } + virtual bool wheel_event (int delta, bool horizontal, const db::DPoint &p, unsigned int buttons, bool prio) { if (f_wheel_event.can_issue ()) { - return f_wheel_event.issue (&lay::ViewService::wheel_event, delta, horizontal, p, buttons, prio); + return f_wheel_event.issue (&PluginBase::wheel_event_noref, delta, horizontal, p, buttons, prio); } else { return lay::ViewService::wheel_event (delta, horizontal, p, buttons, prio); } } + // NOTE: this version doesn't take a point reference which allows up to store the point + bool wheel_event_noref (int delta, bool horizontal, db::DPoint p, unsigned int buttons, bool prio) + { + return wheel_event (delta, horizontal, p, buttons, prio); + } + virtual void activated () { if (f_activated.can_issue ()) { @@ -693,7 +729,7 @@ Class decl_Plugin ("lay", "Plugin", "@param buttons A combination of the constants in the \\ButtonState class which codes both the mouse buttons and the key modifiers (.e. ShiftButton etc).\n" "@return True to terminate dispatcher\n" ) + - callback ("mouse_button_pressed_event", &gsi::PluginBase::mouse_press_event, &gsi::PluginBase::f_mouse_press_event, gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), + callback ("mouse_button_pressed_event", &gsi::PluginBase::mouse_press_event_noref, &gsi::PluginBase::f_mouse_press_event, gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), "@brief Handles the mouse button pressed event\n" "This method will called by the view when a button is pressed on the mouse.\n" "\n" @@ -715,11 +751,11 @@ Class decl_Plugin ("lay", "Plugin", "@param buttons A combination of the constants in the \\ButtonState class which codes both the mouse buttons and the key modifiers (.e. LeftButton, ShiftButton etc).\n" "@return True to terminate dispatcher\n" ) + - callback ("mouse_click_event", &gsi::PluginBase::mouse_click_event, &gsi::PluginBase::f_mouse_click_event, gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), + callback ("mouse_click_event", &gsi::PluginBase::mouse_click_event_noref, &gsi::PluginBase::f_mouse_click_event, gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), "@brief Handles the mouse button click event (after the button has been released)\n" "The behaviour of this callback is the same than for \\mouse_press_event, except that it is called when the mouse button has been released without moving it.\n" ) + - callback ("mouse_double_click_event", &gsi::PluginBase::mouse_double_click_event, &gsi::PluginBase::f_mouse_double_click_event, gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), + callback ("mouse_double_click_event", &gsi::PluginBase::mouse_double_click_event_noref, &gsi::PluginBase::f_mouse_double_click_event, gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), "@brief Handles the mouse button double-click event\n" "The behaviour of this callback is the same than for \\mouse_press_event, except that it is called when the mouse button has been double-clicked.\n" ) + @@ -733,15 +769,15 @@ Class decl_Plugin ("lay", "Plugin", "The behaviour of this callback is the same than for \\mouse_press_event, except that it is called when the mouse enters the canvas area.\n" "This method does not have a position nor button flags.\n" ) + - callback ("mouse_moved_event", &gsi::PluginBase::mouse_move_event, &gsi::PluginBase::f_mouse_move_event, gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), + callback ("mouse_moved_event", &gsi::PluginBase::mouse_move_event_noref, &gsi::PluginBase::f_mouse_move_event, gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), "@brief Handles the mouse move event\n" "The behaviour of this callback is the same than for \\mouse_press_event, except that it is called when the mouse is moved in the canvas area.\n" ) + - callback ("mouse_button_released_event", &gsi::PluginBase::mouse_release_event, &gsi::PluginBase::f_mouse_release_event, gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), + callback ("mouse_button_released_event", &gsi::PluginBase::mouse_release_event_noref, &gsi::PluginBase::f_mouse_release_event, gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), "@brief Handles the mouse button release event\n" "The behaviour of this callback is the same than for \\mouse_press_event, except that it is called when the mouse button is released.\n" ) + - callback ("wheel_event", &gsi::PluginBase::wheel_event, &gsi::PluginBase::f_wheel_event, gsi::arg ("delta"), gsi::arg ("horizontal"), gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), + callback ("wheel_event", &gsi::PluginBase::wheel_event_noref, &gsi::PluginBase::f_wheel_event, gsi::arg ("delta"), gsi::arg ("horizontal"), gsi::arg ("p"), gsi::arg ("buttons"), gsi::arg ("prio"), "The behaviour of this callback is the same than for \\mouse_press_event, except that it is called when the mouse wheel is rotated.\n" "Additional parameters for this event are 'delta' (the rotation angle in units of 1/8th degree) and 'horizontal' which is true when the horizontal wheel was rotated and " "false if the vertical wheel was rotated.\n" diff --git a/src/laybasic/laybasic/layDispatcher.cc b/src/laybasic/laybasic/layDispatcher.cc index 14d3e224f..92642df97 100644 --- a/src/laybasic/laybasic/layDispatcher.cc +++ b/src/laybasic/laybasic/layDispatcher.cc @@ -36,13 +36,26 @@ static Dispatcher *ms_dispatcher_instance = 0; Dispatcher::Dispatcher (Plugin *parent, bool standalone) : Plugin (parent, standalone), - m_menu (this) + m_menu (this), + mp_menu_parent_widget (0), + mp_delegate (0) { if (! parent && ! ms_dispatcher_instance) { ms_dispatcher_instance = this; } } +Dispatcher::Dispatcher (DispatcherDelegate *delegate, Plugin *parent, bool standalone) + : Plugin (parent, standalone), + m_menu (this), + mp_menu_parent_widget (0), + mp_delegate (delegate) +{ + if (! ms_dispatcher_instance) { + ms_dispatcher_instance = this; + } +} + Dispatcher::~Dispatcher () { if (ms_dispatcher_instance == this) { @@ -57,9 +70,23 @@ Dispatcher::configure (const std::string &name, const std::string &value) for (std::vector::const_iterator a = ca.begin (); a != ca.end (); ++a) { (*a)->configure (value); } - return false; + + if (mp_delegate) { + return mp_delegate->configure (name, value); + } else { + return false; + } } +void +Dispatcher::config_finalize () +{ + if (mp_delegate) { + return mp_delegate->config_finalize (); + } +} + + // Writing and Reading of configuration struct ConfigGetAdaptor diff --git a/src/laybasic/laybasic/layDispatcher.h b/src/laybasic/laybasic/layDispatcher.h index a4b537b5b..e1bb70dd8 100644 --- a/src/laybasic/laybasic/layDispatcher.h +++ b/src/laybasic/laybasic/layDispatcher.h @@ -41,11 +41,69 @@ class AbstractMenu; class Action; class ConfigureAction; +/** + * @brief A delegate by which the dispatcher can submit notification events + */ +class LAYBASIC_PUBLIC DispatcherDelegate +{ +public: + /** + * @brief Notifies the plugin root that a new plugin class has been registered + * + * This method is called when a plugin is loaded dynamically during runtime. + */ + virtual void plugin_registered (lay::PluginDeclaration * /*cls*/) + { + // .. this implementation does nothing .. + } + + /** + * @brief Notifies the plugin root that a plugin class is about to be removed + */ + virtual void plugin_removed (lay::PluginDeclaration * /*cls*/) + { + // .. this implementation does nothing .. + } + + /** + * @brief Selects the given mode + * + * The implementation is supposed to select the given mode on all related plugins. + */ + virtual void select_mode (int /*mode*/) + { + // .. this implementation does nothing .. + } + + /** + * @brief Menu command handler + */ + virtual void menu_activated (const std::string & /*symbol*/) + { + // .. this implementation does nothing .. + } + + /** + * @brief Receives configuration events + */ + virtual bool configure (const std::string & /*name*/, const std::string & /*value*/) + { + return false; + } + + /** + * @brief Configuration finalization + */ + virtual void config_finalize () + { + // .. the default implementation does nothing .. + } +}; + /** * @brief The central menu event and configuration dispatcher class * * This class acts as the top level dispatcher for plugin events and the menu configuration. - * */ class LAYBASIC_PUBLIC Dispatcher : public Plugin @@ -57,7 +115,14 @@ public: * @param parent Usually 0, but a dispatcher may have parents. In this case, the dispatcher is not the actual dispatcher, but the real plugin chain's root is. * @param standalone The standalone flag passed to the plugin constructor. */ - Dispatcher (Plugin *parent, bool standalone = false); + Dispatcher (Plugin *parent = 0, bool standalone = false); + + /** + * @brief The root constructor + * + * @param delegate The notification receiver for dispatcher events + */ + Dispatcher (DispatcherDelegate *delegate, Plugin *parent = 0, bool standalone = false); /** * @brief Destructor @@ -95,29 +160,65 @@ public: * * This method is called when a plugin is loaded dynamically during runtime. */ - virtual void plugin_registered (lay::PluginDeclaration * /*cls*/) { } + virtual void plugin_registered (lay::PluginDeclaration *cls) + { + if (mp_delegate) { + mp_delegate->plugin_registered (cls); + } + } /** * @brief Notifies the plugin root that a plugin class is about to be removed */ - virtual void plugin_removed (lay::PluginDeclaration * /*cls*/) { } + virtual void plugin_removed (lay::PluginDeclaration *cls) + { + if (mp_delegate) { + mp_delegate->plugin_registered (cls); + } + } /** * @brief Selects the given mode * * The implementation is supposed to select the given mode on all related plugins. */ - virtual void select_mode (int /*mode*/) { } + virtual void select_mode (int mode) + { + if (mp_delegate) { + mp_delegate->select_mode (mode); + } + } + + /** + * @brief Called, when a menu item is selected + */ + virtual void menu_activated (const std::string &symbol) + { + if (mp_delegate) { + mp_delegate->menu_activated (symbol); + } + } /** * @brief Gets the parent widget */ - virtual QWidget *menu_parent_widget () { return 0; } + QWidget *menu_parent_widget () + { + return mp_menu_parent_widget; + } + + /** + * @brief Gets the parent widget + */ + void set_menu_parent_widget (QWidget *w) + { + mp_menu_parent_widget = w; + } /** * @brief Returns true, if the dispatcher supplies a user interface */ - virtual bool has_ui () { return menu_parent_widget () != 0; } + bool has_ui () { return menu_parent_widget () != 0; } /** * @brief Gets the AbstractMenu object @@ -132,12 +233,15 @@ public: protected: // capture the configuration events so we can change the value of the configuration actions virtual bool configure (const std::string &name, const std::string &value); + virtual void config_finalize (); private: Dispatcher (const Dispatcher &); Dispatcher &operator= (const Dispatcher &); lay::AbstractMenu m_menu; + QWidget *mp_menu_parent_widget; + DispatcherDelegate *mp_delegate; }; } diff --git a/src/laybasic/laybasic/layLayoutView.cc b/src/laybasic/laybasic/layLayoutView.cc index 5f3cbc636..e6e065511 100644 --- a/src/laybasic/laybasic/layLayoutView.cc +++ b/src/laybasic/laybasic/layLayoutView.cc @@ -261,6 +261,7 @@ LayoutView::LayoutView (db::Manager *manager, bool editable, lay::Plugin *plugin { // either it's us or the parent has a dispatcher tl_assert (dispatcher () != 0); + set_menu_parent_widget (this); // ensures the deferred method scheduler is present tl::DeferredMethodScheduler::instance (); @@ -712,11 +713,6 @@ LayoutView::~LayoutView () mp_bookmarks_view = 0; } -QWidget *LayoutView::menu_parent_widget () -{ - return this; -} - lay::EditorOptionsPages *LayoutView::editor_options_pages () { if (! mp_editor_options_frame) { diff --git a/src/laybasic/laybasic/layLayoutView.h b/src/laybasic/laybasic/layLayoutView.h index 7c14db0d5..b7e8b7838 100644 --- a/src/laybasic/laybasic/layLayoutView.h +++ b/src/laybasic/laybasic/layLayoutView.h @@ -2917,9 +2917,6 @@ private: std::list::iterator cellview_iter (int cv_index); std::list::const_iterator cellview_iter (int cv_index) const; - - // implementation of Dispatcher - virtual QWidget *menu_parent_widget (); }; }