From 8ffcd589660022f05d8b3b1dbb36c0c0aa91954a Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 26 Dec 2007 09:20:37 +0000 Subject: [PATCH] Add ConnSignal action for Connector Rename actions to bindings in Logic Add some documentation to Connector --- source/connector.cpp | 6 ++++-- source/connector.h | 50 +++++++++++++++++++++++++++++++++++++++++--- source/logic.cpp | 8 +++---- source/logic.h | 14 +++++++------ 4 files changed, 63 insertions(+), 15 deletions(-) diff --git a/source/connector.cpp b/source/connector.cpp index 837ec80..2ee35c8 100644 --- a/source/connector.cpp +++ b/source/connector.cpp @@ -21,13 +21,15 @@ Connector::~Connector() void Connector::connect(const Logic &logic) { - const list &logic_acts=logic.get_actions(); + const list &logic_binds=logic.get_bindings(); - for(list::const_iterator i=logic_acts.begin(); i!=logic_acts.end(); ++i) + for(list::const_iterator i=logic_binds.begin(); i!=logic_binds.end(); ++i) { map::const_iterator j=actions.find(i->type); if(j!=actions.end()) j->second->connect(*this, *i->wdg, i->data); + else + throw KeyError("Unknown binding type", i->type); } } diff --git a/source/connector.h b/source/connector.h index a936648..1960e81 100644 --- a/source/connector.h +++ b/source/connector.h @@ -10,6 +10,7 @@ Distributed under the LGPL #include #include +#include namespace Msp { namespace GLtk { @@ -57,10 +58,36 @@ private: FuncType func; }; +template +class ConnSignal: public ConnAction +{ +public: + ConnSignal(S W::*s, F f): signal(s), func(f) { } + virtual void connect(Connector &conn, Widget &wdg, const std::string &) const + { + (dynamic_cast(wdg).*signal).connect(sigc::mem_fun(&dynamic_cast(conn).get_object(), func)); + } + +private: + S W::*signal; + F func; +}; + /** -Provides an interface for associating the actions stored in a Logic object with -actual code. Derive a class from this and use the add functions to specify -handlers for each action type. +Provides an interface for associating the bindings stored in a Logic object +with actual code. Derive a class from this and use the add functions to +specify handlers for each binding type. + +Bindings are normally handled by member functions of the Connector class. The +function must take a reference to a widget (of any type) as its first parameter. +If it takes a second parameter, the binding data is passed in as well. + +As a shortcut for simple connections, signals of widgets can be connected +directly to a handler object. For this to work, the Connector class must be a +public inner class of the handler class and it must have a get_object() member +function returning a reference to the handler object. + +TODO: lexical_cast the binding data (requires working around references) */ class Connector { @@ -72,17 +99,34 @@ protected: public: virtual ~Connector(); + /** + Processes all bindings in the Logic object and calls appropriate handlers. + */ void connect(const Logic &); protected: + /** + Adds a handler function for a binding. + */ template void add(const std::string &type, void (C::*func)(W &)) { add(type, new ConnFunc0(func)); } + /** + Adds a handler function for a binding. The binding data is passed in the + second parameter. + */ template void add(const std::string &type, void (C::*func)(W &, const std::string &)) { add(type, new ConnFunc1(func)); } + /** + Adds a signal connector for a binding. + */ + template + void add(const std::string &type, S W::*signal, F H::*func) + { add(type, new ConnSignal(signal, func)); } + private: void add(const std::string &, ConnAction *); }; diff --git a/source/logic.cpp b/source/logic.cpp index 40d06b2..ae93470 100644 --- a/source/logic.cpp +++ b/source/logic.cpp @@ -16,22 +16,22 @@ Logic::Loader::Loader(Logic &l, const map &w): logic(l), widgets(w) { - add("action", &Loader::action); + add("bind", &Loader::bind); } -void Logic::Loader::action(const string &wdg, const string &data) +void Logic::Loader::bind(const string &wdg, const string &data) { map::const_iterator i=widgets.find(wdg); if(i==widgets.end()) throw KeyError("Unknown widget", wdg); unsigned colon=data.find(':'); - WidgetAction act; + WidgetBinding act; act.wdg=i->second; act.type=data.substr(0, colon); if(colon!=string::npos) act.data=data.substr(colon+1); - logic.actions.push_back(act); + logic.bindings.push_back(act); } } // namespace GLtk diff --git a/source/logic.h b/source/logic.h index 689b39b..091c4e1 100644 --- a/source/logic.h +++ b/source/logic.h @@ -21,8 +21,10 @@ namespace GLtk { class Widget; /** -Stores use interface logic. This is stored as actions associated to widgets. -Each action has type and data. See also class Connector. +Stores use interface logic. This is represented as widget bindings. Each +binding has type and data. + +See also class Connector. */ class Logic { @@ -36,10 +38,10 @@ public: public: Loader(Logic &, const std::map &); private: - void action(const std::string &, const std::string &); + void bind(const std::string &, const std::string &); }; - struct WidgetAction + struct WidgetBinding { Widget *wdg; std::string type; @@ -47,10 +49,10 @@ public: }; private: - std::list actions; + std::list bindings; public: - const std::list &get_actions() const { return actions; } + const std::list &get_bindings() const { return bindings; } }; } // namespace GLtk -- 2.43.0