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);
}
}
#include <map>
#include <string>
+#include <sigc++/functors/mem_fun.h>
namespace Msp {
namespace GLtk {
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
{
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 *);
};
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
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
{
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;
};
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