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