]> git.tdb.fi Git - libs/gui.git/blobdiff - source/input/control.cpp
Keep track of edges in Control
[libs/gui.git] / source / input / control.cpp
index 6ff80883f8d39d8df19892b9fd2cf114aac7cc4a..3e2398d15860471dd8dc8eee9cad89ce1596e9c5 100644 (file)
@@ -1,8 +1,11 @@
-#include <msp/core/except.h>
+#include <sigc++/bind_return.h>
 #include <msp/strings/lexicalcast.h>
+#include "binarycontrol.h"
 #include "control.h"
 #include "device.h"
 
+using namespace std;
+
 namespace Msp {
 namespace Input {
 
@@ -29,38 +32,53 @@ std::string ControlSource::str() const
        else if(type==NONE)
                return "None";
 
-       return lexical_cast(index);
+       return lexical_cast<string>(index);
 }
 
 
 Control::Control():
-       capture_dev(0)
+       capture_dev(0),
+       activator(0),
+       origin(0),
+       rising_edge(false),
+       falling_edge(false)
 { }
 
 Control::Control(const ControlSource &s):
        src(s),
-       capture_dev(0)
+       capture_dev(0),
+       activator(0),
+       origin(0),
+       rising_edge(false),
+       falling_edge(false)
 { }
 
 Control::Control(Device &d, ControlSrcType t, unsigned i):
        src(d, t, i),
-       capture_dev(0)
+       capture_dev(0),
+       activator(0),
+       origin(0),
+       rising_edge(false),
+       falling_edge(false)
 {
        connect_signals();
 }
 
+Control::~Control()
+{ }
+
 void Control::capture(Device &d)
 {
        notify_callbacks();
-       capture_dev=&d;
-       capture_dev->signal_button_press.connect(sigc::mem_fun(this, &Control::button_press));
-       capture_dev->signal_axis_motion.connect(sigc::mem_fun(this, &Control::axis_motion));
+       capture_dev = &d;
+       capture_dev->signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &Control::button_press), false));
+       capture_dev->signal_axis_motion.connect(sigc::bind_return(sigc::mem_fun(this, &Control::axis_motion), false));
 }
 
 void Control::cancel_capture()
 {
        notify_callbacks();
-       capture_dev=0;
+       capture_dev = 0;
        connect_signals();
 }
 
@@ -72,10 +90,23 @@ void Control::set_source(Device &d, ControlSrcType t, unsigned i)
 void Control::set_source(const ControlSource &s)
 {
        notify_callbacks();
-       src=s;
+       src = s;
        connect_signals();
 }
 
+void Control::set_activator(BinaryControl *ctrl)
+{
+       notify_callbacks();
+       activator = ctrl;
+       connect_signals();
+}
+
+void Control::reset_edges()
+{
+       rising_edge = false;
+       falling_edge = false;
+}
+
 void Control::connect_signals()
 {
        switch(src.type)
@@ -83,38 +114,39 @@ void Control::connect_signals()
        case NONE:
                break;
        case BUTTON:
-               src.dev->signal_button_press.connect(sigc::mem_fun(this, &Control::button_press));
-               src.dev->signal_button_release.connect(sigc::mem_fun(this, &Control::button_release));
+               src.dev->signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &Control::button_press), false));
+               src.dev->signal_button_release.connect(sigc::bind_return(sigc::mem_fun(this, &Control::button_release), false));
                break;
        case AXIS_POS:
        case AXIS_NEG:
-               src.dev->signal_axis_motion.connect(sigc::mem_fun(this, &Control::axis_motion));
+               src.dev->signal_axis_motion.connect(sigc::bind_return(sigc::mem_fun(this, &Control::axis_motion), false));
                break;
-       default:
-               throw Exception("Invalid source in Control");
        }
+
+       if(activator)
+               activator->signal_release.connect(sigc::mem_fun(this, &Control::deactivate));
 }
 
 void Control::button_press(unsigned i)
 {
        if(capture_dev)
        {
-               src.dev=capture_dev;
-               src.type=BUTTON;
-               src.index=i;
+               src.dev = capture_dev;
+               src.type = BUTTON;
+               src.index = i;
 
                notify_callbacks();
-               capture_dev=0;
+               capture_dev = 0;
                connect_signals();
                signal_capture_complete.emit();
        }
-       else if(src.type==BUTTON && i==src.index)
+       else if(src.type==BUTTON && i==src.index && (!activator || activator->get_state()))
                on_press();
 }
 
 void Control::button_release(unsigned i)
 {
-       if(src.type==BUTTON && i==src.index)
+       if(src.type==BUTTON && i==src.index && (!activator || activator->get_state()))
                on_release();
 }
 
@@ -122,28 +154,42 @@ void Control::axis_motion(unsigned i, float v, float r)
 {
        if(capture_dev)
        {
-               ControlSrcType type=NONE;
+               ControlSrcType type = NONE;
                if(v<-0.9)
-                       type=AXIS_NEG;
+                       type = AXIS_NEG;
                else if(v>0.9)
-                       type=AXIS_POS;
+                       type = AXIS_POS;
 
                if(type!=NONE)
                {
-                       src.dev=capture_dev;
-                       src.type=type;
-                       src.index=i;
+                       src.dev = capture_dev;
+                       src.type = type;
+                       src.index = i;
 
                        notify_callbacks();
-                       capture_dev=0;
+                       capture_dev = 0;
                        connect_signals();
                        signal_capture_complete.emit();
                }
        }
-       else if(src.type==AXIS_POS && i==src.index && v>=0)
-               on_motion(v, r);
-       else if(src.type==AXIS_NEG && i==src.index && v<=0)
-               on_motion(-v, -r);
+       else if(activator && !activator->get_state() && i==src.index)
+               origin = v;
+       else if(src.type==AXIS_POS && i==src.index && v>=origin)
+               on_motion(v-origin, r);
+       else if(src.type==AXIS_NEG && i==src.index && v<=origin)
+               on_motion(origin-v, -r);
+}
+
+void Control::deactivate()
+{
+       if(src.type==BUTTON)
+               on_release();
+       else if(src.type==AXIS_POS || src.type==AXIS_NEG)
+       {
+               float v = src.dev->get_axis_value(src.index);
+               on_motion(0, (src.type==AXIS_POS ? origin-v : v-origin));
+               origin = v;
+       }
 }
 
 } // namespace Input