Simple SFML GUI  0.2a
Pressable.hpp
1 /*
2  * Pressable.hpp
3  *
4  * Created on: 21.04.2017
5  * Author: jakub
6  */
7 
8 #ifndef PRESSABLE_HPP_
9 #define PRESSABLE_HPP_
10 
11 #include <functional>
12 #include <SFML/Graphics.hpp>
13 #include "HaveHover.hpp"
14 #include "HavePressed.hpp"
15 #include "HaveVisible.hpp"
16 #include "HaveFocus.hpp"
17 #include "HaveSelected.hpp"
18 #include "HaveGUIManagerInfo.hpp"
19 #include "FocusAction.hpp"
20 
21 #include "TextInputable.hpp"
22 
23 class Dialog;
24 
25 namespace ActionType {
26  namespace Press {
27  const char* const hold = "holdpress";
28  const char* const click= "clickpress";
29  const char* const gain = "gainpress";
30  const char* const lost = "lostpress";
31  }
32 
33  namespace PressAlt {
34  const char* const hold = "holdpressalt";
35  const char* const click= "clickpressalt";
36  const char* const gain = "gainpressalt";
37  const char* const lost = "lostpressalt";
38  }
39 }
40 
41 template <typename T>
42 class Pressable :
43  public FocusAction<T>,
44  public HavePressed,
45  public HaveSelected,
46  public HaveGUIManagerInfo {
47 public:
48  Pressable():
49  HavePressed(this->getColorProvider()),
50  HaveSelected(this->getColorProvider()),
51  hotKey(sf::Keyboard::Unknown),
52  hotPress(false),
53  stickyPress(false),
54  ignoreAbove(false),
55  ignoreDialogs(false),
56  ignoreTextInputable(false)
57  {}
58 
59  virtual bool setPressed(bool pressed) {
60  if(stickyPress && pressed) {
61  this->setFocus(true);
62  }
63 
64  if((this->hover || hotPress) && this->pressed && !pressed) {
65  hotPress = false;
66  this->setFocus(true);
67  this->doAction(ActionType::Press::click);
68  this->pressed = pressed;
69  return true;
70  }
71  this->pressed = pressed;
72  return false;
73  }
74 
75  virtual bool setPressedAlt(bool pressed) {
76  if(stickyPress && pressed) {
77  this->setFocus(true);
78  }
79 
80  if(this->hover && this->pressedAlt && !pressed) {
81  this->setFocus(true);
82  this->doAction(ActionType::PressAlt::click);
83  this->pressedAlt = pressed;
84  return true;
85  }
86  this->pressedAlt = pressed;
87  return false;
88  }
89 
90  sf::Keyboard::Key getHotKey() const {
91  return hotKey;
92  }
93 
94  void setHotKey(sf::Keyboard::Key hotKey) {
95  this->hotKey = hotKey;
96  }
97 
98  virtual bool update(sf::Vector2f mp = sf::Vector2f(0.f,0.f), bool pressLeft = false, bool pressRight = false, bool aboveHover = false) {
99  FocusAction<T>::update(mp, pressLeft, pressRight, aboveHover);
100 
101  bool lastPressed = pressed;
102  bool lastPressedAlt = pressedAlt;
103  bool hp = false;
104 
105  if(aboveHover && ((!ignoreAbove && !stickyPress) || (!ignoreDialogs && anyDialogExist()))) {
106  pressed = false;
107  pressedAlt = false;
108  if(lastPressed) {
109  this->doAction(ActionType::Press::lost);
110  }
111  if(lastPressedAlt) {
112  this->doAction(ActionType::PressAlt::lost);
113  }
114  lastPressLeft = pressLeft;
115  lastPressRight = pressRight;
116  return true;
117  }
118 
119  if(hotKey != sf::Keyboard::Unknown) {
120  hp = sf::Keyboard::isKeyPressed(hotKey);
121  if(hp && !ignoreTextInputable && TextInputable::isFocused()) {
122  hp = false;
123  }
124 
125  if(hp) {
126  hotPress = true;
127  this->hover = true;
128  setPressed(true);
129  } else {
130  if(hotPress && !pressLeft)
131  setPressed(false);
132  hotPress = false;
133  }
134  }
135 
136  if(!hp) {
137  if(stickyPress) {
138  if(this->visible) {
139  if(pressLeft && pressed && this->lastFocus == this) {
140  setPressed(true);
141  this->hover = true;
142  } else if(this->hover && pressLeft && (!lastPressLeft || pressed)) {
143  setPressed(true);
144  } else {
145  setPressed(false);
146  }
147 
148  if(pressRight && pressedAlt && this->lastFocus == this) {
149  setPressedAlt(true);
150  this->hover = true;
151  } else if(this->hover && pressRight && (!lastPressRight || pressedAlt)) {
152  setPressedAlt(true);
153  } else {
154  setPressedAlt(false);
155  }
156  } else {
157  setPressed(false);
158  setPressedAlt(false);
159  }
160  } else {
161  if(this->visible && this->hover) {
162  if(pressLeft && (!lastPressLeft || pressed)) {
163  setPressed(true);
164  } else {
165  setPressed(false);
166  }
167  if(pressRight && (!lastPressRight || pressedAlt)) {
168  setPressedAlt(true);
169  } else {
170  setPressedAlt(false);
171  }
172  } else {
173  setPressed(false);
174  setPressedAlt(false);
175  }
176  }
177  }
178 
179  if(lastPressed) {
180  if(pressed) {
181  this->doAction(ActionType::Press::hold);
182  } else {
183  this->doAction(ActionType::Press::lost);
184  }
185  } else {
186  if(pressed) {
187  this->doAction(ActionType::Press::gain);
188  }
189  }
190 
191  if(lastPressedAlt) {
192  if(pressedAlt) {
193  this->doAction(ActionType::PressAlt::hold);
194  } else {
195  this->doAction(ActionType::PressAlt::lost);
196  }
197  } else {
198  if(pressedAlt) {
199  this->doAction(ActionType::PressAlt::gain);
200  }
201  }
202 
203  lastPressLeft = pressLeft;
204  return this->hover;
205  }
206 
207  void setStickyPress(bool stickyPress) {
208  this->stickyPress = stickyPress;
209  }
210 
211  void setIgnoreAbove(bool value) {
212  ignoreAbove = value;
213  }
214 
215  void setIgnoreDialogs(bool value) {
216  ignoreDialogs = value;
217  }
218 
219  void setIgnoreTextInputable(bool value) {
220  ignoreTextInputable = value;
221  }
222 
223 
224 protected:
225  sf::Keyboard::Key hotKey;
226  bool hotPress;
227  bool stickyPress;
228 
229  bool ignoreAbove;
230  bool ignoreDialogs;
231  bool ignoreTextInputable;
232 
233 };
234 
235 
236 
237 #endif /* PRESSABLE_HPP_ */
Definition: Dialog.hpp:9
Definition: Checkbox.hpp:13
Definition: HaveSelected.hpp:6
Definition: FocusAction.hpp:27
Definition: HaveGUIManagerInfo.hpp:5
Definition: Pressable.hpp:42
Definition: HavePressed.hpp:14