]> git.tdb.fi Git - libs/gui.git/blob - source/input/device.h
e80029054548fe82c0a985bb2690b23c6773021c
[libs/gui.git] / source / input / device.h
1 #ifndef MSP_INPUT_INPUTDEVICE_H_
2 #define MSP_INPUT_INPUTDEVICE_H_
3
4 #include <string>
5 #include <vector>
6 #include <stdexcept>
7 #include <sigc++/signal.h>
8 #include <msp/strings/lexicalcast.h>
9
10 namespace Msp {
11 namespace Input {
12
13 class device_not_available: public std::runtime_error
14 {
15 public:
16         device_not_available(const std::string &w): std::runtime_error(w) { }
17 };
18
19
20 enum DeviceType
21 {
22         UNSPECIFIED,
23         KEYBOARD,
24         MOUSE,
25         TOUCH_SURFACE,
26         GAME_CONTROLLER
27 };
28
29
30 /**
31 Base class for input devices.  Input devices have two types of controls:
32 buttons and axes.  Buttons are either on or off.  Axes have a floating point
33 value nominally in the range [-1, 1].
34
35 Event handlers return a boolean indicating whether the event is considered
36 processed.  If a handler returns true, no further handlers are invoked.
37 */
38 class Device
39 {
40 protected:
41         struct EventAccumulator
42         {
43                 typedef void result_type;
44
45                 template<typename Iter>
46                 result_type operator()(Iter begin, Iter end) const
47                 {
48                         for(Iter i=begin; i!=end; ++i)
49                                 if(*i)
50                                         return;
51                 }
52         };
53
54 public:
55         sigc::signal<bool, unsigned>::accumulated<EventAccumulator> signal_button_press;
56         sigc::signal<bool, unsigned>::accumulated<EventAccumulator> signal_button_release;
57         sigc::signal<bool, unsigned, float, float>::accumulated<EventAccumulator> signal_axis_motion;
58
59 protected:
60         DeviceType type = UNSPECIFIED;
61         std::string name;
62         std::vector<char> buttons;
63         std::vector<float> axes;
64
65         Device(DeviceType);
66 public:
67         virtual ~Device();
68
69         DeviceType get_type() const { return type; }
70         const std::string &get_name() const { return name; }
71         virtual Device *find_subdevice(DeviceType, unsigned = 0);
72         virtual Device *find_subdevice(const std::string &);
73         bool get_button_state(unsigned) const;
74         float get_axis_value(unsigned) const;
75
76         virtual std::string get_button_name(unsigned) const;
77         virtual std::string get_axis_name(unsigned) const;
78 protected:
79         void set_button_state(unsigned, bool, bool);
80         void set_axis_value(unsigned, float, bool);
81 };
82
83
84 void operator>>(const LexicalConverter &, DeviceType &);
85 void operator<<(LexicalConverter &, DeviceType);
86
87 } // namespace Input
88 } // namespace Msp
89
90 #endif