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.
This commit is contained in:
Matthias Koefferlein 2021-01-26 07:56:49 +01:00
parent bd9afaf865
commit 6a23769387
12 changed files with 348 additions and 79 deletions

View File

@ -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> (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> (a1); \
args.write<A2> (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> (a1); \
args.write<A2> (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> (a1); \
args.write<A2> (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> (a1); \
args.write<A2> (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> (a1); \
args.write<A2> (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> (a1); \
args.write<A2> (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> (a1); \
args.write<A2> (a2); \
@ -243,6 +260,7 @@ struct Callback
#include "gsiCallbackVar.h"
#undef _SETVALUE
#undef _COMMA
#undef _CALLARGS
#undef _CALLARGLIST
#undef _FUNCARGLIST

View File

@ -30,24 +30,24 @@
// _CALLARGLIST ", A1 a1"
// _SETVALUE "args.template write<A1> (a1);"
template <class X _TMPLARGPART>
void issue (void (X::*) (_FUNCARGLIST) _CALLARGLIST) const
template <class X _COMMA _TMPLARGPART>
void issue (void (X::*) (_FUNCARGLIST) _COMMA _CALLARGLIST) const
{
SerialArgs args (argsize), ret (retsize);
_SETVALUE
call_int (args, ret);
}
template <class X _TMPLARGPART>
void issue (void (X::*) (_FUNCARGLIST) const _CALLARGLIST) const
template <class X _COMMA _TMPLARGPART>
void issue (void (X::*) (_FUNCARGLIST) const _COMMA _CALLARGLIST) const
{
SerialArgs args (argsize), ret (retsize);
_SETVALUE
call_int (args, ret);
}
template <class X, class R _TMPLARGPART>
R issue (R (X::*) (_FUNCARGLIST) _CALLARGLIST) const
template <class X, class R _COMMA _TMPLARGPART>
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<R> (heap);
}
template <class X, class R _TMPLARGPART>
R issue (R (X::*) (_FUNCARGLIST) const _CALLARGLIST) const
template <class X, class R _COMMA _TMPLARGPART>
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<R> (heap);
}

View File

@ -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<std::string>
get_config_names (lay::MainWindow *mw)
{
std::vector<std::string> names;
mw->dispatcher ()->get_config_names (names);
return names;
}
void
config_end (lay::MainWindow *mw)
{
mw->dispatcher ()->config_end ();
}
Class<lay::MainWindow> 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<lay::MainWindow> 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"

View File

@ -605,7 +605,7 @@ ApplicationBase::init_app ()
bool editable_from_config = false;
{
lay::Dispatcher cfg (0);
lay::Dispatcher cfg;
for (std::vector <std::string>::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 ();
}
}

View File

@ -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<unsigned int>::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 ("<html><body>"
@ -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 <lay::LayoutView *>::iterator vp = mp_views.begin (); vp != mp_views.end (); ++vp) {

View File

@ -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<lay::Dispatcher *> (&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

View File

@ -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

View File

@ -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, bool, const db::DPoint &, unsigned int, bool> (&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, bool, const db::DPoint &, unsigned int, bool> (&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, bool, const db::DPoint &, unsigned int, bool> (&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, bool, const db::DPoint &, unsigned int, bool> (&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, bool, const db::DPoint &, unsigned int, bool> (&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, bool, int, bool, const db::DPoint &, unsigned int, bool> (&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<gsi::PluginBase> 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<gsi::PluginBase> 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<gsi::PluginBase> 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"

View File

@ -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<lay::ConfigureAction *>::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

View File

@ -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;
};
}

View File

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

View File

@ -2917,9 +2917,6 @@ private:
std::list<lay::CellView>::iterator cellview_iter (int cv_index);
std::list<lay::CellView>::const_iterator cellview_iter (int cv_index) const;
// implementation of Dispatcher
virtual QWidget *menu_parent_widget ();
};
}