]> git.tdb.fi Git - libs/gltk.git/commitdiff
Add ConnSignal action for Connector
authorMikko Rasa <tdb@tdb.fi>
Wed, 26 Dec 2007 09:20:37 +0000 (09:20 +0000)
committerMikko Rasa <tdb@tdb.fi>
Wed, 26 Dec 2007 09:20:37 +0000 (09:20 +0000)
Rename actions to bindings in Logic
Add some documentation to Connector

source/connector.cpp
source/connector.h
source/logic.cpp
source/logic.h

index 837ec80a33563ab7d928de367c51b28234f8b46a..2ee35c8ec8720decce212f6aef0c694f58e3fdc7 100644 (file)
@@ -21,13 +21,15 @@ Connector::~Connector()
 
 void Connector::connect(const Logic &logic)
 {
-       const list<Logic::WidgetAction> &logic_acts=logic.get_actions();
+       const list<Logic::WidgetBinding> &logic_binds=logic.get_bindings();
 
-       for(list<Logic::WidgetAction>::const_iterator i=logic_acts.begin(); i!=logic_acts.end(); ++i)
+       for(list<Logic::WidgetBinding>::const_iterator i=logic_binds.begin(); i!=logic_binds.end(); ++i)
        {
                map<string, ConnAction *>::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);
        }
 }
 
index a93664875df72a3911080d8948329fe591dbaf68..1960e81b133a26af1c0a8fb2c9662d8fad5b6e1f 100644 (file)
@@ -10,6 +10,7 @@ Distributed under the LGPL
 
 #include <map>
 #include <string>
+#include <sigc++/functors/mem_fun.h>
 
 namespace Msp {
 namespace GLtk {
@@ -57,10 +58,36 @@ private:
        FuncType func;
 };
 
+template<typename C, typename W, typename S, typename F>
+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<W &>(wdg).*signal).connect(sigc::mem_fun(&dynamic_cast<C &>(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<typename C, typename W>
        void add(const std::string &type, void (C::*func)(W &))
        { add(type, new ConnFunc0<C, W>(func)); }
 
+       /**
+       Adds a handler function for a binding.  The binding data is passed in the
+       second parameter.
+       */
        template<typename C, typename W>
        void add(const std::string &type, void (C::*func)(W &, const std::string &))
        { add(type, new ConnFunc1<C, W>(func)); }
 
+       /**
+       Adds a signal connector for a binding.
+       */
+       template<typename W, typename S, typename H, typename F>
+       void add(const std::string &type, S W::*signal, F H::*func)
+       { add(type, new ConnSignal<typename H::Connector, W, S, F H::*>(signal, func)); }
+
 private:
        void add(const std::string &, ConnAction *);
 };
index 40d06b218b1aa4b01f9de19ac6df9189bad0d1bb..ae9347019ad14d40ab228a4748f8ce94d67689ab 100644 (file)
@@ -16,22 +16,22 @@ Logic::Loader::Loader(Logic &l, const map<string, Widget *> &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<string, Widget *>::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
index 689b39b41ec0b6f8f9c6504e982230ba1c1cb042..091c4e100def4c0953c7663b7c910d0bbf210bd6 100644 (file)
@@ -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<std::string, Widget *> &);
        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<WidgetAction> actions;
+       std::list<WidgetBinding> bindings;
 
 public:
-       const std::list<WidgetAction> &get_actions() const { return actions; }
+       const std::list<WidgetBinding> &get_bindings() const { return bindings; }
 };
 
 } // namespace GLtk