1 module poison.core.eventargs.buttoneventargs;
2 
3 import std.algorithm : filter;
4 import std.array : array;
5 
6 import poison.core.eventargs : EventArgs;
7 
8 // TODO: handle double click by time checking ...
9 
10 
11 /// Event args that relies on button logic.
12 class ButtonEventArgs(T) : EventArgs {
13   private:
14   /// The currently pressed buttons.
15   T[] _pressed;
16 
17   /// The last pressed button.
18   T _lastPressed;
19 
20   /// The current pressed button.
21   T _currentPressed;
22 
23   protected:
24   /// Creates a new button event args wrapper.
25   this() {
26     super();
27   }
28 
29   public:
30   /**
31   * Presses a button.
32   * Params:
33   *   button =  The button to press.
34   */
35   void press(T button) {
36     if (isPressed(button)) {
37       return;
38     }
39 
40     _pressed ~= button;
41     _lastPressed = _currentPressed;
42     _currentPressed = button;
43   }
44 
45   /**
46   * Releases a button.
47   * Params:
48   *   button =  The button to release.
49   */
50   void release(T button) {
51     _pressed = _pressed.filter!((b) { return b != button; }).array;
52     _lastPressed = _currentPressed;
53   }
54 
55   /**
56   * Checks whether a specific button is pressed or not.
57   * Params:
58   *   pressedButton = The button to check if pressed or not.
59   * Returns:
60   *   true if the button is pressed.
61   */
62   bool isPressed(T pressedButton) {
63     if (_currentPressed == pressedButton) {
64       return true;
65     }
66 
67     foreach (button; _pressed) {
68       if (button == pressedButton) {
69         return true;
70       }
71     }
72 
73     return false;
74   }
75 
76   /**
77   * Checks whether a range of buttons are pressed or not.
78   * Params:
79   *   pressedButtons = The buttons to check if pressed or not.
80   * Returns:
81   *   true if all buttons are pressed.
82   */
83   bool isPressed(Range)(Range pressedButtons) {
84     assert(pressedButtons !is null);
85 
86     foreach (button; pressedButtons) {
87       if (!isPressed(button)) {
88         return false;
89       }
90     }
91 
92     return true;
93   }
94 
95   @property {
96     /// Gets all buttons currently pressed.
97     T[] pressed() { return _pressed; }
98 
99     /// Gets the last button pressed.
100     T lastPressed() { return _lastPressed; }
101 
102     /// Gets the current button pressed.
103     T currentPressed() { return _currentPressed; }
104   }
105 }