#ifndef _BUTTON_H_ #define _BUTTON_H_ #include #include "Reader.h" using namespace admux; class Joystick; // forward declaration enum ButtonType { BUTTON_PASSTHRU = 0x1, // always use the (debounced) absolute state of the input BUTTON_PULSED = 0x2, // on button press, send an on signal followed immediately by an off signal. BUTTON_PULSED_DOUBLE_ACTION = 0x4, // Send a button press twice - once for press and once for release. BUTTON_PULSED_DOUBLE_ACTION_SPLIT = 0x8, // Send two separate button presses - one button on press, another on release. BUTTON_LATCHED_MOMENTARY = 0x10, ENCODER_PULSED_SPLIT = 0x20 // A rotary encoder that should be treated as two different pulsed/momentary buttons, one for each direction }; // The abstract button base class. A button must have, at a minimum: // * a button *type* (typically automatically assigned by the constructor) // * at least one "virtual button" - that is, a Joystick input that it controls // * an update method. class Button { public: Button(uint8_t vbutton, Reader* reader); virtual bool Update(Joystick* js) = 0; virtual void ReleaseButtons(Joystick* js); ButtonType type; protected: uint8_t vbutton; Reader *reader; }; class PassthruButton : public Button { public: PassthruButton(uint8_t vbutton, Reader* reader); bool Update(Joystick* js); }; class LatchedButton : public Button { public: LatchedButton(uint8_t vbutton, Reader* reader); bool Update(Joystick* js); protected: bool pressed; }; class PulsedButton : public Button { public: PulsedButton(uint8_t vbutton, Reader* reader, bool double_action = false, bool split = false); bool Update(Joystick* js); protected: bool double_action; bool split; unsigned long release_time1; unsigned long release_time2; uint8_t vbutton2; }; class EncoderButton : public Button { public: EncoderButton(uint8_t pin1, uint8_t pin2, uint8_t vbutton); bool Update(Joystick* js); protected: Encoder* encoder; long last_value; uint8_t vbutton2; unsigned long release_time1; unsigned long release_time2; }; #endif